Chris@0
|
1 <?php
|
Chris@0
|
2 /**
|
Chris@12
|
3 * @see https://github.com/zendframework/zend-diactoros for the canonical source repository
|
Chris@12
|
4 * @copyright Copyright (c) 2015-2017 Zend Technologies USA Inc. (http://www.zend.com)
|
Chris@0
|
5 * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License
|
Chris@0
|
6 */
|
Chris@0
|
7
|
Chris@0
|
8 namespace Zend\Diactoros\Response;
|
Chris@0
|
9
|
Chris@0
|
10 use InvalidArgumentException;
|
Chris@0
|
11 use Psr\Http\Message\ResponseInterface;
|
Chris@0
|
12 use Psr\Http\Message\StreamInterface;
|
Chris@0
|
13 use UnexpectedValueException;
|
Chris@0
|
14 use Zend\Diactoros\AbstractSerializer;
|
Chris@0
|
15 use Zend\Diactoros\Response;
|
Chris@0
|
16 use Zend\Diactoros\Stream;
|
Chris@0
|
17
|
Chris@16
|
18 use function preg_match;
|
Chris@16
|
19 use function sprintf;
|
Chris@16
|
20
|
Chris@0
|
21 final class Serializer extends AbstractSerializer
|
Chris@0
|
22 {
|
Chris@0
|
23 /**
|
Chris@0
|
24 * Deserialize a response string to a response instance.
|
Chris@0
|
25 *
|
Chris@0
|
26 * @param string $message
|
Chris@0
|
27 * @return Response
|
Chris@0
|
28 * @throws UnexpectedValueException when errors occur parsing the message.
|
Chris@0
|
29 */
|
Chris@0
|
30 public static function fromString($message)
|
Chris@0
|
31 {
|
Chris@0
|
32 $stream = new Stream('php://temp', 'wb+');
|
Chris@0
|
33 $stream->write($message);
|
Chris@0
|
34 return static::fromStream($stream);
|
Chris@0
|
35 }
|
Chris@0
|
36
|
Chris@0
|
37 /**
|
Chris@0
|
38 * Parse a response from a stream.
|
Chris@0
|
39 *
|
Chris@0
|
40 * @param StreamInterface $stream
|
Chris@0
|
41 * @return Response
|
Chris@0
|
42 * @throws InvalidArgumentException when the stream is not readable.
|
Chris@0
|
43 * @throws UnexpectedValueException when errors occur parsing the message.
|
Chris@0
|
44 */
|
Chris@0
|
45 public static function fromStream(StreamInterface $stream)
|
Chris@0
|
46 {
|
Chris@0
|
47 if (! $stream->isReadable() || ! $stream->isSeekable()) {
|
Chris@0
|
48 throw new InvalidArgumentException('Message stream must be both readable and seekable');
|
Chris@0
|
49 }
|
Chris@0
|
50
|
Chris@0
|
51 $stream->rewind();
|
Chris@0
|
52
|
Chris@0
|
53 list($version, $status, $reasonPhrase) = self::getStatusLine($stream);
|
Chris@0
|
54 list($headers, $body) = self::splitStream($stream);
|
Chris@0
|
55
|
Chris@0
|
56 return (new Response($body, $status, $headers))
|
Chris@0
|
57 ->withProtocolVersion($version)
|
Chris@0
|
58 ->withStatus((int) $status, $reasonPhrase);
|
Chris@0
|
59 }
|
Chris@0
|
60
|
Chris@0
|
61 /**
|
Chris@0
|
62 * Create a string representation of a response.
|
Chris@0
|
63 *
|
Chris@0
|
64 * @param ResponseInterface $response
|
Chris@0
|
65 * @return string
|
Chris@0
|
66 */
|
Chris@0
|
67 public static function toString(ResponseInterface $response)
|
Chris@0
|
68 {
|
Chris@0
|
69 $reasonPhrase = $response->getReasonPhrase();
|
Chris@0
|
70 $headers = self::serializeHeaders($response->getHeaders());
|
Chris@0
|
71 $body = (string) $response->getBody();
|
Chris@0
|
72 $format = 'HTTP/%s %d%s%s%s';
|
Chris@0
|
73
|
Chris@0
|
74 if (! empty($headers)) {
|
Chris@0
|
75 $headers = "\r\n" . $headers;
|
Chris@0
|
76 }
|
Chris@0
|
77
|
Chris@0
|
78 $headers .= "\r\n\r\n";
|
Chris@0
|
79
|
Chris@0
|
80 return sprintf(
|
Chris@0
|
81 $format,
|
Chris@0
|
82 $response->getProtocolVersion(),
|
Chris@0
|
83 $response->getStatusCode(),
|
Chris@0
|
84 ($reasonPhrase ? ' ' . $reasonPhrase : ''),
|
Chris@0
|
85 $headers,
|
Chris@0
|
86 $body
|
Chris@0
|
87 );
|
Chris@0
|
88 }
|
Chris@0
|
89
|
Chris@0
|
90 /**
|
Chris@0
|
91 * Retrieve the status line for the message.
|
Chris@0
|
92 *
|
Chris@0
|
93 * @param StreamInterface $stream
|
Chris@0
|
94 * @return array Array with three elements: 0 => version, 1 => status, 2 => reason
|
Chris@0
|
95 * @throws UnexpectedValueException if line is malformed
|
Chris@0
|
96 */
|
Chris@0
|
97 private static function getStatusLine(StreamInterface $stream)
|
Chris@0
|
98 {
|
Chris@0
|
99 $line = self::getLine($stream);
|
Chris@0
|
100
|
Chris@0
|
101 if (! preg_match(
|
Chris@0
|
102 '#^HTTP/(?P<version>[1-9]\d*\.\d) (?P<status>[1-5]\d{2})(\s+(?P<reason>.+))?$#',
|
Chris@0
|
103 $line,
|
Chris@0
|
104 $matches
|
Chris@0
|
105 )) {
|
Chris@0
|
106 throw new UnexpectedValueException('No status line detected');
|
Chris@0
|
107 }
|
Chris@0
|
108
|
Chris@0
|
109 return [$matches['version'], $matches['status'], isset($matches['reason']) ? $matches['reason'] : ''];
|
Chris@0
|
110 }
|
Chris@0
|
111 }
|