public function dispose() { if (!$this->hasObservers()) { parent::dispose(); $this->stream->end(); } }
public function processQueue() { if ($this->commandQueue->count() == 0) { return; } if ($this->connStatus === $this::CONNECTION_BAD) { $this->failAllCommandsWith(new \Exception("Bad connection: " . $this->lastError)); $this->stream->end(); return; } while ($this->commandQueue->count() > 0 && $this->queryState === static::STATE_READY) { /** @var CommandInterface $c */ $c = $this->commandQueue->dequeue(); $this->debug("Sending " . get_class($c)); if ($c instanceof Query) { $this->debug("Sending simple query: " . $c->getQueryString()); } $this->stream->write($c->encodedMessage()); if ($c instanceof Terminate) { $this->stream->end(); } if ($c->shouldWaitForComplete()) { $this->queryState = $this::STATE_BUSY; if ($c instanceof Query) { $this->queryType = $this::QUERY_SIMPLE; } elseif ($c instanceof Sync) { $this->queryType = $this::QUERY_EXTENDED; } $this->currentCommand = $c; return; } } }
/** * @covers React\Stream\Stream::end */ public function testEnd() { $stream = fopen('php://temp', 'r+'); $loop = $this->createLoopMock(); $conn = new Stream($stream, $loop); $conn->end(); $this->assertFalse(is_resource($stream)); }
public function onData($data, Stream $conn) { $message = msgpack_unpack($data); printf("Request method: %s\n", $message['method']); printf("Request params: %s\n", print_r($message['params'], true)); $result = $this->handler->process($message); $conn->write($result); $conn->end(); }
/** * */ public function close() { $this->stream->end(); $this->removeAllListeners(); }
public function close($code = 1000) { $frame = new Frame(pack('n', $code), true, Frame::OP_CLOSE); $this->_stream->write($frame->getContents()); $this->_stream->end(); }
public function handleSocks5(Stream $stream, $auth = null) { $reader = new StreamReader($stream); $that = $this; return $reader->readByte()->then(function ($num) use($reader) { // $num different authentication mechanisms offered return $reader->readLength($num); })->then(function ($methods) use($reader, $stream, $auth) { if ($auth === null && strpos($methods, "") !== false) { // accept "no authentication" $stream->write(pack('C2', 0x5, 0x0)); return 0x0; } else { if ($auth !== null && strpos($methods, "") !== false) { // username/password authentication (RFC 1929) sub negotiation $stream->write(pack('C2', 0x5, 0x2)); return $reader->readByteAssert(0x1)->then(function () use($reader) { return $reader->readByte(); })->then(function ($length) use($reader) { return $reader->readLength($length); })->then(function ($username) use($reader, $auth, $stream) { return $reader->readByte()->then(function ($length) use($reader) { return $reader->readLength($length); })->then(function ($password) use($username, $auth, $stream) { // username and password known => authenticate // echo 'auth: ' . $username.' : ' . $password . PHP_EOL; return $auth($username, $password)->then(function () use($stream, $username) { // accept $stream->emit('auth', array($username)); $stream->write(pack('C2', 0x1, 0x0)); }, function () use($stream) { // reject => send any code but 0x00 $stream->end(pack('C2', 0x1, 0xff)); throw new UnexpectedValueException('Unable to authenticate'); }); }); }); } else { // reject all offered authentication methods $stream->end(pack('C2', 0x5, 0xff)); throw new UnexpectedValueException('No acceptable authentication mechanism found'); } } })->then(function ($method) use($reader, $stream) { return $reader->readBinary(array('version' => 'C', 'command' => 'C', 'null' => 'C', 'type' => 'C')); })->then(function ($data) use($reader) { if ($data['version'] !== 0x5) { throw new UnexpectedValueException('Invalid SOCKS version'); } if ($data['command'] !== 0x1) { throw new UnexpectedValueException('Only CONNECT requests supported'); } // if ($data['null'] !== 0x00) { // throw new UnexpectedValueException('Reserved byte has to be NULL'); // } if ($data['type'] === 0x3) { // target hostname string return $reader->readByte()->then(function ($len) use($reader) { return $reader->readLength($len); }); } else { if ($data['type'] === 0x1) { // target IPv4 return $reader->readLength(4)->then(function ($addr) { return inet_ntop($addr); }); } else { if ($data['type'] === 0x4) { // target IPv6 return $reader->readLength(16)->then(function ($addr) { return inet_ntop($addr); }); } else { throw new UnexpectedValueException('Invalid target type'); } } } })->then(function ($host) use($reader) { return $reader->readBinary(array('port' => 'n'))->then(function ($data) use($host) { return array($host, $data['port']); }); })->then(function ($target) use($that, $stream) { return $that->connectTarget($stream, $target); }, function ($error) use($stream) { throw new UnexpectedValueException('SOCKS5 protocol error', 0, $error); })->then(function (Stream $remote) use($stream) { $stream->write(pack('C4Nn', 0x5, 0x0, 0x0, 0x1, 0, 0)); return $remote; }, function (Exception $error) use($stream) { $code = 0x1; $stream->end(pack('C4Nn', 0x5, $code, 0x0, 0x1, 0, 0)); throw $error; }); }
public function testDataWillBeEmittedInMultipleChunksWhenClientSendsExcessiveAmounts() { $client = stream_socket_client('tcp://localhost:' . $this->port); $stream = new Stream($client, $this->loop); $bytes = 1024 * 1024; $stream->end(str_repeat('*', $bytes)); $mock = $this->expectCallableOnce(); // explicitly unset server because we only accept a single connection // and then already call shutdown() $server = $this->server; $this->server = null; $received = 0; $server->on('connection', function ($conn) use($mock, &$received, $server) { // count number of bytes received $conn->on('data', function ($data) use(&$received) { $received += strlen($data); }); $conn->on('end', $mock); // do not await any further connections in order to let the loop terminate $server->shutdown(); }); $this->loop->run(); $this->assertEquals($bytes, $received); }
/** * @dataProvider loopProvider */ public function testDoesNotEmitDataIfNothingHasBeenWritten($condition, $loopFactory) { if (true !== $condition()) { return $this->markTestSkipped('Loop implementation not available'); } $loop = $loopFactory(); list($sockA, $sockB) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, 0); $streamA = new Stream($sockA, $loop); $streamB = new Stream($sockB, $loop); // end streamA without writing any data $streamA->end(); // streamB should not emit any data $streamB->on('data', $this->expectCallableNever()); $loop->run(); $streamA->close(); $streamB->close(); }