Example #1
0
 private function modifyRedirectRequest(RequestInterface $request, ResponseInterface $response)
 {
     $config = $request->getConfig();
     // Use a GET request if this is an entity enclosing request and we are
     // not forcing RFC compliance, but rather emulating what all browsers
     // would do.
     $statusCode = $response->getStatusCode();
     if ($statusCode == 303 || $statusCode <= 302 && $request->getBody() && !$config->getPath('redirect/strict')) {
         $request->setMethod('GET');
         $request->setBody(null);
     }
     $previousUrl = $request->getUrl();
     $this->setRedirectUrl($request, $response);
     $this->rewindEntityBody($request);
     // Add the Referer header if it is told to do so and only
     // add the header if we are not redirecting from https to http.
     if ($config->getPath('redirect/referer') && ($request->getScheme() == 'https' || $request->getScheme() == $config['redirect_scheme'])) {
         $url = Url::fromString($previousUrl);
         $url->setUsername(null);
         $url->setPassword(null);
         $request->setHeader('Referer', (string) $url);
     } else {
         $request->removeHeader('Referer');
     }
 }
Example #2
0
 /**
  * Creates a Ring request from a request object.
  *
  * This function does not hook up the "then" and "progress" events that
  * would be required for actually sending a Guzzle request through a
  * RingPHP handler.
  *
  * @param RequestInterface $request Request to convert.
  *
  * @return array Converted Guzzle Ring request.
  */
 public static function createRingRequest(RequestInterface $request)
 {
     $options = $request->getConfig()->toArray();
     $url = $request->getUrl();
     // No need to calculate the query string twice (in URL and query).
     $qs = ($pos = strpos($url, '?')) ? substr($url, $pos + 1) : null;
     return ['scheme' => $request->getScheme(), 'http_method' => $request->getMethod(), 'url' => $url, 'uri' => $request->getPath(), 'headers' => $request->getHeaders(), 'body' => $request->getBody(), 'version' => $request->getProtocolVersion(), 'client' => $options, 'query_string' => $qs, 'future' => isset($options['future']) ? $options['future'] : false];
 }
Example #3
0
 public function save(RequestInterface $request, ResponseInterface $response)
 {
     $ttl = (int) $request->getConfig()->get('cache.ttl');
     $key = $this->getCacheKey($request);
     // Persist the response body if needed
     if ($response->getBody() && $response->getBody()->getSize() > 0) {
         $this->cache->save($key, array('code' => $response->getStatusCode(), 'headers' => $response->getHeaders(), 'body' => (string) $response->getBody()), $ttl);
         $request->getConfig()->set('cache.key', $key);
     }
 }
 /**
  * Signs the specified request with an SellerCenter API signing protocol by using the
  * provided SellerCenter API credentials and adding the required headers to the request
  *
  * @param RequestInterface     $request     Request to add a signature to
  * @param CredentialsInterface $credentials Signing credentials
  */
 public function signRequest(RequestInterface $request, CredentialsInterface $credentials)
 {
     $parameters = $request->getQuery()->toArray();
     $parameters['UserID'] = $credentials->getId();
     $parameters['Version'] = '1.0';
     $parameters['Action'] = $request->getConfig()->get('command')->getName();
     $parameters['Timestamp'] = gmdate(DateTime::ISO8601);
     // the keys MUST be in alphabetical order to correct signature calculation
     ksort($parameters);
     $parameters['Signature'] = rawurlencode(hash_hmac('sha256', http_build_query($parameters, '', '&', PHP_QUERY_RFC3986), $credentials->getKey(), false));
     $request->setQuery($parameters);
 }
 private function shouldValidate(RequestInterface $request, ResponseInterface $response)
 {
     if ($request->getMethod() != 'GET' || $request->getConfig()->get('cache.disable')) {
         return false;
     }
     $validate = Utils::getDirective($request, 'Pragma') === 'no-cache' || Utils::getDirective($response, 'Pragma') === 'no-cache' || Utils::getDirective($request, 'must-revalidate') || Utils::getDirective($response, 'must-revalidate') || Utils::getDirective($request, 'no-cache') || Utils::getDirective($response, 'no-cache') || Utils::getDirective($response, 'max-age') === '0' || Utils::getDirective($response, 's-maxage') === '0';
     // Use the strong ETag validator if available and the response contains
     // no Cache-Control directive
     if (!$validate && !$response->hasHeader('Cache-Control') && $response->hasHeader('ETag')) {
         $validate = true;
     }
     return $validate;
 }
Example #6
0
 public function signRequest(RequestInterface $request, CredentialsInterface $credentials)
 {
     /** @var PostBodyInterface $body */
     $body = $request->getBody();
     $body->setField('Timestamp', gmdate('c'));
     $body->setField('SignatureVersion', '2');
     $body->setField('SignatureMethod', 'HmacSHA256');
     $body->setField('AWSAccessKeyId', $credentials->getAccessKeyId());
     if ($token = $credentials->getSecurityToken()) {
         $body->setField('SecurityToken', $token);
     }
     // build string to sign
     $sign = $request->getMethod() . "\n" . $request->getHost() . "\n" . '/' . "\n" . $this->getCanonicalizedParameterString($body);
     $request->getConfig()->set('aws.signature', $sign);
     $body->setField('Signature', base64_encode(hash_hmac('sha256', $sign, $credentials->getSecretKey(), true)));
 }
Example #7
0
 /**
  * Create a redirect request for a specific request object
  *
  * Takes into account strict RFC compliant redirection (e.g. redirect POST
  * with POST) vs doing what most clients do (e.g. redirect POST with GET).
  *
  * @param RequestInterface  $request
  * @param ResponseInterface $response
  *
  * @return RequestInterface Returns a new redirect request
  * @throws CouldNotRewindStreamException If the body cannot be rewound.
  */
 private function createRedirectRequest(RequestInterface $request, ResponseInterface $response)
 {
     $config = $request->getConfig();
     // Use a GET request if this is an entity enclosing request and we are
     // not forcing RFC compliance, but rather emulating what all browsers
     // would do. Be sure to disable redirects on the clone.
     $redirectRequest = clone $request;
     $redirectRequest->getEmitter()->detach($this);
     $statusCode = $response->getStatusCode();
     if ($statusCode == 303 || $statusCode <= 302 && $request->getBody() && !$config->getPath('redirect/strict')) {
         $redirectRequest->setMethod('GET');
         $redirectRequest->setBody(null);
     }
     $this->setRedirectUrl($redirectRequest, $response);
     $this->rewindEntityBody($redirectRequest);
     // Add the Referer header if it is told to do so and only
     // add the header if we are not redirecting from https to http.
     if ($config->getPath('redirect/referer') && ($redirectRequest->getScheme() == 'https' || $redirectRequest->getScheme() == $request->getScheme())) {
         $url = Url::fromString($request->getUrl());
         $url->setUsername(null)->setPassword(null);
         $redirectRequest->setHeader('Referer', (string) $url);
     }
     return $redirectRequest;
 }
Example #8
0
 private function add_decode_content(RequestInterface $request, $value)
 {
     if ($value === false) {
         return;
     }
     if ($value !== true) {
         $request->setHeader('Accept-Encoding', $value);
     }
     $request->getConfig()['decode_content'] = true;
 }
 /**
  * Looks for a Certificate Authority file in the CA folder
  * that matches the host and update the 'verify' option
  * to its full path.
  * If no specific file regarding a host is found, uses
  * curl-ca-bundle.crt by default.
  * @param RequestInterface $httpRequest
  */
 private function verify(RequestInterface $httpRequest)
 {
     $extensions = array('crt', 'pem', 'cer', 'der');
     $caDir = __DIR__ . '/../CA/';
     // Must be https
     $url = $httpRequest->getUrl();
     if (substr($url, 0, 5) != 'https') {
         $httpRequest->getConfig()->set('verify', false);
         return;
     }
     // Default
     $httpRequest->getConfig()->set('verify', $caDir . 'curl-ca-bundle.crt');
     // Look for a host specific CA file
     $host = strtolower(parse_url($url, PHP_URL_HOST));
     if (!$host) {
         return;
     }
     $filename = $host;
     do {
         // Look for the possible extensions
         foreach ($extensions as $ext) {
             if (file_exists($verify = $caDir . $filename . '.' . $ext)) {
                 $httpRequest->getConfig()->set('verify', $verify);
                 return;
             }
         }
         // Remove a subdomain each time
         $filename = substr($filename, strpos($filename, '.') + 1);
     } while (substr_count($filename, '.') > 0);
     // No specific match
     return;
 }
 protected function applyOptions(RequestInterface $request, array $options = [])
 {
     $config = $request->getConfig();
     $emitter = $request->getEmitter();
     foreach ($options as $key => $value) {
         if (isset(self::$configMap[$key])) {
             $config[$key] = $value;
             continue;
         }
         switch ($key) {
             case 'allow_redirects':
                 if ($value === false) {
                     continue;
                 }
                 if ($value === true) {
                     $value = self::$defaultRedirect;
                 } elseif (!isset($value['max'])) {
                     throw new Iae('allow_redirects must be true, false, or an ' . 'array that contains the \'max\' key');
                 } else {
                     // Merge the default settings with the provided settings
                     $value += self::$defaultRedirect;
                 }
                 $config['redirect'] = $value;
                 $emitter->attach($this->redirectPlugin);
                 break;
             case 'decode_content':
                 if ($value === false) {
                     continue;
                 }
                 $config['decode_content'] = true;
                 if ($value !== true) {
                     $request->setHeader('Accept-Encoding', $value);
                 }
                 break;
             case 'headers':
                 if (!is_array($value)) {
                     throw new Iae('header value must be an array');
                 }
                 // Do not overwrite existing headers
                 foreach ($value as $k => $v) {
                     if (!$request->hasHeader($k)) {
                         $request->setHeader($k, $v);
                     }
                 }
                 break;
             case 'exceptions':
                 if ($value === true) {
                     $emitter->attach($this->errorPlugin);
                 }
                 break;
             case 'body':
                 if (is_array($value)) {
                     $this->addPostData($request, $value);
                 } elseif ($value !== null) {
                     $request->setBody(Stream::factory($value));
                 }
                 break;
             case 'auth':
                 if (!$value) {
                     continue;
                 }
                 if (is_array($value)) {
                     $type = isset($value[2]) ? strtolower($value[2]) : 'basic';
                 } else {
                     $type = strtolower($value);
                 }
                 $config['auth'] = $value;
                 if ($type == 'basic') {
                     $request->setHeader('Authorization', 'Basic ' . base64_encode("{$value['0']}:{$value['1']}"));
                 } elseif ($type == 'digest') {
                     // @todo: Do not rely on curl
                     $config->setPath('curl/' . CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
                     $config->setPath('curl/' . CURLOPT_USERPWD, "{$value['0']}:{$value['1']}");
                 }
                 break;
             case 'query':
                 if ($value instanceof Query) {
                     $original = $request->getQuery();
                     // Do not overwrite existing query string variables by
                     // overwriting the object with the query string data passed
                     // in the URL
                     $value->overwriteWith($original->toArray());
                     $request->setQuery($value);
                 } elseif (is_array($value)) {
                     // Do not overwrite existing query string variables
                     $query = $request->getQuery();
                     foreach ($value as $k => $v) {
                         if (!isset($query[$k])) {
                             $query[$k] = $v;
                         }
                     }
                 } else {
                     throw new Iae('query must be an array or Query object');
                 }
                 break;
             case 'cookies':
                 if ($value === true) {
                     static $cookie = null;
                     if (!$cookie) {
                         $cookie = new Cookie();
                     }
                     $emitter->attach($cookie);
                 } elseif (is_array($value)) {
                     $emitter->attach(new Cookie(CookieJar::fromArray($value, $request->getHost())));
                 } elseif ($value instanceof CookieJarInterface) {
                     $emitter->attach(new Cookie($value));
                 } elseif ($value !== false) {
                     throw new Iae('cookies must be an array, true, or CookieJarInterface');
                 }
                 break;
             case 'events':
                 if (!is_array($value)) {
                     throw new Iae('events must be an array');
                 }
                 $this->attachListeners($request, $this->prepareListeners($value, ['before', 'complete', 'error', 'progress', 'end']));
                 break;
             case 'subscribers':
                 if (!is_array($value)) {
                     throw new Iae('subscribers must be an array');
                 }
                 foreach ($value as $subscribers) {
                     $emitter->attach($subscribers);
                 }
                 break;
             case 'json':
                 $request->setBody(Stream::factory(json_encode($value)));
                 if (!$request->hasHeader('Content-Type')) {
                     $request->setHeader('Content-Type', 'application/json');
                 }
                 break;
             default:
                 // Check for custom handler functions.
                 if (isset($this->customOptions[$key])) {
                     $fn = $this->customOptions[$key];
                     $fn($request, $value);
                     continue;
                 }
                 throw new Iae("No method can handle the {$key} config key");
         }
     }
 }
 public function sign(RequestInterface $request, $client_id, $client_secret)
 {
     $request->getConfig()->set('auth', 'basic');
     $request->setHeader('Authorization', 'Basic ' . base64_encode("{$client_id}:{$client_secret}"));
 }
 private function addResponseHeaders(RequestInterface $request, ResponseInterface $response)
 {
     $params = $request->getConfig();
     $lookup = $params['cache_lookup'] . ' from GuzzleCache';
     $response->addHeader('X-Cache-Lookup', $lookup);
     if ($params['cache_hit'] === true) {
         $response->addHeader('X-Cache', 'HIT from GuzzleCache');
     } elseif ($params['cache_hit'] == 'error') {
         $response->addHeader('X-Cache', 'HIT_ERROR from GuzzleCache');
     } else {
         $response->addHeader('X-Cache', 'MISS from GuzzleCache');
     }
     $freshness = Utils::getFreshness($response);
     // Only add a Warning header if we are returning a stale response.
     if ($params['cache_hit'] && $freshness !== null && $freshness <= 0) {
         $response->addHeader('Warning', sprintf('%d GuzzleCache/' . ClientInterface::VERSION . ' "%s"', 110, 'Response is stale'));
     }
 }
 protected function add_wait(RequestInterface $request, $wait)
 {
     $request->getConfig()->set('wait', $wait);
 }
Example #14
0
 private function addExpectHeader(RequestInterface $request, StreamInterface $body)
 {
     // Determine if the Expect header should be used
     if ($request->hasHeader('Expect')) {
         return;
     }
     $expect = $request->getConfig()['expect'];
     // Return if disabled or if you're not using HTTP/1.1
     if ($expect === false || $request->getProtocolVersion() !== '1.1') {
         return;
     }
     // The expect header is unconditionally enabled
     if ($expect === true) {
         $request->setHeader('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
     $size = $body->getSize();
     if ($size === null || $size >= (int) $expect || !$body->isSeekable()) {
         $request->setHeader('Expect', '100-Continue');
     }
 }
 private function applyTransferOptions(RequestInterface $request, RequestMediator $mediator, array &$options)
 {
     static $methods;
     if (!$methods) {
         $methods = array_flip(get_class_methods(__CLASS__));
     }
     foreach ($request->getConfig()->toArray() as $key => $value) {
         $method = "add_{$key}";
         if (isset($methods[$method])) {
             $this->{$method}($request, $mediator, $options, $value);
         }
     }
 }
Example #16
0
 public function send(RequestInterface $request)
 {
     $trans = new Transaction($this, $request);
     $fn = $this->fsm;
     // Ensure a future response is returned if one was requested.
     if ($request->getConfig()->get('future')) {
         try {
             $fn($trans);
             // Turn the normal response into a future if needed.
             return $trans->response instanceof FutureInterface ? $trans->response : new FutureResponse(new FulfilledPromise($trans->response));
         } catch (RequestException $e) {
             // Wrap the exception in a promise if the user asked for a future.
             return new FutureResponse(new RejectedPromise($e));
         }
     } else {
         try {
             $fn($trans);
             return $trans->response instanceof FutureInterface ? $trans->response->wait() : $trans->response;
         } catch (\Exception $e) {
             throw RequestException::wrapException($trans->request, $e);
         }
     }
 }
Example #17
0
 private function add_auth(RequestInterface $request, $value)
 {
     if (!$value) {
         return;
     } elseif (is_array($value)) {
         $authType = isset($value[2]) ? strtolower($value[2]) : 'basic';
     } else {
         $authType = strtolower($value);
     }
     $request->getConfig()->set('auth', $value);
     if ($authType == 'basic') {
         $request->setHeader('Authorization', 'Basic ' . base64_encode("{$value['0']}:{$value['1']}"));
     } elseif ($authType == 'digest') {
         // Currently only implemented by the cURL adapter.
         // @todo: Need an event listener solution that does not rely on cURL
         $config = $request->getConfig();
         $config->setPath('curl/' . CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
         $config->setPath('curl/' . CURLOPT_USERPWD, "{$value['0']}:{$value['1']}");
     }
 }
 /**
  * Checks wether $request is a redirect by inspecting the "redirect_count" property of the request config
  * used by to define the number of redirects of a request GuzzleHttp\Subscriber\Redirect
  * @param RequestInterface $request
  * @return bool
  */
 private function isRedirectRequest(RequestInterface $request)
 {
     $isRedirect = $request->getConfig()->get("redirect_count");
     return $isRedirect !== null && $isRedirect > 0;
 }
 private function applyCustomOptions(RequestInterface $request, array &$options)
 {
     // Overwrite any generated options with custom options
     if ($custom = $request->getConfig()['stream_context']) {
         if (!is_array($custom)) {
             throw new AdapterException('stream_context must be an array');
         }
         $options = array_replace_recursive($options, $custom);
     }
 }
 protected function cacheMiss(RequestInterface $request)
 {
     $request->getConfig()->set('cache_lookup', 'MISS');
 }
Example #21
0
 public function send(RequestInterface $request)
 {
     $isFuture = $request->getConfig()->get('future');
     $trans = new Transaction($this, $request, $isFuture);
     $fn = $this->fsm;
     try {
         $fn($trans);
         if ($isFuture) {
             // Turn the normal response into a future if needed.
             return $trans->response instanceof FutureInterface ? $trans->response : new FutureResponse(new FulfilledPromise($trans->response));
         }
         // Resolve deep futures if this is not a future
         // transaction. This accounts for things like retries
         // that do not have an immediate side-effect.
         while ($trans->response instanceof FutureInterface) {
             $trans->response = $trans->response->wait();
         }
         return $trans->response;
     } catch (\Exception $e) {
         if ($isFuture) {
             // Wrap the exception in a promise
             return new FutureResponse(new RejectedPromise($e));
         }
         throw RequestException::wrapException($trans->request, $e);
     }
 }
 /**
  * @param RequestInterface $request
  * @return RequestInterface
  */
 public function setupRequest(RequestInterface $request)
 {
     $request->getConfig()->set("proxy", $this->getProxyString());
     return $request;
 }