Пример #1
0
 /**
  * Intercept the exception and inject a response
  *
  * @param puzzle_message_ResponseInterface $response Response to set
  */
 public function intercept(puzzle_message_ResponseInterface $response)
 {
     $this->stopPropagation();
     $this->getTransaction()->setResponse($response);
     $this->exception->setThrowImmediately(false);
     puzzle_event_RequestEvents::emitComplete($this->getTransaction());
 }
Пример #2
0
 private function createResponseObject(puzzle_message_RequestInterface $request, array $headers, puzzle_adapter_TransactionInterface $transaction, puzzle_stream_StreamInterface $stream)
 {
     $parts = explode(' ', array_shift($headers), 3);
     $options = array('protocol_version' => substr($parts[0], -3));
     if (isset($parts[2])) {
         $options['reason_phrase'] = $parts[2];
     }
     $response = $this->messageFactory->createResponse($parts[1], $this->headersFromLines($headers), null, $options);
     // Automatically decode responses when instructed.
     if ($request->getConfig()->get('decode_content')) {
         switch ($response->getHeader('Content-Encoding')) {
             case 'gzip':
             case 'deflate':
                 $stream = new puzzle_stream_InflateStream($stream);
                 break;
         }
     }
     // Drain the stream immediately if 'stream' was not enabled.
     $config = $request->getConfig();
     if (!$config['stream']) {
         $stream = $this->getSaveToBody($request, $stream);
     }
     $response->setBody($stream);
     $transaction->setResponse($response);
     puzzle_event_RequestEvents::emitHeaders($transaction);
     return $response;
 }
Пример #3
0
 /**
  * Receive a response header from curl
  *
  * @param resource $curl   Curl handle
  * @param string   $header Received header
  *
  * @return int
  */
 public function receiveResponseHeader($curl, $header)
 {
     static $normalize = array("\r", "\n");
     $length = strlen($header);
     $header = str_replace($normalize, '', $header);
     if (strpos($header, 'HTTP/') === 0) {
         $startLine = explode(' ', $header, 3);
         // Only download the body to a target body when a successful
         // response is received.
         if ($startLine[1][0] != '2') {
             $this->body = null;
         }
         $this->statusCode = $startLine[1];
         $this->reasonPhrase = isset($startLine[2]) ? $startLine[2] : null;
         $this->protocolVersion = substr($startLine[0], -3);
         $this->headers = array();
     } elseif ($pos = strpos($header, ':')) {
         $this->headers[substr($header, 0, $pos)][] = substr($header, $pos + 1);
     } elseif ($header == '' && $this->statusCode >= 200) {
         $response = $this->messageFactory->createResponse($this->statusCode, $this->headers, $this->body, array('protocol_version' => $this->protocolVersion, 'reason_phrase' => $this->reasonPhrase));
         $this->headers = $this->body = null;
         $this->transaction->setResponse($response);
         // Allows events to react before downloading any of the body
         puzzle_event_RequestEvents::emitHeaders($this->transaction);
     }
     return $length;
 }
Пример #4
0
 public function send(puzzle_adapter_TransactionInterface $transaction)
 {
     puzzle_event_RequestEvents::emitBefore($transaction);
     if (!$transaction->getResponse()) {
         // Read the request body if it is present
         if ($transaction->getRequest()->getBody()) {
             $transaction->getRequest()->getBody()->__toString();
         }
         $response = is_callable($this->response) ? call_user_func($this->response, $transaction) : $this->response;
         if (!$response instanceof puzzle_message_ResponseInterface) {
             throw new RuntimeException('Invalid mocked response');
         }
         $transaction->setResponse($response);
         puzzle_event_RequestEvents::emitHeaders($transaction);
         puzzle_event_RequestEvents::emitComplete($transaction);
     }
     return $transaction->getResponse();
 }
Пример #5
0
 private function validateResponseWasSet(puzzle_adapter_TransactionInterface $transaction, puzzle_adapter_curl_BatchContext $context)
 {
     if ($transaction->getResponse()) {
         return true;
     }
     $body = $transaction->getRequest()->getBody();
     if (!$body) {
         // This is weird and should probably never happen.
         puzzle_event_RequestEvents::emitError($transaction, new puzzle_exception_RequestException('No response was received for a request with no body. This' . ' could mean that you are saturating your network.', $transaction->getRequest()));
     } elseif (!$body->isSeekable() || !$body->seek(0)) {
         // Nothing we can do with this. Sorry!
         puzzle_event_RequestEvents::emitError($transaction, new puzzle_exception_RequestException('The connection was unexpectedly closed. The request would' . ' have been retried, but attempting to rewind the' . ' request body failed. Consider wrapping your request' . ' body in a CachingStream decorator to work around this' . ' issue if necessary.', $transaction->getRequest()));
     } else {
         $this->retryFailedConnection($transaction, $context);
     }
     return false;
 }
Пример #6
0
 /**
  * Convenience method for sending multiple requests in parallel and
  * retrieving a hash map of requests to response objects or
  * RequestException objects.
  *
  * Note: This method keeps every request and response in memory, and as
  * such is NOT recommended when sending a large number or an indeterminable
  * number of requests in parallel.
  *
  * @param puzzle_ClientInterface $client   Client used to send the requests
  * @param array|Iterator $requests Requests to send in parallel
  * @param array           $options  Passes through the options available in
  *                                  {@see puzzle_ClientInterface::sendAll()}
  *
  * @return SplObjectStorage Requests are the key and each value is a
  *     {@see puzzle_message_ResponseInterface} if the request succeeded
  *     or a {@see puzzle_exception_RequestException} if it failed.
  * @throws InvalidArgumentException if the event format is incorrect.
  */
 function puzzle_batch(puzzle_ClientInterface $client, $requests, array $options = array())
 {
     global $__closure_puzzle_batch_hash;
     $__closure_puzzle_batch_hash = new puzzle_SplObjectStorage();
     foreach ($requests as $request) {
         $__closure_puzzle_batch_hash->offsetSet($request);
     }
     // Merge the necessary complete and error events to the event listeners
     // so that as each request succeeds or fails, it is added to the result
     // hash.
     $options = puzzle_event_RequestEvents::convertEventArray($options, array('complete', 'error'), array('priority' => puzzle_event_RequestEvents::EARLY, 'once' => true, 'fn' => '__callback_puzzle_batch_convertEvents'));
     // Send the requests in parallel and aggregate the results.
     $client->sendAll($requests, $options);
     // Update the received value for any of the intercepted requests.
     foreach ($__closure_puzzle_batch_hash as $request) {
         $storedEvent = $__closure_puzzle_batch_hash->offsetGet($request);
         if ($storedEvent instanceof puzzle_event_CompleteEvent) {
             $__closure_puzzle_batch_hash->offsetSet($request, $storedEvent->getResponse());
         } elseif ($storedEvent instanceof puzzle_event_ErrorEvent) {
             $__closure_puzzle_batch_hash->offsetSet($request, $storedEvent->getException());
         }
     }
     return $__closure_puzzle_batch_hash;
 }
Пример #7
0
 private function handleError(puzzle_adapter_TransactionInterface $transaction, $info, $handle)
 {
     $error = curl_error($handle);
     $this->releaseEasyHandle($handle);
     puzzle_event_RequestEvents::emitError($transaction, new puzzle_exception_AdapterException("cURL error {$info['curl_result']}: {$error}"), $info);
 }
Пример #8
0
 /**
  * @dataProvider prepareEventProvider
  */
 public function testConvertsEventArrays(array $in, array $events, $add, array $out)
 {
     $result = puzzle_event_RequestEvents::convertEventArray($in, $events, $add);
     $this->assertEquals($out, $result);
 }