Bug 1341678 P1 Make Request::Constructor() expect over-writing a copied body with an initializer. r=asuth
authorBen Kelly <ben@wanderview.com>
Wed, 01 Mar 2017 09:59:01 -0500
changeset 345315 82001a435bce84794ea9c928d5643508f2044b47
parent 345314 232a19e40a52117301918832dbd35a00b2e440ae
child 345316 1adc95479dd12cf02d2617bb390488cbb31f6af9
push id31436
push userkwierso@gmail.com
push dateThu, 02 Mar 2017 01:18:52 +0000
treeherdermozilla-central@e91de6fb2b3d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersasuth
bugs1341678
milestone54.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1341678 P1 Make Request::Constructor() expect over-writing a copied body with an initializer. r=asuth
dom/fetch/Request.cpp
--- a/dom/fetch/Request.cpp
+++ b/dom/fetch/Request.cpp
@@ -272,31 +272,33 @@ private:
 
 } // namespace
 
 /*static*/ already_AddRefed<Request>
 Request::Constructor(const GlobalObject& aGlobal,
                      const RequestOrUSVString& aInput,
                      const RequestInit& aInit, ErrorResult& aRv)
 {
-  nsCOMPtr<nsIInputStream> temporaryBody;
+  bool hasCopiedBody = false;
   RefPtr<InternalRequest> request;
 
   nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
 
   if (aInput.IsRequest()) {
     RefPtr<Request> inputReq = &aInput.GetAsRequest();
     nsCOMPtr<nsIInputStream> body;
     inputReq->GetBody(getter_AddRefs(body));
     if (inputReq->BodyUsed()) {
       aRv.ThrowTypeError<MSG_FETCH_BODY_CONSUMED_ERROR>();
       return nullptr;
     }
+
+    // The body will be copied when GetRequestConstructorCopy() is executed.
     if (body) {
-      temporaryBody = body;
+      hasCopiedBody = true;
     }
 
     request = inputReq->GetInternalRequest();
   } else {
     // aInput is USVString.
     // We need to get url before we create a InternalRequest.
     nsAutoString input;
     input.Assign(aInput.GetAsUSVString());
@@ -524,17 +526,17 @@ Request::Constructor(const GlobalObject&
   }
 
   requestHeaders->Fill(*headers, aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
   if ((aInit.mBody.WasPassed() && !aInit.mBody.Value().IsNull()) ||
-      temporaryBody) {
+      hasCopiedBody) {
     // 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;
     }
@@ -550,29 +552,34 @@ Request::Constructor(const GlobalObject&
       aRv = ExtractByteStreamFromBody(bodyInit,
                                       getter_AddRefs(stream),
                                       contentTypeWithCharset,
                                       contentLengthUnused);
       if (NS_WARN_IF(aRv.Failed())) {
         return nullptr;
       }
 
-      temporaryBody = stream;
+      nsCOMPtr<nsIInputStream> temporaryBody = stream;
 
       if (!contentTypeWithCharset.IsVoid() &&
           !requestHeaders->Has(NS_LITERAL_CSTRING("Content-Type"), aRv)) {
         requestHeaders->Append(NS_LITERAL_CSTRING("Content-Type"),
                                contentTypeWithCharset, aRv);
       }
 
       if (NS_WARN_IF(aRv.Failed())) {
         return nullptr;
       }
 
       request->ClearCreatedByFetchEvent();
+
+      if (hasCopiedBody) {
+        request->SetBody(nullptr);
+      }
+
       request->SetBody(temporaryBody);
     }
   }
 
   RefPtr<Request> domRequest = new Request(global, request);
   domRequest->SetMimeType();
 
   if (aInput.IsRequest()) {