Breaking change 53005: Remove trailing whitespace from HTTP headers

79 views
Skip to first unread message

Brian Quinlan

unread,
Jul 20, 2023, 8:33:03 PM7/20/23
to anno...@dartlang.org
See discussion on breaking change: https://github.com/dart-lang/sdk/issues/53005

Change Intent

The intent of this change is to make the headers field values contained (through HttpHeaders) in HttpRequest and HttpClientResponse never contain trailing spaces and tabs.

For example, an HTTP request like:

POST /test HTTP/1.1
Header-A:  \t  cat \t 

Would be parsed like:

// CURRENT BEHAVIOR: leading whitespace removed, trailing preserved
assert(headers['header-a'] == 'cat \t ');
// PROPOSED BEHAVIOR: leading and trailing whitespace removed.
assert(headers['header-a'] == 'cat');

Justification

It is easier to write correct code if the whitespace has been removed from the field values.

The Dart HTTP parser itself has issues with trailing whitespace. For example, the chunked content encoding detector currently checks for the exact string 'chunked' rather than for 'chunked[ \t]*'.

RFC 2616 section 4.2 specifically says that leading and trailing whitespace is not semantic:

The field-content does not include any leading or trailing LWS:
linear white space occurring before the first non-whitespace
character of the field-value or after the last non-whitespace
character of the field-value. Such leading or trailing LWS MAY be
removed without changing the semantics of the field value.

Finally, this behavior would be consistent with the behavior of XMLHTTPRequest (dart:html HttpRequest) , Cronet (package:cronet_http) and Apple's Foundation URL loading system (package:cupertino_http).

Impact

There are three scenarios that I can imagine:

  1. usage that is currently incorrect but is fixed by this change, e.g., if (header['header-a'] == 'cat') ...
  2. usage that already accounts for the current behavior but will not be broken, e.g., if (header['header-a'].trim() == 'cat') ...
  3. usage that already accounts for the current behavior in a broken way, e.g., if (header['header-a'] == 'cat \t ') ...

I'm guessing that case (1) is the most common and case (3) is the least common.

Mitigation

I think that this is unlikely to have a significant impact.

Reply all
Reply to author
Forward
0 new messages