Bug 1393439 - P1: Don't return TypeError for no-cors mode and don't check SRI for the hidden opaque body. r?bkelly draft
authorTom Tung <shes050117@gmail.com>
Fri, 25 Aug 2017 16:36:59 +0800
changeset 654861 9b64a5e5cbbce000aa77a6ad684b4fac8181e6ee
parent 654683 d7a0ae9b5ad33b4968fc96a2315d195920c36f50
child 654862 62b2a5b6b1b599f848896cefe6ed0972c4804ebb
push id76712
push userttung@mozilla.com
push dateTue, 29 Aug 2017 10:49:06 +0000
reviewersbkelly
bugs1393439
milestone57.0a1
Bug 1393439 - P1: Don't return TypeError for no-cors mode and don't check SRI for the hidden opaque body. r?bkelly MozReview-Commit-ID: 1IspF2IlqqP
dom/fetch/FetchDriver.cpp
dom/fetch/Request.cpp
--- a/dom/fetch/FetchDriver.cpp
+++ b/dom/fetch/FetchDriver.cpp
@@ -38,16 +38,31 @@
 #include "Fetch.h"
 #include "FetchUtil.h"
 #include "InternalRequest.h"
 #include "InternalResponse.h"
 
 namespace mozilla {
 namespace dom {
 
+namespace {
+
+bool
+ShouldCheckSRI(const InternalRequest* const aRequest,
+               const InternalResponse* const aResponse)
+{
+  MOZ_DIAGNOSTIC_ASSERT(aRequest);
+  MOZ_DIAGNOSTIC_ASSERT(aResponse);
+
+  return !aRequest->GetIntegrity().IsEmpty() &&
+         aResponse->Type() != ResponseType::Error;
+}
+
+} // anonymous namespace
+
 NS_IMPL_ISUPPORTS(FetchDriver,
                   nsIStreamListener, nsIChannelEventSink, nsIInterfaceRequestor,
                   nsIThreadRetargetableStreamListener)
 
 FetchDriver::FetchDriver(InternalRequest* aRequest, nsIPrincipal* aPrincipal,
                          nsILoadGroup* aLoadGroup, nsIEventTarget* aMainThreadEventTarget,
                          bool aIsTrackingFetch)
   : mPrincipal(aPrincipal)
@@ -418,18 +433,17 @@ FetchDriver::BeginAndGetFilteredResponse
         break;
       default:
         MOZ_CRASH("Unexpected case");
     }
   }
 
   MOZ_ASSERT(filteredResponse);
   MOZ_ASSERT(mObserver);
-  if (filteredResponse->Type() == ResponseType::Error ||
-      mRequest->GetIntegrity().IsEmpty()) {
+  if (!ShouldCheckSRI(mRequest, filteredResponse)) {
     mObserver->OnResponseAvailable(filteredResponse);
   #ifdef DEBUG
     mResponseAvailableCalled = true;
   #endif
   }
 
   return filteredResponse.forget();
 }
@@ -591,20 +605,18 @@ FetchDriver::OnStartRequest(nsIRequest* 
   // the channel and must regenerate the tainting from the channel in the
   // interception case.
   mRequest->MaybeIncreaseResponseTainting(loadInfo->GetTainting());
 
   // Resolves fetch() promise which may trigger code running in a worker.  Make
   // sure the Response is fully initialized before calling this.
   mResponse = BeginAndGetFilteredResponse(response, foundOpaqueRedirect);
 
-  // From "Main Fetch" step 17: SRI-part1.
-  if (mResponse->Type() != ResponseType::Error &&
-      !mRequest->GetIntegrity().IsEmpty() &&
-      mSRIMetadata.IsEmpty()) {
+  // From "Main Fetch" step 19: SRI-part1.
+  if (ShouldCheckSRI(mRequest, mResponse) && mSRIMetadata.IsEmpty()) {
     nsIConsoleReportCollector* aReporter = nullptr;
     if (mObserver) {
       aReporter = mObserver->GetReporter();
     }
 
     nsAutoCString sourceUri;
     if (mDocument && mDocument->GetDocumentURI()) {
       mDocument->GetDocumentURI()->GetAsciiSpec(sourceUri);
@@ -730,19 +742,20 @@ FetchDriver::OnDataAvailable(nsIRequest*
       }
     }
   }
 
   uint32_t aRead;
   MOZ_ASSERT(mResponse);
   MOZ_ASSERT(mPipeOutputStream);
 
-  // From "Main Fetch" step 17: SRI-part2.
-  if (mResponse->Type() != ResponseType::Error &&
-      !mRequest->GetIntegrity().IsEmpty()) {
+  // From "Main Fetch" step 19: SRI-part2.
+  // Note: Avoid checking the hidden opaque body.
+  if (mResponse->Type() != ResponseType::Opaque &&
+      ShouldCheckSRI(mRequest, mResponse)) {
     MOZ_ASSERT(mSRIDataVerifier);
 
     SRIVerifierAndOutputHolder holder(mSRIDataVerifier, mPipeOutputStream);
     nsresult rv = aInputStream->ReadSegments(CopySegmentToStreamAndSRI,
                                              &holder, aCount, &aRead);
     return rv;
   }
 
@@ -769,19 +782,18 @@ FetchDriver::OnStopRequest(nsIRequest* a
     }
 
     // We proceed as usual here, since we've already created a successful response
     // from OnStartRequest.
   } else {
     MOZ_ASSERT(mResponse);
     MOZ_ASSERT(!mResponse->IsError());
 
-    // From "Main Fetch" step 17: SRI-part3.
-    if (mResponse->Type() != ResponseType::Error &&
-        !mRequest->GetIntegrity().IsEmpty()) {
+    // From "Main Fetch" step 19: SRI-part3.
+    if (ShouldCheckSRI(mRequest, mResponse)) {
       MOZ_ASSERT(mSRIDataVerifier);
 
       nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
 
       nsIConsoleReportCollector* aReporter = nullptr;
       if (mObserver) {
         aReporter = mObserver->GetReporter();
       }
@@ -802,19 +814,18 @@ FetchDriver::OnStopRequest(nsIRequest* a
     }
 
     if (mPipeOutputStream) {
       mPipeOutputStream->Close();
     }
   }
 
   if (mObserver) {
-    if (mResponse->Type() != ResponseType::Error &&
-        !mRequest->GetIntegrity().IsEmpty()) {
-      //From "Main Fetch" step 23: Process response.
+    // From "Main Fetch" step 19.1, 19.2: Process response.
+    if (ShouldCheckSRI(mRequest, mResponse)) {
       MOZ_ASSERT(mResponse);
       mObserver->OnResponseAvailable(mResponse);
       #ifdef DEBUG
         mResponseAvailableCalled = true;
       #endif
     }
 
     mObserver->OnResponseEnd(FetchDriverObserver::eByNetworking);
--- a/dom/fetch/Request.cpp
+++ b/dom/fetch/Request.cpp
@@ -527,21 +527,16 @@ Request::Constructor(const GlobalObject&
     if (!request->HasSimpleMethod()) {
       nsAutoCString method;
       request->GetMethod(method);
       NS_ConvertUTF8toUTF16 label(method);
       aRv.ThrowTypeError<MSG_INVALID_REQUEST_METHOD>(label);
       return nullptr;
     }
 
-    if (!request->GetIntegrity().IsEmpty()) {
-      aRv.ThrowTypeError<MSG_REQUEST_INTEGRITY_METADATA_NOT_EMPTY>();
-      return nullptr;
-    }
-
     requestHeaders->SetGuard(HeadersGuardEnum::Request_no_cors, aRv);
     if (aRv.Failed()) {
       return nullptr;
     }
   }
 
   requestHeaders->Fill(*headers, aRv);
   if (aRv.Failed()) {