diff options
author | Marcos Casagrande <marcoscvp90@gmail.com> | 2022-10-17 15:39:41 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-17 15:39:41 +0200 |
commit | d0e78ca5c6abb75b306e669ed844dd3705992677 (patch) | |
tree | d0412e6d56707adca4a1d17467ed2a81627db227 | |
parent | 698ae4bfed1d4a88002be41cdbc24601ac71ddc1 (diff) |
fix(ext/fetch): set accept-encoding: identity if range header is present (#16197)
https://fetch.spec.whatwg.org/#http-network-or-cache-fetch
> If httpRequest’s header list contains `Range`, then append
(`Accept-Encoding`, `identity`)
> to httpRequest’s header list.
>
> This avoids a failure when handling content codings with a part of an
encoded response.
> Additionally, many servers mistakenly ignore `Range` headers if a
non-identity encoding is accepted.
-rw-r--r-- | ext/fetch/lib.rs | 14 | ||||
-rw-r--r-- | tools/wpt/expectation.json | 2 |
2 files changed, 13 insertions, 3 deletions
diff --git a/ext/fetch/lib.rs b/ext/fetch/lib.rs index c141c3065..5a95fbd30 100644 --- a/ext/fetch/lib.rs +++ b/ext/fetch/lib.rs @@ -34,7 +34,9 @@ use http::header::CONTENT_LENGTH; use reqwest::header::HeaderMap; use reqwest::header::HeaderName; use reqwest::header::HeaderValue; +use reqwest::header::ACCEPT_ENCODING; use reqwest::header::HOST; +use reqwest::header::RANGE; use reqwest::header::USER_AGENT; use reqwest::redirect::Policy; use reqwest::Body; @@ -288,16 +290,26 @@ where None }; + let mut header_map = HeaderMap::new(); for (key, value) in headers { let name = HeaderName::from_bytes(&key) .map_err(|err| type_error(err.to_string()))?; let v = HeaderValue::from_bytes(&value) .map_err(|err| type_error(err.to_string()))?; + if !matches!(name, HOST | CONTENT_LENGTH) { - request = request.header(name, v); + header_map.append(name, v); } } + if header_map.contains_key(RANGE) { + // https://fetch.spec.whatwg.org/#http-network-or-cache-fetch step 18 + // If httpRequest’s header list contains `Range`, then append (`Accept-Encoding`, `identity`) + header_map + .insert(ACCEPT_ENCODING, HeaderValue::from_static("identity")); + } + request = request.headers(header_map); + let options = state.borrow::<Options>(); if let Some(request_builder_hook) = options.request_builder_hook { request = request_builder_hook(request); diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index d713775d0..a3dcaa70c 100644 --- a/tools/wpt/expectation.json +++ b/tools/wpt/expectation.json @@ -3266,12 +3266,10 @@ "range": { "general.any.html": [ "Privileged header not allowed for guard type: request-no-cors", - "Fetch with range header will be sent with Accept-Encoding: identity", "Cross Origin Fetch with non safe range header" ], "general.any.worker.html": [ "Privileged header not allowed for guard type: request-no-cors", - "Fetch with range header will be sent with Accept-Encoding: identity", "Cross Origin Fetch with non safe range header" ], "general.window.html": false |