Mercurial > hg > cmmr2012-drupal-site
comparison vendor/zendframework/zend-diactoros/src/AbstractSerializer.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 Psr\Http\Message\StreamInterface; | |
13 use UnexpectedValueException; | |
14 | |
15 /** | |
16 * Provides base functionality for request and response de/serialization | |
17 * strategies, including functionality for retrieving a line at a time from | |
18 * the message, splitting headers from the body, and serializing headers. | |
19 */ | |
20 abstract class AbstractSerializer | |
21 { | |
22 const CR = "\r"; | |
23 const EOL = "\r\n"; | |
24 const LF = "\n"; | |
25 | |
26 /** | |
27 * Retrieve a single line from the stream. | |
28 * | |
29 * Retrieves a line from the stream; a line is defined as a sequence of | |
30 * characters ending in a CRLF sequence. | |
31 * | |
32 * @param StreamInterface $stream | |
33 * @return string | |
34 * @throws UnexpectedValueException if the sequence contains a CR or LF in | |
35 * isolation, or ends in a CR. | |
36 */ | |
37 protected static function getLine(StreamInterface $stream) | |
38 { | |
39 $line = ''; | |
40 $crFound = false; | |
41 while (! $stream->eof()) { | |
42 $char = $stream->read(1); | |
43 | |
44 if ($crFound && $char === self::LF) { | |
45 $crFound = false; | |
46 break; | |
47 } | |
48 | |
49 // CR NOT followed by LF | |
50 if ($crFound && $char !== self::LF) { | |
51 throw new UnexpectedValueException('Unexpected carriage return detected'); | |
52 } | |
53 | |
54 // LF in isolation | |
55 if (! $crFound && $char === self::LF) { | |
56 throw new UnexpectedValueException('Unexpected line feed detected'); | |
57 } | |
58 | |
59 // CR found; do not append | |
60 if ($char === self::CR) { | |
61 $crFound = true; | |
62 continue; | |
63 } | |
64 | |
65 // Any other character: append | |
66 $line .= $char; | |
67 } | |
68 | |
69 // CR found at end of stream | |
70 if ($crFound) { | |
71 throw new UnexpectedValueException("Unexpected end of headers"); | |
72 } | |
73 | |
74 return $line; | |
75 } | |
76 | |
77 /** | |
78 * Split the stream into headers and body content. | |
79 * | |
80 * Returns an array containing two elements | |
81 * | |
82 * - The first is an array of headers | |
83 * - The second is a StreamInterface containing the body content | |
84 * | |
85 * @param StreamInterface $stream | |
86 * @return array | |
87 * @throws UnexpectedValueException For invalid headers. | |
88 */ | |
89 protected static function splitStream(StreamInterface $stream) | |
90 { | |
91 $headers = []; | |
92 $currentHeader = false; | |
93 | |
94 while ($line = self::getLine($stream)) { | |
95 if (preg_match(';^(?P<name>[!#$%&\'*+.^_`\|~0-9a-zA-Z-]+):(?P<value>.*)$;', $line, $matches)) { | |
96 $currentHeader = $matches['name']; | |
97 if (! isset($headers[$currentHeader])) { | |
98 $headers[$currentHeader] = []; | |
99 } | |
100 $headers[$currentHeader][] = ltrim($matches['value']); | |
101 continue; | |
102 } | |
103 | |
104 if (! $currentHeader) { | |
105 throw new UnexpectedValueException('Invalid header detected'); | |
106 } | |
107 | |
108 if (! preg_match('#^[ \t]#', $line)) { | |
109 throw new UnexpectedValueException('Invalid header continuation'); | |
110 } | |
111 | |
112 // Append continuation to last header value found | |
113 $value = array_pop($headers[$currentHeader]); | |
114 $headers[$currentHeader][] = $value . ltrim($line); | |
115 } | |
116 | |
117 // use RelativeStream to avoid copying initial stream into memory | |
118 return [$headers, new RelativeStream($stream, $stream->tell())]; | |
119 } | |
120 | |
121 /** | |
122 * Serialize headers to string values. | |
123 * | |
124 * @param array $headers | |
125 * @return string | |
126 */ | |
127 protected static function serializeHeaders(array $headers) | |
128 { | |
129 $lines = []; | |
130 foreach ($headers as $header => $values) { | |
131 $normalized = self::filterHeader($header); | |
132 foreach ($values as $value) { | |
133 $lines[] = sprintf('%s: %s', $normalized, $value); | |
134 } | |
135 } | |
136 | |
137 return implode("\r\n", $lines); | |
138 } | |
139 | |
140 /** | |
141 * Filter a header name to wordcase | |
142 * | |
143 * @param string $header | |
144 * @return string | |
145 */ | |
146 protected static function filterHeader($header) | |
147 { | |
148 $filtered = str_replace('-', ' ', $header); | |
149 $filtered = ucwords($filtered); | |
150 return str_replace(' ', '-', $filtered); | |
151 } | |
152 } |