/** * Prepares the headers. * * @param \Ivory\HttpAdapter\Message\InternalRequestInterface $internalRequest The internal request. * @param boolean $associative TRUE if the prepared headers should be associative else FALSE. * @param boolean $contentType TRUE if the content type header should be prepared else FALSE. * @param boolean $contentLength TRUE if the content length header should be prepared else FALSE. * * @return array The prepared headers. */ protected function prepareHeaders(InternalRequestInterface &$internalRequest, $associative = true, $contentType = true, $contentLength = false) { if (!$internalRequest->hasHeader('Connection')) { $internalRequest = $internalRequest->withHeader('Connection', $this->configuration->getKeepAlive() ? 'keep-alive' : 'close'); } if (!$internalRequest->hasHeader('Content-Type')) { $rawDatas = (string) $internalRequest->getBody(); $datas = $internalRequest->getDatas(); $files = $internalRequest->getFiles(); if ($this->configuration->hasEncodingType()) { $internalRequest = $internalRequest->withHeader('Content-Type', $this->configuration->getEncodingType()); } elseif ($contentType && !empty($files)) { $internalRequest = $internalRequest->withHeader('Content-Type', ConfigurationInterface::ENCODING_TYPE_FORMDATA . '; boundary=' . $this->configuration->getBoundary()); } elseif ($contentType && (!empty($datas) || !empty($rawDatas))) { $internalRequest = $internalRequest->withHeader('Content-Type', ConfigurationInterface::ENCODING_TYPE_URLENCODED); } } if ($contentLength && !$internalRequest->hasHeader('Content-Length') && ($length = strlen($this->prepareBody($internalRequest))) > 0) { $internalRequest = $internalRequest->withHeader('Content-Length', (string) $length); } if (!$internalRequest->hasHeader('User-Agent')) { $internalRequest = $internalRequest->withHeader('User-Agent', $this->configuration->getUserAgent()); } return HeadersNormalizer::normalize($internalRequest->getHeaders(), $associative); }
/** * {@inheritdoc} */ protected function doSendInternalRequest(InternalRequestInterface $internalRequest) { $context = stream_context_create(array('http' => array('follow_location' => false, 'max_redirects' => 1, 'ignore_errors' => true, 'timeout' => $this->getConfiguration()->getTimeout(), 'protocol_version' => $internalRequest->getProtocolVersion(), 'method' => $internalRequest->getMethod(), 'header' => $this->prepareHeaders($internalRequest, false), 'content' => $this->prepareBody($internalRequest)))); list($body, $headers) = $this->process($url = (string) $internalRequest->getUrl(), $context); if ($body === false) { $error = error_get_last(); throw HttpAdapterException::cannotFetchUrl($url, $this->getName(), $error['message']); } return $this->getConfiguration()->getMessageFactory()->createResponse(StatusCodeExtractor::extract($headers), ReasonPhraseExtractor::extract($headers), ProtocolVersionExtractor::extract($headers), HeadersNormalizer::normalize($headers), BodyNormalizer::normalize($body, $internalRequest->getMethod())); }
/** * {@inheritdoc} */ protected function sendInternalRequest(InternalRequestInterface $internalRequest) { $this->browser->getClient()->setTimeout($this->getConfiguration()->getTimeout()); $this->browser->getClient()->setMaxRedirects(0); $request = $this->browser->getMessageFactory()->createRequest($internalRequest->getMethod(), $uri = (string) $internalRequest->getUri()); $request->setProtocolVersion($internalRequest->getProtocolVersion()); $request->setHeaders($this->prepareHeaders($internalRequest, false)); $data = $this->browser->getClient() instanceof AbstractCurl ? $this->prepareContent($internalRequest) : $this->prepareBody($internalRequest); $request->setContent($data); try { $response = $this->browser->send($request); } catch (\Exception $e) { throw HttpAdapterException::cannotFetchUri($uri, $this->getName(), $e->getMessage()); } return $this->getConfiguration()->getMessageFactory()->createResponse($response->getStatusCode(), (string) $response->getProtocolVersion(), HeadersNormalizer::normalize($response->getHeaders()), BodyNormalizer::normalize($response->getContent(), $internalRequest->getMethod())); }
/** * {@inheritdoc} */ protected function doSendInternalRequest(InternalRequestInterface $internalRequest) { list($protocol, $host, $port, $path) = $this->parseUrl($url = (string) $internalRequest->getUrl()); $socket = @stream_socket_client($protocol . '://' . $host . ':' . $port, $errno, $errstr, $this->getConfiguration()->getTimeout()); if ($socket === false) { throw HttpAdapterException::cannotFetchUrl($url, $this->getName(), $errstr); } stream_set_timeout($socket, $this->getConfiguration()->getTimeout()); fwrite($socket, $this->prepareRequest($internalRequest, $path, $host, $port)); list($responseHeaders, $body) = $this->parseResponse($socket); $hasTimeout = $this->detectTimeout($socket); fclose($socket); if ($hasTimeout) { throw HttpAdapterException::timeoutExceeded($url, $this->getConfiguration()->getTimeout(), $this->getName()); } return $this->getConfiguration()->getMessageFactory()->createResponse(StatusCodeExtractor::extract($responseHeaders), ReasonPhraseExtractor::extract($responseHeaders), ProtocolVersionExtractor::extract($responseHeaders), $responseHeaders = HeadersNormalizer::normalize($responseHeaders), BodyNormalizer::normalize($this->decodeBody($responseHeaders, $body), $internalRequest->getMethod())); }
/** * {@inheritdoc} */ protected function sendInternalRequest(InternalRequestInterface $internalRequest) { $uri = $internalRequest->getUri(); $socket = @stream_socket_client(($uri->getScheme() === 'https' ? 'ssl' : 'tcp') . '://' . $uri->getHost() . ':' . ($uri->getPort() ?: 80), $errno, $errstr, $this->getConfiguration()->getTimeout()); if ($socket === false) { throw HttpAdapterException::cannotFetchUri($uri, $this->getName(), $errstr); } stream_set_timeout($socket, $this->getConfiguration()->getTimeout()); fwrite($socket, $this->prepareRequest($internalRequest)); list($responseHeaders, $body) = $this->parseResponse($socket); $hasTimeout = $this->detectTimeout($socket); fclose($socket); if ($hasTimeout) { throw HttpAdapterException::timeoutExceeded($uri, $this->getConfiguration()->getTimeout(), $this->getName()); } return $this->getConfiguration()->getMessageFactory()->createResponse(StatusCodeExtractor::extract($responseHeaders), ProtocolVersionExtractor::extract($responseHeaders), $responseHeaders = HeadersNormalizer::normalize($responseHeaders), BodyNormalizer::normalize($this->decodeBody($responseHeaders, $body), $internalRequest->getMethod())); }
/** * Parses the headers. * * @param array|string $headers The headers. * * @return array The parsed headers. */ public static function parse($headers) { if (is_string($headers)) { $headers = explode("\r\n\r\n", trim($headers)); return explode("\r\n", end($headers)); } $parsedHeaders = array(); foreach ($headers as $name => $value) { $value = HeadersNormalizer::normalizeHeaderValue($value); if (is_int($name)) { if (strpos($value, 'HTTP/') === 0) { $parsedHeaders = array($value); } else { $parsedHeaders[] = $value; } } else { $parsedHeaders[] = $name . ': ' . $value; } } return $parsedHeaders; }
/** * Creates a response. * * @param resource $curl The curl resource. * @param string|boolean|null $data The data. * @param \Ivory\HttpAdapter\Message\InternalRequestInterface $internalRequest The internal request. * * @throws \Ivory\HttpAdapter\HttpAdapterException If an error occurred. * * @return \Ivory\HttpAdapter\Message\ResponseInterface The response. */ private function createResponse($curl, $data, InternalRequestInterface $internalRequest) { if (empty($data)) { throw HttpAdapterException::cannotFetchUri((string) $internalRequest->getUri(), $this->getName(), curl_error($curl)); } $headers = substr($data, 0, $headersSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE)); return $this->getConfiguration()->getMessageFactory()->createResponse(StatusCodeExtractor::extract($headers), ProtocolVersionExtractor::extract($headers), HeadersNormalizer::normalize($headers), BodyNormalizer::normalize(substr($data, $headersSize), $internalRequest->getMethod())); }
/** * {@inheritdoc} */ public function createResponse($statusCode = 200, $protocolVersion = RequestInterface::PROTOCOL_VERSION_1_1, array $headers = array(), $body = null, array $parameters = array()) { return (new Response($this->createStream($body), $statusCode, HeadersNormalizer::normalize($headers), $parameters))->withProtocolVersion($protocolVersion); }