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