Skip to content

Commit ef605f1

Browse files
committed
"relax" header value assertion / allow more than ascii
1 parent 16b2687 commit ef605f1

File tree

4 files changed

+29
-21
lines changed

4 files changed

+29
-21
lines changed

src/HttpMessage/AssertionTrait.php

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ private function assertHeaderName($name): void
109109
digit => 0-9
110110
others => !#$%&\'*+-.^_`|~
111111
*/
112-
if (\preg_match('/^[a-zA-Z0-9!#$%&\'*+-.^_`|~]+$/', $name) !== 1) {
112+
if (\preg_match('/^[a-zA-Z0-9!#$%&\'*+-.^_`|~]+$/D', $name) !== 1) {
113113
throw new InvalidArgumentException(\sprintf(
114114
'"%s" is not valid header name, it must be an RFC 7230 compatible string.',
115115
$name
@@ -151,10 +151,21 @@ private function assertHeaderValue($value): void
151151
/**
152152
* Validate header value
153153
*
154+
* headers values should be ISO-8859-1 encoded by default
155+
*
156+
* field-value = *( field-content / obs-fold )
157+
* field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
158+
* field-vchar = VCHAR / obs-text
159+
* VCHAR = %x21-7E
160+
* obs-text = %x80-FF
161+
* obs-fold = CRLF 1*( SP / HTAB )
162+
154163
* @param mixed $value Header value to test
155164
*
156165
* @return void
157166
*
167+
* @see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2
168+
*
158169
* @throws InvalidArgumentException
159170
*
160171
* @psalm-assert string $value
@@ -165,20 +176,21 @@ private function assertHeaderValueLine($value): void
165176
return;
166177
}
167178
$this->assertString($value, 'Header value', true);
168-
/*
169-
https://www.rfc-editor.org/rfc/rfc7230.txt (page.25)
170-
171-
field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
172-
field-vchar = VCHAR / obs-text
173-
obs-text = %x80-FF (character range outside ASCII.)
174-
NOT ALLOWED
175-
SP = space
176-
HTAB = horizontal tab
177-
VCHAR = any visible [USASCII] character. (x21-x7e)
178-
*/
179-
if (\preg_match('/^[ \t\x21-\x7e]+$/', $value) !== 1) {
179+
$value = \trim((string) $value, " \t");
180+
// The regular expression intentionally does not support the obs-fold production, because as
181+
// per RFC 7230#3.2.4:
182+
//
183+
// A sender MUST NOT generate a message that includes
184+
// line folding (i.e., that has any field-value that contains a match to
185+
// the obs-fold rule) unless the message is intended for packaging
186+
// within the message/http media type.
187+
//
188+
// Clients must not send a request with line folding and a server sending folded headers is
189+
// likely very rare. Line folding is a fairly obscure feature of HTTP/1.1 and thus not accepting
190+
// folding is not likely to break any legitimate use case.
191+
if (\preg_match('/^[\x20\x09\x21-\x7E\x80-\xFF]*$/D', $value) !== 1) {
180192
throw new InvalidArgumentException(\sprintf(
181-
'"%s" is not valid header value, it must contains visible ASCII characters only.',
193+
'"%s" is not valid header value.',
182194
$value
183195
));
184196
}

src/HttpMessage/Utility/Uri.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ private static function computePort(UriInterface $uri): int
205205
private static function parsedPartsPrep(array $parsed): array
206206
{
207207
$map = array(
208+
'passwd' => 'pass',
208209
'password' => 'pass',
209210
'username' => 'user',
210211
);

tests/HttpMessage/DataProviderTrait.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,13 +261,15 @@ public function headerValuesInvalid()
261261
'null' => [null],
262262
'object' => [new stdClass()],
263263
'true' => [true],
264+
// 'invisible' => ['This string contains many invisible spaces.'],
264265
];
265266
}
266267

267268
public function headerValuesValid()
268269
{
269270
return [
270271
[1234],
272+
[''], // "opaque data"
271273
['text/plain'],
272274
['PHP 9.1'],
273275
['text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8'],

tests/HttpMessage/MessageTest.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,6 @@ public function testWithAddedHeaderArrayValueAndKeys()
120120
Exceptions
121121
*/
122122

123-
public function testExceptionHeaderValueInvalidString()
124-
{
125-
$this->expectException('InvalidArgumentException');
126-
$this->createMessage()
127-
->withHeader('hello-world', 'This string contains many invisible spaces.');
128-
}
129-
130123
public function testWithHeaderRejectsMultipleHostValues()
131124
{
132125
$this->expectException('InvalidArgumentException');

0 commit comments

Comments
 (0)