diff --git a/moli-fetch/src/headers.rs b/moli-fetch/src/headers.rs index ffa1cfa5d6..31552a56b6 100644 --- a/moli-fetch/src/headers.rs +++ b/moli-fetch/src/headers.rs @@ -10,6 +10,7 @@ pub enum DefaultAcceptKind { Image, EventSource, TextTrack, + TextModule, Other, } @@ -24,6 +25,7 @@ pub fn default_accept_header(kind: DefaultAcceptKind) -> &'static str { } DefaultAcceptKind::EventSource => "text/event-stream", DefaultAcceptKind::TextTrack => "text/vtt,*/*;q=0.1", + DefaultAcceptKind::TextModule => "text/plain,*/*;q=0.5", DefaultAcceptKind::Other => "*/*", } } diff --git a/moli-fetch/src/request.rs b/moli-fetch/src/request.rs index 22ca1464b6..a3c72e2208 100644 --- a/moli-fetch/src/request.rs +++ b/moli-fetch/src/request.rs @@ -825,6 +825,7 @@ impl Request { Some(BrowserRequestMetadata::Image) => crate::DefaultAcceptKind::Image, Some(BrowserRequestMetadata::EventSource) => crate::DefaultAcceptKind::EventSource, Some(BrowserRequestMetadata::TextTrack) => crate::DefaultAcceptKind::TextTrack, + Some(BrowserRequestMetadata::TextModule) => crate::DefaultAcceptKind::TextModule, Some(_) => crate::DefaultAcceptKind::Other, None => return, } diff --git a/moli-fetch/src/tests/cookie_store.rs b/moli-fetch/src/tests/cookie_store.rs index 623a1813c5..bca90a2d5f 100644 --- a/moli-fetch/src/tests/cookie_store.rs +++ b/moli-fetch/src/tests/cookie_store.rs @@ -922,7 +922,10 @@ fn browser_text_module_subresource_headers_use_text_destination() { let headers = outgoing_request_headers(&config, &request, None); - assert_eq!(header_value(&headers, "accept"), Some("*/*")); + assert_eq!( + header_value(&headers, "accept"), + Some("text/plain,*/*;q=0.5") + ); assert_eq!( header_value(&headers, "sec-fetch-site"), Some("same-origin") diff --git a/moli-fetch/src/tests/fetch_metadata.rs b/moli-fetch/src/tests/fetch_metadata.rs index 5c2a230012..bd1f1c44d8 100644 --- a/moli-fetch/src/tests/fetch_metadata.rs +++ b/moli-fetch/src/tests/fetch_metadata.rs @@ -91,7 +91,7 @@ async fn default_accept_is_prepared_for_every_transport() -> Result<()> { ( Some(BrowserRequestMetadata::TextModule), RequestMode::Cors, - "*/*", + "text/plain,*/*;q=0.5", ), ( None, @@ -194,44 +194,51 @@ async fn default_accept_is_prepared_for_every_transport() -> Result<()> { #[tokio::test] async fn accept_is_prepared_after_redirect_restores_interception_headers() -> Result<()> { - for configured in [None, Some("application/json")] { - let server = ScriptedHttpServer::spawn(vec![ - ScriptedResponse::status(302, "Found").with_header("Location", "/final"), - ScriptedResponse::ok("ok"), - ]); - let mut config = FetchConfig::default(); - if let Some(value) = configured { - config.set_default_request_headers(vec![("aCcEpT".to_owned(), value.to_owned())]); - } - let client = FetchClient::new(&config, new_shared_browser_cookie_store()); - let target = Url::parse(&server.url())?; - let request = Request::new_browser( - "GET", - target.clone(), - None, - vec![("Accept".to_owned(), "application/override".to_owned())], - (&target).into(), - ) - .with_request_mode(RequestMode::Cors) - .with_browser_request_metadata(BrowserRequestMetadata::Image) - .with_redirect_headers(Some(crate::RequestHeaders::default())); - assert_eq!(client.fetch_raw(request).await?.status, 200); - let requests = server.requests(); - server.shutdown(); - assert_eq!(requests.len(), 2); - for (request, expected) in requests.iter().zip([ - "application/override", - configured - .unwrap_or("image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"), - ]) { - let values: Vec<_> = request - .lines() - .filter_map(|line| { - let (name, value) = line.split_once(':')?; - name.eq_ignore_ascii_case("accept").then(|| value.trim()) - }) - .collect(); - assert_eq!(values, [expected], "{request}"); + for (metadata, default_accept) in [ + ( + BrowserRequestMetadata::Image, + "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8", + ), + (BrowserRequestMetadata::TextModule, "text/plain,*/*;q=0.5"), + ] { + for configured in [None, Some("application/json")] { + let server = ScriptedHttpServer::spawn(vec![ + ScriptedResponse::status(302, "Found").with_header("Location", "/final"), + ScriptedResponse::ok("ok"), + ]); + let mut config = FetchConfig::default(); + if let Some(value) = configured { + config.set_default_request_headers(vec![("aCcEpT".to_owned(), value.to_owned())]); + } + let client = FetchClient::new(&config, new_shared_browser_cookie_store()); + let target = Url::parse(&server.url())?; + let request = Request::new_browser( + "GET", + target.clone(), + None, + vec![("Accept".to_owned(), "application/override".to_owned())], + (&target).into(), + ) + .with_request_mode(RequestMode::Cors) + .with_browser_request_metadata(metadata) + .with_redirect_headers(Some(crate::RequestHeaders::default())); + assert_eq!(client.fetch_raw(request).await?.status, 200); + let requests = server.requests(); + server.shutdown(); + assert_eq!(requests.len(), 2); + for (request, expected) in requests + .iter() + .zip(["application/override", configured.unwrap_or(default_accept)]) + { + let values: Vec<_> = request + .lines() + .filter_map(|line| { + let (name, value) = line.split_once(':')?; + name.eq_ignore_ascii_case("accept").then(|| value.trim()) + }) + .collect(); + assert_eq!(values, [expected], "{request}"); + } } } Ok(())