Mercurial > hg > cmmr2012-drupal-site
comparison vendor/guzzlehttp/guzzle/src/HandlerStack.php @ 0:c75dbcec494b
Initial commit from drush-created site
author | Chris Cannam |
---|---|
date | Thu, 05 Jul 2018 14:24:15 +0000 |
parents | |
children | 5311817fb629 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c75dbcec494b |
---|---|
1 <?php | |
2 namespace GuzzleHttp; | |
3 | |
4 use Psr\Http\Message\RequestInterface; | |
5 | |
6 /** | |
7 * Creates a composed Guzzle handler function by stacking middlewares on top of | |
8 * an HTTP handler function. | |
9 */ | |
10 class HandlerStack | |
11 { | |
12 /** @var callable */ | |
13 private $handler; | |
14 | |
15 /** @var array */ | |
16 private $stack = []; | |
17 | |
18 /** @var callable|null */ | |
19 private $cached; | |
20 | |
21 /** | |
22 * Creates a default handler stack that can be used by clients. | |
23 * | |
24 * The returned handler will wrap the provided handler or use the most | |
25 * appropriate default handler for you system. The returned HandlerStack has | |
26 * support for cookies, redirects, HTTP error exceptions, and preparing a body | |
27 * before sending. | |
28 * | |
29 * The returned handler stack can be passed to a client in the "handler" | |
30 * option. | |
31 * | |
32 * @param callable $handler HTTP handler function to use with the stack. If no | |
33 * handler is provided, the best handler for your | |
34 * system will be utilized. | |
35 * | |
36 * @return HandlerStack | |
37 */ | |
38 public static function create(callable $handler = null) | |
39 { | |
40 $stack = new self($handler ?: choose_handler()); | |
41 $stack->push(Middleware::httpErrors(), 'http_errors'); | |
42 $stack->push(Middleware::redirect(), 'allow_redirects'); | |
43 $stack->push(Middleware::cookies(), 'cookies'); | |
44 $stack->push(Middleware::prepareBody(), 'prepare_body'); | |
45 | |
46 return $stack; | |
47 } | |
48 | |
49 /** | |
50 * @param callable $handler Underlying HTTP handler. | |
51 */ | |
52 public function __construct(callable $handler = null) | |
53 { | |
54 $this->handler = $handler; | |
55 } | |
56 | |
57 /** | |
58 * Invokes the handler stack as a composed handler | |
59 * | |
60 * @param RequestInterface $request | |
61 * @param array $options | |
62 */ | |
63 public function __invoke(RequestInterface $request, array $options) | |
64 { | |
65 $handler = $this->resolve(); | |
66 | |
67 return $handler($request, $options); | |
68 } | |
69 | |
70 /** | |
71 * Dumps a string representation of the stack. | |
72 * | |
73 * @return string | |
74 */ | |
75 public function __toString() | |
76 { | |
77 $depth = 0; | |
78 $stack = []; | |
79 if ($this->handler) { | |
80 $stack[] = "0) Handler: " . $this->debugCallable($this->handler); | |
81 } | |
82 | |
83 $result = ''; | |
84 foreach (array_reverse($this->stack) as $tuple) { | |
85 $depth++; | |
86 $str = "{$depth}) Name: '{$tuple[1]}', "; | |
87 $str .= "Function: " . $this->debugCallable($tuple[0]); | |
88 $result = "> {$str}\n{$result}"; | |
89 $stack[] = $str; | |
90 } | |
91 | |
92 foreach (array_keys($stack) as $k) { | |
93 $result .= "< {$stack[$k]}\n"; | |
94 } | |
95 | |
96 return $result; | |
97 } | |
98 | |
99 /** | |
100 * Set the HTTP handler that actually returns a promise. | |
101 * | |
102 * @param callable $handler Accepts a request and array of options and | |
103 * returns a Promise. | |
104 */ | |
105 public function setHandler(callable $handler) | |
106 { | |
107 $this->handler = $handler; | |
108 $this->cached = null; | |
109 } | |
110 | |
111 /** | |
112 * Returns true if the builder has a handler. | |
113 * | |
114 * @return bool | |
115 */ | |
116 public function hasHandler() | |
117 { | |
118 return (bool) $this->handler; | |
119 } | |
120 | |
121 /** | |
122 * Unshift a middleware to the bottom of the stack. | |
123 * | |
124 * @param callable $middleware Middleware function | |
125 * @param string $name Name to register for this middleware. | |
126 */ | |
127 public function unshift(callable $middleware, $name = null) | |
128 { | |
129 array_unshift($this->stack, [$middleware, $name]); | |
130 $this->cached = null; | |
131 } | |
132 | |
133 /** | |
134 * Push a middleware to the top of the stack. | |
135 * | |
136 * @param callable $middleware Middleware function | |
137 * @param string $name Name to register for this middleware. | |
138 */ | |
139 public function push(callable $middleware, $name = '') | |
140 { | |
141 $this->stack[] = [$middleware, $name]; | |
142 $this->cached = null; | |
143 } | |
144 | |
145 /** | |
146 * Add a middleware before another middleware by name. | |
147 * | |
148 * @param string $findName Middleware to find | |
149 * @param callable $middleware Middleware function | |
150 * @param string $withName Name to register for this middleware. | |
151 */ | |
152 public function before($findName, callable $middleware, $withName = '') | |
153 { | |
154 $this->splice($findName, $withName, $middleware, true); | |
155 } | |
156 | |
157 /** | |
158 * Add a middleware after another middleware by name. | |
159 * | |
160 * @param string $findName Middleware to find | |
161 * @param callable $middleware Middleware function | |
162 * @param string $withName Name to register for this middleware. | |
163 */ | |
164 public function after($findName, callable $middleware, $withName = '') | |
165 { | |
166 $this->splice($findName, $withName, $middleware, false); | |
167 } | |
168 | |
169 /** | |
170 * Remove a middleware by instance or name from the stack. | |
171 * | |
172 * @param callable|string $remove Middleware to remove by instance or name. | |
173 */ | |
174 public function remove($remove) | |
175 { | |
176 $this->cached = null; | |
177 $idx = is_callable($remove) ? 0 : 1; | |
178 $this->stack = array_values(array_filter( | |
179 $this->stack, | |
180 function ($tuple) use ($idx, $remove) { | |
181 return $tuple[$idx] !== $remove; | |
182 } | |
183 )); | |
184 } | |
185 | |
186 /** | |
187 * Compose the middleware and handler into a single callable function. | |
188 * | |
189 * @return callable | |
190 */ | |
191 public function resolve() | |
192 { | |
193 if (!$this->cached) { | |
194 if (!($prev = $this->handler)) { | |
195 throw new \LogicException('No handler has been specified'); | |
196 } | |
197 | |
198 foreach (array_reverse($this->stack) as $fn) { | |
199 $prev = $fn[0]($prev); | |
200 } | |
201 | |
202 $this->cached = $prev; | |
203 } | |
204 | |
205 return $this->cached; | |
206 } | |
207 | |
208 /** | |
209 * @param $name | |
210 * @return int | |
211 */ | |
212 private function findByName($name) | |
213 { | |
214 foreach ($this->stack as $k => $v) { | |
215 if ($v[1] === $name) { | |
216 return $k; | |
217 } | |
218 } | |
219 | |
220 throw new \InvalidArgumentException("Middleware not found: $name"); | |
221 } | |
222 | |
223 /** | |
224 * Splices a function into the middleware list at a specific position. | |
225 * | |
226 * @param $findName | |
227 * @param $withName | |
228 * @param callable $middleware | |
229 * @param $before | |
230 */ | |
231 private function splice($findName, $withName, callable $middleware, $before) | |
232 { | |
233 $this->cached = null; | |
234 $idx = $this->findByName($findName); | |
235 $tuple = [$middleware, $withName]; | |
236 | |
237 if ($before) { | |
238 if ($idx === 0) { | |
239 array_unshift($this->stack, $tuple); | |
240 } else { | |
241 $replacement = [$tuple, $this->stack[$idx]]; | |
242 array_splice($this->stack, $idx, 1, $replacement); | |
243 } | |
244 } elseif ($idx === count($this->stack) - 1) { | |
245 $this->stack[] = $tuple; | |
246 } else { | |
247 $replacement = [$this->stack[$idx], $tuple]; | |
248 array_splice($this->stack, $idx, 1, $replacement); | |
249 } | |
250 } | |
251 | |
252 /** | |
253 * Provides a debug string for a given callable. | |
254 * | |
255 * @param array|callable $fn Function to write as a string. | |
256 * | |
257 * @return string | |
258 */ | |
259 private function debugCallable($fn) | |
260 { | |
261 if (is_string($fn)) { | |
262 return "callable({$fn})"; | |
263 } | |
264 | |
265 if (is_array($fn)) { | |
266 return is_string($fn[0]) | |
267 ? "callable({$fn[0]}::{$fn[1]})" | |
268 : "callable(['" . get_class($fn[0]) . "', '{$fn[1]}'])"; | |
269 } | |
270 | |
271 return 'callable(' . spl_object_hash($fn) . ')'; | |
272 } | |
273 } |