public function write($data) { if (!$this->in->isWritable()) { throw new \Exception('Stream not writable'); } $this->in->write($data); }
public function onNext($data) { if (!$this->stream->isWritable()) { throw new \Exception('Stream must be writable'); } $this->stream->write($data); }
/** * @dataProvider loopProvider */ public function testBufferReadsLargeChunks($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); $bufferSize = 4096; $streamA->bufferSize = $bufferSize; $streamB->bufferSize = $bufferSize; $testString = str_repeat("*", $streamA->bufferSize + 1); $buffer = ""; $streamB->on('data', function ($data, $streamB) use(&$buffer, &$testString) { $buffer .= $data; }); $streamA->write($testString); $loop->tick(); $loop->tick(); $loop->tick(); $streamA->close(); $streamB->close(); $this->assertEquals($testString, $buffer); }
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::write */ public function testWriteError() { $stream = "Silly developer, you can't write to to a string!"; $loop = $this->createWriteableLoopMock(); $conn = new Stream($stream, $loop); $conn->on('error', $this->expectCallableOnce()); $conn->write('Attempting to write to a string'); }
/** * @covers React\Stream\Stream::write */ public function testWrite() { $stream = fopen('php://temp', 'r+'); $loop = $this->createWriteableLoopMock(); $conn = new Stream($stream, $loop); $conn->write("foo\n"); rewind($stream); $this->assertSame("foo\n", fgets($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 probe(Stream $stream, $compression = false, $encryption = false) { $magic = Protocol::MAGIC; if ($compression) { $magic |= Protocol::FEATURE_COMPRESSION; } if ($encryption) { $magic |= Protocol::FEATURE_ENCRYPTION; } $binary = $this->binary; $stream->write($binary->writeUInt32($magic)); // list of supported protocol types (in order of preference) $types = array(Protocol::TYPE_DATASTREAM, Protocol::TYPE_LEGACY); // last item should get an END marker $last = array_pop($types); $types[] = $last | Protocol::TYPELIST_END; foreach ($types as $type) { $stream->write($binary->writeUInt32($type)); } $deferred = new Deferred(function ($resolve, $reject) use($stream) { $reject(new \RuntimeException('Cancelled')); }); $buffer = ''; $fn = function ($data) use(&$buffer, &$fn, $stream, $deferred, $binary) { $buffer .= $data; if (isset($buffer[4])) { $stream->removeListener('data', $fn); $deferred->reject(new \UnexpectedValueException('Expected 4 bytes response, received more data, is this a quassel core?', Prober::ERROR_PROTOCOL)); return; } if (isset($buffer[3])) { $stream->removeListener('data', $fn); $deferred->resolve($binary->readUInt32($buffer)); } }; $stream->on('data', $fn); $stream->on('close', function () use($deferred) { $deferred->reject(new \RuntimeException('Stream closed, does this (old?) server support probing?', Prober::ERROR_CLOSED)); }); return $deferred->promise(); }
public function __construct(LoopInterface $loop, Renderer $renderer, Stream $barStdin) { $this->loop = $loop; $this->renderer = $renderer; $lastUpdated = ''; $renderer->on('update', function ($string) use($barStdin, &$lastOutput) { if ($lastOutput != $string) { $lastOutput = $string; $barStdin->write($string . PHP_EOL); } }); }
/** * Writes data to the socket and makes sure it is logged. * * @param string $data The data to log. */ public function write($data) { $parsed = $this->api->getParser()->parse($data); if (empty($parsed)) { $this->api->getLogger()->warning('Malformed outgoing message: ' . $data); return; } $this->api->getLogger()->info('>> ' . $data); $this->stream->write($data); // Trigger a new irc.data.out event. $this->api->getEmitter()->emit('irc.data.out', [$parsed]); $this->api->getEmitter()->emit('irc.data.out.' . strtolower($parsed['command']), [$parsed]); }
/** * Continues the given flow. * * @param ReactFlow $flow * @param Packet $packet */ private function continueFlow(ReactFlow $flow, Packet $packet) { try { $response = $flow->next($packet); } catch (\Exception $e) { $this->emitError($e); return; } if ($response !== null) { if ($this->stream->getBuffer()->listening) { $this->sendingFlows[] = $flow; } else { $this->stream->write($response); $this->writtenFlow = $flow; } } elseif ($flow->isFinished()) { $this->loop->nextTick(function () use($flow) { $this->finishFlow($flow); }); } }
/** * @param $binaryData * * @return void */ public function write($binaryData) { $this->reactStream->write($binaryData); }
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; }); }
protected function handleSocks5(Stream $stream, $host, $port, $auth = null) { // protocol version 5 $data = pack('C', 0x5); if ($auth === null) { // one method, no authentication $data .= pack('C2', 0x1, 0x0); } else { // two methods, username/password and no authentication $data .= pack('C3', 0x2, 0x2, 0x0); } $stream->write($data); $that = $this; $reader = new StreamReader($stream); return $reader->readBinary(array('version' => 'C', 'method' => 'C'))->then(function ($data) use($auth, $stream, $reader) { if ($data['version'] !== 0x5) { throw new Exception('Version/Protocol mismatch'); } if ($data['method'] === 0x2 && $auth !== null) { // username/password authentication requested and provided $stream->write($auth); return $reader->readBinary(array('version' => 'C', 'status' => 'C'))->then(function ($data) { if ($data['version'] !== 0x1 || $data['status'] !== 0x0) { throw new Exception('Username/Password authentication failed'); } }); } else { if ($data['method'] !== 0x0) { // any other method than "no authentication" throw new Exception('Unacceptable authentication method requested'); } } })->then(function () use($stream, $reader, $host, $port) { // do not resolve hostname. only try to convert to (binary/packed) IP $ip = @inet_pton($host); $data = pack('C3', 0x5, 0x1, 0x0); if ($ip === false) { // not an IP, send as hostname $data .= pack('C2', 0x3, strlen($host)) . $host; } else { // send as IPv4 / IPv6 $data .= pack('C', strpos($host, ':') === false ? 0x1 : 0x4) . $ip; } $data .= pack('n', $port); $stream->write($data); return $reader->readBinary(array('version' => 'C', 'status' => 'C', 'null' => 'C', 'type' => 'C')); })->then(function ($data) use($reader) { if ($data['version'] !== 0x5 || $data['status'] !== 0x0 || $data['null'] !== 0x0) { throw new Exception('Invalid SOCKS response'); } if ($data['type'] === 0x1) { // IPv4 address => skip IP and port return $reader->readLength(6); } else { if ($data['type'] === 0x3) { // domain name => read domain name length return $reader->readBinary(array('length' => 'C'))->then(function ($data) use($that) { // skip domain name and port return $that->readLength($data['length'] + 2); }); } else { if ($data['type'] === 0x4) { // IPv6 address => skip IP and port return $reader->readLength(18); } else { throw new Exception('Invalid SOCKS reponse: Invalid address type'); } } } }); }
public function initAdapted(\GearmanJob $job) { $this->loop = Factory::create(); $this->read = new \React\Stream\Stream(STDIN, $this->loop); $this->read->bufferSize = 8192; $this->write = new \React\Stream\Stream(STDOUT, $this->loop); $this->write->bufferSize = 8192; $this->job = $job; //protect from repeated execution $initStart = false; $pmErrorDtoAlreadySent = false; /** * Receive sockets params json from PM to set it into performer */ $this->read->on('data', function ($data) use($initStart, $pmErrorDtoAlreadySent) { if (!is_array($this->pmWorkerDta)) { $this->pmWorkerDta = @json_decode($data, true); if ($this->pmWorkerDta !== false && is_array($this->pmWorkerDta)) { if ($initStart === false) { $initStart = true; try { $this->initBasicParams(); $this->adaptedService->getTerminatorPauseStander()->setPublisherPmSocketAddress($this->pmWorkerDta[DataTransferConstants::PUBLISHER_PM]); $this->adaptedService->getTerminatorPauseStander()->setUSleepTime(5000000); $performerSocketParams = new PerformerSocketsParamsDto(); $performerSocketParams->setRequestPulsarRsSocketAddress($this->pmWorkerDta[DataTransferConstants::REQUEST_PULSAR_RS]); $performerSocketParams->setPublisherPulsarSocketAddress($this->pmWorkerDta[DataTransferConstants::PUBLISHER_PULSAR]); $performerSocketParams->setPushPulsarSocketAddress($this->pmWorkerDta[DataTransferConstants::PUSH_PULSAR]); $this->adaptedService->getZmqPerformer()->setSocketsParams($performerSocketParams); $this->adaptedService->getZmqPerformer()->setLogger($this->logger); $this->adaptedService->serviceExec(); $this->adaptedService->getExecutionDto()->setExecutionMessage($this->adaptedService->getParams()); $this->job->sendComplete(serialize($this->adaptedService->getExecutionDto())); $this->jobInfoWasSent = true; $this->logger->critical("Job complete was sent."); } catch (\Exception $e) { $errorMsg = "Adapter die in Exception with \$e: " . $e->getMessage() . "|params: " . serialize($this->adaptedService->getParams()); //. $e->getTraceAsString(); $this->logger->critical($errorMsg . " | " . serialize($this->pmWorkerDta)); $this->job->sendComplete(serialize(InspectionHelper::prepareErrorExecutionDto($this->adaptedService->getTaskId(), $errorMsg))); $this->jobInfoWasSent = true; $this->logger->critical("Job complete with exception was sent."); die; } $this->loop->nextTick(function () { $this->loop->stop(); }); } } else { if ($pmErrorDtoAlreadySent === false) { $pmErrorDtoAlreadySent = true; $pmErrorArr = []; $pmErrorArr[DataTransferConstants::ERROR_LEVEL] = ErrorsConstants::CRITICAL; $pmErrorArr[DataTransferConstants::ERROR_REASON] = PmErrorConstants::WORKER_NOT_RECEIVE_CORRECT_DTO; $pmErrorArr[DataTransferConstants::ERROR_ELEMENT] = $this->pmWorkerDta; //write to PM's allotted STDIN about critical error $this->write->write(json_encode($pmErrorArr)); $this->loop->nextTick(function () { $this->loop->stop(); }); } } } }); $timerIteration = 0; $this->loop->addPeriodicTimer(3, function (Timer $timer) use(&$timerIteration) { if ($this->pmWorkerDta === null) { if ($timerIteration > $this->maxTimerIteration) { $this->initBasicParams(); die; } $timerIteration++; } else { $timer->cancel(); } }); $this->loop->run(); if ($pmErrorDtoAlreadySent) { die; } }
/** * @param string $data * @return bool|void */ public function sendData($data) { return $this->stream->write($data); }
/** * @param string $data * @return PromiseInterface */ public function send($data) { return $this->getConnection()->then(function () use($data) { $this->stream->write($data); }); }
/** * @param Stream $stream * @param $message * @return bool|void */ protected function sendToStream(Stream $stream, $message) { return $stream->write($message); }
/** * @param NetworkSerializable $msg */ public function send(NetworkSerializable $msg) { $net = $msg->getNetworkMessage(); $this->stream->write($net->getBinary()); $this->emit('send', [$net]); }
<?php use Clue\React\Buzz\Browser; use React\Stream\ReadableStreamInterface; use Psr\Http\Message\ResponseInterface; use React\Stream\Stream; use RingCentral\Psr7; $url = isset($argv[1]) ? $argv[1] : 'http://google.com/'; require __DIR__ . '/../vendor/autoload.php'; $loop = React\EventLoop\Factory::create(); $client = new Browser($loop); $out = new Stream(STDOUT, $loop); $out->pause(); $info = new Stream(STDERR, $loop); $info->pause(); $info->write('Requesting ' . $url . '…' . PHP_EOL); $client->withOptions(array('streaming' => true))->get($url)->then(function (ResponseInterface $response) use($info, $out) { $info->write('Received' . PHP_EOL . Psr7\str($response)); $response->getBody()->pipe($out); }, 'printf'); $loop->run();
} $loop = LoopFactory::create(); $factory = new Factory($loop); $client = $factory->createClient(); $out = new Stream(STDOUT, $loop); $out->pause(); $stderr = new Stream(STDERR, $loop); $stderr->pause(); // unkown exit code by default $exit = 1; $client->execCreate($container, $cmd)->then(function ($info) use($client, $out, $stderr, &$exit) { $stream = $client->execStartStream($info['Id'], false, 'stderr'); $stream->pipe($out); // forward custom stderr event to STDERR stream $stream->on('stderr', function ($data) use($stderr, $stream) { if ($stderr->write($data) === false) { $stream->pause(); $stderr->once('drain', function () use($stream) { $stream->resume(); }); } }); $stream->on('error', 'printf'); // remember exit code of executed command once it closes $stream->on('close', function () use($client, $info, &$exit) { $client->execInspect($info['Id'])->then(function ($info) use(&$exit) { $exit = $info['ExitCode']; }, 'printf'); }); }, 'printf'); $loop->run();
require __DIR__ . '/../vendor/autoload.php'; $loop = Factory::create(); if (function_exists('posix_isatty') && posix_isatty(STDIN)) { // Disable icanon (so we can fread each keypress) and echo (we'll do echoing here instead) shell_exec('stty -icanon -echo'); } // process control codes from STDIN $stdin = new Stream(STDIN, $loop); $parser = new ControlCodeParser($stdin); $stdout = new Stream(STDOUT, $loop); $stdout->pause(); // pass all c0 codes through to output $parser->on('c0', array($stdout, 'write')); // replace any color codes (SGR) with a random color $parser->on('csi', function ($code) use($stdout) { // we read any color code (SGR) on the input // assign a new random foreground and background color instead if (substr($code, -1) === 'm') { $code = "[" . mt_rand(30, 37) . ';' . mt_rand(40, 47) . "m"; } $stdout->write($code); }); // reset to default color at the end $stdin->on('close', function () use($stdout) { $stdout->write("[m"); }); // pass plain data to output $parser->pipe($stdout, array('end' => false)); // start with random color $stdin->emit('data', array("[m")); $loop->run();
/** * @dataProvider loopProvider */ public function testDoesNotWriteDataIfClientSideHasBeenClosed($condition, $loopFactory) { if (true !== $condition()) { return $this->markTestSkipped('Loop implementation not available'); } $loop = $loopFactory(); $server = stream_socket_server('tcp://localhost:0'); $client = stream_socket_client(stream_socket_get_name($server, false)); $peer = stream_socket_accept($server); $streamA = new Stream($peer, $loop); $streamB = new Stream($client, $loop); // end streamA without writing any data $streamA->pause(); $streamA->write('hello'); $streamA->on('close', $this->expectCallableOnce()); $streamB->on('data', $this->expectCallableNever()); $streamB->close(); $loop->run(); $streamA->close(); $streamB->close(); }