comparison vendor/zendframework/zend-diactoros/src/Request/Serializer.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\Request;
11
12 use InvalidArgumentException;
13 use Psr\Http\Message\RequestInterface;
14 use Psr\Http\Message\StreamInterface;
15 use UnexpectedValueException;
16 use Zend\Diactoros\AbstractSerializer;
17 use Zend\Diactoros\Request;
18 use Zend\Diactoros\Stream;
19 use Zend\Diactoros\Uri;
20
21 /**
22 * Serialize (cast to string) or deserialize (cast string to Request) messages.
23 *
24 * This class provides functionality for serializing a RequestInterface instance
25 * to a string, as well as the reverse operation of creating a Request instance
26 * from a string/stream representing a message.
27 */
28 final class Serializer extends AbstractSerializer
29 {
30 /**
31 * Deserialize a request string to a request instance.
32 *
33 * Internally, casts the message to a stream and invokes fromStream().
34 *
35 * @param string $message
36 * @return Request
37 * @throws UnexpectedValueException when errors occur parsing the message.
38 */
39 public static function fromString($message)
40 {
41 $stream = new Stream('php://temp', 'wb+');
42 $stream->write($message);
43 return self::fromStream($stream);
44 }
45
46 /**
47 * Deserialize a request stream to a request instance.
48 *
49 * @param StreamInterface $stream
50 * @return Request
51 * @throws UnexpectedValueException when errors occur parsing the message.
52 */
53 public static function fromStream(StreamInterface $stream)
54 {
55 if (! $stream->isReadable() || ! $stream->isSeekable()) {
56 throw new InvalidArgumentException('Message stream must be both readable and seekable');
57 }
58
59 $stream->rewind();
60
61 list($method, $requestTarget, $version) = self::getRequestLine($stream);
62 $uri = self::createUriFromRequestTarget($requestTarget);
63
64 list($headers, $body) = self::splitStream($stream);
65
66 return (new Request($uri, $method, $body, $headers))
67 ->withProtocolVersion($version)
68 ->withRequestTarget($requestTarget);
69 }
70
71 /**
72 * Serialize a request message to a string.
73 *
74 * @param RequestInterface $request
75 * @return string
76 */
77 public static function toString(RequestInterface $request)
78 {
79 $httpMethod = $request->getMethod();
80 if (empty($httpMethod)) {
81 throw new UnexpectedValueException('Object can not be serialized because HTTP method is empty');
82 }
83 $headers = self::serializeHeaders($request->getHeaders());
84 $body = (string) $request->getBody();
85 $format = '%s %s HTTP/%s%s%s';
86
87 if (! empty($headers)) {
88 $headers = "\r\n" . $headers;
89 }
90 if (! empty($body)) {
91 $headers .= "\r\n\r\n";
92 }
93
94 return sprintf(
95 $format,
96 $httpMethod,
97 $request->getRequestTarget(),
98 $request->getProtocolVersion(),
99 $headers,
100 $body
101 );
102 }
103
104 /**
105 * Retrieve the components of the request line.
106 *
107 * Retrieves the first line of the stream and parses it, raising an
108 * exception if it does not follow specifications; if valid, returns a list
109 * with the method, target, and version, in that order.
110 *
111 * @param StreamInterface $stream
112 * @return array
113 */
114 private static function getRequestLine(StreamInterface $stream)
115 {
116 $requestLine = self::getLine($stream);
117
118 if (! preg_match(
119 '#^(?P<method>[!\#$%&\'*+.^_`|~a-zA-Z0-9-]+) (?P<target>[^\s]+) HTTP/(?P<version>[1-9]\d*\.\d+)$#',
120 $requestLine,
121 $matches
122 )) {
123 throw new UnexpectedValueException('Invalid request line detected');
124 }
125
126 return [$matches['method'], $matches['target'], $matches['version']];
127 }
128
129 /**
130 * Create and return a Uri instance based on the provided request target.
131 *
132 * If the request target is of authority or asterisk form, an empty Uri
133 * instance is returned; otherwise, the value is used to create and return
134 * a new Uri instance.
135 *
136 * @param string $requestTarget
137 * @return Uri
138 */
139 private static function createUriFromRequestTarget($requestTarget)
140 {
141 if (preg_match('#^https?://#', $requestTarget)) {
142 return new Uri($requestTarget);
143 }
144
145 if (preg_match('#^(\*|[^/])#', $requestTarget)) {
146 return new Uri();
147 }
148
149 return new Uri($requestTarget);
150 }
151 }