Skip to content

Support all whitespace characters in header values - #862

Open
TimvdLippe wants to merge 1 commit into
hyperium:masterfrom
TimvdLippe:whitespace-characters
Open

Support all whitespace characters in header values#862
TimvdLippe wants to merge 1 commit into
hyperium:masterfrom
TimvdLippe:whitespace-characters

Conversation

@TimvdLippe

@TimvdLippe TimvdLippe commented Aug 12, 2026

Copy link
Copy Markdown

This PR is part of a series of PRs across several crates, to eventually fix web-platform-test failures for Servo.

Servo currently fails /content-security-policy/generic/only-valid-whitespaces-are-allowed.html which is a test that checks whether various whitespace characters are properly parsed in the Content-Security-Policy header.

Currently, Servo times out on this test, since it attempts to send a HTTP request with Hyper. Hyper calls httparse to parse the response returned by the test server with, which includes the Content-Security-Policy with the special whitespace character. When httparse attempts to parse this, it fails since it contains characters it currently does not accept.

While RFC7230 (HTTP) does not allow such characters to be present, for web browsers section 3.5 is relevant. That section states that for historical reasons (which is the case for web browsers), both %x0B and %x0C MAY be treated as regular space characters.

Since currently httparse rejects parsing, Servo is unable to implement that requirement. To fix this issue, the following changes are made:

  1. In httparse, support parsing %x0B and %x0C in header values (Support all whitespace characters in header values seanmonstar/httparse#225)
  2. In http, consider %x0B and %x0C as opaque bytes for byte constructors (Support all whitespace characters in header values #862)
  3. In hyper, use HeaderValue::from_bytes rather than the generic HeaderValue::from_maybe_shared_unchecked to operate on the raw bytes (Support all whitespace characters in header values hyper#4155)
  4. In content-security-policy update policy parsing to check if directive value is an ASCII string. It already handles %x0B and %x0C in is_char_ascii_whitespace, but with the HTTP changes it exposed this other missing check (Support all whitespace characters in header values rust-ammonia/rust-content-security-policy#74)
  5. In Servo, replace header.to_str() with str::from_utf8(header.as_bytes()) (net, script: Support all whitespace characters in header values servo/servo#47194)

This PR is part of a series of PRs across several crates,
to eventually fix web-platform-test failures for Servo.

Servo currently fails [`/content-security-policy/generic/only-valid-whitespaces-are-allowed.html`](https://wpt.fyi/results/content-security-policy/generic/only-valid-whitespaces-are-allowed.html?product=servo)
which is a test that checks whether various whitespace characters
are properly parsed in the `Content-Security-Policy` header.

Currently, Servo times out on this test, since it attempts to
send a HTTP request with Hyper. Hyper calls `httparse` to parse the
response returned by the test server with, which includes the
`Content-Security-Policy` with the special whitespace character.
When `httparse` attempts to parse this, it fails since it contains
characters it currently does not accept.

While RFC7230 (HTTP) does not allow such characters to be present,
for web browsers [section 3.5](https://datatracker.ietf.org/doc/html/rfc7230#section-3.5) is relevant.
That section states that for historical reasons (which is the
case for web browsers), both `%x0B` and `%x0C` MAY be treated
as regular space characters.

Since currently `httparse` rejects parsing, Servo is unable to
implement that requirement. To fix this issue, the following changes
are made:

1. In `httparse`, support parsing `%x0B` and `%x0C` in header values
2. In `http`, consider `%x0B` and `%x0C` as opaque bytes for byte constructors
3. In `hyper`, use `HeaderValue::from_bytes` rather than the generic
`HeaderValue::from_maybe_shared_unchecked` to operate on the raw bytes
4. In `content-security-policy` update policy parsing to check if directive
value is an ASCII string. It already handles `%x0B` and `%x0C` in
`is_char_ascii_whitespace`, but with the HTTP changes it exposed this other
missing check
5. In Servo, replace `header.to_str()` with `str::from_utf8(header.as_bytes())`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant