/** * @return string */ public function getRequestId() { if ($this->request->hasHeader($this->headerName)) { return $this->request->getHeader($this->headerName); } return $this->fallback->getRequestId(); }
/** * {@inheritdoc} */ public function getHeader($header) { if (!$this->request->hasHeader($header)) { if (strtolower($header) === 'host' && ($this->request->getUri() && $this->request->getUri()->getHost())) { return array($this->getHostFromUri()); } return array(); } return $this->request->getHeader($header); }
/** * 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; }
/** * Invoke middleware * * @param RequestInterface $request PSR7 request object * @param ResponseInterface $response PSR7 response object * @param callable $next Next middleware callable * * @return ResponseInterface PSR7 response object */ public function __invoke(RequestInterface $request, ResponseInterface $response, callable $next) { $uri = $request->getUri(); if (false !== strpos($uri->getPath(), $this->route)) { $authUser = $request->getHeader('PHP_AUTH_USER') ? $request->getHeader('PHP_AUTH_USER')[0] : null; $authPass = $request->getHeader('PHP_AUTH_PW') ? $request->getHeader('PHP_AUTH_PW')[0] : null; if ($authUser && $authPass && $authUser === $this->username && $authPass === $this->password) { return $next($request, $response); } else { return $response->withStatus(401)->withHeader('WWW-Authenticate', sprintf('Basic realm="%s"', $this->realm)); } } return $next($request, $response); }
/** * @param RequestInterface $request * @return bool */ protected function requestContentTypeIsJson(RequestInterface $request) { $contentTypes = $request->getHeader('Content-Type'); if (empty($contentTypes)) { throw new InvalidArgumentException("Given request is missing Content-Type header"); } $contentType = reset($contentTypes); return substr($contentType, 0, 16) === self::JSON_MIME; }
/** * 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]); }
public function __invoke(RequestInterface $request) : Data { $tokens = array_filter(array_map([$this, 'parseToken'], $request->getHeader('Cookie')), function (Token $token) use($request) { return $this->tokenValidator->__invoke($token, $request); }); /* @var $token Token|bool */ $token = reset($tokens); $session = $token ? $this->tokenSerializer->deSerialize($token) : Data::newEmptySession(); if (!$this->sessionValidator->__invoke($session, $request)) { // if all validation fails, simply reset the session (scrap it) return Data::newEmptySession(); } return $session; }
/** * @param RequestInterface $request * @param array $options * @param ResponseInterface|PromiseInterface $response * * @return ResponseInterface|PromiseInterface */ public function processResponse(RequestInterface $request, array $options, ResponseInterface $response) { $response = $response->withHeader('X-Blackfire-Profile-Uuid', $request->getHeader('X-Blackfire-Profile-Uuid')); if (!$response->hasHeader('X-Blackfire-Response')) { return $response; } parse_str($response->getHeader('X-Blackfire-Response')[0], $values); if (!isset($values['continue']) || 'true' !== $values['continue']) { return $response; } Psr7\rewind_body($request); /* @var PromiseInterface|ResponseInterface $promise */ return $this($request, $options); }
/** * @param RequestInterface $request * @param callable $next * @return mixed */ public function __invoke(RequestInterface $request, callable $next) { $isXHR = in_array('XMLHttpRequest', $request->getHeader('X-Requested-With'), true); switch ($this->state) { case self::ONLY_XHR: if (!$isXHR) { return null; } break; case self::ONLY_NO_XHR: if ($isXHR) { return null; } break; } return $next($request); }
/** * Get request payload from request object. * * @todo check $request->getHeaderLine('content-type') ?? * * @param RequestInterface $request * @return array * * @throws \Exception */ private function getPayloadFromRequest(RequestInterface $request) { $contentType = $request->getHeader('Content-Type'); $expected = 'application/json; charset=UTF-8'; if (empty($contentType) || $expected != $contentType[0]) { throw new \Exception('Expected Content-Type: ' . $expected); } $payload = json_decode($request->getBody(), true); switch (json_last_error()) { case JSON_ERROR_DEPTH: throw new \Exception('Invalid JSON, maximum stack depth exceeded.', 400); case JSON_ERROR_UTF8: throw new \Exception('Malformed UTF-8 characters, possibly incorrectly encoded.', 400); case JSON_ERROR_SYNTAX: case JSON_ERROR_CTRL_CHAR: case JSON_ERROR_STATE_MISMATCH: throw new \Exception('Invalid JSON.', 400); } return is_null($payload) ? [] : $payload; }
/** * {@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'])); }
public function adapt(array $tokens = [], $status = 200, array $headers = []) { list($contentType, $body) = $this->encoder->encode($this->request->getHeader('Accept'), $tokens); return new Response($this->asStream($body), $status, $this->getHeadersForResponse($contentType, $headers)); }
/** * @param RequestInterface $request * * @return null|string */ private function getRequestHostHeader(RequestInterface $request) { $hostHeaderValue = $request->getHeader(CorsRequestHeaders::HOST); $host = empty($hostHeaderValue) === true ? null : $hostHeaderValue[0]; return $host; }
/** * Fetch the access token * * @return string|null Base64 encoded JSON Web Token or null if not found. */ public function fetchToken(RequestInterface $request) { /* If using PHP in CGI mode and non standard environment */ $server_params = $request->getServerParams(); if (isset($server_params[$this->options["environment"]])) { $message = "Using token from environent"; $header = $server_params[$this->options["environment"]]; } else { $message = "Using token from request header"; $header = $request->getHeader("Authorization"); $header = isset($header[0]) ? $header[0] : ""; } if (preg_match("/Bearer\\s+(.*)\$/i", $header, $matches)) { $this->log(LogLevel::DEBUG, $message); return $matches[1]; } /* Bearer not found, try a cookie. */ $cookie_params = $request->getCookieParams(); if (isset($cookie_params[$this->options["cookie"]])) { $this->log(LogLevel::DEBUG, "Using token from cookie"); $this->log(LogLevel::DEBUG, $cookie_params[$this->options["cookie"]]); return $cookie_params[$this->options["cookie"]]; } /* If everything fails log and return false. */ $this->message = "Token not found"; $this->log(LogLevel::WARNING, $this->message); return false; }
/** * @param Request $request * @param Response $response * @param $args * @return Response * @throws \Doctrine\ORM\EntityNotFoundException */ public function remove(Request $request, Response $response, $args) { foreach (explode(',', $request->getHeader('id')[0]) as $id) { $ticket = $this->em->find('App\\Entity\\Ticket', $id); if ($ticket) { $this->em->remove($ticket); } else { throw new EntityNotFoundException(); } } $this->em->flush(); return $response; }
/** * @param RequestInterface $request * * @return ParsedUrlInterface|null */ protected function getOrigin(RequestInterface $request) { $origin = null; if ($request->hasHeader(CorsRequestHeaders::ORIGIN) === true) { $headerValue = $request->getHeader(CorsRequestHeaders::ORIGIN); empty($headerValue) === false ? $origin = $this->factory->createParsedUrl($headerValue[0]) : null; } return $origin; }
/** * 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); } }
/** * 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); }
/** * Fetch the access token * * @return string|null Base64 encoded JSON Web Token or null if not found. */ public function fetchToken(RequestInterface $request) { /* If using PHP in CGI mode and non standard environment */ $server_params = $request->getServerParams(); $header = ""; /* Check for each given environment */ foreach ((array) $this->options["environment"] as $environment) { if (isset($server_params[$environment])) { $message = "Using token from environment"; $header = $server_params[$environment]; } } /* Nothing in environment, try header instead */ if (empty($header)) { $message = "Using token from request header"; $headers = $request->getHeader("Authorization"); $header = isset($headers[0]) ? $headers[0] : ""; } /* Try apache_request_headers() as last resort */ if (empty($header) && function_exists("apache_request_headers")) { $headers = apache_request_headers(); $header = isset($headers["Authorization"]) ? $headers["Authorization"] : ""; } if (preg_match("/Bearer\\s+(.*)\$/i", $header, $matches)) { $this->log(LogLevel::DEBUG, $message); return $matches[1]; } /* Bearer not found, try a cookie. */ $cookie_params = $request->getCookieParams(); if (isset($cookie_params[$this->options["cookie"]])) { $this->log(LogLevel::DEBUG, "Using token from cookie"); $this->log(LogLevel::DEBUG, $cookie_params[$this->options["cookie"]]); return $cookie_params[$this->options["cookie"]]; } /* If everything fails log and return false. */ $this->message = "Token not found"; $this->log(LogLevel::WARNING, $this->message); return false; }
/** * @param RequestInterface $request * @param ResponseInterface $response * * @return bool true if success */ public function cache(RequestInterface $request, ResponseInterface $response) { $reqCacheControl = new KeyValueHttpHeader($request->getHeader('Cache-Control')); if ($reqCacheControl->has('no-store')) { // No caching allowed return false; } $cacheObject = $this->getCacheObject($request, $response); if ($cacheObject !== null) { return $this->storage->save($this->getCacheKey($request), $cacheObject); } return false; }
/** * @param RequestInterface $request * * @return array */ protected function mockApiCall(RequestInterface $request) { if (empty($request->getHeader('Authorization')) || $request->getHeader('Authorization')[0] == 'Bearer tokenInvalid' && isset($this->options[self::KEY_TOKEN_INVALID_COUNT]) && $this->tokenInvalidCount < $this->options[self::KEY_TOKEN_INVALID_COUNT]) { if ($request->getHeader('Authorization')[0] == 'Bearer tokenInvalid') { ++$this->tokenInvalidCount; } return new Response(401); } return new Response(200, [], json_encode('Hello World!')); }
/** * 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] = false; $options[CURLOPT_SSL_VERIFYPEER] = $this->options['ssl_verify_peer']; $options[CURLOPT_TIMEOUT] = $this->options['timeout']; switch ($request->getMethod()) { case 'HEAD': $options[CURLOPT_NOBODY] = true; break; case 'OPTIONS': case 'POST': case 'PUT': $options[CURLOPT_CUSTOMREQUEST] = $request->getMethod(); $body = (string) $request->getBody(); if ('' !== $body) { $options[CURLOPT_POSTFIELDS] = $body; } break; case 'CONNECT': case 'DELETE': case 'PATCH': case 'TRACE': $options[CURLOPT_CUSTOMREQUEST] = $request->getMethod(); break; } $headers = array_keys($request->getHeaders()); foreach ($headers as $name) { if (strtolower($name) === 'content-length') { $values = [0]; if (array_key_exists(CURLOPT_POSTFIELDS, $options)) { $values = [strlen($options[CURLOPT_POSTFIELDS])]; } } else { $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; }
/** * 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; }
/** * Create headers array for CURLOPT_HTTPHEADER * * @param RequestInterface $request * @param array $options cURL options * * @return string[] */ private function createHeaders(RequestInterface $request, array $options) { $curlHeaders = []; $headers = array_keys($request->getHeaders()); foreach ($headers as $name) { $header = strtolower($name); if ('expect' === $header) { // curl-client does not support "Expect-Continue", so dropping "expect" headers continue; } if ('content-length' === $header) { $values = [0]; if (array_key_exists(CURLOPT_POSTFIELDS, $options)) { $values = [strlen($options[CURLOPT_POSTFIELDS])]; } } else { $values = $request->getHeader($name); } foreach ($values as $value) { $curlHeaders[] = $name . ': ' . $value; } } /* * curl-client does not support "Expect-Continue", but cURL adds "Expect" header by default. * We can not suppress it, but we can set it to empty. */ $curlHeaders[] = 'Expect:'; return $curlHeaders; }
/** * @param RequestInterface $request * @return bool */ public function satisfies(RequestInterface $request) { return !empty($request->getHeader('X-Github-Event') && $this->requestContentTypeIsAcceptable($request)); }
/** * @param RequestInterface $request * @param array $options * * @return PromiseInterface */ public function __invoke(RequestInterface $request, array $options) { $fn = $this->nextHandler; $accept = $request->getHeader('Accept'); if (empty($accept)) { return $fn($request, $options); } return $fn($request, $options)->then(function (ResponseInterface $response) use($request, $options) { return $this->checkContentType($request, $options, $response); }); }