Ejemplo n.º 1
0
 /**
  * {@inheritdoc}
  */
 public function writeRequest(Socket $socket, Request $request, float $timeout = 0) : \Generator
 {
     $written = (yield from $socket->write($this->encoder->encodeRequest($request)));
     $stream = $request->getBody();
     if ($stream->isReadable()) {
         $written += (yield from Stream\pipe($stream, $socket, false, 0, null, $timeout));
     }
     return $written;
 }
Ejemplo n.º 2
0
 /**
  * @coroutine
  *
  * @param \Icicle\Http\Message\Message $message
  * @param float|int $timeout
  *
  * @return \Generator
  *
  * @resolve \Icicle\Http\Message\Message
  *
  * @throws \Icicle\Http\Exception\MessageException
  */
 private function buildIncomingStream(Message $message, float $timeout = 0) : \Generator
 {
     $body = $message->getBody();
     if ($body instanceof SeekableStream && $body->isOpen()) {
         yield from $body->seek(0);
     }
     if (!$body->isReadable()) {
         return $message;
     }
     if (strtolower($message->getHeader('Transfer-Encoding') === 'chunked')) {
         $stream = new ChunkedDecoder($this->hwm);
         $coroutine = new Coroutine(Stream\pipe($body, $stream, true, 0, null, $timeout));
         $coroutine->done(null, [$stream, 'close']);
         $message = $message->withBody($stream);
     } elseif ($message->hasHeader('Content-Length')) {
         $length = (int) $message->getHeader('Content-Length');
         if (0 > $length) {
             throw new MessageException(Response::BAD_REQUEST, 'Content-Length header invalid.');
         }
         $stream = new MemoryStream($this->hwm);
         if (0 === $length) {
             yield from $stream->end();
         } else {
             $coroutine = new Coroutine(Stream\pipe($body, $stream, true, $length, null, $timeout));
             $coroutine->done(null, [$stream, 'close']);
         }
         $message = $message->withBody($stream);
     } elseif ($message instanceof Request) {
         switch ($message->getMethod()) {
             case 'POST':
             case 'PUT':
                 // Post and put messages must have content length or be transfer encoded.
                 throw new MessageException(Response::LENGTH_REQUIRED, 'Content-Length header required.');
             default:
                 // Assume 0 length body.
                 $stream = new MemoryStream();
                 yield from $stream->end();
                 // Creates empty request body.
                 return $message->withBody($stream);
         }
     } elseif (strtolower($message->getHeader('Connection')) !== 'close') {
         throw new MessageException(Response::LENGTH_REQUIRED, 'Content-Length header required.');
     }
     $contentEncoding = strtolower($message->getHeader('Content-Encoding'));
     switch ($contentEncoding) {
         case 'deflate':
             $stream = new ZlibDecoder(ZlibDecoder::DEFLATE, $this->hwm);
             break;
         case 'gzip':
             $stream = new ZlibDecoder(ZlibDecoder::GZIP, $this->hwm);
             break;
         case '':
             // No content encoding.
             return $message;
         default:
             throw new MessageException(Response::BAD_REQUEST, sprintf('Unsupported content encoding received: %s', $contentEncoding));
     }
     $coroutine = new Coroutine(Stream\pipe($message->getBody(), $stream, true, 0, null, $timeout));
     $coroutine->done(null, [$stream, 'close']);
     return $message->withBody($stream);
 }