From d0e78ca5c6abb75b306e669ed844dd3705992677 Mon Sep 17 00:00:00 2001 From: Marcos Casagrande Date: Mon, 17 Oct 2022 15:39:41 +0200 Subject: [PATCH] fix(ext/fetch): set accept-encoding: identity if range header is present (#16197) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- ext/fetch/lib.rs | 14 +++++++++++++- 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 c141c3065da129..5a95fbd30cc825 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::(); 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 d713775d06085d..a3dcaa70c32b3f 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