function it_handles_empty_response_data(\Socket\Raw\Socket $socket, \gries\Rcon\Message $message) { $message->convertToRconData(2)->willReturn('abc1234'); $lengthData = ''; // call to find out the packet length $socket->read(4)->shouldBeCalled()->willReturn($lengthData); $this->sendMessage($message); }
function it_sends_a_packet(Socket $client, Packet $packet) { $rawPacket = pack('VV', 1, Packet::SERVERDATA_EXECCOMMAND) . '/command' . pack('HH', 0x0, 0x0); $packet->convertToRcon()->willReturn($rawPacket); $rawPacket = pack('V', mb_strlen($rawPacket)) . $rawPacket; $client->write($rawPacket)->shouldBeCalled(); $rawPacket = pack('VV', 1, Packet::SERVERDATA_RESPONSE_VALUE) . 'Command result' . pack('HH', 0x0, 0x0); $packetSize = pack('V', mb_strlen($rawPacket)); $client->read(4)->willReturn($packetSize); $client->read(mb_strlen($rawPacket))->willReturn($rawPacket); $response = $this->sendPacket($packet); $response->shouldHaveType('Minecraft\\Rcon\\Packet'); $response->getId()->shouldReturn(1); $response->getType()->shouldReturn(Packet::SERVERDATA_RESPONSE_VALUE); $response->getBody()->shouldReturn('Command result'); }
public function __destruct() { if (!$this->socket) { return; } $this->socket->close(); }
/** * Sends a packet through the connection * * @param Packet $packet * * @return Packet */ public function sendPacket(Packet $packet) { // Create a raw packet $rawPacket = $packet->convertToRcon(); // Attach size $rawPacket = pack('V', mb_strlen($rawPacket)) . $rawPacket; // Write to the socket $this->socket->write($rawPacket); // Read the packet size $packetSize = $this->socket->read(4); $packetSize = unpack('V', $packetSize); $packetSize = reset($packetSize); // TODO: multi-packet responses // Read the packet $rawPacket = $this->socket->read($packetSize); // Parse and return the packet return Packet::createFromRcon($rawPacket); }
/** * @param string $character * @param Socket $socket * * @return bool * @throws TelnetExceptionInterface */ public function interpret($character, Socket $socket) { if ($character != $this->IAC) { return false; } try { $command = $socket->read(1); $option = $socket->read(1); if (in_array($command, [$this->DO, $this->DONT])) { $socket->write($this->IAC . $this->WONT . $option); return true; } if (in_array($command, [$this->WILL, $this->WONT])) { $socket->write($this->IAC . $this->DONT . $option); return true; } } catch (Exception $e) { throw new TelnetException('failed negotiating IAC', 0, $e); } throw new UndefinedCommandException($command); }
/** * This handles a fragmented response. * (https://developer.valvesoftware.com/wiki/Source_RCON_Protocol#Multiple-packet_Responses) * * We basically send a RESPONSE_VALUE Message to the server to force the response of the rest of the package, * until we receive another package or an empty response. * * All the received data is then appended to the current ResponseMessage. * * @param $responseMessage * @throws Exception\InvalidPacketException */ protected function handleFragmentedResponse(Message $responseMessage) { do { usleep(20000); // some servers stop responding if we send to many packages so we wait 20ms $this->client->write(Message::TYPE_RESPONSE_VALUE); $responseData = $this->client->read(4096); if (empty($responseData)) { break; } $fragmentedMessage = new Message(); $fragmentedMessage->initializeFromRconData($responseData, true); $responseMessage->append($fragmentedMessage); if ($fragmentedMessage->getType() !== Message::TYPE_RESPONSE_VALUE) { break; } } while (true); }
/** * @param string $buffer * @return int * @throws Exception */ public function write($buffer) { $totalSent = 0; $length = strlen($buffer); while (true) { $sent = parent::write($buffer); $totalSent += $sent; // Check if the entire message has been sent if ($sent >= $length) { break; } // If not sent the entire message. // Get the part of the message that has not yet been sent as message $buffer = substr($buffer, $sent); // Get the length of the not sent part $length -= $sent; } return $totalSent; }
/** * @depends testServerNonBlocking */ public function testServerNonBlockingAcceptClient(Socket $server) { // create local client connected to the given server $client = $this->factory->createClient($server->getSockName()); // client connected, so we can not accept() this socket $peer = $server->accept(); // peer should be writable right away $this->assertTrue($peer->selectWrite(0.1)); $peer->write('test'); // expect to receive the message in one chunk $this->assertEquals('test', $client->read(100)); // disconnect local client $client->close(); // disconnection should be detected withing 1s max $this->assertTrue($peer->selectRead(1.0)); $peer->close(); }
/** * A wrapper to cleanly read a response from clamd * * @return string */ private function _receiveResponse() { $result = $this->socket->read(4096); $this->socket->close(); return trim($result); }
public function testScanStream() { $this->socket->expects($this->any())->method('read')->will($this->returnValue('stream: Eicar-Test-Signature FOUND')); $result = $this->quahog->scanStream('stream'); $this->assertSame(array('filename' => 'stream', 'reason' => 'Eicar-Test-Signature', 'status' => 'FOUND'), $result); }
public function shutdown() { $this->loop->removeReadStream($this->socket->getResource()); $this->socket->shutdown(); $this->socket->close(); }
public function getRemoteAddress() { $name = $this->socket->getPeerName(); return trim(substr($name, 0, strrpos($name, ':')), '[]'); }
/** * * @param Socket $socket * @depends testCreateListenRandom * @expectedException Exception */ public function testCreateListenInUseFails(Socket $socket) { $address = $socket->getSockName(); $port = substr($address, strrpos($address, ':') + 1); $this->factory->createListen($port); }
/** * Receive response * * @param Socket $socket * @param callable $onSuccess * @param callable $onFailure * * @return boolean */ protected function receiveResponse(Socket $socket, $onSuccess, $onFailure) { try { $message = $socket->recvFrom(1024, MSG_WAITALL, $remote); } catch (SocketException $exception) { return $onFailure($socket, $exception); } return $onSuccess($socket, $message, $remote); }