/** * Add cookies to a request based on the destination of the request and * the cookies stored in the storage backend. Any previously set cookies * will be removed. * * @param RequestInterface $request Request to add cookies to. If the * request object already has a cookie header, then no further cookies * will be added. * * @return array Returns an array of the cookies that were added */ public function addCookies(RequestInterface $request) { $request->removeHeader('Cookie'); // Find cookies that match this request $cookies = $this->jar->getCookies($request->getHost(), $request->getPath()); $match = false; if ($cookies) { foreach ($cookies as $cookie) { $match = true; // If a port restriction is set, validate the port if (!empty($cookie['port'])) { if (!in_array($request->getPort(), $cookie['port'])) { $match = false; } } // Validate the secure flag if ($cookie['secure']) { if ($request->getScheme() != 'https') { $match = false; } } // If this request is eligible for the cookie, then merge it in if ($match) { $request->addCookie($cookie['cookie'][0], isset($cookie['cookie'][1]) ? $cookie['cookie'][1] : null); } } } return $match && $cookies ? $cookies : array(); }
/** * Calculate the hash key of a request object * * @param RequestInterface $request Request to hash * @param string $raw Set to TRUE to retrieve the un-encoded string for debugging * * @return string */ public function getCacheKey(RequestInterface $request, $raw = false) { // See if the key has already been calculated $key = $request->getParams()->get('cache.key'); // Always recalculate when using the raw option if (!$key || $raw) { // Generate the start of the key $key = $request->getMethod() . '_' . $request->getScheme() . '_' . $request->getHost() . $request->getPath(); $filterHeaders = array('Cache-Control'); $filterQuery = array(); // Check to see how and if the key should be filtered foreach (explode(';', $request->getParams()->get('cache.key_filter')) as $part) { $pieces = array_map('trim', explode('=', $part)); if (isset($pieces[1])) { $remove = array_map('trim', explode(',', $pieces[1])); if ($pieces[0] == 'header') { $filterHeaders = array_merge($filterHeaders, $remove); } elseif ($pieces[0] == 'query') { $filterQuery = array_merge($filterQuery, $remove); } } } // Use the filtered query string $queryString = (string) $request->getQuery()->filter(function ($key, $value) use($filterQuery) { return !in_array($key, $filterQuery); }); // Use the filtered headers $headerString = http_build_query($request->getHeaders()->map(function ($key, $value) { return count($value) == 1 ? $value[0] : $value; })->filter(function ($key, $value) use($filterHeaders) { return !in_array($key, $filterHeaders); })->getAll()); if ($raw) { $key = strtolower('gz_' . $key . $queryString . '_' . $headerString); } else { $key = strtolower('gz_' . md5($key . $queryString . '_' . $headerString)); $request->getParams()->set('cache.key', $key); } } return $key; }
/** * {@inheritdoc} */ public function getMatchingCookies(RequestInterface $request) { // Find cookies that match this request $cookies = $this->all($request->getHost(), $request->getPath()); // Remove ineligible cookies foreach ($cookies as $index => $cookie) { if (!$cookie->matchesPort($request->getPort()) || $cookie->getSecure() && $request->getScheme() != 'https') { unset($cookies[$index]); } } return $cookies; }
/** * Collect & sanitize data about a Guzzle request * * @param Guzzle\Http\Message\RequestInterface $request * * @return array */ private function collectRequest(GuzzleRequestInterface $request) { $body = null; if ($request instanceof EntityEnclosingRequestInterface) { $body = (string) $request->getBody(); } return array('headers' => $request->getHeaders(), 'method' => $request->getMethod(), 'scheme' => $request->getScheme(), 'host' => $request->getHost(), 'port' => $request->getPort(), 'path' => $request->getPath(), 'query' => $request->getQuery(), 'body' => $body); }
private function exec(\Guzzle\Http\Message\RequestInterface $request) { $start = microtime(true); $this->responseCode = 0; // Get snapshot of request headers. $request_headers = $request->getRawHeaders(); // Mask authorization for logs. $request_headers = preg_replace('!\\nAuthorization: (Basic|Digest) [^\\r\\n]+\\r!i', "\nAuthorization: \$1 [**masked**]\r", $request_headers); try { $response = $request->send(); } catch (\Guzzle\Http\Exception\BadResponseException $e) { $response = $e->getResponse(); } catch (\Guzzle\Http\Exception\CurlException $e) { // Timeouts etc. DebugData::$raw = ''; DebugData::$code = $e->getErrorNo(); DebugData::$code_status = $e->getError(); DebugData::$code_class = 0; DebugData::$exception = $e->getMessage(); DebugData::$opts = array('request_headers' => $request_headers); DebugData::$data = null; $exception = new ResponseException($e->getError(), $e->getErrorNo(), $request->getUrl(), DebugData::$opts); $exception->requestObj = $request; // Log Exception $headers_array = $request->getHeaders(); unset($headers_array['Authorization']); $headerString = ''; foreach ($headers_array as $value) { $headerString .= $value->getName() . ': ' . $value . " "; } $log_message = '{code_status} ({code}) Request Details:[ {r_method} {r_resource} {r_scheme} {r_headers} ]'; $httpScheme = strtoupper(str_replace('https', 'http', $request->getScheme())) . $request->getProtocolVersion(); $log_params = array('code' => $e->getErrorNo(), 'code_status' => $e->getError(), 'r_method' => $request->getUrl(), 'r_resource' => $request->getRawHeaders(), 'r_scheme' => $httpScheme, 'r_headers' => $headerString); self::$logger->emergency($log_message, $log_params); throw $exception; } $this->responseCode = $response->getStatusCode(); $this->responseText = trim($response->getBody(true)); $this->responseLength = $response->getContentLength(); $this->responseMimeType = $response->getContentType(); $this->responseObj = array(); $content_type = $response->getContentType(); $firstChar = substr($this->responseText, 0, 1); if (strpos($content_type, '/json') !== false && ($firstChar == '{' || $firstChar == '[')) { $response_obj = @json_decode($this->responseText, true); if (is_array($response_obj)) { $this->responseObj = $response_obj; } } $status = self::getStatusMessage($this->responseCode); $code_class = floor($this->responseCode / 100); DebugData::$raw = $this->responseText; DebugData::$opts = array('request_headers' => $request_headers, 'response_headers' => $response->getRawHeaders()); if ($request instanceof \Guzzle\Http\Message\EntityEnclosingRequestInterface) { DebugData::$opts['request_body'] = (string) $request->getBody(); } DebugData::$opts['request_type'] = class_implements($request); DebugData::$data = $this->responseObj; DebugData::$code = $this->responseCode; DebugData::$code_status = $status; DebugData::$code_class = $code_class; DebugData::$exception = null; DebugData::$time_elapsed = microtime(true) - $start; if ($code_class != 2) { $uri = $request->getUrl(); if (!empty($this->responseCode) && isset($this->responseObj['message'])) { $message = 'Code: ' . $this->responseCode . '; Message: ' . $this->responseObj['message']; } else { $message = 'API returned HTTP code of ' . $this->responseCode . ' when fetching from ' . $uri; } DebugData::$exception = $message; $this->debugCallback(DebugData::toArray()); self::$logger->error($this->responseText); // Create better status to show up in logs $status .= ': ' . $request->getMethod() . ' ' . $uri; if ($request instanceof \Guzzle\Http\Message\EntityEnclosingRequestInterface) { $body = $request->getBody(); if ($body instanceof \Guzzle\Http\EntityBodyInterface) { $status .= ' with Content-Length of ' . $body->getContentLength() . ' and Content-Type of ' . $body->getContentType(); } } $exception = new ResponseException($status, $this->responseCode, $uri, DebugData::$opts, $this->responseText); $exception->requestObj = $request; $exception->responseObj = $response; throw $exception; } $this->debugCallback(DebugData::toArray()); }
/** * Log a message based on a request and response * * @param RequestInterface $request Request to log * @param Response $response Response to log */ private function log(RequestInterface $request, Response $response = null) { $message = ''; if ($this->settings & self::LOG_CONTEXT) { // Log common contextual information $message = $request->getHost() . ' - "' . $request->getMethod() . ' ' . $request->getResource() . ' ' . strtoupper($request->getScheme()) . '/' . $request->getProtocolVersion() . '"'; // If a response is set, then log additional contextual information if ($response) { $message .= sprintf(' - %s %s - %s %s %s', $response->getStatusCode(), $response->getContentLength() ?: 0, $response->getInfo('total_time'), $response->getInfo('speed_upload'), $response->getInfo('speed_download')); } } // Check if we are logging anything that will come from cURL if ($request->getParams()->get('curl_handle') && ($this->settings & self::LOG_DEBUG || $this->settings & self::LOG_HEADERS || $this->settings & self::LOG_BODY)) { // If context logging too, then add a new line for cleaner messages if ($this->settings & self::LOG_CONTEXT) { $message .= "\n"; } // Filter cURL's verbose output based on config settings $message .= $this->parseCurlLog($request); // Log the response body if the response is available if ($this->settings & self::LOG_BODY && $response) { if ($request->getParams()->get('response_wire')) { $message .= (string) $request->getParams()->get('response_wire'); } else { $message .= $response->getBody(true); } } } // Send the log message to the adapter, adding a category and host $priority = $response && !$response->isSuccessful() ? LOG_ERR : LOG_DEBUG; $this->logAdapter->log(trim($message), $priority, array('category' => 'guzzle.request', 'host' => $this->hostname)); }
/** * Get the URI scheme of the request (http, https, ftp, etc) * * @return string */ public function getScheme() { return $this->wrapped->getScheme(); }