public function signRequest(RequestInterface $request, CredentialsInterface $credentials) { // Add a date header if one is not set if (!$request->hasHeader('date') && !$request->hasHeader('x-amz-date')) { $request->setHeader('Date', gmdate(DateFormat::RFC1123, $this->getTimestamp())); } // Add the security token if one is present if ($credentials->getSecurityToken()) { $request->setHeader('x-amz-security-token', $credentials->getSecurityToken()); } // Determine the string to sign $stringToSign = (string) ($request->getHeader('Date') ?: $request->getHeader('x-amz-date')); $request->getParams()->set('aws.string_to_sign', $stringToSign); // Calculate the signature $signature = base64_encode(hash_hmac('sha256', $stringToSign, $credentials->getSecretKey(), true)); // Add the authorization header to the request $headerFormat = 'AWS3-HTTPS AWSAccessKeyId=%s,Algorithm=HmacSHA256,Signature=%s'; $request->setHeader('X-Amzn-Authorization', sprintf($headerFormat, $credentials->getAccessKeyId(), $signature)); }
/** * Prepare the request for redirection and enforce the maximum number of allowed redirects per client * * @param RequestInterface $original Original request * @param RequestInterface $request Request to prepare and validate * @param Response $response The current response * * @return RequestInterface */ protected function prepareRedirection(RequestInterface $original, RequestInterface $request, Response $response) { $params = $original->getParams(); // This is a new redirect, so increment the redirect counter $current = $params[self::REDIRECT_COUNT] + 1; $params[self::REDIRECT_COUNT] = $current; // Use a provided maximum value or default to a max redirect count of 5 $max = isset($params[self::MAX_REDIRECTS]) ? $params[self::MAX_REDIRECTS] : $this->defaultMaxRedirects; // Throw an exception if the redirect count is exceeded if ($current > $max) { $this->throwTooManyRedirectsException($original, $max); return false; } else { // Create a redirect request based on the redirect rules set on the request return $this->createRedirectRequest($request, $response->getStatusCode(), trim($response->getLocation()), $original); } }
/** * Prepare a request to be sent from the Client by adding client specific behaviors and properties to the request. * * @param RequestInterface $request Request to prepare for the client * @param array $options Options to apply to the request * * @return RequestInterface */ protected function prepareRequest(RequestInterface $request, array $options = array()) { $request->setClient($this)->setEventDispatcher(clone $this->getEventDispatcher()); if ($curl = $this->config[self::CURL_OPTIONS]) { $request->getCurlOptions()->overwriteWith(CurlHandle::parseCurlConfig($curl)); } if ($params = $this->config[self::REQUEST_PARAMS]) { Version::warn('request.params is deprecated. Use request.options to add default request options.'); $request->getParams()->overwriteWith($params); } if ($this->userAgent && !$request->hasHeader('User-Agent')) { $request->setHeader('User-Agent', $this->userAgent); } if ($defaults = $this->config[self::REQUEST_OPTIONS]) { $this->requestFactory->applyOptions($request, $defaults, RequestFactoryInterface::OPTIONS_AS_DEFAULTS); } if ($options) { $this->requestFactory->applyOptions($request, $options); } $this->dispatch('client.create_request', array('client' => $this, 'request' => $request)); return $request; }
/** * Add the plugin's headers to a response * * @param RequestInterface $request Request * @param Response $response Response to add headers to */ protected function addResponseHeaders(RequestInterface $request, Response $response) { $params = $request->getParams(); $response->setHeader('Via', sprintf('%s GuzzleCache/%s', $request->getProtocolVersion(), Version::VERSION)); $lookup = ($params['cache.lookup'] === true ? 'HIT' : 'MISS') . ' from GuzzleCache'; if ($header = $response->getHeader('X-Cache-Lookup')) { // Don't add duplicates $values = $header->toArray(); $values[] = $lookup; $response->setHeader('X-Cache-Lookup', array_unique($values)); } else { $response->setHeader('X-Cache-Lookup', $lookup); } if ($params['cache.hit'] === true) { $xcache = 'HIT from GuzzleCache'; } elseif ($params['cache.hit'] == 'error') { $xcache = 'HIT_ERROR from GuzzleCache'; } else { $xcache = 'MISS from GuzzleCache'; } if ($header = $response->getHeader('X-Cache')) { // Don't add duplicates $values = $header->toArray(); $values[] = $xcache; $response->setHeader('X-Cache', array_unique($values)); } else { $response->setHeader('X-Cache', $xcache); } if ($response->isFresh() === false) { $response->addHeader('Warning', sprintf('110 GuzzleCache/%s "Response is stale"', Version::VERSION)); if ($params['cache.hit'] === 'error') { $response->addHeader('Warning', sprintf('111 GuzzleCache/%s "Revalidation failed"', Version::VERSION)); } } }
/** * Create a canonicalized resource for a request * * @param RequestInterface $request Request for the resource * * @return string */ private function createCanonicalizedResource(RequestInterface $request) { $buffer = $request->getParams()->get('s3.resource'); // When sending a raw HTTP request (e.g. $client->get()) if (null === $buffer) { $bucket = $request->getParams()->get('bucket') ?: $this->parseBucketName($request); // Use any specified bucket name, the parsed bucket name, or no bucket name when interacting with GetService $buffer = $bucket ? "/{$bucket}" : ''; // Remove encoding from the path and use the S3 specific encoding $path = S3Client::encodeKey(rawurldecode($request->getPath())); // if the bucket was path style, then ensure that the bucket wasn't duplicated in the resource $buffer .= preg_replace("#^/{$bucket}/{$bucket}#", "/{$bucket}", $path); } // Remove double slashes $buffer = str_replace('//', '/', $buffer); // Add sub resource parameters $query = $request->getQuery(); $first = true; foreach ($this->signableQueryString as $key) { if ($query->hasKey($key)) { $value = $query[$key]; $buffer .= $first ? '?' : '&'; $first = false; $buffer .= $key; // Don't add values for empty sub-resources if ($value !== '' && $value !== false && $value !== null && $value !== QueryString::BLANK) { $buffer .= "={$value}"; } } } return $buffer; }
protected function visit_params(RequestInterface $request, $value, $flags) { if (!is_array($value)) { throw new InvalidArgumentException('params value must be an array'); } $request->getParams()->overwriteWith($value); }
/** * Hash a request URL into a string that returns cache metadata * * @param RequestInterface $request * * @return string */ protected function getCacheKey(RequestInterface $request) { // Allow cache.key_filter to trim down the URL cache key by removing generate query string values (e.g. auth) if ($filter = $request->getParams()->get('cache.key_filter')) { $url = $request->getUrl(true); foreach (explode(',', $filter) as $remove) { $url->getQuery()->remove(trim($remove)); } } else { $url = $request->getUrl(); } return $this->keyPrefix . md5($request->getMethod() . ' ' . $url); }