Skip to content

Commit 8a91749

Browse files
brianquinlanCommit Queue
authored and
Commit Queue
committed
Fix parsing of folded header field values.
Bug: #53227 Bug: #53185 Change-Id: Ibbdbdf9c8f2875e8f687244982810fffee20e69c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/320920 Commit-Queue: Brian Quinlan <[email protected]> Reviewed-by: Alexander Aprelev <[email protected]>
1 parent a4381f1 commit 8a91749

File tree

3 files changed

+42
-8
lines changed

3 files changed

+42
-8
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,12 @@ constraint][language version] lower bound to 3.2 or greater (`sdk: '^3.2.0'`).
8888
`HttpClientResponse.headers` and `HttpRequest.headers` no longer include
8989
trailing whitespace in their values.
9090

91+
- **Breaking change** [#53227][]: Folded headers values returned by
92+
`HttpClientResponse.headers` and `HttpRequest.headers` now have a space
93+
inserted at the fold point.
94+
9195
[#53005]: https://dartbug.com/53005
96+
[#53227]: https://dartbug.com/53227
9297

9398
#### `dart:isolate`
9499

sdk/lib/_http/http_parser.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,13 @@ class _HttpParser extends Stream<_HttpIncoming> {
680680

681681
case _State.HEADER_VALUE_FOLD_OR_END:
682682
if (byte == _CharCode.SP || byte == _CharCode.HT) {
683-
_state = _State.HEADER_VALUE_START;
683+
// This is an obs-fold as defined in RFC 7230 and we should
684+
// "...replace each received obs-fold with one or more SP octets
685+
// prior to interpreting the field value or forwarding the
686+
// message downstream."
687+
// See https://www.rfc-editor.org/rfc/rfc7230#section-3.2.4
688+
_addWithValidation(_headerValue, _CharCode.SP);
689+
_state = _State.HEADER_VALUE_START; // Strips leading whitespace.
684690
} else {
685691
String headerField = String.fromCharCodes(_headerField);
686692
// The field value does not include any leading or trailing whitespace.

tests/standalone/io/http_parser_test.dart

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -425,19 +425,42 @@ Empty-Header-2:\t \t \r
425425
headers["empty-header-2"] = "";
426426
_testParseRequestLean(request, "POST", "/test", expectedHeaders: headers);
427427

428+
// Test folded headers.
428429
request = """
429430
POST /test HTTP/1.1\r
430-
Header-A: \t AA\r
431-
A \t \r
432-
X-Header-B: b\r
433-
b\r
434-
\t b \t \r
431+
Header-A: h\r
432+
ell\r
433+
o\r
434+
X-Header-B: w\r
435+
o\r
436+
r\r
437+
l\r
438+
d\r
435439
\r
436440
""";
437441

438442
headers = new Map();
439-
headers["header-a"] = "AAA";
440-
headers["x-header-b"] = "bbb";
443+
headers["header-a"] = "h ell o";
444+
headers["x-header-b"] = "w o r l d";
445+
_testParseRequestLean(request, "POST", "/test", expectedHeaders: headers);
446+
447+
// Test folded headers with leading and trailing whitespace.
448+
request = """
449+
POST /test HTTP/1.1\r
450+
Header-A: \t h \t \r
451+
\t ell \t \t \r
452+
\to \t \r
453+
X-Header-B:w\r
454+
\t\to\t\t\r
455+
\t\tr\t\t\r
456+
\tl \r
457+
\td \t\r
458+
\r
459+
""";
460+
461+
headers = new Map();
462+
headers["header-a"] = "h \t ell \t \t o";
463+
headers["x-header-b"] = "w o\t\t r\t\t l d";
441464
_testParseRequestLean(request, "POST", "/test", expectedHeaders: headers);
442465

443466
// _testParseRequestLean encodes the request as ISO-8859-1. Test that the

0 commit comments

Comments
 (0)