/** * {@inheritdoc} * @throws \UnexpectedValueException If a controller is not \Ratchet\Http\HttpServerInterface */ public function onOpen(ConnectionInterface $conn, RequestInterface $request = null) { if (null === $request) { throw new \UnexpectedValueException('$request can not be null'); } $context = $this->_matcher->getContext(); $context->setMethod($request->getMethod()); $context->setHost($request->getHost()); try { $route = $this->_matcher->match($request->getPath()); } catch (MethodNotAllowedException $nae) { return $this->close($conn, 403); } catch (ResourceNotFoundException $nfe) { return $this->close($conn, 404); } if (is_string($route['_controller']) && class_exists($route['_controller'])) { $route['_controller'] = new $route['_controller'](); } if (!$route['_controller'] instanceof HttpServerInterface) { throw new \UnexpectedValueException('All routes must implement Ratchet\\Http\\HttpServerInterface'); } $parameters = array(); foreach ($route as $key => $value) { if (is_string($key) && '_' !== substr($key, 0, 1)) { $parameters[$key] = $value; } } $url = Url::factory($request->getPath()); $url->setQuery($parameters); $request->setUrl($url); $conn->controller = $route['_controller']; $conn->controller->onOpen($conn, $request); }
/** * @param RequestInterface|EntityEnclosingRequestInterface $request * @param Credentials $credentials */ public function signRequest($request, $credentials) { $request->setHeader('X-HMB-Signature-Method', self::DEFAULT_METHOD); $request->setHeader('X-HMB-Signature-Version', self::DEFAULT_SIGN_VERSION); $request->setHeader('X-HMB-TimeStamp', time()); $contentMd5 = $request instanceof EntityEnclosingRequestInterface ? md5($request->getBody()) : ''; if ($contentMd5) { $request->setHeader('Content-MD5', $contentMd5); } $sign = array(); $sign[] = strtoupper($request->getMethod()); $sign[] = $request->getHost(); if ($request->getHeader('Content-MD5')) { $sign[] = $request->getHeader('Content-MD5'); } if ($request->getHeader('Content-Type')) { $sign[] = $request->getHeader('Content-Type'); } $sign[] = $request->getHeader('X-HMB-Signature-Method'); $sign[] = $request->getHeader('X-HMB-Signature-Version'); $sign[] = $request->getHeader('X-HMB-TimeStamp'); if ($request->getHeader('X-HMB-User-Session-Token')) { $sign[] = $request->getHeader('X-HMB-User-Session-Token'); } $sign[] = $request->getQuery(true) ? $request->getPath() . '?' . $request->getQuery(true) : $request->getPath(); $signature = base64_encode(hash_hmac(strtolower($request->getHeader('X-HMB-Signature-Method')), implode("\n", $sign), $credentials->getSecret())); $request->setHeader('Authorization', sprintf('%s %s:%s', self::AUTHORIZATION_SCHME, $credentials->getKey(), $signature)); }
/** * 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(); }
/** * {@inheritdoc} */ public function onOpen(ConnectionInterface $conn, RequestInterface $request = null) { if (null === $request) { throw new \UnexpectedValueException('$request can not be null'); } $context = $this->_matcher->getContext(); $context->setMethod($request->getMethod()); $context->setHost($request->getHost()); try { $parameters = $this->_matcher->match($request->getPath()); } catch (MethodNotAllowedException $nae) { return $this->close($conn, 403); } catch (ResourceNotFoundException $nfe) { return $this->close($conn, 404); } if ($parameters['_controller'] instanceof ServingCapableInterface) { $parameters['_controller']->serve($conn, $request, $parameters); } else { $query = array(); foreach ($query as $key => $value) { if (is_string($key) && '_' !== substr($key, 0, 1)) { $query[$key] = $value; } } $url = Url::factory($request->getPath()); $url->setQuery($query); $request->setUrl($url); $conn->controller = $parameters['_controller']; $conn->controller->onOpen($conn, $request); } }
/** * Returns an HTML-formatted string representation of the exception. * * @return string * @internal */ public function __toString() { $msg = $this->getMessage(); if (is_object($this->requestObj) && $this->requestObj instanceof \Guzzle\Http\Message\Request) { $request = array('url' => $this->requestObj->getUrl(), 'host' => $this->requestObj->getHost(), 'headers' => $this->requestObj->getRawHeaders(), 'query' => (string) $this->requestObj->getQuery()); if ($this->requestObj instanceof \Guzzle\Http\Message\EntityEnclosingRequestInterface) { $request_body = $this->requestObj->getBody(); $request['content-type'] = $request_body->getContentType(); $request['content-length'] = $request_body->getContentLength(); $request['body'] = $request_body->__toString(); } $msg .= "\n\nRequest: <pre>" . htmlspecialchars(print_r($request, true)) . '</pre>'; } if (is_object($this->responseObj) && $this->responseObj instanceof \Guzzle\Http\Message\Response) { $response = array('status' => $this->responseObj->getStatusCode(), 'headers' => $this->responseObj->getRawHeaders(), 'body' => $this->responseBody); $msg .= "\n\nResponse: <pre>" . htmlspecialchars(print_r($response, true)) . '</pre>'; } return $msg; }
/** * 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} * @throws \UnexpectedValueException If a controller is not \Ratchet\Http\HttpServerInterface */ public function onOpen(ConnectionInterface $conn, RequestInterface $request = null) { if (null === $request) { throw new \UnexpectedValueException('$request can not be null'); } $context = $this->_matcher->getContext(); $context->setMethod($request->getMethod()); $context->setHost($request->getHost()); try { $route = $this->_matcher->match($request->getPath()); } catch (MethodNotAllowedException $nae) { return $this->close($conn, 403); } catch (ResourceNotFoundException $nfe) { return $this->close($conn, 404); } if (is_string($route['_controller']) && class_exists($route['_controller'])) { $route['_controller'] = new $route['_controller'](); } if (!$route['_controller'] instanceof HttpServerInterface) { throw new \UnexpectedValueException('All routes must implement Ratchet\\Http\\HttpServerInterface'); } $conn->controller = $route['_controller']; $conn->controller->onOpen($conn, $request); }
/** * Parse the bucket name from a request object * * @param RequestInterface $request Request to parse * * @return string */ private function parseBucketName(RequestInterface $request) { $baseUrl = Url::factory($request->getClient()->getBaseUrl()); $baseHost = $baseUrl->getHost(); $host = $request->getHost(); if (strpos($host, $baseHost) === false) { // Does not contain the base URL, so it's either a redirect, CNAME, or using a different region $baseHost = ''; // For every known S3 host, check if that host is present on the request $regions = $request->getClient()->getDescription()->getData('regions'); foreach ($regions as $region) { if (strpos($host, $region['hostname']) !== false) { // This host matches the request host. Tells use the region and endpoint-- we can derive the bucket $baseHost = $region['hostname']; break; } } // If no matching base URL was found, then assume that this is a CNAME, and the CNAME is the bucket if (!$baseHost) { return $host; } } // Remove the baseURL from the host of the request to attempt to determine the bucket name return trim(str_replace($baseHost, '', $request->getHost()), ' .'); }
/** * {@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; }
/** * Returns a formatted message * * @param RequestInterface $request Request that was sent * @param Response $response Response that was received * @param CurlHandle $handle Curl handle associated with the message * @param array $customData Associative array of custom template data * * @return string */ public function format(RequestInterface $request, Response $response = null, CurlHandle $handle = null, array $customData = array()) { $cache = $customData; return preg_replace_callback('/{\\s*([A-Za-z_\\-\\.0-9]+)\\s*}/', function (array $matches) use($request, $response, $handle, &$cache) { if (array_key_exists($matches[1], $cache)) { return $cache[$matches[1]]; } $result = ''; switch ($matches[1]) { case 'request': $result = (string) $request; break; case 'response': $result = (string) $response; break; case 'req_body': $result = $request instanceof EntityEnclosingRequestInterface ? (string) $request->getBody() : ''; break; case 'res_body': $result = $response ? $response->getBody(true) : ''; break; case 'ts': $result = gmdate('c'); break; case 'method': $result = $request->getMethod(); break; case 'url': $result = (string) $request->getUrl(); break; case 'resource': $result = $request->getResource(); break; case 'protocol': $result = 'HTTP'; break; case 'version': $result = $request->getProtocolVersion(); break; case 'host': $result = $request->getHost(); break; case 'hostname': $result = gethostname(); break; case 'port': $result = $request->getPort(); break; case 'code': $result = $response ? $response->getStatusCode() : ''; break; case 'phrase': $result = $response ? $response->getReasonPhrase() : ''; break; case 'connect_time': if ($handle) { $result = $handle->getInfo(CURLINFO_CONNECT_TIME); } elseif ($response) { $result = $response->getInfo('connect_time'); } break; case 'total_time': if ($handle) { $result = $handle->getInfo(CURLINFO_TOTAL_TIME); } elseif ($response) { $result = $response->getInfo('total_time'); } break; case 'curl_error': $result = $handle ? $handle->getError() : ''; break; case 'curl_code': $result = $handle ? $handle->getErrorNo() : ''; break; case 'curl_stderr': $result = $handle ? $handle->getStderr() : ''; break; default: if (strpos($matches[1], 'req_header_') === 0) { $result = $request->getHeader(substr($matches[1], 11)); } elseif (strpos($matches[1], 'res_header_') === 0) { $result = $response->getHeader(substr($matches[1], 11)); } } $cache[$matches[1]] = $result; return $result; }, $this->template); }
/** * 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); }
/** * 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 host of the request * * @return string */ public function getHost() { return $this->wrapped->getHost(); }
/** * Create a canonicalized resource for a request * * @param RequestInterface $request Request for the resource * * @return string */ protected function createCanonicalizedResource(RequestInterface $request) { // If this is a virtual hosted bucket, then append the bucket name $host = $request->getHost(); $parts = explode('.', $host); $totalParts = count($parts); if ($parts[$totalParts - 2] !== 'amazonaws') { // The host does not contain S3, so it must be a CNAME $buffer = '/' . $host; } elseif ($totalParts > 3) { // The host contains more than three parts, so it is a virtual hosted bucket $buffer = '/' . implode('.', array_slice($parts, 0, -3)); } else { // The host does not contain any bucket information $buffer = ''; } $buffer .= $request->getPath(); $buffer = str_replace('//', '/', $buffer); // Add sub resource parameters $query = $request->getQuery(); $first = true; foreach ($this->signableQueryString as $key) { if ($value = $query->get($key)) { $buffer .= $first ? '?' : '&'; $first = false; $buffer .= $key; if ($value !== QueryString::BLANK) { $buffer .= "={$value}"; } } } return $buffer; }