2 namespace GuzzleHttp\Handler;
4 use GuzzleHttp\Exception\RequestException;
5 use GuzzleHttp\HandlerStack;
6 use GuzzleHttp\Promise\PromiseInterface;
7 use GuzzleHttp\Promise\RejectedPromise;
8 use GuzzleHttp\TransferStats;
9 use Psr\Http\Message\RequestInterface;
10 use Psr\Http\Message\ResponseInterface;
13 * Handler that returns responses or throw exceptions from a queue.
15 class MockHandler implements \Countable
24 * Creates a new MockHandler that uses the default handler stack list of
27 * @param array $queue Array of responses, callables, or exceptions.
28 * @param callable $onFulfilled Callback to invoke when the return value is fulfilled.
29 * @param callable $onRejected Callback to invoke when the return value is rejected.
31 * @return HandlerStack
33 public static function createWithMiddleware(
35 callable $onFulfilled = null,
36 callable $onRejected = null
38 return HandlerStack::create(new self($queue, $onFulfilled, $onRejected));
42 * The passed in value must be an array of
43 * {@see Psr7\Http\Message\ResponseInterface} objects, Exceptions,
44 * callables, or Promises.
47 * @param callable $onFulfilled Callback to invoke when the return value is fulfilled.
48 * @param callable $onRejected Callback to invoke when the return value is rejected.
50 public function __construct(
52 callable $onFulfilled = null,
53 callable $onRejected = null
55 $this->onFulfilled = $onFulfilled;
56 $this->onRejected = $onRejected;
59 call_user_func_array([$this, 'append'], $queue);
63 public function __invoke(RequestInterface $request, array $options)
66 throw new \OutOfBoundsException('Mock queue is empty');
69 if (isset($options['delay'])) {
70 usleep($options['delay'] * 1000);
73 $this->lastRequest = $request;
74 $this->lastOptions = $options;
75 $response = array_shift($this->queue);
77 if (isset($options['on_headers'])) {
78 if (!is_callable($options['on_headers'])) {
79 throw new \InvalidArgumentException('on_headers must be callable');
82 $options['on_headers']($response);
83 } catch (\Exception $e) {
84 $msg = 'An error was encountered during the on_headers event';
85 $response = new RequestException($msg, $request, $response, $e);
89 if (is_callable($response)) {
90 $response = call_user_func($response, $request, $options);
93 $response = $response instanceof \Exception
94 ? \GuzzleHttp\Promise\rejection_for($response)
95 : \GuzzleHttp\Promise\promise_for($response);
97 return $response->then(
98 function ($value) use ($request, $options) {
99 $this->invokeStats($request, $options, $value);
100 if ($this->onFulfilled) {
101 call_user_func($this->onFulfilled, $value);
103 if (isset($options['sink'])) {
104 $contents = (string) $value->getBody();
105 $sink = $options['sink'];
107 if (is_resource($sink)) {
108 fwrite($sink, $contents);
109 } elseif (is_string($sink)) {
110 file_put_contents($sink, $contents);
111 } elseif ($sink instanceof \Psr\Http\Message\StreamInterface) {
112 $sink->write($contents);
118 function ($reason) use ($request, $options) {
119 $this->invokeStats($request, $options, null, $reason);
120 if ($this->onRejected) {
121 call_user_func($this->onRejected, $reason);
123 return \GuzzleHttp\Promise\rejection_for($reason);
129 * Adds one or more variadic requests, exceptions, callables, or promises
132 public function append()
134 foreach (func_get_args() as $value) {
135 if ($value instanceof ResponseInterface
136 || $value instanceof \Exception
137 || $value instanceof PromiseInterface
138 || is_callable($value)
140 $this->queue[] = $value;
142 throw new \InvalidArgumentException('Expected a response or '
143 . 'exception. Found ' . \GuzzleHttp\describe_type($value));
149 * Get the last received request.
151 * @return RequestInterface
153 public function getLastRequest()
155 return $this->lastRequest;
159 * Get the last received request options.
163 public function getLastOptions()
165 return $this->lastOptions;
169 * Returns the number of remaining items in the queue.
173 public function count()
175 return count($this->queue);
178 private function invokeStats(
179 RequestInterface $request,
181 ResponseInterface $response = null,
184 if (isset($options['on_stats'])) {
185 $stats = new TransferStats($request, $response, 0, $reason);
186 call_user_func($options['on_stats'], $stats);