/** * {@inheritdoc} */ public function handleRequest(RequestInterface $request, callable $next, callable $first) { $method = strtoupper($request->getMethod()); // if the request not is cachable, move to $next if ($method !== 'GET' && $method !== 'HEAD') { return $next($request); } // If we can cache the request $key = $this->createCacheKey($request); $cacheItem = $this->pool->getItem($key); if ($cacheItem->isHit()) { // return cached response $data = $cacheItem->get(); $response = $data['response']; $response = $response->withBody($this->streamFactory->createStream($data['body'])); return new FulfilledPromise($response); } return $next($request)->then(function (ResponseInterface $response) use($cacheItem) { if ($this->isCacheable($response)) { $bodyStream = $response->getBody(); $body = $bodyStream->__toString(); if ($bodyStream->isSeekable()) { $bodyStream->rewind(); } else { $response = $response->withBody($this->streamFactory->createStream($body)); } $cacheItem->set(['response' => $response, 'body' => $body])->expiresAfter($this->getMaxAge($response)); $this->pool->save($cacheItem); } return $response; }); }
/** * {@inheritdoc} */ public function sendAsyncRequest(RequestInterface $request) { $reactRequest = $this->buildReactRequest($request); $deferred = new Deferred(); $reactRequest->on('error', function (\Exception $error) use($deferred, $request) { $deferred->reject(new RequestException($error->getMessage(), $request, $error)); }); $reactRequest->on('response', function (ReactResponse $reactResponse = null) use($deferred, $reactRequest, $request) { $bodyStream = $this->streamFactory->createStream(); $reactResponse->on('data', function ($data) use(&$bodyStream) { $bodyStream->write((string) $data); }); $reactResponse->on('end', function (\Exception $error = null) use($deferred, $request, $reactResponse, &$bodyStream) { $response = $this->buildResponse($reactResponse, $bodyStream); if (null !== $error) { $deferred->reject(new HttpException($error->getMessage(), $request, $response, $error)); } else { $deferred->resolve($response); } }); }); $reactRequest->end((string) $request->getBody()); $promise = new Promise($deferred->promise()); $promise->setLoop($this->loop); return $promise; }
public function createSnitcherRequest(UriInterface $uri, Message $message) { $headers = $this->createHeaders($this->userAgent); $body = $this->createBody($message); $stream = $this->streamFactory->createStream($body); $request = $this->messageFactory->createRequest("POST", $uri, $headers, $stream); return $request; }
/** * @param CacheItemInterface $cacheItem * * @return ResponseInterface */ private function createResponseFromCacheItem(CacheItemInterface $cacheItem) { $data = $cacheItem->get(); /** @var ResponseInterface $response */ $response = $data['response']; $response = $response->withBody($this->streamFactory->createStream($data['body'])); return $response; }
/** * Create new ResponseBuilder instance * * @return ResponseBuilder * * @throws \RuntimeException If creating the stream from $body fails. */ private function createResponseBuilder() { try { $body = $this->streamFactory->createStream(fopen('php://temp', 'w+')); } catch (\InvalidArgumentException $e) { throw new \RuntimeException('Can not create "php://temp" stream.'); } $response = $this->messageFactory->createResponse(200, null, [], $body); return new ResponseBuilder($response); }
/** * Build the stream. * * @return StreamInterface */ public function build() { $streams = ''; foreach ($this->data as $data) { // Add start and headers $streams .= "--{$this->getBoundary()}\r\n" . $this->getHeaders($data['headers']) . "\r\n"; // Convert the stream to string $streams .= (string) $data['contents']; $streams .= "\r\n"; } // Append end $streams .= "--{$this->getBoundary()}--\r\n"; return $this->streamFactory->createStream($streams); }
/** * Sends a PSR-7 request. * * @param RequestInterface $request * * @return ResponseInterface * * @throws \Http\Client\Exception If an error happens during processing the request. * @throws \Exception If processing the request is impossible (eg. bad configuration). */ public function sendRequest(RequestInterface $request) { $body = (string) $request->getBody(); $headers = []; foreach (array_keys($request->getHeaders()) as $headerName) { if (strtolower($headerName) === 'content-length') { $values = array(strlen($body)); } else { $values = $request->getHeader($headerName); } foreach ($values as $value) { $headers[] = $headerName . ': ' . $value; } } $streamContextOptions = array('protocol_version' => $request->getProtocolVersion(), 'method' => $request->getMethod(), 'header' => implode("\r\n", $headers), 'timeout' => $this->timeout, 'ignore_errors' => true, 'follow_location' => $this->followRedirects ? 1 : 0, 'max_redirects' => 100); if (strlen($body) > 0) { $streamContextOptions['content'] = $body; } $context = stream_context_create(array('http' => $streamContextOptions, 'https' => $streamContextOptions)); $httpHeadersOffset = 0; $finalUrl = (string) $request->getUri(); stream_context_set_params($context, array('notification' => function ($code, $severity, $msg, $msgCode, $bytesTx, $bytesMax) use(&$remoteDocument, &$http_response_header, &$httpHeadersOffset) { if ($code === STREAM_NOTIFY_REDIRECTED) { $finalUrl = $msg; $httpHeadersOffset = count($http_response_header); } })); $response = $this->messageFactory->createResponse(); if (false === ($responseBody = @file_get_contents((string) $request->getUri(), false, $context))) { if (!isset($http_response_header)) { throw new NetworkException('Unable to execute request', $request); } } else { $response = $response->withBody($this->streamFactory->createStream($responseBody)); } $parser = new HeaderParser(); try { return $parser->parseArray(array_slice($http_response_header, $httpHeadersOffset), $response); } catch (\Exception $e) { throw new RequestException($e->getMessage(), $request, $e); } }
/** * Unserialize data from binary string. * * @param string $string * * @return MessageInterface Unserialized data. * * @throws UnserializeException If $string can not be unserialized. * * @since 1.0 */ public function unserialize($string) { $parts = explode("\r\n", $string, 2); if (count($parts) !== 2) { throw new UnserializeException('Serialized data does not contain message type ID'); } $type = $parts[0]; $string = $parts[1]; switch ($type) { case self::REQUEST: list($part, $string) = explode("\r\n", $string, 2); $pattern = "/^HTTP\\/(?P<version>\\d\\.\\d) (?P<method>[A-Z]+) (?P<uri>.+)\$/"; if (preg_match($pattern, $part, $matches) === 0) { throw new UnserializeException(sprintf('Line "%s" not matches HTTP heading format', $part)); } $message = $this->messageFactory->createRequest($matches['method'], $matches['uri']); $message = $message->withProtocolVersion($matches['version']); break; case self::RESPONSE: $message = $this->messageFactory->createResponse(); break; default: throw new UnserializeException(); } /** @var MessageInterface $message */ list($part, $string) = explode("\r\n\r\n", $string, 2); $headers = explode("\r\n", $part); foreach ($headers as $header) { list($name, $value) = explode(':', $header, 2); $name = trim(urldecode($name)); $value = trim(urldecode($value)); if ($message->hasHeader($name)) { $message = $message->withAddedHeader($name, $value); } else { $message = $message->withHeader($name, $value); } } $body = $this->streamFactory->createStream($string); $message = $message->withBody($body); return $message; }