diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index 9503db5f249b5..0512d6563436a 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -127,6 +127,7 @@ #include "nsSize.h" #include "nsThreadUtils.h" #include "nsURIHashKey.h" +#include "nsURLHelper.h" #include "nsVideoFrame.h" #include "ReferrerInfo.h" #include "TimeUnits.h" @@ -1305,6 +1306,10 @@ HTMLMediaElement::MediaLoadListener::OnStartRequest(nsIRequest* aRequest) { Unused << hc->GetResponseStatus(&responseStatus); nsAutoCString statusText; Unused << hc->GetResponseStatusText(statusText); + // we need status text for resist fingerprinting mode's message allowlist + if (statusText.IsEmpty()) { + net_GetDefaultStatusTextForCode(responseStatus, statusText); + } element->NotifyLoadError( nsPrintfCString("%u: %s", responseStatus, statusText.get())); diff --git a/dom/xhr/tests/mochitest.ini b/dom/xhr/tests/mochitest.ini index ed59ac67188ff..e0bbd3ac86fbd 100644 --- a/dom/xhr/tests/mochitest.ini +++ b/dom/xhr/tests/mochitest.ini @@ -42,6 +42,7 @@ support-files = xhr_worker.js xhr2_worker.js xhrAbort_worker.js + test_XHR.js test_worker_xhr_parameters.js test_worker_xhr_system.js worker_xhr_cors_redirect.js @@ -114,6 +115,7 @@ skip-if = [test_worker_xhrAbort.html] skip-if = (os == "win") || (os == "mac") [test_XHR.html] +skip-if = http2 [test_xhr_abort_after_load.html] [test_XHR_anon.html] skip-if = @@ -124,6 +126,8 @@ skip-if = skip-if = http3 http2 +[test_XHR_http2.html] +skip-if = !http2 [test_XHR_onuploadprogress.html] [test_xhr_overridemimetype_throws_on_invalid_state.html] [test_XHR_parameters.html] diff --git a/dom/xhr/tests/test_XHR.html b/dom/xhr/tests/test_XHR.html index 161efe455e342..b8925750f62e7 100644 --- a/dom/xhr/tests/test_XHR.html +++ b/dom/xhr/tests/test_XHR.html @@ -11,373 +11,7 @@
-
+
 
diff --git a/dom/xhr/tests/test_XHR.js b/dom/xhr/tests/test_XHR.js new file mode 100644 index 0000000000000..12eb06e4f6ad1 --- /dev/null +++ b/dom/xhr/tests/test_XHR.js @@ -0,0 +1,438 @@ +"use strict"; +SimpleTest.waitForExplicitFinish(); + +var gen = runTests(); +function continueTest() { + gen.next(); +} + +function* runTests() { + var expectHttp2Results = location.href.includes("http2"); + + var path = "/tests/dom/xhr/tests/"; + + var passFiles = [ + ["file_XHR_pass1.xml", "GET", 200, "OK", "text/xml"], + ["file_XHR_pass2.txt", "GET", 200, "OK", "text/plain"], + ["file_XHR_pass3.txt", "GET", 200, "OK", "text/plain"], + ["data:text/xml,%3Cres%3Ehello%3C/res%3E%0A", "GET", 200, "OK", "text/xml"], + ["data:text/plain,hello%20pass%0A", "GET", 200, "OK", "text/plain"], + ["data:,foo", "GET", 200, "OK", "text/plain;charset=US-ASCII", "foo"], + ["data:text/plain;base64,Zm9v", "GET", 200, "OK", "text/plain", "foo"], + ["data:text/plain,foo#bar", "GET", 200, "OK", "text/plain", "foo"], + ["data:text/plain,foo%23bar", "GET", 200, "OK", "text/plain", "foo#bar"], + ]; + + var blob = new Blob(["foo"], { type: "text/plain" }); + var blobURL = URL.createObjectURL(blob); + + passFiles.push([blobURL, "GET", 200, "OK", "text/plain", "foo"]); + + var failFiles = [ + ["//example.com" + path + "file_XHR_pass1.xml", "GET"], + ["ftp://localhost" + path + "file_XHR_pass1.xml", "GET"], + ["file_XHR_fail1.txt", "GET"], + ]; + + for (i = 0; i < passFiles.length; ++i) { + // Function to give our hacked is() a scope + (function (oldIs) { + function is(actual, expected, message) { + oldIs(actual, expected, message + " for " + passFiles[i][0]); + } + xhr = new XMLHttpRequest(); + is(xhr.getResponseHeader("Content-Type"), null, "should be null"); + is(xhr.getAllResponseHeaders(), "", "should be empty string"); + is(xhr.responseType, "", "wrong initial responseType"); + xhr.open(passFiles[i][1], passFiles[i][0], false); + xhr.send(null); + is(xhr.status, passFiles[i][2], "wrong status"); + + // over HTTP2, no status text is received for network requests (but + // data/blob URLs default to "200 OK" responses) + let expectedStatusText = passFiles[i][3]; + if ( + expectHttp2Results && + !passFiles[i][0].startsWith("data:") && + !passFiles[i][0].startsWith("blob:") + ) { + expectedStatusText = ""; + } + is(xhr.statusText, expectedStatusText, "wrong statusText"); + + is( + xhr.getResponseHeader("Content-Type"), + passFiles[i][4], + "wrong content type" + ); + var headers = xhr.getAllResponseHeaders(); + ok( + /(?:^|\n)Content-Type:\s*([^\r\n]*)\r\n/i.test(headers) && + RegExp.$1 === passFiles[i][4], + "wrong response headers" + ); + if (xhr.responseXML) { + is( + new XMLSerializer().serializeToString( + xhr.responseXML.documentElement + ), + passFiles[i][5] || "hello", + "wrong responseXML" + ); + is( + xhr.response, + passFiles[i][5] || "hello\n", + "wrong response" + ); + } else { + is( + xhr.responseText, + passFiles[i][5] || "hello pass\n", + "wrong responseText" + ); + is(xhr.response, passFiles[i][5] || "hello pass\n", "wrong response"); + } + })(is); + } + + URL.revokeObjectURL(blobURL); + + for (i = 0; i < failFiles.length; ++i) { + xhr = new XMLHttpRequest(); + let didthrow = false; + try { + xhr.open(failFiles[i][1], failFiles[i][0], false); + xhr.send(null); + } catch (e) { + didthrow = true; + } + if (!didthrow) { + is(xhr.status, 301, "wrong status"); + is(xhr.responseText, "redirect file\n", "wrong response"); + } else { + ok(1, "should have thrown or given incorrect result"); + } + } + + function checkResponseTextAccessThrows(xhr) { + let didthrow = false; + try { + xhr.responseText; + } catch (e) { + didthrow = true; + } + ok(didthrow, "should have thrown when accessing responseText"); + } + function checkResponseXMLAccessThrows(xhr) { + let didthrow = false; + try { + xhr.responseXML; + } catch (e) { + didthrow = true; + } + ok(didthrow, "should have thrown when accessing responseXML"); + } + function checkSetResponseType(xhr, type) { + let didthrow = false; + try { + xhr.responseType = type; + } catch (e) { + didthrow = true; + } + is(xhr.responseType, type, "responseType should be " + type); + ok(!didthrow, "should not have thrown when setting responseType"); + } + function checkSetResponseTypeThrows(xhr, type) { + let didthrow = false; + try { + xhr.responseType = type; + } catch (e) { + didthrow = true; + } + ok(didthrow, "should have thrown when setting responseType"); + } + function checkOpenThrows(xhr, method, url, async) { + let didthrow = false; + try { + xhr.open(method, url, async); + } catch (e) { + didthrow = true; + } + ok(didthrow, "should have thrown when open is called"); + } + + // test if setting responseType before calling open() works + xhr = new XMLHttpRequest(); + checkSetResponseType(xhr, ""); + checkSetResponseType(xhr, "text"); + checkSetResponseType(xhr, "document"); + checkSetResponseType(xhr, "arraybuffer"); + checkSetResponseType(xhr, "blob"); + checkSetResponseType(xhr, "json"); + checkOpenThrows(xhr, "GET", "file_XHR_pass2.txt", false); + + // test response (sync, responseType is not changeable) + xhr = new XMLHttpRequest(); + xhr.open("GET", "file_XHR_pass2.txt", false); + checkSetResponseTypeThrows(xhr, ""); + checkSetResponseTypeThrows(xhr, "text"); + checkSetResponseTypeThrows(xhr, "document"); + checkSetResponseTypeThrows(xhr, "arraybuffer"); + checkSetResponseTypeThrows(xhr, "blob"); + checkSetResponseTypeThrows(xhr, "json"); + xhr.send(null); + checkSetResponseTypeThrows(xhr, "document"); + is(xhr.status, 200, "wrong status"); + is(xhr.response, "hello pass\n", "wrong response"); + + // test response (responseType='document') + xhr = new XMLHttpRequest(); + xhr.open("GET", "file_XHR_pass1.xml"); + xhr.responseType = "document"; + xhr.onloadend = continueTest; + xhr.send(null); + yield undefined; + checkSetResponseTypeThrows(xhr, "document"); + is(xhr.status, 200, "wrong status"); + checkResponseTextAccessThrows(xhr); + is( + new XMLSerializer().serializeToString(xhr.response.documentElement), + "hello", + "wrong response" + ); + + // test response (responseType='text') + xhr = new XMLHttpRequest(); + xhr.open("GET", "file_XHR_pass2.txt"); + xhr.responseType = "text"; + xhr.onloadend = continueTest; + xhr.send(null); + yield undefined; + is(xhr.status, 200, "wrong status"); + checkResponseXMLAccessThrows(xhr); + is(xhr.response, "hello pass\n", "wrong response"); + + // test response (responseType='arraybuffer') + function arraybuffer_equals_to(ab, s) { + is(ab.byteLength, s.length, "wrong arraybuffer byteLength"); + + var u8v = new Uint8Array(ab); + is(String.fromCharCode.apply(String, u8v), s, "wrong values"); + } + + // with a simple text file + xhr = new XMLHttpRequest(); + xhr.open("GET", "file_XHR_pass2.txt"); + xhr.responseType = "arraybuffer"; + xhr.onloadend = continueTest; + xhr.send(null); + yield undefined; + is(xhr.status, 200, "wrong status"); + checkResponseTextAccessThrows(xhr); + checkResponseXMLAccessThrows(xhr); + var ab = xhr.response; + ok(ab != null, "should have a non-null arraybuffer"); + arraybuffer_equals_to(ab, "hello pass\n"); + + // test reusing the same XHR (Bug 680816) + xhr.open("GET", "file_XHR_binary1.bin"); + xhr.responseType = "arraybuffer"; + xhr.onloadend = continueTest; + xhr.send(null); + yield undefined; + is(xhr.status, 200, "wrong status"); + var ab2 = xhr.response; + ok(ab2 != null, "should have a non-null arraybuffer"); + ok(ab2 != ab, "arraybuffer on XHR reuse should be distinct"); + arraybuffer_equals_to(ab, "hello pass\n"); + arraybuffer_equals_to(ab2, "\xaa\xee\0\x03\xff\xff\xff\xff\xbb\xbb\xbb\xbb"); + + // with a binary file + xhr = new XMLHttpRequest(); + xhr.open("GET", "file_XHR_binary1.bin"); + xhr.responseType = "arraybuffer"; + xhr.onloadend = continueTest; + xhr.send(null); + yield undefined; + is(xhr.status, 200, "wrong status"); + checkResponseTextAccessThrows(xhr); + checkResponseXMLAccessThrows(xhr); + ab = xhr.response; + ok(ab != null, "should have a non-null arraybuffer"); + arraybuffer_equals_to(ab, "\xaa\xee\0\x03\xff\xff\xff\xff\xbb\xbb\xbb\xbb"); + is(xhr.response, xhr.response, "returns the same ArrayBuffer"); + + // test response (responseType='json') + var xhr = new XMLHttpRequest(); + xhr.open("POST", "responseIdentical.sjs"); + xhr.responseType = "json"; + var jsonObjStr = JSON.stringify({ title: "aBook", author: "john" }); + xhr.onloadend = continueTest; + xhr.send(jsonObjStr); + yield undefined; + is(xhr.status, 200, "wrong status"); + checkResponseTextAccessThrows(xhr); + checkResponseXMLAccessThrows(xhr); + is(JSON.stringify(xhr.response), jsonObjStr, "correct result"); + is(xhr.response, xhr.response, "returning the same object on each access"); + + // with invalid json + xhr = new XMLHttpRequest(); + xhr.open("POST", "responseIdentical.sjs"); + xhr.responseType = "json"; + xhr.onloadend = continueTest; + xhr.send("{"); + yield undefined; + is(xhr.status, 200, "wrong status"); + checkResponseTextAccessThrows(xhr); + checkResponseXMLAccessThrows(xhr); + is(xhr.response, null, "Bad JSON should result in null response."); + is( + xhr.response, + null, + "Bad JSON should result in null response even 2nd time." + ); + + // Test status/statusText in all readyStates + xhr = new XMLHttpRequest(); + function checkXHRStatus() { + if (xhr.readyState == xhr.UNSENT || xhr.readyState == xhr.OPENED) { + is(xhr.status, 0, "should be 0 before getting data"); + is(xhr.statusText, "", "should be empty before getting data"); + } else { + is(xhr.status, 200, "should be 200 when we have data"); + if (expectHttp2Results) { + is(xhr.statusText, "", "should be '' when over HTTP2"); + } else { + is(xhr.statusText, "OK", "should be OK when we have data"); + } + } + } + checkXHRStatus(); + xhr.open("GET", "file_XHR_binary1.bin"); + checkXHRStatus(); + xhr.responseType = "arraybuffer"; + xhr.send(null); + xhr.onreadystatechange = continueTest; + while (xhr.readyState != 4) { + checkXHRStatus(); + yield undefined; + } + checkXHRStatus(); + + // test response (responseType='blob') + // with a simple text file + xhr = new XMLHttpRequest(); + xhr.open("GET", "file_XHR_pass2.txt"); + xhr.responseType = "blob"; + xhr.onloadend = continueTest; + xhr.send(null); + yield undefined; + is(xhr.status, 200, "wrong status"); + checkResponseTextAccessThrows(xhr); + checkResponseXMLAccessThrows(xhr); + var b = xhr.response; + ok(b, "should have a non-null blob"); + ok(b instanceof Blob, "should be a Blob"); + ok(!(b instanceof File), "should not be a File"); + is(b.size, "hello pass\n".length, "wrong blob size"); + + var fr = new FileReader(); + fr.onload = continueTest; + fr.readAsBinaryString(b); + yield undefined; + is(fr.result, "hello pass\n", "wrong values"); + + // with a binary file + xhr = new XMLHttpRequest(); + xhr.open("GET", "file_XHR_binary1.bin", true); + xhr.send(null); + xhr.onreadystatechange = continueTest; + while (xhr.readyState != 2) { + yield undefined; + } + + is(xhr.status, 200, "wrong status"); + xhr.responseType = "blob"; + + while (xhr.readyState != 4) { + yield undefined; + } + + xhr.onreadystatechange = null; + + b = xhr.response; + ok(b != null, "should have a non-null blob"); + is(b.size, 12, "wrong blob size"); + + fr = new FileReader(); + fr.readAsBinaryString(b); + xhr = null; // kill the XHR object + b = null; + SpecialPowers.gc(); + fr.onload = continueTest; + yield undefined; + is( + fr.result, + "\xaa\xee\0\x03\xff\xff\xff\xff\xbb\xbb\xbb\xbb", + "wrong values" + ); + + // with a larger binary file + xhr = new XMLHttpRequest(); + xhr.open("GET", "file_XHR_binary2.bin", true); + xhr.responseType = "blob"; + xhr.send(null); + xhr.onreadystatechange = continueTest; + + while (xhr.readyState != 4) { + yield undefined; + } + + xhr.onreadystatechange = null; + + b = xhr.response; + ok(b != null, "should have a non-null blob"); + is(b.size, 65536, "wrong blob size"); + + fr = new FileReader(); + fr.readAsArrayBuffer(b); + fr.onload = continueTest; + xhr = null; // kill the XHR object + b = null; + SpecialPowers.gc(); + yield undefined; + + var u8 = new Uint8Array(fr.result); + for (var i = 0; i < 65536; i++) { + if (u8[i] !== (i & 255)) { + break; + } + } + is(i, 65536, "wrong value at offset " + i); + + var client = new XMLHttpRequest(); + client.open("GET", "file_XHR_pass1.xml", true); + client.send(); + client.onreadystatechange = function () { + if (client.readyState == 4) { + try { + is(client.responseXML, null, "responseXML should be null."); + is(client.responseText, "", "responseText should be empty string."); + is(client.response, "", "response should be empty string."); + is(client.status, 0, "status should be 0."); + is(client.statusText, "", "statusText should be empty string."); + is( + client.getAllResponseHeaders(), + "", + "getAllResponseHeaders() should return empty string." + ); + } catch (ex) { + ok(false, "Shouldn't throw! [" + ex + "]"); + } + } + }; + client.abort(); + + SimpleTest.finish(); +} /* runTests */ diff --git a/dom/xhr/tests/test_XHR_http2.html b/dom/xhr/tests/test_XHR_http2.html new file mode 100644 index 0000000000000..b8925750f62e7 --- /dev/null +++ b/dom/xhr/tests/test_XHR_http2.html @@ -0,0 +1,17 @@ + + + + Test for XMLHttpRequest + + + + +

+ +
+
+
+ + diff --git a/netwerk/base/nsURLHelper.cpp b/netwerk/base/nsURLHelper.cpp index 31eb5851a2b73..298937e17804e 100644 --- a/netwerk/base/nsURLHelper.cpp +++ b/netwerk/base/nsURLHelper.cpp @@ -908,6 +908,195 @@ bool net_IsValidIPv6Addr(const nsACString& aAddr) { return mozilla::net::rust_net_is_valid_ipv6_addr(&aAddr); } +bool net_GetDefaultStatusTextForCode(uint16_t aCode, nsACString& aOutText) { + switch (aCode) { + // start with the most common + case 200: + aOutText.AssignLiteral("OK"); + break; + case 404: + aOutText.AssignLiteral("Not Found"); + break; + case 301: + aOutText.AssignLiteral("Moved Permanently"); + break; + case 304: + aOutText.AssignLiteral("Not Modified"); + break; + case 307: + aOutText.AssignLiteral("Temporary Redirect"); + break; + case 500: + aOutText.AssignLiteral("Internal Server Error"); + break; + + // also well known + case 100: + aOutText.AssignLiteral("Continue"); + break; + case 101: + aOutText.AssignLiteral("Switching Protocols"); + break; + case 201: + aOutText.AssignLiteral("Created"); + break; + case 202: + aOutText.AssignLiteral("Accepted"); + break; + case 203: + aOutText.AssignLiteral("Non Authoritative"); + break; + case 204: + aOutText.AssignLiteral("No Content"); + break; + case 205: + aOutText.AssignLiteral("Reset Content"); + break; + case 206: + aOutText.AssignLiteral("Partial Content"); + break; + case 207: + aOutText.AssignLiteral("Multi-Status"); + break; + case 208: + aOutText.AssignLiteral("Already Reported"); + break; + case 300: + aOutText.AssignLiteral("Multiple Choices"); + break; + case 302: + aOutText.AssignLiteral("Found"); + break; + case 303: + aOutText.AssignLiteral("See Other"); + break; + case 305: + aOutText.AssignLiteral("Use Proxy"); + break; + case 308: + aOutText.AssignLiteral("Permanent Redirect"); + break; + case 400: + aOutText.AssignLiteral("Bad Request"); + break; + case 401: + aOutText.AssignLiteral("Unauthorized"); + break; + case 402: + aOutText.AssignLiteral("Payment Required"); + break; + case 403: + aOutText.AssignLiteral("Forbidden"); + break; + case 405: + aOutText.AssignLiteral("Method Not Allowed"); + break; + case 406: + aOutText.AssignLiteral("Not Acceptable"); + break; + case 407: + aOutText.AssignLiteral("Proxy Authentication Required"); + break; + case 408: + aOutText.AssignLiteral("Request Timeout"); + break; + case 409: + aOutText.AssignLiteral("Conflict"); + break; + case 410: + aOutText.AssignLiteral("Gone"); + break; + case 411: + aOutText.AssignLiteral("Length Required"); + break; + case 412: + aOutText.AssignLiteral("Precondition Failed"); + break; + case 413: + aOutText.AssignLiteral("Request Entity Too Large"); + break; + case 414: + aOutText.AssignLiteral("Request URI Too Long"); + break; + case 415: + aOutText.AssignLiteral("Unsupported Media Type"); + break; + case 416: + aOutText.AssignLiteral("Requested Range Not Satisfiable"); + break; + case 417: + aOutText.AssignLiteral("Expectation Failed"); + break; + case 418: + aOutText.AssignLiteral("I'm a teapot"); + break; + case 421: + aOutText.AssignLiteral("Misdirected Request"); + break; + case 422: + aOutText.AssignLiteral("Unprocessable Entity"); + break; + case 423: + aOutText.AssignLiteral("Locked"); + break; + case 424: + aOutText.AssignLiteral("Failed Dependency"); + break; + case 425: + aOutText.AssignLiteral("Too Early"); + break; + case 426: + aOutText.AssignLiteral("Upgrade Required"); + break; + case 428: + aOutText.AssignLiteral("Precondition Required"); + break; + case 429: + aOutText.AssignLiteral("Too Many Requests"); + break; + case 431: + aOutText.AssignLiteral("Request Header Fields Too Large"); + break; + case 451: + aOutText.AssignLiteral("Unavailable For Legal Reasons"); + break; + case 501: + aOutText.AssignLiteral("Not Implemented"); + break; + case 502: + aOutText.AssignLiteral("Bad Gateway"); + break; + case 503: + aOutText.AssignLiteral("Service Unavailable"); + break; + case 504: + aOutText.AssignLiteral("Gateway Timeout"); + break; + case 505: + aOutText.AssignLiteral("HTTP Version Unsupported"); + break; + case 506: + aOutText.AssignLiteral("Variant Also Negotiates"); + break; + case 507: + aOutText.AssignLiteral("Insufficient Storage "); + break; + case 508: + aOutText.AssignLiteral("Loop Detected"); + break; + case 510: + aOutText.AssignLiteral("Not Extended"); + break; + case 511: + aOutText.AssignLiteral("Network Authentication Required"); + break; + default: + aOutText.AssignLiteral("No Reason Phrase"); + return false; + } + return true; +} + namespace mozilla { static auto MakeNameMatcher(const nsAString& aName) { return [&aName](const auto& param) { return param.mKey.Equals(aName); }; diff --git a/netwerk/base/nsURLHelper.h b/netwerk/base/nsURLHelper.h index f97d947652124..f5ccc8bac6637 100644 --- a/netwerk/base/nsURLHelper.h +++ b/netwerk/base/nsURLHelper.h @@ -226,6 +226,12 @@ bool net_IsValidIPv4Addr(const nsACString& aAddr); */ bool net_IsValidIPv6Addr(const nsACString& aAddr); +/** + * Returns the default status text for a given HTTP status code (useful if HTTP2 + * does not provide one, for instance). + */ +bool net_GetDefaultStatusTextForCode(uint16_t aCode, nsACString& aOutText); + namespace mozilla { /** * A class for handling form-urlencoded query strings. diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp index 298e05e54e540..1d91631229a77 100644 --- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -2160,7 +2160,14 @@ HttpBaseChannel::GetResponseStatus(uint32_t* aValue) { NS_IMETHODIMP HttpBaseChannel::GetResponseStatusText(nsACString& aValue) { if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE; - mResponseHead->StatusText(aValue); + nsAutoCString version; + // https://fetch.spec.whatwg.org : + // Responses over an HTTP/2 connection will always have the empty byte + // sequence as status message as HTTP/2 does not support them. + if (NS_WARN_IF(NS_FAILED(GetProtocolVersion(version))) || + !version.EqualsLiteral("h2")) { + mResponseHead->StatusText(aValue); + } return NS_OK; } diff --git a/netwerk/protocol/http/nsHttpResponseHead.cpp b/netwerk/protocol/http/nsHttpResponseHead.cpp index 1ce51afd93c9d..351397215787c 100644 --- a/netwerk/protocol/http/nsHttpResponseHead.cpp +++ b/netwerk/protocol/http/nsHttpResponseHead.cpp @@ -347,191 +347,7 @@ void nsHttpResponseHead::AssignDefaultStatusText() { // In particular, HTTP/2 does not use reason phrases at all so they need to // always be injected. - switch (mStatus) { - // start with the most common - case 200: - mStatusText.AssignLiteral("OK"); - break; - case 404: - mStatusText.AssignLiteral("Not Found"); - break; - case 301: - mStatusText.AssignLiteral("Moved Permanently"); - break; - case 304: - mStatusText.AssignLiteral("Not Modified"); - break; - case 307: - mStatusText.AssignLiteral("Temporary Redirect"); - break; - case 500: - mStatusText.AssignLiteral("Internal Server Error"); - break; - - // also well known - case 100: - mStatusText.AssignLiteral("Continue"); - break; - case 101: - mStatusText.AssignLiteral("Switching Protocols"); - break; - case 201: - mStatusText.AssignLiteral("Created"); - break; - case 202: - mStatusText.AssignLiteral("Accepted"); - break; - case 203: - mStatusText.AssignLiteral("Non Authoritative"); - break; - case 204: - mStatusText.AssignLiteral("No Content"); - break; - case 205: - mStatusText.AssignLiteral("Reset Content"); - break; - case 206: - mStatusText.AssignLiteral("Partial Content"); - break; - case 207: - mStatusText.AssignLiteral("Multi-Status"); - break; - case 208: - mStatusText.AssignLiteral("Already Reported"); - break; - case 300: - mStatusText.AssignLiteral("Multiple Choices"); - break; - case 302: - mStatusText.AssignLiteral("Found"); - break; - case 303: - mStatusText.AssignLiteral("See Other"); - break; - case 305: - mStatusText.AssignLiteral("Use Proxy"); - break; - case 308: - mStatusText.AssignLiteral("Permanent Redirect"); - break; - case 400: - mStatusText.AssignLiteral("Bad Request"); - break; - case 401: - mStatusText.AssignLiteral("Unauthorized"); - break; - case 402: - mStatusText.AssignLiteral("Payment Required"); - break; - case 403: - mStatusText.AssignLiteral("Forbidden"); - break; - case 405: - mStatusText.AssignLiteral("Method Not Allowed"); - break; - case 406: - mStatusText.AssignLiteral("Not Acceptable"); - break; - case 407: - mStatusText.AssignLiteral("Proxy Authentication Required"); - break; - case 408: - mStatusText.AssignLiteral("Request Timeout"); - break; - case 409: - mStatusText.AssignLiteral("Conflict"); - break; - case 410: - mStatusText.AssignLiteral("Gone"); - break; - case 411: - mStatusText.AssignLiteral("Length Required"); - break; - case 412: - mStatusText.AssignLiteral("Precondition Failed"); - break; - case 413: - mStatusText.AssignLiteral("Request Entity Too Large"); - break; - case 414: - mStatusText.AssignLiteral("Request URI Too Long"); - break; - case 415: - mStatusText.AssignLiteral("Unsupported Media Type"); - break; - case 416: - mStatusText.AssignLiteral("Requested Range Not Satisfiable"); - break; - case 417: - mStatusText.AssignLiteral("Expectation Failed"); - break; - case 418: - mStatusText.AssignLiteral("I'm a teapot"); - break; - case 421: - mStatusText.AssignLiteral("Misdirected Request"); - break; - case 422: - mStatusText.AssignLiteral("Unprocessable Entity"); - break; - case 423: - mStatusText.AssignLiteral("Locked"); - break; - case 424: - mStatusText.AssignLiteral("Failed Dependency"); - break; - case 425: - mStatusText.AssignLiteral("Too Early"); - break; - case 426: - mStatusText.AssignLiteral("Upgrade Required"); - break; - case 428: - mStatusText.AssignLiteral("Precondition Required"); - break; - case 429: - mStatusText.AssignLiteral("Too Many Requests"); - break; - case 431: - mStatusText.AssignLiteral("Request Header Fields Too Large"); - break; - case 451: - mStatusText.AssignLiteral("Unavailable For Legal Reasons"); - break; - case 501: - mStatusText.AssignLiteral("Not Implemented"); - break; - case 502: - mStatusText.AssignLiteral("Bad Gateway"); - break; - case 503: - mStatusText.AssignLiteral("Service Unavailable"); - break; - case 504: - mStatusText.AssignLiteral("Gateway Timeout"); - break; - case 505: - mStatusText.AssignLiteral("HTTP Version Unsupported"); - break; - case 506: - mStatusText.AssignLiteral("Variant Also Negotiates"); - break; - case 507: - mStatusText.AssignLiteral("Insufficient Storage "); - break; - case 508: - mStatusText.AssignLiteral("Loop Detected"); - break; - case 510: - mStatusText.AssignLiteral("Not Extended"); - break; - case 511: - mStatusText.AssignLiteral("Network Authentication Required"); - break; - default: - mStatusText.AssignLiteral("No Reason Phrase"); - break; - } + net_GetDefaultStatusTextForCode(mStatus, mStatusText); } void nsHttpResponseHead::ParseStatusLine(const nsACString& line) { diff --git a/testing/web-platform/meta/fetch/api/basic/status.h2.any.js.ini b/testing/web-platform/meta/fetch/api/basic/status.h2.any.js.ini index 78ddfcce6cc2c..4f0ffb00b90c7 100644 --- a/testing/web-platform/meta/fetch/api/basic/status.h2.any.js.ini +++ b/testing/web-platform/meta/fetch/api/basic/status.h2.any.js.ini @@ -1,48 +1,8 @@ [status.h2.any.html] expected: if (os == "android") and fission: [OK, TIMEOUT] - [statusText over H2 for status 200 should be the empty string] - expected: FAIL - - [statusText over H2 for status 210 should be the empty string] - expected: FAIL - - [statusText over H2 for status 400 should be the empty string] - expected: FAIL - - [statusText over H2 for status 404 should be the empty string] - expected: FAIL - - [statusText over H2 for status 410 should be the empty string] - expected: FAIL - - [statusText over H2 for status 500 should be the empty string] - expected: FAIL - - [statusText over H2 for status 502 should be the empty string] - expected: FAIL [status.h2.any.worker.html] expected: if (os == "android") and fission: [OK, TIMEOUT] - [statusText over H2 for status 200 should be the empty string] - expected: FAIL - - [statusText over H2 for status 210 should be the empty string] - expected: FAIL - - [statusText over H2 for status 400 should be the empty string] - expected: FAIL - - [statusText over H2 for status 404 should be the empty string] - expected: FAIL - - [statusText over H2 for status 410 should be the empty string] - expected: FAIL - - [statusText over H2 for status 500 should be the empty string] - expected: FAIL - - [statusText over H2 for status 502 should be the empty string] - expected: FAIL diff --git a/testing/web-platform/meta/xhr/status.h2.window.js.ini b/testing/web-platform/meta/xhr/status.h2.window.js.ini index 33deaeb8d686a..a161765a10e3b 100644 --- a/testing/web-platform/meta/xhr/status.h2.window.js.ini +++ b/testing/web-platform/meta/xhr/status.h2.window.js.ini @@ -1,23 +1,3 @@ [status.h2.window.html] expected: if (os == "android") and fission: [OK, TIMEOUT] - [statusText over H2 for status 200 should be the empty string] - expected: FAIL - - [statusText over H2 for status 210 should be the empty string] - expected: FAIL - - [statusText over H2 for status 400 should be the empty string] - expected: FAIL - - [statusText over H2 for status 404 should be the empty string] - expected: FAIL - - [statusText over H2 for status 410 should be the empty string] - expected: FAIL - - [statusText over H2 for status 500 should be the empty string] - expected: FAIL - - [statusText over H2 for status 502 should be the empty string] - expected: FAIL