/** * Retrieves the HTTP protocol version as a string. * * The string MUST contain only the HTTP version number (e.g., "1.1", "1.0"). * * @return string HTTP protocol version. */ public function getProtocolVersion() { if ($this->overRidingProtocol !== null) { return $this->overRidingProtocol; } return $this->request->getProtocolVersion(); }
/** * {@inheritdoc} */ public function formatRequest(RequestInterface $request) { $command = sprintf('curl %s', escapeshellarg((string) $request->getUri()->withFragment(''))); if ($request->getProtocolVersion() === '1.0') { $command .= ' --http1.0'; } elseif ($request->getProtocolVersion() === '2.0') { $command .= ' --http2'; } $method = strtoupper($request->getMethod()); if ('HEAD' === $method) { $command .= ' --head'; } elseif ('GET' !== $method) { $command .= ' --request ' . $method; } $command .= $this->getHeadersAsCommandOptions($request); $body = $request->getBody(); if ($body->getSize() > 0) { if (!$body->isSeekable()) { return 'Cant format Request as cUrl command if body stream is not seekable.'; } $command .= sprintf(' --data %s', escapeshellarg($body->__toString())); $body->rewind(); } return $command; }
private function addExpectHeader(RequestInterface $request, array $options, array &$modify) { // Determine if the Expect header should be used if ($request->hasHeader('Expect')) { return; } $expect = isset($options['expect']) ? $options['expect'] : null; // Return if disabled or if you're not using HTTP/1.1 or HTTP/2.0 if ($expect === false || $request->getProtocolVersion() < 1.1) { return; } // The expect header is unconditionally enabled if ($expect === true) { $modify['set_headers']['Expect'] = '100-Continue'; return; } // By default, send the expect header when the payload is > 1mb if ($expect === null) { $expect = 1048576; } // Always add if the body cannot be rewound, the size cannot be // determined, or the size is greater than the cutoff threshold $body = $request->getBody(); $size = $body->getSize(); if ($size === null || $size >= (int) $expect || !$body->isSeekable()) { $modify['set_headers']['Expect'] = '100-Continue'; } }
/** * {@inheritdoc} */ public function formatRequest(RequestInterface $request) { $message = sprintf("%s %s HTTP/%s\n", $request->getMethod(), $request->getRequestTarget(), $request->getProtocolVersion()); foreach ($request->getHeaders() as $name => $values) { $message .= $name . ': ' . implode(', ', $values) . "\n"; } return $this->addBody($request, $message); }
/** * Converts a PSR request into a Guzzle request. * * @param RequestInterface $request * * @return GuzzleRequest */ private function createRequest(RequestInterface $request) { $options = ['exceptions' => false, 'allow_redirects' => false]; $options['version'] = $request->getProtocolVersion(); $options['headers'] = $request->getHeaders(); $options['body'] = (string) $request->getBody(); return $this->client->createRequest($request->getMethod(), (string) $request->getUri(), $options); }
/** * @return HttpRequest mixed */ protected function setupRequest() { $headers = []; foreach ($this->request->getHeaders() as $key => $values) { $headers[$key] = implode(';', $values); } return $this->httpClient->request($this->request->getMethod(), (string) $this->request->getUri(), $headers, $this->request->getProtocolVersion()); }
/** * Produce the header of request as a string based on a PSR Request * * @param RequestInterface $request * * @return string */ protected function transformRequestHeadersToString(RequestInterface $request) { $message = vsprintf('%s %s HTTP/%s', [strtoupper($request->getMethod()), $request->getRequestTarget(), $request->getProtocolVersion()]) . "\r\n"; foreach ($request->getHeaders() as $name => $values) { $message .= $name . ': ' . implode(', ', $values) . "\r\n"; } $message .= "\r\n"; return $message; }
public static function request(RequestInterface $request) { $method = $request->getMethod(); $url = $request->getUri(); $body = $request->getBody()->getContents(); $headers = $request->getHeaders(); $protocolVersion = $request->getProtocolVersion(); return new HttpObservable($method, $url, $body, $headers, $protocolVersion); }
/** * Converts a PSR request into a BuzzRequest request. * * @param RequestInterface $request * * @return BuzzRequest */ private function createRequest(RequestInterface $request) { $buzzRequest = new BuzzRequest(); $buzzRequest->setMethod($request->getMethod()); $buzzRequest->fromUrl($request->getUri()->__toString()); $buzzRequest->setProtocolVersion($request->getProtocolVersion()); $buzzRequest->setContent((string) $request->getBody()); $this->addPsrHeadersToBuzzRequest($request, $buzzRequest); return $buzzRequest; }
/** * Assigns options specific to handling HTTP requests. * NOTE: THIS METHOD SHOULD BE CALLED ONLY FROM prepareCUrl()! * * @throws UnsupportedFeatureException Thrown if POST method was requested. */ private function prepareHttpCUrl() { if ($this->fetchRequest->getMethod() !== 'GET') { throw new UnsupportedFeatureException('Request other than GET are not supported'); } $headers = []; foreach ($this->fetchRequest->getHeaders() as $name => $values) { $headers[] = $name . ": " . implode(", ", $values); } curl_setopt_array($this->cUrl, [CURLOPT_AUTOREFERER => 1, CURLOPT_FOLLOWLOCATION => 1, CURLOPT_FAILONERROR => 1, CURLOPT_HTTP_VERSION => $this->fetchRequest->getProtocolVersion() === '1.0' ? CURL_HTTP_VERSION_1_0 : CURL_HTTP_VERSION_1_1, CURLOPT_USERAGENT => $this->fetchRequest->getHeader('User-Agent') ?: $this->getDefaultUserAgent(), CURLOPT_HTTPHEADER => $headers]); }
protected function getFileName(RequestInterface $request) { $result = trim($request->getMethod() . ' ' . $request->getRequestTarget()) . ' HTTP/' . $request->getProtocolVersion(); foreach ($request->getHeaders() as $name => $values) { if (array_key_exists(strtoupper($name), $this->ignored_headers)) { continue; } $result .= "\r\n{$name}: " . implode(', ', $values); } $request = $result . "\r\n\r\n" . $request->getBody(); return md5((string) $request) . ".txt"; }
/** * Serialize a request message to a string. * * @param RequestInterface $request * @return string */ public static function toString(RequestInterface $request) { $headers = self::serializeHeaders($request->getHeaders()); $body = (string) $request->getBody(); $format = '%s %s HTTP/%s%s%s'; if (!empty($headers)) { $headers = "\r\n" . $headers; } if (!empty($body)) { $headers .= "\r\n\r\n"; } return sprintf($format, $request->getMethod(), $request->getRequestTarget(), $request->getProtocolVersion(), $headers, $body); }
/** * Given an array of the headers this method will run through all verification methods * @param RequestInterface $request * @return bool TRUE if all headers are valid, FALSE if 1 or more were invalid */ public function verifyAll(RequestInterface $request) { $passes = 0; $passes += (int) $this->verifyMethod($request->getMethod()); $passes += (int) $this->verifyHTTPVersion($request->getProtocolVersion()); $passes += (int) $this->verifyRequestURI($request->getUri()->getPath()); $passes += (int) $this->verifyHost($request->getHeader('Host')); $passes += (int) $this->verifyUpgradeRequest($request->getHeader('Upgrade')); $passes += (int) $this->verifyConnection($request->getHeader('Connection')); $passes += (int) $this->verifyKey($request->getHeader('Sec-WebSocket-Key')); $passes += (int) $this->verifyVersion($request->getHeader('Sec-WebSocket-Version')); return 8 === $passes; }
/** * @return Request */ protected function convertRequest(RequestInterface $request, array $options) { $artaxRequest = new Request(); $artaxRequest->setProtocol($request->getProtocolVersion()); $artaxRequest->setMethod($request->getMethod()); $artaxRequest->setUri((string) $request->getUri()); $artaxRequest->setAllHeaders($request->getHeaders()); $body = $request->getBody(); if ($body->getSize() === null || $body->getSize() > 0) { $body->rewind(); $artaxRequest->setBody(new PsrStreamIterator($body)); } return $artaxRequest; }
/** * Serialize a request message to a string. * * @param RequestInterface $request * @return string */ public static function toString(RequestInterface $request) { $httpMethod = $request->getMethod(); if (empty($httpMethod)) { throw new UnexpectedValueException('Object can not be serialized because HTTP method is empty'); } $headers = self::serializeHeaders($request->getHeaders()); $body = (string) $request->getBody(); $format = '%s %s HTTP/%s%s%s'; if (!empty($headers)) { $headers = "\r\n" . $headers; } if (!empty($body)) { $headers .= "\r\n\r\n"; } return sprintf($format, $httpMethod, $request->getRequestTarget(), $request->getProtocolVersion(), $headers, $body); }
/** * {@inheritdoc} */ public function handshake(RequestInterface $request) { if (true !== $this->verifier->verifyMethod($request->getMethod())) { return new Response(405); } if (true !== $this->verifier->verifyHTTPVersion($request->getProtocolVersion())) { return new Response(505); } if (true !== $this->verifier->verifyRequestURI($request->getUri()->getPath())) { return new Response(400); } if (true !== $this->verifier->verifyHost($request->getHeader('Host'))) { return new Response(400); } if (true !== $this->verifier->verifyUpgradeRequest($request->getHeader('Upgrade'))) { return new Response(400, [], '1.1', null, 'Upgrade header MUST be provided'); } if (true !== $this->verifier->verifyConnection($request->getHeader('Connection'))) { return new Response(400, [], '1.1', null, 'Connection header MUST be provided'); } if (true !== $this->verifier->verifyKey($request->getHeader('Sec-WebSocket-Key'))) { return new Response(400, [], '1.1', null, 'Invalid Sec-WebSocket-Key'); } if (true !== $this->verifier->verifyVersion($request->getHeader('Sec-WebSocket-Version'))) { return new Response(426, ['Sec-WebSocket-Version' => $this->getVersionNumber()]); } $headers = []; $subProtocols = $request->getHeader('Sec-WebSocket-Protocol'); if (count($subProtocols) > 0 || count($this->_supportedSubProtocols) > 0 && $this->_strictSubProtocols) { $subProtocols = array_map('trim', explode(',', implode(',', $subProtocols))); $match = array_reduce($subProtocols, function ($accumulator, $protocol) { return $accumulator ?: (isset($this->_supportedSubProtocols[$protocol]) ? $protocol : null); }, null); if ($this->_strictSubProtocols && null === $match) { return new Response(400, [], '1.1', null, 'No Sec-WebSocket-Protocols requested supported'); } if (null !== $match) { $headers['Sec-WebSocket-Protocol'] = $match; } } return new Response(101, array_merge($headers, ['Upgrade' => 'websocket', 'Connection' => 'Upgrade', 'Sec-WebSocket-Accept' => $this->sign((string) $request->getHeader('Sec-WebSocket-Key')[0]), 'X-Powered-By' => 'RxPHPWebsocket'])); }
/** * Prepare options * * @param RequestInterface $request */ protected function prepareOptions(RequestInterface $request) { $this->options[CURLOPT_URL] = (string) $request->getUri(); $this->options[CURLOPT_HTTP_VERSION] = $request->getProtocolVersion(); // Set request method if (strtoupper($request->getMethod()) === 'GET') { $this->options[CURLOPT_HTTPGET] = true; } elseif (strtoupper($request->getMethod()) === 'HEAD') { $this->options[CURLOPT_NOBODY] = true; } else { $this->options[CURLOPT_CUSTOMREQUEST] = $request->getMethod(); } // Prepare and set request headers foreach ($request->getHeaders() as $name => $values) { foreach ($values as $value) { $this->options[CURLOPT_HTTPHEADER][] = sprintf('%s: %s', $name, $value); } } curl_setopt_array($this->handle, $this->options); }
/** * {@inheritdoc} */ public function sendRequest(RequestInterface $request) { $cakeRequest = new Request(); $cakeRequest->method($request->getMethod()); $cakeRequest->url((string) $request->getUri()); $cakeRequest->version($request->getProtocolVersion()); $cakeRequest->body($request->getBody()->getContents()); foreach ($request->getHeaders() as $header => $values) { $cakeRequest->header($header, $request->getHeaderLine($header)); } if (null === $cakeRequest->header('Content-Type')) { $cakeRequest->header('Content-Type', 'application/x-www-form-urlencoded'); } try { $cakeResponse = $this->client->send($cakeRequest, $this->client->config()); } catch (Exception $exception) { throw new NetworkException('Failed to send request', $request, $exception); } return $this->responseFactory->createResponse($cakeResponse->statusCode(), null, $cakeResponse->headers(), $cakeResponse->body(), $cakeResponse->version()); }
/** * Get context fields to add to the time-line entry. * * @param \Psr\Http\Message\RequestInterface $request * @param \Psr\Http\Message\ResponseInterface $response * * @return array */ protected function getParameters(RequestInterface $request, ResponseInterface $response = null) { $params = []; $result = ''; $keys = array_intersect($this->context, $this->availableParameters); foreach ($keys as $key) { switch ($key) { case 'method': $result = $request->getMethod(); break; case 'url': $result = $request->getUri()->__toString(); break; case 'request_version': $result = $request->getProtocolVersion(); break; case 'response_version': $result = $response ? $response->getProtocolVersion() : 'NULL'; break; case 'host': $result = $request->getUri()->getHost(); break; case 'hostname': $result = gethostname(); break; case 'status_code': $result = $response ? $response->getStatusCode() : 'NULL'; break; case 'phrase': $result = $response ? $response->getReasonPhrase() : 'NULL'; break; } $params[$key] = (string) $result ?: ''; } return $params; }
private function getDefaultContext(RequestInterface $request) { $headers = ''; foreach ($request->getHeaders() as $name => $value) { foreach ($value as $val) { $headers .= "{$name}: {$val}\r\n"; } } $context = ['http' => ['method' => $request->getMethod(), 'header' => $headers, 'protocol_version' => $request->getProtocolVersion(), 'ignore_errors' => true, 'follow_location' => 0]]; $body = (string) $request->getBody(); if (!empty($body)) { $context['http']['content'] = $body; // Prevent the HTTP handler from adding a Content-Type header. if (!$request->hasHeader('Content-Type')) { $context['http']['header'] .= "Content-Type:\r\n"; } } $context['http']['header'] = rtrim($context['http']['header']); return $context; }
/** * Clone and modify a request with the given changes. * * The changes can be one of: * - method: (string) Changes the HTTP method. * - set_headers: (array) Sets the given headers. * - remove_headers: (array) Remove the given headers. * - body: (mixed) Sets the given body. * - uri: (UriInterface) Set the URI. * - query: (string) Set the query string value of the URI. * - version: (string) Set the protocol version. * * @param RequestInterface $request Request to clone and modify. * @param array $changes Changes to apply. * * @return RequestInterface */ function modify_request(RequestInterface $request, array $changes) { if (!$changes) { return $request; } $headers = $request->getHeaders(); if (!isset($changes['uri'])) { $uri = $request->getUri(); } else { // Remove the host header if one is on the URI if ($host = $changes['uri']->getHost()) { $changes['set_headers']['Host'] = $host; if ($port = $changes['uri']->getPort()) { $standardPorts = ['http' => 80, 'https' => 443]; $scheme = $changes['uri']->getScheme(); if (isset($standardPorts[$scheme]) && $port != $standardPorts[$scheme]) { $changes['set_headers']['Host'] .= ':' . $port; } } } $uri = $changes['uri']; } if (!empty($changes['remove_headers'])) { $headers = _caseless_remove($changes['remove_headers'], $headers); } if (!empty($changes['set_headers'])) { $headers = _caseless_remove(array_keys($changes['set_headers']), $headers); $headers = $changes['set_headers'] + $headers; } if (isset($changes['query'])) { $uri = $uri->withQuery($changes['query']); } if ($request instanceof ServerRequestInterface) { return new ServerRequest(isset($changes['method']) ? $changes['method'] : $request->getMethod(), $uri, $headers, isset($changes['body']) ? $changes['body'] : $request->getBody(), isset($changes['version']) ? $changes['version'] : $request->getProtocolVersion(), $request->getServerParams()); } return new Request(isset($changes['method']) ? $changes['method'] : $request->getMethod(), $uri, $headers, isset($changes['body']) ? $changes['body'] : $request->getBody(), isset($changes['version']) ? $changes['version'] : $request->getProtocolVersion()); }
/** * Send a request to the server and return a Response object with the response. * * @param RequestInterface $request The request object to store request params. * * @return ResponseInterface * * @since 2.1 */ protected function doRequest(RequestInterface $request) { // Setup the cURL handle. $ch = curl_init(); // Set the request method. $options[CURLOPT_CUSTOMREQUEST] = $request->getMethod(); // Don't wait for body when $method is HEAD $options[CURLOPT_NOBODY] = $request->getMethod() === 'HEAD'; // Initialize the certificate store $options[CURLOPT_CAINFO] = $this->getOption('certpath', __DIR__ . '/cacert.pem'); // Set HTTP Version switch ($request->getProtocolVersion()) { case '1.0': $options[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_0; break; case '1.1': $options[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_1; break; case '2.0': if (defined('CURL_HTTP_VERSION_2_0')) { $options[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_2_0; } } // If data exists let's encode it and make sure our Content-type header is set. $data = (string) $request->getBody(); if (isset($data)) { // If the data is a scalar value simply add it to the cURL post fields. if (is_scalar($data) || strpos($request->getHeaderLine('Content-Type'), 'multipart/form-data') === 0) { $options[CURLOPT_POSTFIELDS] = $data; } else { $options[CURLOPT_POSTFIELDS] = http_build_query($data); } if (!$request->getHeaderLine('Content-Type')) { $request = $request->withHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'); } // Add the relevant headers. if (is_scalar($options[CURLOPT_POSTFIELDS])) { $request = $request->withHeader('Content-Length', strlen($options[CURLOPT_POSTFIELDS])); } } // Build the headers string for the request. if ($headers = $request->getHeaders()) { // Add the headers string into the stream context options array. $options[CURLOPT_HTTPHEADER] = HeaderHelper::toHeaderLine($headers); } // If an explicit timeout is given user it. if ($timeout = $this->getOption('timeout')) { $options[CURLOPT_TIMEOUT] = (int) $timeout; $options[CURLOPT_CONNECTTIMEOUT] = (int) $timeout; } // If an explicit user agent is given use it. if ($userAgent = $this->getOption('userAgent')) { $options[CURLOPT_USERAGENT] = $userAgent; } // Set the request URL. $options[CURLOPT_URL] = (string) $request->getRequestTarget(); // We want our headers. :-) $options[CURLOPT_HEADER] = true; // Return it... echoing it would be tacky. $options[CURLOPT_RETURNTRANSFER] = true; // Override the Expect header to prevent cURL from confusing itself in its own stupidity. // Link: http://the-stickman.com/web-development/php-and-curl-disabling-100-continue-header/ $options[CURLOPT_HTTPHEADER][] = 'Expect:'; /* * Follow redirects if server config allows * @deprecated safe_mode is removed in PHP 5.4, check will be dropped when PHP 5.3 support is dropped */ if (!ini_get('safe_mode') && !ini_get('open_basedir')) { $options[CURLOPT_FOLLOWLOCATION] = (bool) isset($this->options['follow_location']) ? $this->options['follow_location'] : true; } // Set any custom transport options if ($this->getOption('options')) { foreach ((array) $this->getOption('options') as $key => $value) { $options[$key] = $value; } } // Set the cURL options. curl_setopt_array($ch, $options); // Execute the request and close the connection. $content = curl_exec($ch); if (!$this->getOption('allow_empty_result', false) && !trim($content)) { $message = curl_error($ch); // Error but nothing from cURL? Create our own $message = $message ?: 'No HTTP response received'; throw new \RuntimeException($message); } // Get the request information. $info = curl_getinfo($ch); // Close the connection. curl_close($ch); return $this->getResponse($content, $info); }
private function createRequest(RequestInterface $request) { return $this->client->createRequest($request->getMethod(), (string) $request->getUri(), ['exceptions' => false, 'allow_redirects' => false, 'version' => $request->getProtocolVersion(), 'headers' => $request->getHeaders(), 'body' => (string) $request->getBody()]); }
/** * Generates cURL options * * @param RequestInterface $request * * @throws UnexpectedValueException if unsupported HTTP version requested * * @return array */ private function createCurlOptions(RequestInterface $request) { $options = array_key_exists('curl_options', $this->options) ? $this->options['curl_options'] : []; $options[CURLOPT_HEADER] = true; $options[CURLOPT_RETURNTRANSFER] = true; $options[CURLOPT_HTTP_VERSION] = $this->getProtocolVersion($request->getProtocolVersion()); $options[CURLOPT_URL] = (string) $request->getUri(); $options[CURLOPT_CONNECTTIMEOUT] = $this->options['connection_timeout']; $options[CURLOPT_FOLLOWLOCATION] = $this->options['follow_redirects']; $options[CURLOPT_MAXREDIRS] = $this->options['max_redirects']; $options[CURLOPT_SSL_VERIFYPEER] = $this->options['ssl_verify_peer']; $options[CURLOPT_TIMEOUT] = $this->options['timeout']; if ($this->options['decode_content'] && $request->hasHeader('accept-encoding')) { $options[CURLOPT_ENCODING] = $request->getHeaderLine('accept-encoding'); } if ($this->options['use_cookies'] && $request->hasHeader('cookie')) { $options[CURLOPT_COOKIE] = implode('; ', $request->getHeader('cookie')); } switch ($request->getMethod()) { case 'GET': $options[CURLOPT_HTTPGET] = true; break; case 'HEAD': $options[CURLOPT_NOBODY] = true; break; case 'POST': case 'CONNECT': case 'DELETE': case 'PATCH': case 'PUT': case 'TRACE': $options[CURLOPT_CUSTOMREQUEST] = $request->getMethod(); break; } $headers = array_keys($request->getHeaders()); foreach ($headers as $name) { $values = $request->getHeader($name); foreach ($values as $value) { $options[CURLOPT_HTTPHEADER][] = $name . ': ' . $value; } } if ($request->getUri()->getUserInfo()) { $options[CURLOPT_USERPWD] = $request->getUri()->getUserInfo(); } return $options; }
/** * Clone and modify a request with the given changes. * * The changes can be one of: * - method: (string) Changes the HTTP method. * - set_headers: (array) Sets the given headers. * - remove_headers: (array) Remove the given headers. * - body: (mixed) Sets the given body. * - uri: (UriInterface) Set the URI. * - query: (string) Set the query string value of the URI. * - version: (string) Set the protocol version. * * @param RequestInterface $request Request to clone and modify. * @param array $changes Changes to apply. * * @return RequestInterface */ function modify_request(RequestInterface $request, array $changes) { if (!$changes) { return $request; } $headers = $request->getHeaders(); if (!isset($changes['uri'])) { $uri = $request->getUri(); } else { // Remove the host header if one is on the URI if ($host = $changes['uri']->getHost()) { $changes['set_headers']['Host'] = $host; } $uri = $changes['uri']; } if (!empty($changes['remove_headers'])) { $headers = _caseless_remove($changes['remove_headers'], $headers); } if (!empty($changes['set_headers'])) { $headers = _caseless_remove(array_keys($changes['set_headers']), $headers); $headers = $changes['set_headers'] + $headers; } if (isset($changes['query'])) { $uri = $uri->withQuery($changes['query']); } return new Request(isset($changes['method']) ? $changes['method'] : $request->getMethod(), $uri, $headers, isset($changes['body']) ? $changes['body'] : $request->getBody(), isset($changes['version']) ? $changes['version'] : $request->getProtocolVersion()); }
/** * Send a request to the server and return a Response object with the response. * * @param RequestInterface $request The request object to store request params. * * @return ResponseInterface * * @since 2.1 */ protected function doRequest(RequestInterface $request) { // Create the stream context options array with the required method offset. $options = array('method' => $request->getMethod()); // Set HTTP Version $options['protocol_version'] = $request->getProtocolVersion(); // If data exists let's encode it and make sure our Content-Type header is set. $data = (string) $request->getBody(); if (isset($data)) { // If the data is a scalar value simply add it to the stream context options. if (is_scalar($data)) { $options['content'] = $data; } else { $options['content'] = http_build_query($data); } if (!$request->getHeader('Content-Type')) { $request = $request->withHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'); } // Add the relevant headers. $request = $request->withHeader('Content-Length', strlen($options['content'])); } // Speed up stream get URL // @see http://stackoverflow.com/questions/3629504/php-file-get-contents-very-slow-when-using-full-url // @see http://stackoverflow.com/questions/13679976/how-to-speed-up-file-get-contents $request = $request->withHeader('Connection', 'Close'); // Build the headers string for the request. if ($headers = $request->getHeaders()) { // Add the headers string into the stream context options array. $options['header'] = HeaderHelper::toHeaderLine($headers, true); } // If an explicit timeout is given user it. if ($this->getOption('timeout')) { $options['timeout'] = (int) $this->getOption('timeout'); } // If an explicit user agent is given use it. if ($this->getOption('userAgent')) { $options['user_agent'] = $this->getOption('userAgent'); } // Ignore HTTP errors so that we can capture them. $options['ignore_errors'] = 1; // Follow redirects. $options['follow_location'] = (int) $this->getOption('follow_location', 1); foreach ((array) $this->getOption('options') as $key => $value) { $options[$key] = $value; } // Create the stream context for the request. $context = stream_context_create(array('http' => $options)); // Capture PHP errors $php_errormsg = ''; $track_errors = ini_get('track_errors'); ini_set('track_errors', true); $connection = @fopen($request->getRequestTarget(), Stream::MODE_READ_ONLY_FROM_BEGIN, false, $context); if (!$connection) { if (!$php_errormsg) { // Error but nothing from php? Create our own $php_errormsg = sprintf('Could not connect to resource: %s', $request->getRequestTarget()); } // Restore error tracking to give control to the exception handler ini_set('track_errors', $track_errors); throw new \RuntimeException($php_errormsg); } $stream = new Stream($connection); if ($dest = $this->getOption('target_file')) { $content = ''; StreamHelper::copyTo($stream, $dest); } else { $content = $stream->getContents(); } $metadata = $stream->getMetadata(); $stream->close(); if (isset($metadata['wrapper_data']['headers'])) { $headers = $metadata['wrapper_data']['headers']; } elseif (isset($metadata['wrapper_data'])) { $headers = $metadata['wrapper_data']; } else { $headers = array(); } return $this->getResponse($headers, $content); }
/** * 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); } }
/** * @return string */ public function getProtocolVersion() { return $this->request->getProtocolVersion(); }
public function translate(RequestInterface $request) : Request { list($major, $minor) = explode('.', $request->getProtocolVersion()); return new Request(Url::fromString((string) $request->getUri()), new Method(strtoupper($request->getMethod())), new ProtocolVersion((int) $major, (int) $minor), $this->translateHeaders($request->getHeaders()), new StringStream((string) $request->getBody())); }
private function createRequestOptions(RequestInterface $request) { // DEFAULT $options = $this->options; $options[CURLOPT_HEADER] = true; $options[CURLOPT_RETURNTRANSFER] = true; $options[CURLOPT_FOLLOWLOCATION] = true; $options[CURLOPT_HTTP_VERSION] = $this->getProtocolVersion($request->getProtocolVersion()); $options[CURLOPT_URL] = (string) $request->getUri(); // METHOD SPECIFIC if (in_array($request->getMethod(), ['OPTIONS', 'POST', 'PUT'], true)) { // cURL allows request body only for these methods. $body = (string) $request->getBody(); if ('' !== $body) { $options[CURLOPT_POSTFIELDS] = $body; } } if ($request->getMethod() === 'HEAD') { $options[CURLOPT_NOBODY] = true; } elseif ($request->getMethod() !== 'GET') { // GET is a default method. Other methods should be specified explicitly. $options[CURLOPT_CUSTOMREQUEST] = $request->getMethod(); } // HEADERS $options[CURLOPT_HTTPHEADER] = $this->createHeaders($request); // USER AGENT if ($request->hasHeader('User-Agent')) { $options[CURLOPT_USERAGENT] = implode(',', $request->getHeader('User-Agent')); } // AUTH if ($request->getUri()->getUserInfo()) { $options[CURLOPT_USERPWD] = $request->getUri()->getUserInfo(); } return $options; }