/** * @param ClientInterface $client * @param string $buffer * @param int $length * @param bool $isError * @return RequestHandlerInterface */ public function __invoke(Event $event, ClientInterface $client, $buffer, $length, $isError) { if ($isError) { $this->getLogger()->error(sprintf('%s encountered an error.', __METHOD__)); (new Response())->setReturnCode(500, 'Internal Server Error')->setBody('Server Error')->setHeader('Connection', 'close')->send($client); return $this; } if (($request = $this->initRequest($client, $buffer, $length)) === null) { return $this; } if (($response = $this->initResponse($client)) === null) { return $this; } if ($this->setupUpgrades($client, $request, $response)) { return $this; } $response->on(['ready'], function (Event $event) use($client, $request) { $response = $event->getData('eventEmitter'); $response->send($client); }); // FIXME: what if the request was chunked? // FIXME: what if the request does not close after response? $this->emit(new Event('request'), [$client, $request, $response]); return $this; }
/** * @param Event $event * @param ClientInterface $client * @param string $buffer * @param int $length * @param bool $isError * @return RequestHandlerInterface */ public function __invoke(Event $event, ClientInterface $client, $buffer, $length, $isError) { echo 'HTTP: Analyzing TCP request.' . PHP_EOL; if ($isError) { $response = (new Response())->setReturnCode(500, 'Internal Server Error')->setBody('Server Error')->setHeader('Connection', 'close'); $this->emit(new Event('error'), [$response, 500, LogLevel::ERROR]); $response->send($client); return $this; } if (($request = $this->initRequest($client, $buffer, $length)) === null) { return $this; } if (($response = $this->initResponse($client)) === null) { return $this; } if ($this->setupUpgrades($client, $request, $response)) { return $this; } $response->on(['ready'], function (Event $event) use($client, $request) { /** @var ResponseInterface $response */ $response = $event->getEventEmitter(); $response->send($client); }); // FIXME: what if the request was chunked? // FIXME: what if the request does not close after response? $this->emit(new Event('request'), [$client, $request, $response]); return $this; }
public function testIsStoppedWhileNotStopped() { $event = new Event('my_event_name'); $this->assertFalse($event->isStopped()); }
/** * @param ClientInterface $client * @param string $input * @param int $length * @param bool $isError * @throws RuntimeException * @return RequestHandlerInterface */ public function __invoke(Event $event, ClientInterface $client, $input, $length, $isError) { $this->buffer .= $input; $request = $this->getServiceManager()->get('Request'); $response = $this->getServiceManager()->get('Response'); $response->on(['ready'], function (Event $event) use($client, $request) { /** @var Response $response */ $response = $event->getEventEmitter(); $response->send($client); }); while (strlen($this->buffer) > 2) { $offset = 0; $tmp = ord(substr($this->buffer, $offset++, 1)); // $fin = (bool) (($tmp & 0x80) >> 7); // $rsv = (($tmp & 0x70) >> 4); // $opcode = ($tmp & 0x0F); // if ($rsv !== 0) { // throw new Exception\BadRequestException('RSV bits defined while unsupported by any extension'); // } /* * TODO: $opcode possible values: * * %x0 denotes a continuation frame * %x1 denotes a text frame * %x2 denotes a binary frame * %x3-7 are reserved for further non-control frames * %x8 denotes a connection close * %x9 denotes a ping * %xA denotes a pong * %xB-F are reserved for further control frames */ $tmp = ord(substr($this->buffer, $offset++, 1)); $maskBit = (bool) ($tmp & 0x80); $lengthMarker = $tmp & 0x7f; if ($lengthMarker == 126) { $length = $this->_parseInt($offset, 2); $offset += 2; if ($length <= 126) { throw new Exception\BadRequestException('Wrong message length.'); } } else { if ($lengthMarker == 127) { $length = $this->_parseInt($offset, 8); $offset += 8; if ($length <= 127) { throw new Exception\BadRequestException('Wrong message length.'); } } else { $length = $lengthMarker; } } $mask = []; if ($maskBit) { $mask = [ord(substr($this->buffer, $offset++, 1)) & 0xff, ord(substr($this->buffer, $offset++, 1)) & 0xff, ord(substr($this->buffer, $offset++, 1)) & 0xff, ord(substr($this->buffer, $offset++, 1)) & 0xff]; // $this->getLogger()->warning('Client data should be masked.'); } if (strlen($this->buffer) < $offset + $length) { break; } $rawPayload = substr($this->buffer, $offset, $length); $this->buffer = substr($this->buffer, $offset + $length); if ($maskBit) { $payload = ''; for ($i = 0; $i < $length; $i++) { $payload .= chr(ord($rawPayload[$i]) ^ $mask[$i % 4]); } } else { $payload = $rawPayload; } $request->enqueue($payload); } $this->emit(new Event('data'), [$client, $request, $response]); return $this; }