/** @dataProvider provideEntityEnclosingInterfaceMethods */
 public function testEntityEnclosingInterfaceMethods($method, array $params = [])
 {
     $this->wrappedEntityEnclosingRequest->expects($this->once())->method($method)->will($this->returnValue('ENTITY_ENCL_REQ'))->getMatcher()->parametersMatcher = new ParametersMatcher($params);
     $this->assertSame('ENTITY_ENCL_REQ', call_user_func_array([$this->unifiedEnclosingEntityRequest, $method], $params));
     $this->wrappedRequest->expects($this->any())->method('getMethod')->will($this->returnValue('METHOD'));
     $this->wrappedRequest->expects($this->any())->method('getPath')->will($this->returnValue('/foo'));
     $this->setExpectedException('BadMethodCallException', sprintf('Cannot call method "%s" on a request that does not enclose an entity. Did you expect a POST/PUT request instead of METHOD /foo?', $method));
     call_user_func_array([$this->unifiedRequest, $method], $params);
 }
Example #2
0
 protected function addExpectHeader(EntityEnclosingRequestInterface $request, EntityBodyInterface $body, $expect)
 {
     if ($expect === false) {
         $request->removeHeader('Expect');
     } elseif ($expect !== true) {
         $expect = $expect ?: 1048576;
         if (is_numeric($expect) && $body->getSize()) {
             if ($body->getSize() < $expect) {
                 $request->removeHeader('Expect');
             } else {
                 $request->setHeader('Expect', '100-Continue');
             }
         }
     }
 }
Example #3
0
 /**
  * Add the appropriate expect header to a request
  *
  * @param EntityEnclosingRequestInterface $request Request to update
  * @param EntityBodyInterface             $body    Entity body of the request
  * @param string|int                      $expect  Expect header setting
  */
 protected function addExpectHeader(EntityEnclosingRequestInterface $request, EntityBodyInterface $body, $expect)
 {
     // Allow the `expect` data parameter to be set to remove the Expect header from the request
     if ($expect === false) {
         $request->removeHeader('Expect');
     } elseif ($expect !== true) {
         // Default to using a MB as the point in which to start using the expect header
         $expect = $expect ?: 1048576;
         // If the expect_header value is numeric then only add if the size is greater than the cutoff
         if (is_numeric($expect) && $body->getSize()) {
             if ($body->getSize() < $expect) {
                 $request->removeHeader('Expect');
             } else {
                 $request->setHeader('Expect', '100-Continue');
             }
         }
     }
 }
 /**
  * Helper method to extract the items from a request object for a BatchWriteItem operation
  *
  * @param EntityEnclosingRequestInterface $request
  *
  * @return array
  */
 private function extractItemsFromRequestObject(EntityEnclosingRequestInterface $request)
 {
     $items = json_decode((string) $request->getBody(), true);
     return $this->convertResultsToUnprocessedRequests($items['RequestItems'] ?: array());
 }
Example #5
0
 /**
  * @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));
 }
Example #6
0
 /**
  * Converts a POST request to a GET request by moving POST fields into the
  * query string.
  *
  * Useful for pre-signing query protocol requests.
  *
  * @param EntityEnclosingRequestInterface $request Request to clone
  *
  * @return RequestInterface
  * @throws \InvalidArgumentException if the method is not POST
  */
 public static function convertPostToGet(EntityEnclosingRequestInterface $request)
 {
     if ($request->getMethod() !== 'POST') {
         throw new \InvalidArgumentException('Expected a POST request but ' . 'received a ' . $request->getMethod() . ' request.');
     }
     $cloned = RequestFactory::getInstance()->cloneRequestWithMethod($request, 'GET');
     // Move POST fields to the query if they are present
     foreach ($request->getPostFields() as $name => $value) {
         $cloned->getQuery()->set($name, $value);
     }
     return $cloned;
 }
Example #7
0
 protected function handleRequestBody(EntityEnclosingRequestInterface $request, array $data)
 {
     $files = array_filter($data, function ($element) {
         return is_string($element) && strpos($element, '@') === 0;
     });
     $request->addPostFields($data);
     if ($files) {
         $request->addPostFiles($files);
     }
 }
 /**
  * Handles exceptions caused by the request being too large (over 1 MB). The
  * response will have a status code of 413. In this case the batch should be
  * split up into smaller batches and retried.
  *
  * @param EntityEnclosingRequestInterface   $request             The failed request
  * @param UnprocessedWriteRequestsException $unprocessedRequests Collection of unprocessed items
  */
 protected function retryLargeRequest(EntityEnclosingRequestInterface $request, UnprocessedWriteRequestsException $unprocessedRequests)
 {
     // Collect the items out from the request object
     $items = json_decode($request->getBody(true), true);
     $items = $this->convertResultsToUnprocessedRequests($items['RequestItems']);
     // Divide batch into smaller batches and transfer them via recursion
     // NOTE: Dividing the batch into 3 (instead of 2) batches resulted in less recursion during testing
     if ($items) {
         $newBatches = array_chunk($items, ceil(count($items) / 3));
         foreach ($newBatches as $newBatch) {
             $this->performTransfer($newBatch, $unprocessedRequests);
         }
     }
 }
Example #9
0
 /**
  * Clone a request while changing the method to GET. Emulates the behavior of
  * {@see Guzzle\Http\Message\Request::clone}, but can change the HTTP method.
  *
  * @param EntityEnclosingRequestInterface $request Request to clone
  *
  * @return RequestInterface Returns a GET request
  */
 protected function cloneRequestWithGetMethod(EntityEnclosingRequestInterface $request)
 {
     // Create a new GET request using the original request's URL
     $redirectRequest = $request->getClient()->get($request->getUrl());
     $redirectRequest->getCurlOptions()->replace($request->getCurlOptions()->getAll());
     // Copy over the headers, while ensuring that the Content-Length is not copied
     $redirectRequest->setHeaders($request->getHeaders()->getAll())->removeHeader('Content-Length');
     $redirectRequest->setEventDispatcher(clone $request->getEventDispatcher());
     $redirectRequest->getParams()->replace($request->getParams()->getAll())->remove('curl_handle')->remove('queued_response')->remove('curl_multi');
     return $redirectRequest;
 }