mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-08 17:40:28 +00:00
feat: HTTP add TLS fingerprint fallback (#1444)
This commit is contained in:
68 files changed
+7243
-1604
No files matched your search
@@ -0,0 +1,13 @@
|
||||
// META: global=window,worker
|
||||
|
||||
// https://fetch.spec.whatwg.org/#forbidden-method
|
||||
for (const method of [
|
||||
'CONNECT', 'TRACE', 'TRACK',
|
||||
'connect', 'trace', 'track'
|
||||
]) {
|
||||
test(function() {
|
||||
assert_throws_js(TypeError,
|
||||
function() { new Request('./', {method: method}); }
|
||||
);
|
||||
}, 'Request() with a forbidden method ' + method + ' must throw.');
|
||||
}
|
||||
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
// META: global=window,worker
|
||||
|
||||
promise_test(async () => {
|
||||
const stream = new ReadableStream({
|
||||
start(controller) {
|
||||
controller.enqueue(new TextEncoder().encode("hello"));
|
||||
controller.close();
|
||||
}
|
||||
});
|
||||
|
||||
const r1 = new Request("https://example.com/", { method: "POST", body: stream, duplex: "half" });
|
||||
const r2 = r1.clone();
|
||||
assert_false(r2.bodyUsed, "clone should not be marked as used");
|
||||
assert_not_equals(r2.body, null, "clone should have a body");
|
||||
|
||||
// Constructing a new Request from the clone should preserve the body.
|
||||
const r3 = new Request(r2);
|
||||
assert_not_equals(r3.body, null, "Request constructed from clone should have a body");
|
||||
|
||||
const text = await r3.text();
|
||||
assert_equals(text, "hello", "body content should be preserved through clone() and new Request()");
|
||||
}, "new Request(clone) preserves a ReadableStream body that came from clone()");
|
||||
Vendored
+37
@@ -0,0 +1,37 @@
|
||||
promise_test(async function () {
|
||||
const req1 = new Request("https://example.com/", {
|
||||
body: "req1",
|
||||
method: "POST",
|
||||
});
|
||||
|
||||
const text1 = await req1.text();
|
||||
assert_equals(
|
||||
text1,
|
||||
"req1",
|
||||
"The body of the first request should be 'req1'."
|
||||
);
|
||||
|
||||
const req2 = new Request(req1, { body: "req2" });
|
||||
const bodyText = await req2.text();
|
||||
assert_equals(
|
||||
bodyText,
|
||||
"req2",
|
||||
"The body of the second request should be overridden to 'req2'."
|
||||
);
|
||||
|
||||
}, "Check that the body of a new request can be overridden when created from an existing Request object");
|
||||
|
||||
promise_test(async function () {
|
||||
const req1 = new Request("https://example.com/", {
|
||||
body: "req1",
|
||||
method: "POST",
|
||||
});
|
||||
|
||||
const req2 = new Request("https://example.com/", req1);
|
||||
const bodyText = await req2.text();
|
||||
assert_equals(
|
||||
bodyText,
|
||||
"req1",
|
||||
"The body of the second request should be the same as the first."
|
||||
);
|
||||
}, "Check that the body of a new request can be duplicated from an existing Request object");
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
// META: global=window,worker
|
||||
// META: title=Request consume empty bodies
|
||||
|
||||
function checkBodyText(test, request) {
|
||||
return request.text().then(function(bodyAsText) {
|
||||
assert_equals(bodyAsText, "", "Resolved value should be empty");
|
||||
assert_false(request.bodyUsed);
|
||||
});
|
||||
}
|
||||
|
||||
async function checkBodyBlob(test, request) {
|
||||
const bodyAsBlob = await request.blob();
|
||||
const body = await bodyAsBlob.text();
|
||||
assert_equals(body, "", "Resolved value should be empty");
|
||||
assert_false(request.bodyUsed);
|
||||
}
|
||||
|
||||
function checkBodyArrayBuffer(test, request) {
|
||||
return request.arrayBuffer().then(function(bodyAsArrayBuffer) {
|
||||
assert_equals(bodyAsArrayBuffer.byteLength, 0, "Resolved value should be empty");
|
||||
assert_false(request.bodyUsed);
|
||||
});
|
||||
}
|
||||
|
||||
function checkBodyJSON(test, request) {
|
||||
return request.json().then(
|
||||
function(bodyAsJSON) {
|
||||
assert_unreached("JSON parsing should fail");
|
||||
},
|
||||
function() {
|
||||
assert_false(request.bodyUsed);
|
||||
});
|
||||
}
|
||||
|
||||
function checkBodyFormData(test, request) {
|
||||
return request.formData().then(function(bodyAsFormData) {
|
||||
assert_true(bodyAsFormData instanceof FormData, "Should receive a FormData");
|
||||
assert_false(request.bodyUsed);
|
||||
});
|
||||
}
|
||||
|
||||
function checkBodyFormDataError(test, request) {
|
||||
return promise_rejects_js(test, TypeError, request.formData()).then(function() {
|
||||
assert_false(request.bodyUsed);
|
||||
});
|
||||
}
|
||||
|
||||
function checkRequestWithNoBody(bodyType, checkFunction, headers = []) {
|
||||
promise_test(function(test) {
|
||||
var request = new Request("", {"method": "POST", "headers": headers});
|
||||
assert_false(request.bodyUsed);
|
||||
return checkFunction(test, request);
|
||||
}, "Consume request's body as " + bodyType);
|
||||
}
|
||||
|
||||
checkRequestWithNoBody("text", checkBodyText);
|
||||
checkRequestWithNoBody("blob", checkBodyBlob);
|
||||
checkRequestWithNoBody("arrayBuffer", checkBodyArrayBuffer);
|
||||
checkRequestWithNoBody("json (error case)", checkBodyJSON);
|
||||
checkRequestWithNoBody("formData with correct multipart type (error case)", checkBodyFormDataError, [["Content-Type", 'multipart/form-data; boundary="boundary"']]);
|
||||
checkRequestWithNoBody("formData with correct urlencoded type", checkBodyFormData, [["Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"]]);
|
||||
checkRequestWithNoBody("formData without correct type (error case)", checkBodyFormDataError);
|
||||
|
||||
function checkRequestWithEmptyBody(bodyType, body, asText) {
|
||||
promise_test(function(test) {
|
||||
var request = new Request("", {"method": "POST", "body": body});
|
||||
assert_false(request.bodyUsed, "bodyUsed is false at init");
|
||||
if (asText) {
|
||||
return request.text().then(function(bodyAsString) {
|
||||
assert_equals(bodyAsString.length, 0, "Resolved value should be empty");
|
||||
assert_true(request.bodyUsed, "bodyUsed is true after being consumed");
|
||||
});
|
||||
}
|
||||
return request.arrayBuffer().then(function(bodyAsArrayBuffer) {
|
||||
assert_equals(bodyAsArrayBuffer.byteLength, 0, "Resolved value should be empty");
|
||||
assert_true(request.bodyUsed, "bodyUsed is true after being consumed");
|
||||
});
|
||||
}, "Consume empty " + bodyType + " request body as " + (asText ? "text" : "arrayBuffer"));
|
||||
}
|
||||
|
||||
// FIXME: Add BufferSource, FormData and URLSearchParams.
|
||||
checkRequestWithEmptyBody("blob", new Blob([], { "type" : "text/plain" }), false);
|
||||
checkRequestWithEmptyBody("text", "", false);
|
||||
checkRequestWithEmptyBody("blob", new Blob([], { "type" : "text/plain" }), true);
|
||||
checkRequestWithEmptyBody("text", "", true);
|
||||
checkRequestWithEmptyBody("URLSearchParams", new URLSearchParams(""), true);
|
||||
// FIXME: This test assumes that the empty string be returned but it is not clear whether that is right. See https://github.com/web-platform-tests/wpt/pull/3950.
|
||||
checkRequestWithEmptyBody("FormData", new FormData(), true);
|
||||
checkRequestWithEmptyBody("ArrayBuffer", new ArrayBuffer(), true);
|
||||
@@ -0,0 +1,148 @@
|
||||
// META: global=window,worker
|
||||
// META: title=Request consume
|
||||
// META: script=../resources/utils.js
|
||||
|
||||
function checkBodyText(request, expectedBody) {
|
||||
return request.text().then(function(bodyAsText) {
|
||||
assert_equals(bodyAsText, expectedBody, "Retrieve and verify request's body");
|
||||
assert_true(request.bodyUsed, "body as text: bodyUsed turned true");
|
||||
});
|
||||
}
|
||||
|
||||
async function checkBodyBlob(request, expectedBody, checkContentType) {
|
||||
const bodyAsBlob = await request.blob();
|
||||
|
||||
if (checkContentType)
|
||||
assert_equals(bodyAsBlob.type, "text/plain", "Blob body type should be computed from the request Content-Type");
|
||||
|
||||
const body = await bodyAsBlob.text();
|
||||
assert_equals(body, expectedBody, "Retrieve and verify request's body");
|
||||
assert_true(request.bodyUsed, "body as blob: bodyUsed turned true");
|
||||
}
|
||||
|
||||
function checkBodyArrayBuffer(request, expectedBody) {
|
||||
return request.arrayBuffer().then(function(bodyAsArrayBuffer) {
|
||||
validateBufferFromString(bodyAsArrayBuffer, expectedBody, "Retrieve and verify request's body");
|
||||
assert_true(request.bodyUsed, "body as arrayBuffer: bodyUsed turned true");
|
||||
});
|
||||
}
|
||||
|
||||
function checkBodyBytes(request, expectedBody) {
|
||||
return request.bytes().then(function(bodyAsUint8Array) {
|
||||
assert_true(bodyAsUint8Array instanceof Uint8Array);
|
||||
validateBufferFromString(bodyAsUint8Array.buffer, expectedBody, "Retrieve and verify request's body");
|
||||
assert_true(request.bodyUsed, "body as bytes: bodyUsed turned true");
|
||||
});
|
||||
}
|
||||
|
||||
function checkBodyJSON(request, expectedBody) {
|
||||
return request.json().then(function(bodyAsJSON) {
|
||||
var strBody = JSON.stringify(bodyAsJSON)
|
||||
assert_equals(strBody, expectedBody, "Retrieve and verify request's body");
|
||||
assert_true(request.bodyUsed, "body as json: bodyUsed turned true");
|
||||
});
|
||||
}
|
||||
|
||||
function checkBodyFormData(request, expectedBody) {
|
||||
return request.formData().then(function(bodyAsFormData) {
|
||||
assert_true(bodyAsFormData instanceof FormData, "Should receive a FormData");
|
||||
assert_true(request.bodyUsed, "body as formData: bodyUsed turned true");
|
||||
});
|
||||
}
|
||||
|
||||
function checkRequestBody(body, expected, bodyType) {
|
||||
promise_test(function(test) {
|
||||
var request = new Request("", {"method": "POST", "body": body, "headers": [["Content-Type", "text/PLAIN"]] });
|
||||
assert_false(request.bodyUsed, "bodyUsed is false at init");
|
||||
return checkBodyText(request, expected);
|
||||
}, "Consume " + bodyType + " request's body as text");
|
||||
promise_test(function(test) {
|
||||
var request = new Request("", {"method": "POST", "body": body });
|
||||
assert_false(request.bodyUsed, "bodyUsed is false at init");
|
||||
return checkBodyBlob(request, expected);
|
||||
}, "Consume " + bodyType + " request's body as blob");
|
||||
promise_test(function(test) {
|
||||
var request = new Request("", {"method": "POST", "body": body });
|
||||
assert_false(request.bodyUsed, "bodyUsed is false at init");
|
||||
return checkBodyArrayBuffer(request, expected);
|
||||
}, "Consume " + bodyType + " request's body as arrayBuffer");
|
||||
promise_test(function(test) {
|
||||
var request = new Request("", {"method": "POST", "body": body });
|
||||
assert_false(request.bodyUsed, "bodyUsed is false at init");
|
||||
return checkBodyBytes(request, expected);
|
||||
}, "Consume " + bodyType + " request's body as bytes");
|
||||
promise_test(function(test) {
|
||||
var request = new Request("", {"method": "POST", "body": body });
|
||||
assert_false(request.bodyUsed, "bodyUsed is false at init");
|
||||
return checkBodyJSON(request, expected);
|
||||
}, "Consume " + bodyType + " request's body as JSON");
|
||||
}
|
||||
|
||||
var textData = JSON.stringify("This is response's body");
|
||||
var blob = new Blob([textData], { "type" : "text/plain" });
|
||||
|
||||
checkRequestBody(textData, textData, "String");
|
||||
|
||||
var string = "\"123456\"";
|
||||
function getArrayBuffer() {
|
||||
var arrayBuffer = new ArrayBuffer(8);
|
||||
var int8Array = new Int8Array(arrayBuffer);
|
||||
for (var cptr = 0; cptr < 8; cptr++)
|
||||
int8Array[cptr] = string.charCodeAt(cptr);
|
||||
return arrayBuffer;
|
||||
}
|
||||
|
||||
function getArrayBufferWithZeros() {
|
||||
var arrayBuffer = new ArrayBuffer(10);
|
||||
var int8Array = new Int8Array(arrayBuffer);
|
||||
for (var cptr = 0; cptr < 8; cptr++)
|
||||
int8Array[cptr + 1] = string.charCodeAt(cptr);
|
||||
return arrayBuffer;
|
||||
}
|
||||
|
||||
checkRequestBody(getArrayBuffer(), string, "ArrayBuffer");
|
||||
checkRequestBody(new Uint8Array(getArrayBuffer()), string, "Uint8Array");
|
||||
checkRequestBody(new Int8Array(getArrayBufferWithZeros(), 1, 8), string, "Int8Array");
|
||||
checkRequestBody(new Float32Array(getArrayBuffer()), string, "Float32Array");
|
||||
checkRequestBody(new DataView(getArrayBufferWithZeros(), 1, 8), string, "DataView");
|
||||
|
||||
promise_test(function(test) {
|
||||
var formData = new FormData();
|
||||
formData.append("name", "value")
|
||||
var request = new Request("", {"method": "POST", "body": formData });
|
||||
assert_false(request.bodyUsed, "bodyUsed is false at init");
|
||||
return checkBodyFormData(request, formData);
|
||||
}, "Consume FormData request's body as FormData");
|
||||
|
||||
function checkBlobResponseBody(blobBody, blobData, bodyType, checkFunction) {
|
||||
promise_test(function(test) {
|
||||
var response = new Response(blobBody);
|
||||
assert_false(response.bodyUsed, "bodyUsed is false at init");
|
||||
return checkFunction(response, blobData);
|
||||
}, "Consume blob response's body as " + bodyType);
|
||||
}
|
||||
|
||||
checkBlobResponseBody(blob, textData, "blob", checkBodyBlob);
|
||||
checkBlobResponseBody(blob, textData, "text", checkBodyText);
|
||||
checkBlobResponseBody(blob, textData, "json", checkBodyJSON);
|
||||
checkBlobResponseBody(blob, textData, "arrayBuffer", checkBodyArrayBuffer);
|
||||
checkBlobResponseBody(blob, textData, "bytes", checkBodyBytes);
|
||||
checkBlobResponseBody(new Blob([""]), "", "blob (empty blob as input)", checkBodyBlob);
|
||||
|
||||
var goodJSONValues = ["null", "1", "true", "\"string\""];
|
||||
goodJSONValues.forEach(function(value) {
|
||||
promise_test(function(test) {
|
||||
var request = new Request("", {"method": "POST", "body": value});
|
||||
return request.json().then(function(v) {
|
||||
assert_equals(v, JSON.parse(value));
|
||||
});
|
||||
}, "Consume JSON from text: '" + JSON.stringify(value) + "'");
|
||||
});
|
||||
|
||||
var badJSONValues = ["undefined", "{", "a", "["];
|
||||
badJSONValues.forEach(function(value) {
|
||||
promise_test(function(test) {
|
||||
var request = new Request("", {"method": "POST", "body": value});
|
||||
return promise_rejects_js(test, SyntaxError, request.json());
|
||||
}, "Trying to consume bad JSON text as JSON: '" + value + "'");
|
||||
});
|
||||
@@ -0,0 +1,109 @@
|
||||
// META: global=window,worker
|
||||
// META: title=Request disturbed
|
||||
// META: script=../resources/utils.js
|
||||
|
||||
var initValuesDict = {"method" : "POST",
|
||||
"body" : "Request's body"
|
||||
};
|
||||
|
||||
var noBodyConsumed = new Request("");
|
||||
var bodyConsumed = new Request("", initValuesDict);
|
||||
|
||||
test(() => {
|
||||
assert_equals(noBodyConsumed.body, null, "body's default value is null");
|
||||
assert_false(noBodyConsumed.bodyUsed , "bodyUsed is false when request is not disturbed");
|
||||
assert_not_equals(bodyConsumed.body, null, "non-null body");
|
||||
assert_true(bodyConsumed.body instanceof ReadableStream, "non-null body type");
|
||||
assert_false(noBodyConsumed.bodyUsed, "bodyUsed is false when request is not disturbed");
|
||||
}, "Request's body: initial state");
|
||||
|
||||
noBodyConsumed.blob();
|
||||
bodyConsumed.blob();
|
||||
|
||||
test(function() {
|
||||
assert_false(noBodyConsumed.bodyUsed , "bodyUsed is false when request is not disturbed");
|
||||
try {
|
||||
noBodyConsumed.clone();
|
||||
} catch (e) {
|
||||
assert_unreached("Can use request not disturbed for creating or cloning request");
|
||||
}
|
||||
}, "Request without body cannot be disturbed");
|
||||
|
||||
test(function() {
|
||||
assert_true(bodyConsumed.bodyUsed , "bodyUsed is true when request is disturbed");
|
||||
assert_throws_js(TypeError, function() { bodyConsumed.clone(); });
|
||||
}, "Check cloning a disturbed request");
|
||||
|
||||
test(function() {
|
||||
assert_true(bodyConsumed.bodyUsed , "bodyUsed is true when request is disturbed");
|
||||
assert_throws_js(TypeError, function() { new Request(bodyConsumed); });
|
||||
}, "Check creating a new request from a disturbed request");
|
||||
|
||||
promise_test(function() {
|
||||
assert_true(bodyConsumed.bodyUsed , "bodyUsed is true when request is disturbed");
|
||||
const originalBody = bodyConsumed.body;
|
||||
const bodyReplaced = new Request(bodyConsumed, { body: "Replaced body" });
|
||||
assert_not_equals(bodyReplaced.body, originalBody, "new request's body is new");
|
||||
assert_false(bodyReplaced.bodyUsed, "bodyUsed is false when request is not disturbed");
|
||||
return bodyReplaced.text().then(text => {
|
||||
assert_equals(text, "Replaced body");
|
||||
});
|
||||
}, "Check creating a new request with a new body from a disturbed request");
|
||||
|
||||
promise_test(function() {
|
||||
var bodyRequest = new Request("", initValuesDict);
|
||||
const originalBody = bodyRequest.body;
|
||||
assert_false(bodyRequest.bodyUsed , "bodyUsed is false when request is not disturbed");
|
||||
var requestFromRequest = new Request(bodyRequest);
|
||||
assert_true(bodyRequest.bodyUsed , "bodyUsed is true when request is disturbed");
|
||||
assert_equals(bodyRequest.body, originalBody, "body should not change");
|
||||
assert_not_equals(originalBody, undefined, "body should not be undefined");
|
||||
assert_not_equals(originalBody, null, "body should not be null");
|
||||
assert_not_equals(requestFromRequest.body, originalBody, "new request's body is new");
|
||||
return requestFromRequest.text().then(text => {
|
||||
assert_equals(text, "Request's body");
|
||||
});
|
||||
}, "Input request used for creating new request became disturbed");
|
||||
|
||||
promise_test(() => {
|
||||
const bodyRequest = new Request("", initValuesDict);
|
||||
const originalBody = bodyRequest.body;
|
||||
assert_false(bodyRequest.bodyUsed , "bodyUsed is false when request is not disturbed");
|
||||
const requestFromRequest = new Request(bodyRequest, { body : "init body" });
|
||||
assert_true(bodyRequest.bodyUsed , "bodyUsed is true when request is disturbed");
|
||||
assert_equals(bodyRequest.body, originalBody, "body should not change");
|
||||
assert_not_equals(originalBody, undefined, "body should not be undefined");
|
||||
assert_not_equals(originalBody, null, "body should not be null");
|
||||
assert_not_equals(requestFromRequest.body, originalBody, "new request's body is new");
|
||||
|
||||
return requestFromRequest.text().then(text => {
|
||||
assert_equals(text, "init body");
|
||||
});
|
||||
}, "Input request used for creating new request became disturbed even if body is not used");
|
||||
|
||||
promise_test(function(test) {
|
||||
assert_true(bodyConsumed.bodyUsed , "bodyUsed is true when request is disturbed");
|
||||
return promise_rejects_js(test, TypeError, bodyConsumed.blob());
|
||||
}, "Check consuming a disturbed request");
|
||||
|
||||
test(function() {
|
||||
var req = new Request(URL, {method: 'POST', body: 'hello'});
|
||||
assert_false(req.bodyUsed,
|
||||
'Request should not be flagged as used if it has not been ' +
|
||||
'consumed.');
|
||||
assert_throws_js(TypeError,
|
||||
function() { new Request(req, {method: 'GET'}); },
|
||||
'A get request may not have body.');
|
||||
|
||||
assert_false(req.bodyUsed, 'After the GET case');
|
||||
|
||||
assert_throws_js(TypeError,
|
||||
function() { new Request(req, {method: 'CONNECT'}); },
|
||||
'Request() with a forbidden method must throw.');
|
||||
|
||||
assert_false(req.bodyUsed, 'After the forbidden method case');
|
||||
|
||||
var req2 = new Request(req);
|
||||
assert_true(req.bodyUsed,
|
||||
'Request should be flagged as used if it has been consumed.');
|
||||
}, 'Request construction failure should not set "bodyUsed"');
|
||||
@@ -0,0 +1,56 @@
|
||||
// META: global=window,worker
|
||||
// META: title=Request error
|
||||
// META: script=request-error.js
|
||||
|
||||
// badRequestArgTests is from response-error.js
|
||||
for (const { args, testName } of badRequestArgTests) {
|
||||
test(() => {
|
||||
assert_throws_js(
|
||||
TypeError,
|
||||
() => new Request(...args),
|
||||
"Expect TypeError exception"
|
||||
);
|
||||
}, testName);
|
||||
}
|
||||
|
||||
test(function() {
|
||||
assert_throws_js(
|
||||
TypeError,
|
||||
() => Request("about:blank"),
|
||||
"Calling Request constructor without 'new' must throw"
|
||||
);
|
||||
});
|
||||
|
||||
test(function() {
|
||||
var initialHeaders = new Headers([["Content-Type", "potato"]]);
|
||||
var initialRequest = new Request("", {"headers" : initialHeaders});
|
||||
var request = new Request(initialRequest);
|
||||
assert_equals(request.headers.get("Content-Type"), "potato");
|
||||
}, "Request should get its content-type from the init request");
|
||||
|
||||
test(function() {
|
||||
var initialHeaders = new Headers([["Content-Type", "potato"]]);
|
||||
var initialRequest = new Request("", {"headers" : initialHeaders});
|
||||
var headers = new Headers([]);
|
||||
var request = new Request(initialRequest, {"headers" : headers});
|
||||
assert_false(request.headers.has("Content-Type"));
|
||||
}, "Request should not get its content-type from the init request if init headers are provided");
|
||||
|
||||
test(function() {
|
||||
var initialHeaders = new Headers([["Content-Type-Extra", "potato"]]);
|
||||
var initialRequest = new Request("", {"headers" : initialHeaders, "body" : "this is my plate", "method" : "POST"});
|
||||
var request = new Request(initialRequest);
|
||||
assert_equals(request.headers.get("Content-Type"), "text/plain;charset=UTF-8");
|
||||
}, "Request should get its content-type from the body if none is provided");
|
||||
|
||||
test(function() {
|
||||
var initialHeaders = new Headers([["Content-Type", "potato"]]);
|
||||
var initialRequest = new Request("", {"headers" : initialHeaders, "body" : "this is my plate", "method" : "POST"});
|
||||
var request = new Request(initialRequest);
|
||||
assert_equals(request.headers.get("Content-Type"), "potato");
|
||||
}, "Request should get its content-type from init headers if one is provided");
|
||||
|
||||
test(function() {
|
||||
var options = {"cache": "only-if-cached", "mode": "same-origin"};
|
||||
new Request("test", options);
|
||||
}, "Request with cache mode: only-if-cached and fetch mode: same-origin");
|
||||
@@ -0,0 +1,57 @@
|
||||
const badRequestArgTests = [
|
||||
{
|
||||
args: ["", { "window": "http://test.url" }],
|
||||
testName: "RequestInit's window is not null"
|
||||
},
|
||||
{
|
||||
args: ["http://:not a valid URL"],
|
||||
testName: "Input URL is not valid"
|
||||
},
|
||||
{
|
||||
args: ["http://user:[email protected]"],
|
||||
testName: "Input URL has credentials"
|
||||
},
|
||||
{
|
||||
args: ["", { "mode": "navigate" }],
|
||||
testName: "RequestInit's mode is navigate"
|
||||
},
|
||||
{
|
||||
args: ["", { "referrer": "http://:not a valid URL" }],
|
||||
testName: "RequestInit's referrer is invalid"
|
||||
},
|
||||
{
|
||||
args: ["", { "method": "IN VALID" }],
|
||||
testName: "RequestInit's method is invalid"
|
||||
},
|
||||
{
|
||||
args: ["", { "method": "TRACE" }],
|
||||
testName: "RequestInit's method is forbidden"
|
||||
},
|
||||
{
|
||||
args: ["", { "mode": "no-cors", "method": "PUT" }],
|
||||
testName: "RequestInit's mode is no-cors and method is not simple"
|
||||
},
|
||||
{
|
||||
args: ["", { "mode": "cors", "cache": "only-if-cached" }],
|
||||
testName: "RequestInit's cache mode is only-if-cached and mode is not same-origin"
|
||||
},
|
||||
{
|
||||
args: ["test", { "cache": "only-if-cached", "mode": "cors" }],
|
||||
testName: "Request with cache mode: only-if-cached and fetch mode cors"
|
||||
},
|
||||
{
|
||||
args: ["test", { "cache": "only-if-cached", "mode": "no-cors" }],
|
||||
testName: "Request with cache mode: only-if-cached and fetch mode no-cors"
|
||||
}
|
||||
];
|
||||
|
||||
badRequestArgTests.push(
|
||||
...["referrerPolicy", "mode", "credentials", "cache", "redirect"].map(optionProp => {
|
||||
const options = {};
|
||||
options[optionProp] = "BAD";
|
||||
return {
|
||||
args: ["", options],
|
||||
testName: `Bad ${optionProp} init parameter value`
|
||||
};
|
||||
})
|
||||
);
|
||||
@@ -0,0 +1,177 @@
|
||||
// META: global=window,worker
|
||||
// META: title=Request Headers
|
||||
|
||||
var validRequestHeaders = [
|
||||
["Content-Type", "OK"],
|
||||
["Potato", "OK"],
|
||||
["proxy", "OK"],
|
||||
["proxya", "OK"],
|
||||
["sec", "OK"],
|
||||
["secb", "OK"],
|
||||
["Set-Cookie2", "OK"],
|
||||
["User-Agent", "OK"],
|
||||
];
|
||||
var invalidRequestHeaders = [
|
||||
["Accept-Charset", "KO"],
|
||||
["accept-charset", "KO"],
|
||||
["ACCEPT-ENCODING", "KO"],
|
||||
["Accept-Encoding", "KO"],
|
||||
["Access-Control-Request-Headers", "KO"],
|
||||
["Access-Control-Request-Method", "KO"],
|
||||
["Connection", "KO"],
|
||||
["Content-Length", "KO"],
|
||||
["Cookie", "KO"],
|
||||
["Cookie2", "KO"],
|
||||
["Date", "KO"],
|
||||
["DNT", "KO"],
|
||||
["Expect", "KO"],
|
||||
["Host", "KO"],
|
||||
["Keep-Alive", "KO"],
|
||||
["Origin", "KO"],
|
||||
["Referer", "KO"],
|
||||
["Set-Cookie", "KO"],
|
||||
["TE", "KO"],
|
||||
["Trailer", "KO"],
|
||||
["Transfer-Encoding", "KO"],
|
||||
["Upgrade", "KO"],
|
||||
["Via", "KO"],
|
||||
["Proxy-", "KO"],
|
||||
["proxy-a", "KO"],
|
||||
["Sec-", "KO"],
|
||||
["sec-b", "KO"],
|
||||
];
|
||||
|
||||
var validRequestNoCorsHeaders = [
|
||||
["Accept", "OK"],
|
||||
["Accept-Language", "OK"],
|
||||
["content-language", "OK"],
|
||||
["content-type", "application/x-www-form-urlencoded"],
|
||||
["content-type", "application/x-www-form-urlencoded;charset=UTF-8"],
|
||||
["content-type", "multipart/form-data"],
|
||||
["content-type", "multipart/form-data;charset=UTF-8"],
|
||||
["content-TYPE", "text/plain"],
|
||||
["CONTENT-type", "text/plain;charset=UTF-8"],
|
||||
];
|
||||
var invalidRequestNoCorsHeaders = [
|
||||
["Content-Type", "KO"],
|
||||
["Potato", "KO"],
|
||||
["proxy", "KO"],
|
||||
["proxya", "KO"],
|
||||
["sec", "KO"],
|
||||
["secb", "KO"],
|
||||
["Empty-Value", ""],
|
||||
];
|
||||
|
||||
validRequestHeaders.forEach(function(header) {
|
||||
test(function() {
|
||||
var request = new Request("");
|
||||
request.headers.set(header[0], header[1]);
|
||||
assert_equals(request.headers.get(header[0]), header[1]);
|
||||
}, "Adding valid request header \"" + header[0] + ": " + header[1] + "\"");
|
||||
});
|
||||
invalidRequestHeaders.forEach(function(header) {
|
||||
test(function() {
|
||||
var request = new Request("");
|
||||
request.headers.set(header[0], header[1]);
|
||||
assert_equals(request.headers.get(header[0]), null);
|
||||
}, "Adding invalid request header \"" + header[0] + ": " + header[1] + "\"");
|
||||
});
|
||||
|
||||
validRequestNoCorsHeaders.forEach(function(header) {
|
||||
test(function() {
|
||||
var requestNoCors = new Request("", {"mode": "no-cors"});
|
||||
requestNoCors.headers.set(header[0], header[1]);
|
||||
assert_equals(requestNoCors.headers.get(header[0]), header[1]);
|
||||
}, "Adding valid no-cors request header \"" + header[0] + ": " + header[1] + "\"");
|
||||
});
|
||||
invalidRequestNoCorsHeaders.forEach(function(header) {
|
||||
test(function() {
|
||||
var requestNoCors = new Request("", {"mode": "no-cors"});
|
||||
requestNoCors.headers.set(header[0], header[1]);
|
||||
assert_equals(requestNoCors.headers.get(header[0]), null);
|
||||
}, "Adding invalid no-cors request header \"" + header[0] + ": " + header[1] + "\"");
|
||||
});
|
||||
|
||||
test(function() {
|
||||
var headers = new Headers([["Cookie2", "potato"]]);
|
||||
var request = new Request("", {"headers": headers});
|
||||
assert_equals(request.headers.get("Cookie2"), null);
|
||||
}, "Check that request constructor is filtering headers provided as init parameter");
|
||||
|
||||
test(function() {
|
||||
var headers = new Headers([["Content-Type", "potato"]]);
|
||||
var request = new Request("", {"headers": headers, "mode": "no-cors"});
|
||||
assert_equals(request.headers.get("Content-Type"), null);
|
||||
}, "Check that no-cors request constructor is filtering headers provided as init parameter");
|
||||
|
||||
test(function() {
|
||||
var headers = new Headers([["Content-Type", "potato"]]);
|
||||
var initialRequest = new Request("", {"headers": headers});
|
||||
var request = new Request(initialRequest, {"mode": "no-cors"});
|
||||
assert_equals(request.headers.get("Content-Type"), null);
|
||||
}, "Check that no-cors request constructor is filtering headers provided as part of request parameter");
|
||||
|
||||
test(function() {
|
||||
var initialHeaders = new Headers([["Content-Type", "potato"]]);
|
||||
var initialRequest = new Request("", {"headers" : initialHeaders});
|
||||
var request = new Request(initialRequest);
|
||||
assert_equals(request.headers.get("Content-Type"), "potato");
|
||||
}, "Request should get its content-type from the init request");
|
||||
|
||||
test(function() {
|
||||
var initialHeaders = new Headers([["Content-Type", "potato"]]);
|
||||
var initialRequest = new Request("", {"headers" : initialHeaders});
|
||||
var headers = new Headers([]);
|
||||
var request = new Request(initialRequest, {"headers" : headers});
|
||||
assert_false(request.headers.has("Content-Type"));
|
||||
}, "Request should not get its content-type from the init request if init headers are provided");
|
||||
|
||||
test(function() {
|
||||
var initialHeaders = new Headers([["Content-Type-Extra", "potato"]]);
|
||||
var initialRequest = new Request("", {"headers" : initialHeaders, "body" : "this is my plate", "method" : "POST"});
|
||||
var request = new Request(initialRequest);
|
||||
assert_equals(request.headers.get("Content-Type"), "text/plain;charset=UTF-8");
|
||||
}, "Request should get its content-type from the body if none is provided");
|
||||
|
||||
test(function() {
|
||||
var initialHeaders = new Headers([["Content-Type", "potato"]]);
|
||||
var initialRequest = new Request("", {"headers" : initialHeaders, "body" : "this is my plate", "method" : "POST"});
|
||||
var request = new Request(initialRequest);
|
||||
assert_equals(request.headers.get("Content-Type"), "potato");
|
||||
}, "Request should get its content-type from init headers if one is provided");
|
||||
|
||||
test(function() {
|
||||
var array = [["hello", "worldAHH"]];
|
||||
var object = {"hello": 'worldOOH'};
|
||||
var headers = new Headers(array);
|
||||
|
||||
assert_equals(headers.get("hello"), "worldAHH");
|
||||
|
||||
var request1 = new Request("", {"headers": headers});
|
||||
var request2 = new Request("", {"headers": array});
|
||||
var request3 = new Request("", {"headers": object});
|
||||
|
||||
assert_equals(request1.headers.get("hello"), "worldAHH");
|
||||
assert_equals(request2.headers.get("hello"), "worldAHH");
|
||||
assert_equals(request3.headers.get("hello"), "worldOOH");
|
||||
}, "Testing request header creations with various objects");
|
||||
|
||||
promise_test(function(test) {
|
||||
var request = new Request("", {"headers" : [["Content-Type", ""]], "body" : "this is my plate", "method" : "POST"});
|
||||
return request.blob().then(function(blob) {
|
||||
assert_equals(blob.type, "", "Blob type should be the empty string");
|
||||
});
|
||||
}, "Testing empty Request Content-Type header");
|
||||
|
||||
test(function() {
|
||||
const request1 = new Request("");
|
||||
assert_equals(request1.headers, request1.headers);
|
||||
|
||||
const request2 = new Request("", {"headers": {"X-Foo": "bar"}});
|
||||
assert_equals(request2.headers, request2.headers);
|
||||
const headers = request2.headers;
|
||||
request2.headers.set("X-Foo", "quux");
|
||||
assert_equals(headers, request2.headers);
|
||||
headers.set("X-Other-Header", "baz");
|
||||
assert_equals(headers, request2.headers);
|
||||
}, "Test that Request.headers has the [SameObject] extended attribute");
|
||||
@@ -0,0 +1,60 @@
|
||||
// META: global=window,worker
|
||||
// META: title=Request init: headers and body
|
||||
|
||||
test(function() {
|
||||
var headerDict = {"name1": "value1",
|
||||
"name2": "value2",
|
||||
"name3": "value3"
|
||||
};
|
||||
var headers = new Headers(headerDict);
|
||||
var request = new Request("", { "headers" : headers })
|
||||
for (var name in headerDict) {
|
||||
assert_equals(request.headers.get(name), headerDict[name],
|
||||
"request's headers has " + name + " : " + headerDict[name]);
|
||||
}
|
||||
}, "Initialize Request with headers values");
|
||||
|
||||
function makeRequestInit(body, method) {
|
||||
return {"method": method, "body": body};
|
||||
}
|
||||
|
||||
function checkRequestInit(body, bodyType, expectedTextBody) {
|
||||
promise_test(function(test) {
|
||||
var request = new Request("", makeRequestInit(body, "POST"));
|
||||
if (body) {
|
||||
assert_throws_js(TypeError, function() { new Request("", makeRequestInit(body, "GET")); });
|
||||
assert_throws_js(TypeError, function() { new Request("", makeRequestInit(body, "HEAD")); });
|
||||
} else {
|
||||
new Request("", makeRequestInit(body, "GET")); // should not throw
|
||||
}
|
||||
var reqHeaders = request.headers;
|
||||
var mime = reqHeaders.get("Content-Type");
|
||||
assert_true(!body || (mime && mime.search(bodyType) > -1), "Content-Type header should be \"" + bodyType + "\", not \"" + mime + "\"");
|
||||
return request.text().then(function(bodyAsText) {
|
||||
//not equals: cannot guess formData exact value
|
||||
assert_true( bodyAsText.search(expectedTextBody) > -1, "Retrieve and verify request body");
|
||||
});
|
||||
}, `Initialize Request's body with "${body}", ${bodyType}`);
|
||||
}
|
||||
|
||||
var blob = new Blob(["This is a blob"], {type: "application/octet-binary"});
|
||||
var formaData = new FormData();
|
||||
formaData.append("name", "value");
|
||||
var usvString = "This is a USVString"
|
||||
|
||||
checkRequestInit(undefined, undefined, "");
|
||||
checkRequestInit(null, null, "");
|
||||
checkRequestInit(blob, "application/octet-binary", "This is a blob");
|
||||
checkRequestInit(formaData, "multipart/form-data", "name=\"name\"\r\n\r\nvalue");
|
||||
checkRequestInit(usvString, "text/plain;charset=UTF-8", "This is a USVString");
|
||||
checkRequestInit({toString: () => "hi!"}, "text/plain;charset=UTF-8", "hi!");
|
||||
|
||||
// Ensure test does not time out in case of missing URLSearchParams support.
|
||||
if (self.URLSearchParams) {
|
||||
var urlSearchParams = new URLSearchParams("name=value");
|
||||
checkRequestInit(urlSearchParams, "application/x-www-form-urlencoded;charset=UTF-8", "name=value");
|
||||
} else {
|
||||
promise_test(function(test) {
|
||||
return Promise.reject("URLSearchParams not supported");
|
||||
}, "Initialize Request's body with application/x-www-form-urlencoded;charset=UTF-8");
|
||||
}
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
function requestFromBody(body) {
|
||||
return new Request(
|
||||
"https://example.com",
|
||||
{
|
||||
method: "POST",
|
||||
body,
|
||||
duplex: "half",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
test(() => {
|
||||
const request = requestFromBody(undefined);
|
||||
assert_equals(request.headers.get("Content-Type"), null);
|
||||
}, "Default Content-Type for Request with empty body");
|
||||
|
||||
test(() => {
|
||||
const blob = new Blob([]);
|
||||
const request = requestFromBody(blob);
|
||||
assert_equals(request.headers.get("Content-Type"), null);
|
||||
}, "Default Content-Type for Request with Blob body (no type set)");
|
||||
|
||||
test(() => {
|
||||
const blob = new Blob([], { type: "" });
|
||||
const request = requestFromBody(blob);
|
||||
assert_equals(request.headers.get("Content-Type"), null);
|
||||
}, "Default Content-Type for Request with Blob body (empty type)");
|
||||
|
||||
test(() => {
|
||||
const blob = new Blob([], { type: "a/b; c=d" });
|
||||
const request = requestFromBody(blob);
|
||||
assert_equals(request.headers.get("Content-Type"), "a/b; c=d");
|
||||
}, "Default Content-Type for Request with Blob body (set type)");
|
||||
|
||||
test(() => {
|
||||
const buffer = new Uint8Array();
|
||||
const request = requestFromBody(buffer);
|
||||
assert_equals(request.headers.get("Content-Type"), null);
|
||||
}, "Default Content-Type for Request with buffer source body");
|
||||
|
||||
promise_test(async () => {
|
||||
const formData = new FormData();
|
||||
formData.append("a", "b");
|
||||
const request = requestFromBody(formData);
|
||||
const boundary = (await request.text()).split("\r\n")[0].slice(2);
|
||||
assert_equals(
|
||||
request.headers.get("Content-Type"),
|
||||
`multipart/form-data; boundary=${boundary}`,
|
||||
);
|
||||
}, "Default Content-Type for Request with FormData body");
|
||||
|
||||
test(() => {
|
||||
const usp = new URLSearchParams();
|
||||
const request = requestFromBody(usp);
|
||||
assert_equals(
|
||||
request.headers.get("Content-Type"),
|
||||
"application/x-www-form-urlencoded;charset=UTF-8",
|
||||
);
|
||||
}, "Default Content-Type for Request with URLSearchParams body");
|
||||
|
||||
test(() => {
|
||||
const request = requestFromBody("");
|
||||
assert_equals(
|
||||
request.headers.get("Content-Type"),
|
||||
"text/plain;charset=UTF-8",
|
||||
);
|
||||
}, "Default Content-Type for Request with string body");
|
||||
|
||||
test(() => {
|
||||
const stream = new ReadableStream();
|
||||
const request = requestFromBody(stream);
|
||||
assert_equals(request.headers.get("Content-Type"), null);
|
||||
}, "Default Content-Type for Request with ReadableStream body");
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
const OVERRIDE_MIME = "test/only; mime=type";
|
||||
|
||||
function requestFromBodyWithOverrideMime(body) {
|
||||
return new Request(
|
||||
"https://example.com",
|
||||
{
|
||||
method: "POST",
|
||||
body,
|
||||
headers: { "Content-Type": OVERRIDE_MIME },
|
||||
duplex: "half",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
test(() => {
|
||||
const request = requestFromBodyWithOverrideMime(undefined);
|
||||
assert_equals(request.headers.get("Content-Type"), OVERRIDE_MIME);
|
||||
}, "Can override Content-Type for Request with empty body");
|
||||
|
||||
test(() => {
|
||||
const blob = new Blob([]);
|
||||
const request = requestFromBodyWithOverrideMime(blob);
|
||||
assert_equals(request.headers.get("Content-Type"), OVERRIDE_MIME);
|
||||
}, "Can override Content-Type for Request with Blob body (no type set)");
|
||||
|
||||
test(() => {
|
||||
const blob = new Blob([], { type: "" });
|
||||
const request = requestFromBodyWithOverrideMime(blob);
|
||||
assert_equals(request.headers.get("Content-Type"), OVERRIDE_MIME);
|
||||
}, "Can override Content-Type for Request with Blob body (empty type)");
|
||||
|
||||
test(() => {
|
||||
const blob = new Blob([], { type: "a/b; c=d" });
|
||||
const request = requestFromBodyWithOverrideMime(blob);
|
||||
assert_equals(request.headers.get("Content-Type"), OVERRIDE_MIME);
|
||||
}, "Can override Content-Type for Request with Blob body (set type)");
|
||||
|
||||
test(() => {
|
||||
const buffer = new Uint8Array();
|
||||
const request = requestFromBodyWithOverrideMime(buffer);
|
||||
assert_equals(request.headers.get("Content-Type"), OVERRIDE_MIME);
|
||||
}, "Can override Content-Type for Request with buffer source body");
|
||||
|
||||
test(() => {
|
||||
const formData = new FormData();
|
||||
const request = requestFromBodyWithOverrideMime(formData);
|
||||
assert_equals(request.headers.get("Content-Type"), OVERRIDE_MIME);
|
||||
}, "Can override Content-Type for Request with FormData body");
|
||||
|
||||
test(() => {
|
||||
const usp = new URLSearchParams();
|
||||
const request = requestFromBodyWithOverrideMime(usp);
|
||||
assert_equals(request.headers.get("Content-Type"), OVERRIDE_MIME);
|
||||
}, "Can override Content-Type for Request with URLSearchParams body");
|
||||
|
||||
test(() => {
|
||||
const request = requestFromBodyWithOverrideMime("");
|
||||
assert_equals(request.headers.get("Content-Type"), OVERRIDE_MIME);
|
||||
}, "Can override Content-Type for Request with string body");
|
||||
|
||||
test(() => {
|
||||
const stream = new ReadableStream();
|
||||
const request = requestFromBodyWithOverrideMime(stream);
|
||||
assert_equals(request.headers.get("Content-Type"), OVERRIDE_MIME);
|
||||
}, "Can override Content-Type for Request with ReadableStream body");
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
var priorities = ["high",
|
||||
"low",
|
||||
"auto"
|
||||
];
|
||||
|
||||
for (idx in priorities) {
|
||||
test(() => {
|
||||
new Request("", {priority: priorities[idx]});
|
||||
}, "new Request() with a '" + priorities[idx] + "' priority does not throw an error");
|
||||
}
|
||||
|
||||
test(() => {
|
||||
assert_throws_js(TypeError, () => {
|
||||
new Request("", {priority: 'invalid'});
|
||||
}, "a new Request() must throw a TypeError if RequestInit's priority is an invalid value");
|
||||
}, "new Request() throws a TypeError if any of RequestInit's members' values are invalid");
|
||||
|
||||
for (idx in priorities) {
|
||||
promise_test(function(t) {
|
||||
return fetch('hello.txt', { priority: priorities[idx] });
|
||||
}, "fetch() with a '" + priorities[idx] + "' priority completes successfully");
|
||||
}
|
||||
|
||||
promise_test(function(t) {
|
||||
return promise_rejects_js(t, TypeError, fetch('hello.txt', { priority: 'invalid' }));
|
||||
}, "fetch() with an invalid priority returns a rejected promise with a TypeError");
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
// META: global=window,worker
|
||||
|
||||
"use strict";
|
||||
|
||||
const duplex = "half";
|
||||
const method = "POST";
|
||||
|
||||
test(() => {
|
||||
const body = new ReadableStream();
|
||||
const request = new Request("...", { method, body, duplex });
|
||||
assert_equals(request.body, body);
|
||||
}, "Constructing a Request with a stream holds the original object.");
|
||||
|
||||
test((t) => {
|
||||
const body = new ReadableStream();
|
||||
body.getReader();
|
||||
assert_throws_js(TypeError,
|
||||
() => new Request("...", { method, body, duplex }));
|
||||
}, "Constructing a Request with a stream on which getReader() is called");
|
||||
|
||||
test((t) => {
|
||||
const body = new ReadableStream();
|
||||
body.getReader().read();
|
||||
assert_throws_js(TypeError,
|
||||
() => new Request("...", { method, body, duplex }));
|
||||
}, "Constructing a Request with a stream on which read() is called");
|
||||
|
||||
promise_test(async (t) => {
|
||||
const body = new ReadableStream({ pull: c => c.enqueue(new Uint8Array()) });
|
||||
const reader = body.getReader();
|
||||
await reader.read();
|
||||
reader.releaseLock();
|
||||
assert_throws_js(TypeError,
|
||||
() => new Request("...", { method, body, duplex }));
|
||||
}, "Constructing a Request with a stream on which read() and releaseLock() are called");
|
||||
|
||||
test((t) => {
|
||||
const request = new Request("...", { method: "POST", body: "..." });
|
||||
request.body.getReader();
|
||||
assert_throws_js(TypeError, () => new Request(request));
|
||||
// This doesn't throw.
|
||||
new Request(request, { body: "..." });
|
||||
}, "Constructing a Request with a Request on which body.getReader() is called");
|
||||
|
||||
test((t) => {
|
||||
const request = new Request("...", { method: "POST", body: "..." });
|
||||
request.body.getReader().read();
|
||||
assert_throws_js(TypeError, () => new Request(request));
|
||||
// This doesn't throw.
|
||||
new Request(request, { body: "..." });
|
||||
}, "Constructing a Request with a Request on which body.getReader().read() is called");
|
||||
|
||||
promise_test(async (t) => {
|
||||
const request = new Request("...", { method: "POST", body: "..." });
|
||||
const reader = request.body.getReader();
|
||||
await reader.read();
|
||||
reader.releaseLock();
|
||||
assert_throws_js(TypeError, () => new Request(request));
|
||||
// This doesn't throw.
|
||||
new Request(request, { body: "..." });
|
||||
}, "Constructing a Request with a Request on which read() and releaseLock() are called");
|
||||
|
||||
test((t) => {
|
||||
new Request("...", { method, body: null });
|
||||
}, "It is OK to omit .duplex when the body is null.");
|
||||
|
||||
test((t) => {
|
||||
new Request("...", { method, body: "..." });
|
||||
}, "It is OK to omit .duplex when the body is a string.");
|
||||
|
||||
test((t) => {
|
||||
new Request("...", { method, body: new Uint8Array(3) });
|
||||
}, "It is OK to omit .duplex when the body is a Uint8Array.");
|
||||
|
||||
test((t) => {
|
||||
new Request("...", { method, body: new Blob([]) });
|
||||
}, "It is OK to omit .duplex when the body is a Blob.");
|
||||
|
||||
test((t) => {
|
||||
const body = new ReadableStream();
|
||||
assert_throws_js(TypeError,
|
||||
() => new Request("...", { method, body }));
|
||||
}, "It is error to omit .duplex when the body is a ReadableStream.");
|
||||
|
||||
test((t) => {
|
||||
new Request("...", { method, body: null, duplex: "half" });
|
||||
}, "It is OK to set .duplex = 'half' when the body is null.");
|
||||
|
||||
test((t) => {
|
||||
new Request("...", { method, body: "...", duplex: "half" });
|
||||
}, "It is OK to set .duplex = 'half' when the body is a string.");
|
||||
|
||||
test((t) => {
|
||||
new Request("...", { method, body: new Uint8Array(3), duplex: "half" });
|
||||
}, "It is OK to set .duplex = 'half' when the body is a Uint8Array.");
|
||||
|
||||
test((t) => {
|
||||
new Request("...", { method, body: new Blob([]), duplex: "half" });
|
||||
}, "It is OK to set .duplex = 'half' when the body is a Blob.");
|
||||
|
||||
test((t) => {
|
||||
const body = new ReadableStream();
|
||||
new Request("...", { method, body, duplex: "half" });
|
||||
}, "It is OK to set .duplex = 'half' when the body is a ReadableStream.");
|
||||
|
||||
test((t) => {
|
||||
const body = null;
|
||||
const duplex = "full";
|
||||
assert_throws_js(TypeError,
|
||||
() => new Request("...", { method, body, duplex }));
|
||||
}, "It is error to set .duplex = 'full' when the body is null.");
|
||||
|
||||
test((t) => {
|
||||
const body = "...";
|
||||
const duplex = "full";
|
||||
assert_throws_js(TypeError,
|
||||
() => new Request("...", { method, body, duplex }));
|
||||
}, "It is error to set .duplex = 'full' when the body is a string.");
|
||||
|
||||
test((t) => {
|
||||
const body = new Uint8Array(3);
|
||||
const duplex = "full";
|
||||
assert_throws_js(TypeError,
|
||||
() => new Request("...", { method, body, duplex }));
|
||||
}, "It is error to set .duplex = 'full' when the body is a Uint8Array.");
|
||||
|
||||
test((t) => {
|
||||
const body = new Blob([]);
|
||||
const duplex = "full";
|
||||
assert_throws_js(TypeError,
|
||||
() => new Request("...", { method, body, duplex }));
|
||||
}, "It is error to set .duplex = 'full' when the body is a Blob.");
|
||||
|
||||
test((t) => {
|
||||
const body = new ReadableStream();
|
||||
const duplex = "full";
|
||||
assert_throws_js(TypeError,
|
||||
() => new Request("...", { method, body, duplex }));
|
||||
}, "It is error to set .duplex = 'full' when the body is a ReadableStream.");
|
||||
|
||||
test((t) => {
|
||||
const body = new ReadableStream();
|
||||
const duplex = "half";
|
||||
const req1 = new Request("...", { method, body, duplex });
|
||||
const req2 = new Request(req1);
|
||||
}, "It is OK to omit duplex when init.body is not given and input.body is given.");
|
||||
@@ -0,0 +1,17 @@
|
||||
// META: global=window,worker
|
||||
// META: title=Request keepalive
|
||||
// META: script=/common/utils.js
|
||||
// META: script=/common/get-host-info.sub.js
|
||||
|
||||
test(() => {
|
||||
assert_false(new Request('/').keepalive, 'default');
|
||||
assert_true(new Request('/', {keepalive: true}).keepalive, 'true');
|
||||
assert_false(new Request('/', {keepalive: false}).keepalive, 'false');
|
||||
assert_true(new Request('/', {keepalive: 1}).keepalive, 'truish');
|
||||
assert_false(new Request('/', {keepalive: 0}).keepalive, 'falsy');
|
||||
}, 'keepalive flag');
|
||||
|
||||
test(() => {
|
||||
const init = {method: 'POST', keepalive: true, body: new ReadableStream()};
|
||||
assert_throws_js(TypeError, () => {new Request('/', init)});
|
||||
}, 'keepalive flag with stream body');
|
||||
@@ -0,0 +1,143 @@
|
||||
// META: global=window,worker
|
||||
// META: title=Request structure
|
||||
|
||||
var request = new Request("");
|
||||
var methods = ["clone",
|
||||
//Request implements Body
|
||||
"arrayBuffer",
|
||||
"blob",
|
||||
"formData",
|
||||
"json",
|
||||
"text"
|
||||
];
|
||||
var attributes = ["method",
|
||||
"url",
|
||||
"headers",
|
||||
"destination",
|
||||
"referrer",
|
||||
"referrerPolicy",
|
||||
"mode",
|
||||
"credentials",
|
||||
"cache",
|
||||
"redirect",
|
||||
"integrity",
|
||||
"isReloadNavigation",
|
||||
"isHistoryNavigation",
|
||||
"duplex",
|
||||
//Request implements Body
|
||||
"bodyUsed"
|
||||
];
|
||||
var internalAttributes = ["priority",
|
||||
"internalpriority",
|
||||
"blocking"
|
||||
];
|
||||
|
||||
function isReadOnly(request, attributeToCheck) {
|
||||
var defaultValue = undefined;
|
||||
var newValue = undefined;
|
||||
switch (attributeToCheck) {
|
||||
case "method":
|
||||
defaultValue = "GET";
|
||||
newValue = "POST";
|
||||
break;
|
||||
|
||||
case "url":
|
||||
//default value is base url
|
||||
//i.e http://example.com/fetch/api/request-structure.html
|
||||
newValue = "http://url.test";
|
||||
break;
|
||||
|
||||
case "headers":
|
||||
request.headers = new Headers ({"name":"value"});
|
||||
assert_false(request.headers.has("name"), "Headers attribute is read only");
|
||||
return;
|
||||
|
||||
case "destination":
|
||||
defaultValue = "";
|
||||
newValue = "worker";
|
||||
break;
|
||||
|
||||
case "referrer":
|
||||
defaultValue = "about:client";
|
||||
newValue = "http://url.test";
|
||||
break;
|
||||
|
||||
case "referrerPolicy":
|
||||
defaultValue = "";
|
||||
newValue = "unsafe-url";
|
||||
break;
|
||||
|
||||
case "mode":
|
||||
defaultValue = "cors";
|
||||
newValue = "navigate";
|
||||
break;
|
||||
|
||||
case "credentials":
|
||||
defaultValue = "same-origin";
|
||||
newValue = "cors";
|
||||
break;
|
||||
|
||||
case "cache":
|
||||
defaultValue = "default";
|
||||
newValue = "reload";
|
||||
break;
|
||||
|
||||
case "redirect":
|
||||
defaultValue = "follow";
|
||||
newValue = "manual";
|
||||
break;
|
||||
|
||||
case "integrity":
|
||||
newValue = "CannotWriteIntegrity";
|
||||
break;
|
||||
|
||||
case "bodyUsed":
|
||||
defaultValue = false;
|
||||
newValue = true;
|
||||
break;
|
||||
|
||||
case "isReloadNavigation":
|
||||
defaultValue = false;
|
||||
newValue = true;
|
||||
break;
|
||||
|
||||
case "isHistoryNavigation":
|
||||
defaultValue = false;
|
||||
newValue = true;
|
||||
break;
|
||||
|
||||
case "duplex":
|
||||
defaultValue = "half";
|
||||
newValue = "full";
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
request[attributeToCheck] = newValue;
|
||||
if (defaultValue === undefined)
|
||||
assert_not_equals(request[attributeToCheck], newValue, "Attribute " + attributeToCheck + " is read only");
|
||||
else
|
||||
assert_equals(request[attributeToCheck], defaultValue,
|
||||
"Attribute " + attributeToCheck + " is read only. Default value is " + defaultValue);
|
||||
}
|
||||
|
||||
for (var idx in methods) {
|
||||
test(function() {
|
||||
assert_true(methods[idx] in request, "request has " + methods[idx] + " method");
|
||||
}, "Request has " + methods[idx] + " method");
|
||||
}
|
||||
|
||||
for (var idx in attributes) {
|
||||
test(function() {
|
||||
assert_true(attributes[idx] in request, "request has " + attributes[idx] + " attribute");
|
||||
isReadOnly(request, attributes[idx]);
|
||||
}, "Check " + attributes[idx] + " attribute");
|
||||
}
|
||||
|
||||
for (var idx in internalAttributes) {
|
||||
test(function() {
|
||||
assert_false(internalAttributes[idx] in request, "request does not expose " + internalAttributes[idx] + " attribute");
|
||||
}, "Request does not expose " + internalAttributes[idx] + " attribute");
|
||||
}
|
||||
Reference in new issue
Block a user