From 610be35159e6d1649694170631bb8b41d56f634c Mon Sep 17 00:00:00 2001 From: Nikhil Marathe Date: Thu, 15 Jan 2015 12:11:12 -0800 Subject: [PATCH] Bug 1122194 - Follow method validation rules when constructing Request. r=baku,bkelly --HG-- extra : amend_source : 78950befd29e5aff54956b3399993ade769a21c5 extra : transplant_source : c%B3%E0%87%E7Zdx%03%A6%AA%0A%1C%5E%A8%EF%95%FF%3D%86 --- dom/fetch/Request.cpp | 32 +++++++++++++------ dom/workers/test/fetch/worker_test_request.js | 20 ++++++++++-- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/dom/fetch/Request.cpp b/dom/fetch/Request.cpp index 2f3e3ad8988..dc64ecb17a2 100644 --- a/dom/fetch/Request.cpp +++ b/dom/fetch/Request.cpp @@ -151,23 +151,35 @@ Request::Constructor(const GlobalObject& aGlobal, request->SetCredentialsMode(credentials); } + // Request constructor step 14. if (aInit.mMethod.WasPassed()) { - nsCString method = aInit.mMethod.Value(); - ToLowerCase(method); + nsAutoCString method(aInit.mMethod.Value()); + nsAutoCString upperCaseMethod = method; + ToUpperCase(upperCaseMethod); - if (!method.EqualsASCII("options") && - !method.EqualsASCII("get") && - !method.EqualsASCII("head") && - !method.EqualsASCII("post") && - !method.EqualsASCII("put") && - !method.EqualsASCII("delete")) { + // Step 14.1. Disallow forbidden methods, and anything that is not a HTTP + // token, since HTTP states that Method may be any of the defined values or + // a token (extension method). + if (upperCaseMethod.EqualsLiteral("CONNECT") || + upperCaseMethod.EqualsLiteral("TRACE") || + upperCaseMethod.EqualsLiteral("TRACK") || + !NS_IsValidHTTPToken(method)) { NS_ConvertUTF8toUTF16 label(method); aRv.ThrowTypeError(MSG_INVALID_REQUEST_METHOD, &label); return nullptr; } - ToUpperCase(method); - request->SetMethod(method); + // Step 14.2 + if (upperCaseMethod.EqualsLiteral("DELETE") || + upperCaseMethod.EqualsLiteral("GET") || + upperCaseMethod.EqualsLiteral("HEAD") || + upperCaseMethod.EqualsLiteral("POST") || + upperCaseMethod.EqualsLiteral("PUT") || + upperCaseMethod.EqualsLiteral("OPTIONS")) { + request->SetMethod(upperCaseMethod); + } else { + request->SetMethod(method); + } } nsRefPtr requestHeaders = request->Headers(); diff --git a/dom/workers/test/fetch/worker_test_request.js b/dom/workers/test/fetch/worker_test_request.js index bca12bab94e..2cb3c156774 100644 --- a/dom/workers/test/fetch/worker_test_request.js +++ b/dom/workers/test/fetch/worker_test_request.js @@ -78,17 +78,33 @@ function testBug1109574() { } function testMethod() { - var allowed = ["delete", "get", "head", "options", "post", "put"]; + // These get normalized. + var allowed = ["delete", "get", "head", "options", "post", "put" ]; for (var i = 0; i < allowed.length; ++i) { try { var r = new Request("", { method: allowed[i] }); ok(true, "Method " + allowed[i] + " should be allowed"); + is(r.method, allowed[i].toUpperCase(), + "Standard HTTP method " + allowed[i] + " should be normalized"); } catch(e) { ok(false, "Method " + allowed[i] + " should be allowed"); } } - var forbidden = ["aardvark", "connect", "trace", "track"]; + var allowed = [ "pAtCh", "foo" ]; + for (var i = 0; i < allowed.length; ++i) { + try { + var r = new Request("", { method: allowed[i] }); + ok(true, "Method " + allowed[i] + " should be allowed"); + is(r.method, allowed[i], + "Non-standard but valid HTTP method " + allowed[i] + + " should not be normalized"); + } catch(e) { + ok(false, "Method " + allowed[i] + " should be allowed"); + } + } + + var forbidden = ["connect", "trace", "track", "