Bug 1110814 P0 Fully initialize Response before resolve Fetch promise. r=nsm
authorBen Kelly <ben@wanderview.com>
Sun, 22 Mar 2015 02:52:12 -0400
changeset 234980 498032321f32
parent 234965 45366e6959e2
child 234981 61cb338ad147
push id28462
push usercbook@mozilla.com
push dateMon, 23 Mar 2015 12:19:34 +0000
treeherdermozilla-central@bc85c479668a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnsm
bugs1110814
milestone39.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 1110814 P0 Fully initialize Response before resolve Fetch promise. r=nsm
dom/fetch/FetchDriver.cpp
--- a/dom/fetch/FetchDriver.cpp
+++ b/dom/fetch/FetchDriver.cpp
@@ -666,24 +666,16 @@ FetchDriver::OnStartRequest(nsIRequest* 
   nsRefPtr<InternalResponse> response = new InternalResponse(responseStatus, statusText);
 
   nsRefPtr<FillResponseHeaders> visitor = new FillResponseHeaders(response);
   rv = channel->VisitResponseHeaders(visitor);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     NS_WARNING("Failed to visit all headers.");
   }
 
-  mResponse = BeginAndGetFilteredResponse(response);
-
-  nsCOMPtr<nsISupports> securityInfo;
-  rv = channel->GetSecurityInfo(getter_AddRefs(securityInfo));
-  if (securityInfo) {
-    mResponse->SetSecurityInfo(securityInfo);
-  }
-
   // We open a pipe so that we can immediately set the pipe's read end as the
   // response's body. Setting the segment size to UINT32_MAX means that the
   // pipe has infinite space. The nsIChannel will continue to buffer data in
   // xpcom events even if we block on a fixed size pipe.  It might be possible
   // to suspend the channel and then resume when there is space available, but
   // for now use an infinite pipe to avoid blocking.
   nsCOMPtr<nsIInputStream> pipeInputStream;
   rv = NS_NewPipe(getter_AddRefs(pipeInputStream),
@@ -692,18 +684,27 @@ FetchDriver::OnStartRequest(nsIRequest* 
                   UINT32_MAX /* infinite pipe */,
                   true /* non-blocking input, otherwise you deadlock */,
                   false /* blocking output, since the pipe is 'in'finite */ );
   if (NS_WARN_IF(NS_FAILED(rv))) {
     FailWithNetworkError();
     // Cancel request.
     return rv;
   }
+  response->SetBody(pipeInputStream);
 
-  mResponse->SetBody(pipeInputStream);
+  nsCOMPtr<nsISupports> securityInfo;
+  rv = channel->GetSecurityInfo(getter_AddRefs(securityInfo));
+  if (securityInfo) {
+    response->SetSecurityInfo(securityInfo);
+  }
+
+  // Resolves fetch() promise which may trigger code running in a worker.  Make
+  // sure the Response is fully initialized before calling this.
+  mResponse = BeginAndGetFilteredResponse(response);
 
   nsCOMPtr<nsIEventTarget> sts = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     FailWithNetworkError();
     // Cancel request.
     return rv;
   }