public function visit(CommandInterface $command, RequestInterface $request, Parameter $param, $value) { $this->fqname = $command->getName(); $query = array(); $this->customResolver($value, $param, $query, $param->getWireName()); $request->addPostFields($query); }
public function visit(CommandInterface $command, RequestInterface $request, Parameter $param, $value) { $value = $param->filter($value); if ($value instanceof PostFileInterface) { $request->addPostFile($value); } else { $request->addPostFile($param->getWireName(), $value); } }
/** * Add a prefixed array of headers to the request * * @param RequestInterface $request Request to update * @param Parameter $param Parameter object * @param array $value Header array to add * * @throws InvalidArgumentException */ protected function addPrefixedHeaders(RequestInterface $request, Parameter $param, $value) { if (!is_array($value)) { throw new InvalidArgumentException('An array of mapped headers expected, but received a single value'); } $prefix = $param->getSentAs(); foreach ($value as $headerName => $headerValue) { $request->setHeader($prefix . $headerName, $headerValue); } }
public function visit(CommandInterface $command, RequestInterface $request, Parameter $param, $value) { $value = $param->filter($value); $entityBody = EntityBody::factory($value); $request->setBody($entityBody); $this->addExpectHeader($request, $entityBody, $param->getData('expect_header')); // Add the Content-Encoding header if one is set on the EntityBody if ($encoding = $entityBody->getContentEncoding()) { $request->setHeader('Content-Encoding', $encoding); } }
public function after(CommandInterface $command, RequestInterface $request) { if (isset($this->data[$command])) { // Don't overwrite the Content-Type if one is set if ($this->jsonContentType && !$request->hasHeader('Content-Type')) { $request->setHeader('Content-Type', $this->jsonContentType); } $request->setBody(json_encode($this->data[$command])); unset($this->data[$command]); } }
/** * Add a request to the history * * @param RequestInterface $request Request to add * @param Response $response Response of the request * * @return HistoryPlugin */ public function add(RequestInterface $request, Response $response = null) { if (!$response && $request->getResponse()) { $response = $request->getResponse(); } $this->transactions[] = array('request' => $request, 'response' => $response); if (count($this->transactions) > $this->getlimit()) { array_shift($this->transactions); } return $this; }
public function canCacheRequest(RequestInterface $request) { // Only GET and HEAD requests can be cached if ($request->getMethod() != RequestInterface::GET && $request->getMethod() != RequestInterface::HEAD) { return false; } // Never cache requests when using no-store if ($request->hasHeader('Cache-Control') && $request->getHeader('Cache-Control')->hasDirective('no-store')) { return false; } return true; }
/** * Get the canonicalized query/parameter string for a request * * @param RequestInterface $request Request used to build canonicalized string * * @return string */ private function getCanonicalizedParameterString(RequestInterface $request) { if ($request->getMethod() == 'POST') { $params = $request->getPostFields()->toArray(); } else { $params = $request->getQuery()->toArray(); } // Don't resign a previous signature value unset($params['Signature']); uksort($params, 'strcmp'); $str = ''; foreach ($params as $key => $val) { $str .= rawurlencode($key) . '=' . rawurlencode($val) . '&'; } return substr($str, 0, -1); }
/** * Factory method to create a new response exception based on the response code. * * @param RequestInterface $request Request * @param Response $response Response received * * @return BadResponseException */ public static function factory(RequestInterface $request, Response $response) { if ($response->isClientError()) { $label = 'Client error response'; $class = __NAMESPACE__ . '\\ClientErrorResponseException'; } elseif ($response->isServerError()) { $label = 'Server error response'; $class = __NAMESPACE__ . '\\ServerErrorResponseException'; } else { $label = 'Unsuccessful response'; $class = __CLASS__; } $message = $label . PHP_EOL . implode(PHP_EOL, array('[status code] ' . $response->getStatusCode(), '[reason phrase] ' . $response->getReasonPhrase(), '[url] ' . $request->getUrl())); $e = new $class($message); $e->setResponse($response); $e->setRequest($request); return $e; }
/** * Read data from the request body and send it to curl * * @param resource $ch Curl handle * @param resource $fd File descriptor * @param int $length Amount of data to read * * @return string */ public function readRequestBody($ch, $fd, $length) { if (!($body = $this->request->getBody())) { return ''; } $read = (string) $body->read($length); if ($this->emitIo) { $this->request->dispatch('curl.callback.read', array('request' => $this->request, 'read' => $read)); } return $read; }
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)); }
public function after(CommandInterface $command, RequestInterface $request) { $xml = null; // If data was found that needs to be serialized, then do so if (isset($this->data[$command])) { $xml = $this->finishDocument($this->data[$command]); unset($this->data[$command]); } else { // Check if XML should always be sent for the command $operation = $command->getOperation(); if ($operation->getData('xmlAllowEmpty')) { $xmlWriter = $this->createRootElement($operation); $xml = $this->finishDocument($xmlWriter); } } if ($xml) { // Don't overwrite the Content-Type if one is set if ($this->contentType && !$request->hasHeader('Content-Type')) { $request->setHeader('Content-Type', $this->contentType); } $request->setBody($xml); } }
/** * Add proxy parameters to the context if needed * * @param RequestInterface $request Request */ protected function addProxyOptions(RequestInterface $request) { if ($proxy = $request->getCurlOptions()->get(CURLOPT_PROXY)) { $this->setContextValue('http', 'proxy', $proxy); } }
public function visit(CommandInterface $command, RequestInterface $request, Parameter $param, $value) { $request->setResponseBody($value); }
/** * Update a request based on the log messages of the CurlHandle * * @param RequestInterface $request Request to update */ public function updateRequestFromTransfer(RequestInterface $request) { if (!$request->getResponse()) { return; } // Update the transfer stats of the response $request->getResponse()->setInfo($this->getInfo()); if (!($log = $this->getStderr(true))) { return; } // Parse the cURL stderr output for outgoing requests $headers = ''; fseek($log, 0); while (($line = fgets($log)) !== false) { if ($line && $line[0] == '>') { $headers = substr(trim($line), 2) . "\r\n"; while (($line = fgets($log)) !== false) { if ($line[0] == '*' || $line[0] == '<') { break; } else { $headers .= trim($line) . "\r\n"; } } } } // Add request headers to the request exactly as they were sent if ($headers) { $parsed = ParserRegistry::getInstance()->getParser('message')->parseRequest($headers); if (!empty($parsed['headers'])) { $request->setHeaders(array()); foreach ($parsed['headers'] as $name => $value) { $request->setHeader($name, $value); } } if (!empty($parsed['version'])) { $request->setProtocolVersion($parsed['version']); } } }
/** * 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': $result = $handle && $handle->getInfo(CURLINFO_CONNECT_TIME) ? $handle->getInfo(CURLINFO_CONNECT_TIME) : ($response ? $response->getInfo('connect_time') : ''); break; case 'total_time': $result = $handle && $handle->getInfo(CURLINFO_TOTAL_TIME) ? $handle->getInfo(CURLINFO_TOTAL_TIME) : ($response ? $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 ($response && strpos($matches[1], 'res_header_') === 0) { $result = $response->getHeader(substr($matches[1], 11)); } } $cache[$matches[1]] = $result; return $result; }, $this->template); }
protected function visit_ssl_key(RequestInterface $request, $value, $flags) { if (is_array($value)) { $request->getCurlOptions()->set(CURLOPT_SSLKEY, $value[0]); $request->getCurlOptions()->set(CURLOPT_SSLKEYPASSWD, $value[1]); } else { $request->getCurlOptions()->set(CURLOPT_SSLKEY, $value); } }
/** * Create a pre-signed URL for a request * * @param RequestInterface $request Request to generate the URL for. Use the factory methods of the client to * create this request object * @param int|string|\DateTime $expires The time at which the URL should expire. This can be a Unix timestamp, a * PHP DateTime object, or a string that can be evaluated by strtotime * * @return string * @throws InvalidArgumentException if the request is not associated with this client object */ public function createPresignedUrl(RequestInterface $request, $expires) { if ($request->getClient() !== $this) { throw new InvalidArgumentException('The request object must be associated with the client. Use the ' . '$client->get(), $client->head(), $client->post(), $client->put(), etc. methods when passing in a ' . 'request object'); } return $this->signature->createPresignedUrl($request, $this->credentials, $expires); }
/** * @link https://github.com/guzzle/guzzle/issues/710 */ private function validateResponseWasSet(RequestInterface $request) { if ($request->getResponse()) { return true; } $body = $request instanceof EntityEnclosingRequestInterface ? $request->getBody() : null; if (!$body) { $rex = new RequestException('No response was received for a request with no body. This' . ' could mean that you are saturating your network.'); $rex->setRequest($request); $this->removeErroredRequest($request, $rex); } elseif (!$body->isSeekable() || !$body->seek(0)) { // Nothing we can do with this. Sorry! $rex = new RequestException('The connection was unexpectedly closed. The request would' . ' have been retried, but attempting to rewind the' . ' request body failed.'); $rex->setRequest($request); $this->removeErroredRequest($request, $rex); } else { $this->remove($request); // Add the request back to the batch to retry automatically. $this->requests[] = $request; $this->addHandle($request); } return false; }
/** * 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()), ' .'); }
/** * Throw a too many redirects exception for a request * * @param RequestInterface $original Request * @param int $max Max allowed redirects * * @throws TooManyRedirectsException when too many redirects have been issued */ protected function throwTooManyRedirectsException(RequestInterface $original, $max) { $original->getEventDispatcher()->addListener('request.complete', $func = function ($e) use(&$func, $original, $max) { $original->getEventDispatcher()->removeListener('request.complete', $func); $str = "{$max} redirects were issued for this request:\n" . $e['request']->getRawHeaders(); throw new TooManyRedirectsException($str); }); }
public function visit(CommandInterface $command, RequestInterface $request, Parameter $param, $value) { $request->setPostField($param->getWireName(), $this->prepareValue($value, $param)); }
private function moveHeadersToQuery(RequestInterface $request) { $query = $request->getQuery(); foreach ($request->getHeaders() as $name => $header) { if (substr($name, 0, 5) == 'x-amz') { $query[$header->getName()] = (string) $header; } if ($name !== 'host') { $request->removeHeader($name); } } }
/** * 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)); } } }
/** * Get a response from the front of the list and add it to a request * * @param RequestInterface $request Request to mock * * @return self * @throws CurlException When request.send is called and an exception is queued */ public function dequeue(RequestInterface $request) { $this->dispatch('mock.request', array('plugin' => $this, 'request' => $request)); $item = array_shift($this->queue); if ($item instanceof Response) { if ($this->readBodies && $request instanceof EntityEnclosingRequestInterface) { $request->getEventDispatcher()->addListener('request.sent', $f = function (Event $event) use(&$f) { while ($data = $event['request']->getBody()->read(8096)) { } // Remove the listener after one-time use $event['request']->getEventDispatcher()->removeListener('request.sent', $f); }); } $request->setResponse($item); } elseif ($item instanceof CurlException) { // Emulates exceptions encountered while transferring requests $item->setRequest($request); $state = $request->setState(RequestInterface::STATE_ERROR, array('exception' => $item)); // Only throw if the exception wasn't handled if ($state == RequestInterface::STATE_ERROR) { throw $item; } } return $this; }
/** * 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; }
/** * Amazon S3 does not double-encode the path component in the canonical req */ protected function createCanonicalizedPath(RequestInterface $request) { return '/' . ltrim($request->getPath(), '/'); }
/** * Handles a 200 response response from revalidating. The server does not support validation, so use this response. * * @param RequestInterface $request Request that was sent * @param Response $validateResponse Response received * * @return bool Returns true if valid, false if invalid */ protected function handle200Response(RequestInterface $request, Response $validateResponse) { $request->setResponse($validateResponse); if ($this->canCache->canCacheResponse($validateResponse)) { $this->storage->cache($request, $validateResponse); } return false; }
/** * Returns a Nonce Based on the unique id and URL. This will allow for multiple requests in parallel with the same * exact timestamp to use separate nonce's. * * @param RequestInterface $request Request to generate a nonce for * * @return string */ public function generateNonce(RequestInterface $request) { return sha1(uniqid('', true) . $request->getUrl()); }
/** * 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); }