Bug 1122677 - Disallow request body when method is HEAD/GET.

Spec bug https://www.w3.org/Bugs/Public/show_bug.cgi?id=27846
and :annevk OKed putting the check in the constructor and throwing http://logs.glob.uno/?c=content#c259382
This commit is contained in:
Nikhil Marathe 2015-01-16 13:08:19 -08:00
parent a74d0f5ce3
commit 25784bf67f
3 changed files with 37 additions and 9 deletions

View File

@ -64,4 +64,5 @@ MSG_DEF(MSG_INVALID_REQUEST_METHOD, 1, "Invalid request method {0}.")
MSG_DEF(MSG_REQUEST_BODY_CONSUMED_ERROR, 0, "Request body has already been consumed.")
MSG_DEF(MSG_RESPONSE_INVALID_STATUSTEXT_ERROR, 0, "Response statusText may not contain newline or carriage return.")
MSG_DEF(MSG_FETCH_FAILED, 0, "NetworkError when attempting to fetch resource.")
MSG_DEF(MSG_NO_BODY_ALLOWED_FOR_GET_AND_HEAD, 0, "HEAD or GET Request cannot have a body.")
MSG_DEF(MSG_DEFINE_NON_CONFIGURABLE_PROP_ON_WINDOW, 0, "Not allowed to define a non-configurable property on the WindowProxy object")

View File

@ -218,6 +218,15 @@ Request::Constructor(const GlobalObject& aGlobal,
}
if (aInit.mBody.WasPassed()) {
// HEAD and GET are not allowed to have a body.
nsAutoCString method;
request->GetMethod(method);
// method is guaranteed to be uppercase due to step 14.2 above.
if (method.EqualsLiteral("HEAD") || method.EqualsLiteral("GET")) {
aRv.ThrowTypeError(MSG_NO_BODY_ALLOWED_FOR_GET_AND_HEAD);
return nullptr;
}
const OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams& bodyInit = aInit.mBody.Value();
nsCOMPtr<nsIInputStream> stream;
nsCString contentType;

View File

@ -44,7 +44,7 @@ function testClone() {
function testUsedRequest() {
// Passing a used request should fail.
var req = new Request("", { body: "This is foo" });
var req = new Request("", { method: 'post', body: "This is foo" });
var p1 = req.text().then(function(v) {
try {
var req2 = new Request(req);
@ -55,7 +55,7 @@ function testUsedRequest() {
});
// Passing a request should set the request as used.
var reqA = new Request("", { body: "This is foo" });
var reqA = new Request("", { method: 'post', body: "This is foo" });
var reqB = new Request(reqA);
is(reqA.bodyUsed, true, "Passing a Request to another Request should set the former as used");
return p1;
@ -133,6 +133,24 @@ function testMethod() {
ok(true, "Method " + forbiddenNoCors[i] + " should be forbidden in no-cors mode");
}
}
// HEAD/GET requests cannot have a body.
try {
var r = new Request("", { method: "get", body: "hello" });
ok(false, "HEAD/GET request cannot have a body");
} catch(e) {
is(e.name, "TypeError", "HEAD/GET request cannot have a body");
}
try {
var r = new Request("", { method: "head", body: "hello" });
ok(false, "HEAD/GET request cannot have a body");
} catch(e) {
is(e.name, "TypeError", "HEAD/GET request cannot have a body");
}
// Non HEAD/GET should not throw.
var r = new Request("", { method: "patch", body: "hello" });
}
function testUrlFragment() {
@ -141,7 +159,7 @@ function testUrlFragment() {
}
function testBodyUsed() {
var req = new Request("./bodyused", { body: "Sample body" });
var req = new Request("./bodyused", { method: 'post', body: "Sample body" });
is(req.bodyUsed, false, "bodyUsed is initially false.");
return req.text().then((v) => {
is(v, "Sample body", "Body should match");
@ -157,23 +175,23 @@ function testBodyUsed() {
function testBodyCreation() {
var text = "κόσμε";
var req1 = new Request("", { body: text });
var req1 = new Request("", { method: 'post', body: text });
var p1 = req1.text().then(function(v) {
ok(typeof v === "string", "Should resolve to string");
is(text, v, "Extracted string should match");
});
var req2 = new Request("", { body: new Uint8Array([72, 101, 108, 108, 111]) });
var req2 = new Request("", { method: 'post', body: new Uint8Array([72, 101, 108, 108, 111]) });
var p2 = req2.text().then(function(v) {
is("Hello", v, "Extracted string should match");
});
var req2b = new Request("", { body: (new Uint8Array([72, 101, 108, 108, 111])).buffer });
var req2b = new Request("", { method: 'post', body: (new Uint8Array([72, 101, 108, 108, 111])).buffer });
var p2b = req2b.text().then(function(v) {
is("Hello", v, "Extracted string should match");
});
var reqblob = new Request("", { body: new Blob([text]) });
var reqblob = new Request("", { method: 'post', body: new Blob([text]) });
var pblob = reqblob.text().then(function(v) {
is(v, text, "Extracted string should match");
});
@ -182,7 +200,7 @@ function testBodyCreation() {
params.append("item", "Geckos");
params.append("feature", "stickyfeet");
params.append("quantity", "700");
var req3 = new Request("", { body: params });
var req3 = new Request("", { method: 'post', body: params });
var p3 = req3.text().then(function(v) {
var extracted = new URLSearchParams(v);
is(extracted.get("item"), "Geckos", "Param should match");
@ -195,7 +213,7 @@ function testBodyCreation() {
function testBodyExtraction() {
var text = "κόσμε";
var newReq = function() { return new Request("", { body: text }); }
var newReq = function() { return new Request("", { method: 'post', body: text }); }
return newReq().text().then(function(v) {
ok(typeof v === "string", "Should resolve to string");
is(text, v, "Extracted string should match");