@@ -171,14 +171,14 @@ private function setHeaders(array $headers): void
171171 private function normalizeHeaderValue ($ value ): array
172172 {
173173 if (!is_array ($ value )) {
174- return $ this ->trimHeaderValues ([$ value ]);
174+ return $ this ->trimAndValidateHeaderValues ([$ value ]);
175175 }
176176
177177 if (count ($ value ) === 0 ) {
178178 throw new \InvalidArgumentException ('Header value can not be an empty array. ' );
179179 }
180180
181- return $ this ->trimHeaderValues ($ value );
181+ return $ this ->trimAndValidateHeaderValues ($ value );
182182 }
183183
184184 /**
@@ -195,7 +195,7 @@ private function normalizeHeaderValue($value): array
195195 *
196196 * @see https://tools.ietf.org/html/rfc7230#section-3.2.4
197197 */
198- private function trimHeaderValues (array $ values ): array
198+ private function trimAndValidateHeaderValues (array $ values ): array
199199 {
200200 return array_map (function ($ value ) {
201201 if (!is_scalar ($ value ) && null !== $ value ) {
@@ -205,7 +205,10 @@ private function trimHeaderValues(array $values): array
205205 ));
206206 }
207207
208- return trim ((string ) $ value , " \t" );
208+ $ trimmed = trim ((string ) $ value , " \t" );
209+ $ this ->assertValue ($ trimmed );
210+
211+ return $ trimmed ;
209212 }, array_values ($ values ));
210213 }
211214
@@ -232,4 +235,32 @@ private function assertHeader($header): void
232235 );
233236 }
234237 }
238+
239+ /**
240+ * @see https://tools.ietf.org/html/rfc7230#section-3.2
241+ *
242+ * field-value = *( field-content / obs-fold )
243+ * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
244+ * field-vchar = VCHAR / obs-text
245+ * VCHAR = %x21-7E
246+ * obs-text = %x80-FF
247+ * obs-fold = CRLF 1*( SP / HTAB )
248+ */
249+ private function assertValue (string $ value ): void
250+ {
251+ // The regular expression intentionally does not support the obs-fold production, because as
252+ // per RFC 7230#3.2.4:
253+ //
254+ // A sender MUST NOT generate a message that includes
255+ // line folding (i.e., that has any field-value that contains a match to
256+ // the obs-fold rule) unless the message is intended for packaging
257+ // within the message/http media type.
258+ //
259+ // Clients must not send a request with line folding and a server sending folded headers is
260+ // likely very rare. Line folding is a fairly obscure feature of HTTP/1.1 and thus not accepting
261+ // folding is not likely to break any legitimate use case.
262+ if (! preg_match ('/^(?:[\x21-\x7E\x80-\xFF](?:[\x20\x09]+[\x21-\x7E\x80-\xFF])?)*$/ ' , $ value )) {
263+ throw new \InvalidArgumentException (sprintf ('"%s" is not valid header value ' , $ value ));
264+ }
265+ }
235266}
0 commit comments