diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs index e824d09d0bf..0271fd49ece 100644 --- a/components/net/fetch/methods.rs +++ b/components/net/fetch/methods.rs @@ -271,6 +271,8 @@ pub fn main_fetch(request: &mut Request, let response_is_network_error = response.is_network_error(); let should_replace_with_nosniff_error = !response_is_network_error && should_be_blocked_due_to_nosniff(request.type_, &response.headers); + let should_replace_with_mime_type_error = + !response_is_network_error && should_be_blocked_due_to_mime_type(request.type_, &response.headers); // Step 15. let mut network_error_response = response.get_network_error().cloned().map(Response::network_error); @@ -288,13 +290,16 @@ pub fn main_fetch(request: &mut Request, // Step 17. // TODO: handle blocking as mixed content. // TODO: handle blocking by content security policy. - // TODO: handle blocking due to MIME type. let blocked_error_response; let internal_response = if should_replace_with_nosniff_error { // Defer rebinding result blocked_error_response = Response::network_error(NetworkError::Internal("Blocked by nosniff".into())); &blocked_error_response + } else if should_replace_with_mime_type_error { + // Defer rebinding result + blocked_error_response = Response::network_error(NetworkError::Internal("Blocked by mime type".into())); + &blocked_error_response } else { internal_response }; @@ -625,6 +630,21 @@ pub fn should_be_blocked_due_to_nosniff(request_type: Type, response_headers: &H }; } +/// https://fetch.spec.whatwg.org/#should-response-to-request-be-blocked-due-to-mime-type? +fn should_be_blocked_due_to_mime_type(request_type: Type, response_headers: &Headers) -> bool { + let mime_type = match response_headers.get::() { + Some(header) => header, + None => return false, + }; + request_type == Type::Script && match *mime_type { + ContentType(Mime(TopLevel::Audio, _, _)) | + ContentType(Mime(TopLevel::Video, _, _)) | + ContentType(Mime(TopLevel::Image, _, _)) => true, + ContentType(Mime(TopLevel::Text, SubLevel::Ext(ref ext), _)) => ext == "csv", + _ => false, + } +} + /// https://fetch.spec.whatwg.org/#block-bad-port pub fn should_be_blocked_due_to_bad_port(url: &ServoUrl) -> bool { // Step 1 is not applicable, this function just takes the URL directly. diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json index 654c6c1950c..bdf9832d314 100644 --- a/tests/wpt/metadata/MANIFEST.json +++ b/tests/wpt/metadata/MANIFEST.json @@ -43604,6 +43604,11 @@ {} ] ], + "fetch/api/resources/script-with-header.py": [ + [ + {} + ] + ], "fetch/api/resources/status.py": [ [ {} @@ -87238,6 +87243,12 @@ {} ] ], + "fetch/api/basic/block-mime-as-script.html": [ + [ + "/fetch/api/basic/block-mime-as-script.html", + {} + ] + ], "fetch/api/basic/conditional-get.html": [ [ "/fetch/api/basic/conditional-get.html", @@ -163675,6 +163686,10 @@ "f6d0b4fe4850c1dda40fab0f83ca04cba49e2e84", "support" ], + "fetch/api/basic/block-mime-as-script.html": [ + "1dd503f1537b09f7aa875ea9a636d587b03601e3", + "testharness" + ], "fetch/api/basic/conditional-get.html": [ "77822a239b405b0b5c0259a335bac6cbe26b7fed", "testharness" @@ -164411,6 +164426,10 @@ "387c35bf1e576f00a10ce5abb4cc92e78da56845", "support" ], + "fetch/api/resources/script-with-header.py": [ + "0c988e869e2e7af06bef67a2eba8211554b38323", + "support" + ], "fetch/api/resources/status.py": [ "d521bae08fa1ee19e7bbf4301157703e567ad5c6", "support" diff --git a/tests/wpt/web-platform-tests/fetch/api/basic/block-mime-as-script.html b/tests/wpt/web-platform-tests/fetch/api/basic/block-mime-as-script.html new file mode 100644 index 00000000000..37c38839d17 --- /dev/null +++ b/tests/wpt/web-platform-tests/fetch/api/basic/block-mime-as-script.html @@ -0,0 +1,39 @@ + + +Block mime type as script + + +
+ diff --git a/tests/wpt/web-platform-tests/fetch/api/resources/script-with-header.py b/tests/wpt/web-platform-tests/fetch/api/resources/script-with-header.py new file mode 100644 index 00000000000..778871b4406 --- /dev/null +++ b/tests/wpt/web-platform-tests/fetch/api/resources/script-with-header.py @@ -0,0 +1,4 @@ +def main(request, response): + headers = [("Content-type", request.GET.first("mime"))] + content = "console.log('Script loaded')" + return 200, headers, content