Mercurial > hg > cmmr2012-drupal-site
comparison vendor/zendframework/zend-diactoros/src/RequestTrait.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 /** | |
3 * Zend Framework (http://framework.zend.com/) | |
4 * | |
5 * @see http://github.com/zendframework/zend-diactoros for the canonical source repository | |
6 * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com) | |
7 * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License | |
8 */ | |
9 | |
10 namespace Zend\Diactoros; | |
11 | |
12 use InvalidArgumentException; | |
13 use Psr\Http\Message\StreamInterface; | |
14 use Psr\Http\Message\UriInterface; | |
15 | |
16 /** | |
17 * Trait with common request behaviors. | |
18 * | |
19 * Server and client-side requests differ slightly in how the Host header is | |
20 * handled; on client-side, it should be calculated on-the-fly from the | |
21 * composed URI (if present), while on server-side, it will be calculated from | |
22 * the environment. As such, this trait exists to provide the common code | |
23 * between both client-side and server-side requests, and each can then | |
24 * use the headers functionality required by their implementations. | |
25 */ | |
26 trait RequestTrait | |
27 { | |
28 use MessageTrait; | |
29 | |
30 /** | |
31 * @var string | |
32 */ | |
33 private $method = ''; | |
34 | |
35 /** | |
36 * The request-target, if it has been provided or calculated. | |
37 * | |
38 * @var null|string | |
39 */ | |
40 private $requestTarget; | |
41 | |
42 /** | |
43 * @var UriInterface | |
44 */ | |
45 private $uri; | |
46 | |
47 /** | |
48 * Initialize request state. | |
49 * | |
50 * Used by constructors. | |
51 * | |
52 * @param null|string|UriInterface $uri URI for the request, if any. | |
53 * @param null|string $method HTTP method for the request, if any. | |
54 * @param string|resource|StreamInterface $body Message body, if any. | |
55 * @param array $headers Headers for the message, if any. | |
56 * @throws InvalidArgumentException for any invalid value. | |
57 */ | |
58 private function initialize($uri = null, $method = null, $body = 'php://memory', array $headers = []) | |
59 { | |
60 $this->validateMethod($method); | |
61 | |
62 $this->method = $method ?: ''; | |
63 $this->uri = $this->createUri($uri); | |
64 $this->stream = $this->getStream($body, 'wb+'); | |
65 | |
66 $this->setHeaders($headers); | |
67 | |
68 // per PSR-7: attempt to set the Host header from a provided URI if no | |
69 // Host header is provided | |
70 if (! $this->hasHeader('Host') && $this->uri->getHost()) { | |
71 $this->headerNames['host'] = 'Host'; | |
72 $this->headers['Host'] = [$this->getHostFromUri()]; | |
73 } | |
74 } | |
75 | |
76 /** | |
77 * Create and return a URI instance. | |
78 * | |
79 * If `$uri` is a already a `UriInterface` instance, returns it. | |
80 * | |
81 * If `$uri` is a string, passes it to the `Uri` constructor to return an | |
82 * instance. | |
83 * | |
84 * If `$uri is null, creates and returns an empty `Uri` instance. | |
85 * | |
86 * Otherwise, it raises an exception. | |
87 * | |
88 * @param null|string|UriInterface $uri | |
89 * @return UriInterface | |
90 * @throws InvalidArgumentException | |
91 */ | |
92 private function createUri($uri) | |
93 { | |
94 if ($uri instanceof UriInterface) { | |
95 return $uri; | |
96 } | |
97 if (is_string($uri)) { | |
98 return new Uri($uri); | |
99 } | |
100 if ($uri === null) { | |
101 return new Uri(); | |
102 } | |
103 throw new InvalidArgumentException( | |
104 'Invalid URI provided; must be null, a string, or a Psr\Http\Message\UriInterface instance' | |
105 ); | |
106 } | |
107 | |
108 /** | |
109 * Retrieves the message's request target. | |
110 * | |
111 * Retrieves the message's request-target either as it will appear (for | |
112 * clients), as it appeared at request (for servers), or as it was | |
113 * specified for the instance (see withRequestTarget()). | |
114 * | |
115 * In most cases, this will be the origin-form of the composed URI, | |
116 * unless a value was provided to the concrete implementation (see | |
117 * withRequestTarget() below). | |
118 * | |
119 * If no URI is available, and no request-target has been specifically | |
120 * provided, this method MUST return the string "/". | |
121 * | |
122 * @return string | |
123 */ | |
124 public function getRequestTarget() | |
125 { | |
126 if (null !== $this->requestTarget) { | |
127 return $this->requestTarget; | |
128 } | |
129 | |
130 $target = $this->uri->getPath(); | |
131 if ($this->uri->getQuery()) { | |
132 $target .= '?' . $this->uri->getQuery(); | |
133 } | |
134 | |
135 if (empty($target)) { | |
136 $target = '/'; | |
137 } | |
138 | |
139 return $target; | |
140 } | |
141 | |
142 /** | |
143 * Create a new instance with a specific request-target. | |
144 * | |
145 * If the request needs a non-origin-form request-target — e.g., for | |
146 * specifying an absolute-form, authority-form, or asterisk-form — | |
147 * this method may be used to create an instance with the specified | |
148 * request-target, verbatim. | |
149 * | |
150 * This method MUST be implemented in such a way as to retain the | |
151 * immutability of the message, and MUST return a new instance that has the | |
152 * changed request target. | |
153 * | |
154 * @link http://tools.ietf.org/html/rfc7230#section-2.7 (for the various | |
155 * request-target forms allowed in request messages) | |
156 * @param mixed $requestTarget | |
157 * @return static | |
158 * @throws InvalidArgumentException if the request target is invalid. | |
159 */ | |
160 public function withRequestTarget($requestTarget) | |
161 { | |
162 if (preg_match('#\s#', $requestTarget)) { | |
163 throw new InvalidArgumentException( | |
164 'Invalid request target provided; cannot contain whitespace' | |
165 ); | |
166 } | |
167 | |
168 $new = clone $this; | |
169 $new->requestTarget = $requestTarget; | |
170 return $new; | |
171 } | |
172 | |
173 /** | |
174 * Retrieves the HTTP method of the request. | |
175 * | |
176 * @return string Returns the request method. | |
177 */ | |
178 public function getMethod() | |
179 { | |
180 return $this->method; | |
181 } | |
182 | |
183 /** | |
184 * Return an instance with the provided HTTP method. | |
185 * | |
186 * While HTTP method names are typically all uppercase characters, HTTP | |
187 * method names are case-sensitive and thus implementations SHOULD NOT | |
188 * modify the given string. | |
189 * | |
190 * This method MUST be implemented in such a way as to retain the | |
191 * immutability of the message, and MUST return an instance that has the | |
192 * changed request method. | |
193 * | |
194 * @param string $method Case-insensitive method. | |
195 * @return static | |
196 * @throws InvalidArgumentException for invalid HTTP methods. | |
197 */ | |
198 public function withMethod($method) | |
199 { | |
200 $this->validateMethod($method); | |
201 $new = clone $this; | |
202 $new->method = $method; | |
203 return $new; | |
204 } | |
205 | |
206 /** | |
207 * Retrieves the URI instance. | |
208 * | |
209 * This method MUST return a UriInterface instance. | |
210 * | |
211 * @link http://tools.ietf.org/html/rfc3986#section-4.3 | |
212 * @return UriInterface Returns a UriInterface instance | |
213 * representing the URI of the request, if any. | |
214 */ | |
215 public function getUri() | |
216 { | |
217 return $this->uri; | |
218 } | |
219 | |
220 /** | |
221 * Returns an instance with the provided URI. | |
222 * | |
223 * This method will update the Host header of the returned request by | |
224 * default if the URI contains a host component. If the URI does not | |
225 * contain a host component, any pre-existing Host header will be carried | |
226 * over to the returned request. | |
227 * | |
228 * You can opt-in to preserving the original state of the Host header by | |
229 * setting `$preserveHost` to `true`. When `$preserveHost` is set to | |
230 * `true`, the returned request will not update the Host header of the | |
231 * returned message -- even if the message contains no Host header. This | |
232 * means that a call to `getHeader('Host')` on the original request MUST | |
233 * equal the return value of a call to `getHeader('Host')` on the returned | |
234 * request. | |
235 * | |
236 * This method MUST be implemented in such a way as to retain the | |
237 * immutability of the message, and MUST return an instance that has the | |
238 * new UriInterface instance. | |
239 * | |
240 * @link http://tools.ietf.org/html/rfc3986#section-4.3 | |
241 * @param UriInterface $uri New request URI to use. | |
242 * @param bool $preserveHost Preserve the original state of the Host header. | |
243 * @return static | |
244 */ | |
245 public function withUri(UriInterface $uri, $preserveHost = false) | |
246 { | |
247 $new = clone $this; | |
248 $new->uri = $uri; | |
249 | |
250 if ($preserveHost && $this->hasHeader('Host')) { | |
251 return $new; | |
252 } | |
253 | |
254 if (! $uri->getHost()) { | |
255 return $new; | |
256 } | |
257 | |
258 $host = $uri->getHost(); | |
259 if ($uri->getPort()) { | |
260 $host .= ':' . $uri->getPort(); | |
261 } | |
262 | |
263 $new->headerNames['host'] = 'Host'; | |
264 | |
265 // Remove an existing host header if present, regardless of current | |
266 // de-normalization of the header name. | |
267 // @see https://github.com/zendframework/zend-diactoros/issues/91 | |
268 foreach (array_keys($new->headers) as $header) { | |
269 if (strtolower($header) === 'host') { | |
270 unset($new->headers[$header]); | |
271 } | |
272 } | |
273 | |
274 $new->headers['Host'] = [$host]; | |
275 | |
276 return $new; | |
277 } | |
278 | |
279 /** | |
280 * Validate the HTTP method | |
281 * | |
282 * @param null|string $method | |
283 * @throws InvalidArgumentException on invalid HTTP method. | |
284 */ | |
285 private function validateMethod($method) | |
286 { | |
287 if (null === $method) { | |
288 return; | |
289 } | |
290 | |
291 if (! is_string($method)) { | |
292 throw new InvalidArgumentException(sprintf( | |
293 'Unsupported HTTP method; must be a string, received %s', | |
294 (is_object($method) ? get_class($method) : gettype($method)) | |
295 )); | |
296 } | |
297 | |
298 if (! preg_match('/^[!#$%&\'*+.^_`\|~0-9a-z-]+$/i', $method)) { | |
299 throw new InvalidArgumentException(sprintf( | |
300 'Unsupported HTTP method "%s" provided', | |
301 $method | |
302 )); | |
303 } | |
304 } | |
305 | |
306 /** | |
307 * Retrieve the host from the URI instance | |
308 * | |
309 * @return string | |
310 */ | |
311 private function getHostFromUri() | |
312 { | |
313 $host = $this->uri->getHost(); | |
314 $host .= $this->uri->getPort() ? ':' . $this->uri->getPort() : ''; | |
315 return $host; | |
316 } | |
317 } |