Bug 1112073 - Implement Response.redirect. r=baku,bkelly

--HG--
extra : rebase_source : b84a118d61103227e3e021d0efe344f709115fc9
This commit is contained in:
Nikhil Marathe 2014-12-26 09:44:09 -08:00
parent 049cb54131
commit 60d4b5d56f
4 changed files with 83 additions and 6 deletions

View File

@ -52,12 +52,64 @@ Response::Error(const GlobalObject& aGlobal)
/* static */ already_AddRefed<Response>
Response::Redirect(const GlobalObject& aGlobal, const nsAString& aUrl,
uint16_t aStatus)
uint16_t aStatus, ErrorResult& aRv)
{
ErrorResult result;
ResponseInit init;
nsAutoString parsedURL;
if (NS_IsMainThread()) {
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
nsCOMPtr<nsIURI> docURI = window->GetDocumentURI();
nsAutoCString spec;
aRv = docURI->GetSpec(spec);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
nsRefPtr<mozilla::dom::URL> url =
dom::URL::Constructor(aGlobal, aUrl, NS_ConvertUTF8toUTF16(spec), aRv);
if (aRv.Failed()) {
return nullptr;
}
url->Stringify(parsedURL, aRv);
} else {
workers::WorkerPrivate* worker = workers::GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(worker);
worker->AssertIsOnWorkerThread();
NS_ConvertUTF8toUTF16 baseURL(worker->GetLocationInfo().mHref);
nsRefPtr<workers::URL> url =
workers::URL::Constructor(aGlobal, aUrl, baseURL, aRv);
if (aRv.Failed()) {
return nullptr;
}
url->Stringify(parsedURL, aRv);
}
if (aRv.Failed()) {
return nullptr;
}
if (aStatus != 301 && aStatus != 302 && aStatus != 303 && aStatus != 307 && aStatus != 308) {
aRv.Throw(NS_ERROR_RANGE_ERR);
return nullptr;
}
Optional<ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams> body;
nsRefPtr<Response> r = Response::Constructor(aGlobal, body, init, result);
ResponseInit init;
init.mStatus = aStatus;
nsRefPtr<Response> r = Response::Constructor(aGlobal, body, init, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
r->GetInternalHeaders()->Set(NS_LITERAL_CSTRING("Location"),
NS_ConvertUTF16toUTF8(parsedURL), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
return r.forget();
}

View File

@ -83,7 +83,7 @@ public:
Error(const GlobalObject& aGlobal);
static already_AddRefed<Response>
Redirect(const GlobalObject& aGlobal, const nsAString& aUrl, uint16_t aStatus);
Redirect(const GlobalObject& aGlobal, const nsAString& aUrl, uint16_t aStatus, ErrorResult& aRv);
static already_AddRefed<Response>
Constructor(const GlobalObject& aGlobal,

View File

@ -12,7 +12,8 @@
Func="mozilla::dom::Headers::PrefEnabled"]
interface Response {
[NewObject] static Response error();
[NewObject] static Response redirect(USVString url, optional unsigned short status = 302);
[Throws,
NewObject] static Response redirect(USVString url, optional unsigned short status = 302);
readonly attribute ResponseType type;

View File

@ -29,6 +29,29 @@ function testClone() {
is(res.headers.get('content-length'), "5", "Response content-length should be 5.");
}
function testRedirect() {
var res = Response.redirect("./redirect.response");
is(res.status, 302, "Default redirect has status code 302");
var h = res.headers.get("location");
ok(h === (new URL("./redirect.response", self.location.href)).href, "Location header should be correct absolute URL");
var successStatus = [301, 302, 303, 307, 308];
for (var i = 0; i < successStatus.length; ++i) {
var res = Response.redirect("./redirect.response", successStatus[i]);
is(res.status, successStatus[i], "Status code should match");
}
var failStatus = [300, 0, 304, 305, 306, 309, 500];
for (var i = 0; i < failStatus.length; ++i) {
try {
var res = Response.redirect(".", failStatus[i]);
ok(false, "Invalid status code should fail " + failStatus[i]);
} catch(e) {
is(e.name, "RangeError", "Invalid status code should fail " + failStatus[i]);
}
}
}
function testBodyUsed() {
var res = new Response("Sample body");
ok(!res.bodyUsed, "bodyUsed is initially false.");
@ -115,6 +138,7 @@ onmessage = function() {
testDefaultCtor();
testClone();
testRedirect();
Promise.resolve()
.then(testBodyCreation)