mirror of
https://github.com/dart-lang/sdk
synced 2024-10-03 01:34:42 +00:00
Remove trailing whitespace from header values.
Bug: https://github.com/dart-lang/sdk/issues/53005 Bug: https://github.com/dart-lang/sdk/issues/51532 Change-Id: I8a2fc04f48d50103819d655ccd300e73d59fbecc Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319903 Reviewed-by: Alexander Aprelev <aam@google.com> Commit-Queue: Brian Quinlan <bquinlan@google.com>
This commit is contained in:
parent
aa74293d3a
commit
ce0d051c9c
|
@ -18,6 +18,14 @@
|
||||||
|
|
||||||
### Libraries
|
### Libraries
|
||||||
|
|
||||||
|
#### `dart:io`
|
||||||
|
|
||||||
|
- **Breaking change** [#53005][]: The headers returned by
|
||||||
|
`HttpClientResponse.headers` and `HttpRequest.headers` no longer include
|
||||||
|
trailing whitespace in their values.
|
||||||
|
|
||||||
|
[#52334]: https://dartbug.com/53005
|
||||||
|
|
||||||
#### `dart:js_interop`
|
#### `dart:js_interop`
|
||||||
|
|
||||||
- **JSNumber.toDart and Object.toJS**:
|
- **JSNumber.toDart and Object.toJS**:
|
||||||
|
|
|
@ -683,6 +683,9 @@ class _HttpParser extends Stream<_HttpIncoming> {
|
||||||
_state = _State.HEADER_VALUE_START;
|
_state = _State.HEADER_VALUE_START;
|
||||||
} else {
|
} else {
|
||||||
String headerField = String.fromCharCodes(_headerField);
|
String headerField = String.fromCharCodes(_headerField);
|
||||||
|
// The field value does not include any leading or trailing whitespace.
|
||||||
|
// See https://www.rfc-editor.org/rfc/rfc7230#section-3.2.4
|
||||||
|
_removeTrailingSpaces(_headerValue);
|
||||||
String headerValue = String.fromCharCodes(_headerValue);
|
String headerValue = String.fromCharCodes(_headerValue);
|
||||||
const errorIfBothText = "Both Content-Length and Transfer-Encoding "
|
const errorIfBothText = "Both Content-Length and Transfer-Encoding "
|
||||||
"are specified, at most one is allowed";
|
"are specified, at most one is allowed";
|
||||||
|
@ -1002,6 +1005,17 @@ class _HttpParser extends Stream<_HttpIncoming> {
|
||||||
return (byte > 31 && byte < 128) || (byte == _CharCode.HT);
|
return (byte > 31 && byte < 128) || (byte == _CharCode.HT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _removeTrailingSpaces(List<int> value) {
|
||||||
|
var length = value.length;
|
||||||
|
while (length > 0 &&
|
||||||
|
(value[length - 1] == _CharCode.SP ||
|
||||||
|
value[length - 1] == _CharCode.HT)) {
|
||||||
|
--length;
|
||||||
|
}
|
||||||
|
|
||||||
|
value.length = length;
|
||||||
|
}
|
||||||
|
|
||||||
static List<String> _tokenizeFieldValue(String headerValue) {
|
static List<String> _tokenizeFieldValue(String headerValue) {
|
||||||
List<String> tokens = <String>[];
|
List<String> tokens = <String>[];
|
||||||
int start = 0;
|
int start = 0;
|
||||||
|
|
|
@ -381,13 +381,24 @@ POST /test HTTP/1.1\r
|
||||||
|
|
||||||
request = """
|
request = """
|
||||||
POST /test HTTP/1.1\r
|
POST /test HTTP/1.1\r
|
||||||
Header-A: AAA\r
|
Header-A: AAA aaa\r
|
||||||
X-Header-B: bbb\r
|
X-Header-B: bbb BBB\r
|
||||||
\r
|
\r
|
||||||
""";
|
""";
|
||||||
headers = new Map();
|
headers = new Map();
|
||||||
headers["header-a"] = "AAA";
|
headers["header-a"] = "AAA aaa";
|
||||||
headers["x-header-b"] = "bbb";
|
headers["x-header-b"] = "bbb BBB";
|
||||||
|
_testParseRequestLean(request, "POST", "/test", expectedHeaders: headers);
|
||||||
|
|
||||||
|
request = """
|
||||||
|
POST /test HTTP/1.1\r
|
||||||
|
Header-A: \t AAA aaa \t \r
|
||||||
|
X-Header-B: \t bbb BBB \t \r
|
||||||
|
\r
|
||||||
|
""";
|
||||||
|
headers = new Map();
|
||||||
|
headers["header-a"] = "AAA aaa";
|
||||||
|
headers["x-header-b"] = "bbb BBB";
|
||||||
_testParseRequestLean(request, "POST", "/test", expectedHeaders: headers);
|
_testParseRequestLean(request, "POST", "/test", expectedHeaders: headers);
|
||||||
|
|
||||||
request = """
|
request = """
|
||||||
|
@ -404,22 +415,23 @@ Empty-Header-2:\r
|
||||||
|
|
||||||
request = """
|
request = """
|
||||||
POST /test HTTP/1.1\r
|
POST /test HTTP/1.1\r
|
||||||
Header-A: AAA\r
|
Empty-Header-1:\t \t \r
|
||||||
X-Header-B:\t \t bbb\r
|
Empty-Header-2:\t \t \r
|
||||||
|
\r
|
||||||
\r
|
\r
|
||||||
""";
|
""";
|
||||||
headers = new Map();
|
headers = new Map();
|
||||||
headers["header-a"] = "AAA";
|
headers["empty-header-1"] = "";
|
||||||
headers["x-header-b"] = "bbb";
|
headers["empty-header-2"] = "";
|
||||||
_testParseRequestLean(request, "POST", "/test", expectedHeaders: headers);
|
_testParseRequestLean(request, "POST", "/test", expectedHeaders: headers);
|
||||||
|
|
||||||
request = """
|
request = """
|
||||||
POST /test HTTP/1.1\r
|
POST /test HTTP/1.1\r
|
||||||
Header-A: AA\r
|
Header-A: \t AA\r
|
||||||
A\r
|
A \t \r
|
||||||
X-Header-B: b\r
|
X-Header-B: b\r
|
||||||
b\r
|
b\r
|
||||||
\t b\r
|
\t b \t \r
|
||||||
\r
|
\r
|
||||||
""";
|
""";
|
||||||
|
|
||||||
|
@ -461,6 +473,19 @@ Transfer-Encoding: chunked\r
|
||||||
01234\r
|
01234\r
|
||||||
5\r
|
5\r
|
||||||
56789\r
|
56789\r
|
||||||
|
0\r\n\r\n""";
|
||||||
|
_testParseRequest(request, "POST", "/test",
|
||||||
|
expectedTransferLength: -1, expectedBytesReceived: 10, chunked: true);
|
||||||
|
|
||||||
|
// Test LWS around chunked encoding header value.
|
||||||
|
request = """
|
||||||
|
POST /test HTTP/1.1\r
|
||||||
|
Transfer-Encoding: \t chunked \t \r
|
||||||
|
\r
|
||||||
|
5\r
|
||||||
|
01234\r
|
||||||
|
5\r
|
||||||
|
56789\r
|
||||||
0\r\n\r\n""";
|
0\r\n\r\n""";
|
||||||
_testParseRequest(request, "POST", "/test",
|
_testParseRequest(request, "POST", "/test",
|
||||||
expectedTransferLength: -1, expectedBytesReceived: 10, chunked: true);
|
expectedTransferLength: -1, expectedBytesReceived: 10, chunked: true);
|
||||||
|
@ -569,6 +594,10 @@ Sec-WebSocket-Version: 13\r
|
||||||
_testParseResponse(response, 100, "Continue",
|
_testParseResponse(response, 100, "Continue",
|
||||||
expectedTransferLength: 10, expectedBytesReceived: 0);
|
expectedTransferLength: 10, expectedBytesReceived: 0);
|
||||||
|
|
||||||
|
response = "HTTP/1.1 100 Continue\r\nContent-Length: \t 10 \t \r\n\r\n";
|
||||||
|
_testParseResponse(response, 100, "Continue",
|
||||||
|
expectedTransferLength: 10, expectedBytesReceived: 0);
|
||||||
|
|
||||||
response = "HTTP/1.1 200 OK\r\nContent-Length: 0\r\n"
|
response = "HTTP/1.1 200 OK\r\nContent-Length: 0\r\n"
|
||||||
"Connection: Close\r\n\r\n";
|
"Connection: Close\r\n\r\n";
|
||||||
_testParseResponse(response, 200, "OK", connectionClose: true);
|
_testParseResponse(response, 200, "OK", connectionClose: true);
|
||||||
|
|
Loading…
Reference in a new issue