Bug 1303025 - Accept null for body param in constructor of Response. r?bkelly
MozReview-Commit-ID: LeEFcQzPJlv
--- a/dom/fetch/Response.cpp
+++ b/dom/fetch/Response.cpp
@@ -135,17 +135,17 @@ Response::Redirect(const GlobalObject& a
return nullptr;
}
if (aStatus != 301 && aStatus != 302 && aStatus != 303 && aStatus != 307 && aStatus != 308) {
aRv.ThrowRangeError<MSG_INVALID_REDIRECT_STATUSCODE_ERROR>();
return nullptr;
}
- Optional<fetch::ResponseBodyInit> body;
+ Optional<Nullable<fetch::ResponseBodyInit>> body;
ResponseInit init;
init.mStatus = aStatus;
RefPtr<Response> r = Response::Constructor(aGlobal, body, init, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
r->GetInternalHeaders()->Set(NS_LITERAL_CSTRING("Location"),
@@ -156,17 +156,17 @@ Response::Redirect(const GlobalObject& a
r->GetInternalHeaders()->SetGuard(HeadersGuardEnum::Immutable, aRv);
MOZ_ASSERT(!aRv.Failed());
return r.forget();
}
/*static*/ already_AddRefed<Response>
Response::Constructor(const GlobalObject& aGlobal,
- const Optional<fetch::ResponseBodyInit>& aBody,
+ const Optional<Nullable<fetch::ResponseBodyInit>>& aBody,
const ResponseInit& aInit, ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
if (aInit.mStatus < 200 || aInit.mStatus > 599) {
aRv.ThrowRangeError<MSG_INVALID_RESPONSE_STATUSCODE_ERROR>();
return nullptr;
}
@@ -222,29 +222,29 @@ Response::Constructor(const GlobalObject
}
internalResponse->Headers()->Fill(*headers->GetInternalHeaders(), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
}
- if (aBody.WasPassed()) {
+ if (aBody.WasPassed() && !aBody.Value().IsNull()) {
if (aInit.mStatus == 204 || aInit.mStatus == 205 || aInit.mStatus == 304) {
aRv.ThrowTypeError<MSG_RESPONSE_NULL_STATUS_WITH_BODY>();
return nullptr;
}
nsCString contentTypeWithCharset;
nsCOMPtr<nsIInputStream> bodyStream;
int64_t bodySize = InternalResponse::UNKNOWN_BODY_SIZE;
- if (aBody.Value().IsReadableStream()) {
- const ReadableStream& readableStream =
- aBody.Value().GetAsReadableStream();
+ const fetch::ResponseBodyInit& body = aBody.Value().Value();
+ if (body.IsReadableStream()) {
+ const ReadableStream& readableStream = body.GetAsReadableStream();
JS::Rooted<JSObject*> readableStreamObj(aGlobal.Context(),
readableStream.Obj());
if (JS::ReadableStreamIsDisturbed(readableStreamObj) ||
JS::ReadableStreamIsLocked(readableStreamObj) ||
!JS::ReadableStreamIsReadable(readableStreamObj)) {
aRv.ThrowTypeError<MSG_FETCH_BODY_CONSUMED_ERROR>();
@@ -283,17 +283,17 @@ Response::Constructor(const GlobalObject
getter_AddRefs(r->mFetchStreamReader),
getter_AddRefs(bodyStream));
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
}
} else {
uint64_t size = 0;
- aRv = ExtractByteStreamFromBody(aBody.Value(),
+ aRv = ExtractByteStreamFromBody(body,
getter_AddRefs(bodyStream),
contentTypeWithCharset,
size);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
bodySize = size;
--- a/dom/fetch/Response.h
+++ b/dom/fetch/Response.h
@@ -115,17 +115,17 @@ public:
static already_AddRefed<Response>
Error(const GlobalObject& aGlobal);
static already_AddRefed<Response>
Redirect(const GlobalObject& aGlobal, const nsAString& aUrl, uint16_t aStatus, ErrorResult& aRv);
static already_AddRefed<Response>
Constructor(const GlobalObject& aGlobal,
- const Optional<fetch::ResponseBodyInit>& aBody,
+ const Optional<Nullable<fetch::ResponseBodyInit>>& aBody,
const ResponseInit& aInit, ErrorResult& rv);
nsIGlobalObject* GetParentObject() const
{
return mOwner;
}
already_AddRefed<Response>
--- a/dom/webidl/Response.webidl
+++ b/dom/webidl/Response.webidl
@@ -4,17 +4,17 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* https://fetch.spec.whatwg.org/#response-class
*/
// This should be Constructor(optional BodyInit... but BodyInit doesn't include
// ReadableStream yet because we don't want to expose Streams API to Request.
-[Constructor(optional (Blob or BufferSource or FormData or URLSearchParams or ReadableStream or USVString) body, optional ResponseInit init),
+[Constructor(optional (Blob or BufferSource or FormData or URLSearchParams or ReadableStream or USVString)? body, optional ResponseInit init),
Exposed=(Window,Worker)]
interface Response {
[NewObject] static Response error();
[Throws,
NewObject] static Response redirect(USVString url, optional unsigned short status = 302);
readonly attribute ResponseType type;
--- a/testing/web-platform/tests/fetch/api/response/response-init-002.html
+++ b/testing/web-platform/tests/fetch/api/response/response-init-002.html
@@ -60,11 +60,16 @@
promise_test(function(test) {
var response = new Response("This is my fork", {"headers" : [["Content-Type", ""]]});
return response.blob().then(function(blob) {
assert_equals(blob.type, "", "Blob type should be the empty string");
});
}, "Testing empty Response Content-Type header");
+ test(function() {
+ var response = new Response(null, {status: 204});
+ assert_equals(response.body, null);
+ }, "Testing null Response body");
+
</script>
</body>
</html>