forked from mirrors/gecko-dev
Backed out changeset 675cf3cb3d33 (bug 1397646) for causing mochitest failures on test_fetch_basic_http.html. CLOSED TREE
This commit is contained in:
parent
ae64997bee
commit
3b2efb9273
11 changed files with 613 additions and 669 deletions
|
|
@ -127,7 +127,6 @@
|
||||||
#include "nsSize.h"
|
#include "nsSize.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "nsURIHashKey.h"
|
#include "nsURIHashKey.h"
|
||||||
#include "nsURLHelper.h"
|
|
||||||
#include "nsVideoFrame.h"
|
#include "nsVideoFrame.h"
|
||||||
#include "ReferrerInfo.h"
|
#include "ReferrerInfo.h"
|
||||||
#include "TimeUnits.h"
|
#include "TimeUnits.h"
|
||||||
|
|
@ -1306,10 +1305,6 @@ HTMLMediaElement::MediaLoadListener::OnStartRequest(nsIRequest* aRequest) {
|
||||||
Unused << hc->GetResponseStatus(&responseStatus);
|
Unused << hc->GetResponseStatus(&responseStatus);
|
||||||
nsAutoCString statusText;
|
nsAutoCString statusText;
|
||||||
Unused << hc->GetResponseStatusText(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(
|
element->NotifyLoadError(
|
||||||
nsPrintfCString("%u: %s", responseStatus, statusText.get()));
|
nsPrintfCString("%u: %s", responseStatus, statusText.get()));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@ support-files =
|
||||||
xhr_worker.js
|
xhr_worker.js
|
||||||
xhr2_worker.js
|
xhr2_worker.js
|
||||||
xhrAbort_worker.js
|
xhrAbort_worker.js
|
||||||
test_XHR.js
|
|
||||||
test_worker_xhr_parameters.js
|
test_worker_xhr_parameters.js
|
||||||
test_worker_xhr_system.js
|
test_worker_xhr_system.js
|
||||||
worker_xhr_cors_redirect.js
|
worker_xhr_cors_redirect.js
|
||||||
|
|
@ -115,7 +114,6 @@ skip-if =
|
||||||
[test_worker_xhrAbort.html]
|
[test_worker_xhrAbort.html]
|
||||||
skip-if = (os == "win") || (os == "mac")
|
skip-if = (os == "win") || (os == "mac")
|
||||||
[test_XHR.html]
|
[test_XHR.html]
|
||||||
skip-if = http2
|
|
||||||
[test_xhr_abort_after_load.html]
|
[test_xhr_abort_after_load.html]
|
||||||
[test_XHR_anon.html]
|
[test_XHR_anon.html]
|
||||||
skip-if =
|
skip-if =
|
||||||
|
|
@ -126,8 +124,6 @@ skip-if =
|
||||||
skip-if =
|
skip-if =
|
||||||
http3
|
http3
|
||||||
http2
|
http2
|
||||||
[test_XHR_http2.html]
|
|
||||||
skip-if = !http2
|
|
||||||
[test_XHR_onuploadprogress.html]
|
[test_XHR_onuploadprogress.html]
|
||||||
[test_xhr_overridemimetype_throws_on_invalid_state.html]
|
[test_xhr_overridemimetype_throws_on_invalid_state.html]
|
||||||
[test_XHR_parameters.html]
|
[test_XHR_parameters.html]
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,373 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<pre id="test">
|
<pre id="test">
|
||||||
<script class="testbody" type="application/javascript" src="test_XHR.js"></script>
|
<script class="testbody" type="application/javascript">
|
||||||
|
"use strict";
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
|
var gen = runTests();
|
||||||
|
function continueTest() { gen.next(); }
|
||||||
|
|
||||||
|
function* runTests() {
|
||||||
|
|
||||||
|
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");
|
||||||
|
is(xhr.statusText, passFiles[i][3], "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] || "<res>hello</res>", "wrong responseXML");
|
||||||
|
is(xhr.response, passFiles[i][5] || "<res>hello</res>\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),
|
||||||
|
"<res>hello</res>",
|
||||||
|
"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");
|
||||||
|
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 */
|
||||||
|
</script>
|
||||||
</pre>
|
</pre>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -1,438 +0,0 @@
|
||||||
"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] || "<res>hello</res>",
|
|
||||||
"wrong responseXML"
|
|
||||||
);
|
|
||||||
is(
|
|
||||||
xhr.response,
|
|
||||||
passFiles[i][5] || "<res>hello</res>\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),
|
|
||||||
"<res>hello</res>",
|
|
||||||
"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 */
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Test for XMLHttpRequest</title>
|
|
||||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
||||||
</head>
|
|
||||||
<body onload="gen.next();">
|
|
||||||
<p id="display"></p>
|
|
||||||
<div id="content" style="display: none">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<pre id="test">
|
|
||||||
<script class="testbody" type="application/javascript" src="test_XHR.js"></script>
|
|
||||||
</pre>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -908,195 +908,6 @@ bool net_IsValidIPv6Addr(const nsACString& aAddr) {
|
||||||
return mozilla::net::rust_net_is_valid_ipv6_addr(&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 {
|
namespace mozilla {
|
||||||
static auto MakeNameMatcher(const nsAString& aName) {
|
static auto MakeNameMatcher(const nsAString& aName) {
|
||||||
return [&aName](const auto& param) { return param.mKey.Equals(aName); };
|
return [&aName](const auto& param) { return param.mKey.Equals(aName); };
|
||||||
|
|
|
||||||
|
|
@ -226,12 +226,6 @@ bool net_IsValidIPv4Addr(const nsACString& aAddr);
|
||||||
*/
|
*/
|
||||||
bool net_IsValidIPv6Addr(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 {
|
namespace mozilla {
|
||||||
/**
|
/**
|
||||||
* A class for handling form-urlencoded query strings.
|
* A class for handling form-urlencoded query strings.
|
||||||
|
|
|
||||||
|
|
@ -2160,14 +2160,7 @@ HttpBaseChannel::GetResponseStatus(uint32_t* aValue) {
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpBaseChannel::GetResponseStatusText(nsACString& aValue) {
|
HttpBaseChannel::GetResponseStatusText(nsACString& aValue) {
|
||||||
if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
|
if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
|
||||||
nsAutoCString version;
|
mResponseHead->StatusText(aValue);
|
||||||
// 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;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -347,7 +347,191 @@ void nsHttpResponseHead::AssignDefaultStatusText() {
|
||||||
// In particular, HTTP/2 does not use reason phrases at all so they need to
|
// In particular, HTTP/2 does not use reason phrases at all so they need to
|
||||||
// always be injected.
|
// always be injected.
|
||||||
|
|
||||||
net_GetDefaultStatusTextForCode(mStatus, mStatusText);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsHttpResponseHead::ParseStatusLine(const nsACString& line) {
|
void nsHttpResponseHead::ParseStatusLine(const nsACString& line) {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,48 @@
|
||||||
[status.h2.any.html]
|
[status.h2.any.html]
|
||||||
expected:
|
expected:
|
||||||
if (os == "android") and fission: [OK, TIMEOUT]
|
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]
|
[status.h2.any.worker.html]
|
||||||
expected:
|
expected:
|
||||||
if (os == "android") and fission: [OK, TIMEOUT]
|
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
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,23 @@
|
||||||
[status.h2.window.html]
|
[status.h2.window.html]
|
||||||
expected:
|
expected:
|
||||||
if (os == "android") and fission: [OK, TIMEOUT]
|
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
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue