Bug 1214752. Fix CORS preflights to provide a useful nsILoadContext, so they show up in our devtools network monitor properly. r=sicking
authorBoris Zbarsky <bzbarsky@mit.edu>
Thu, 26 May 2016 20:36:09 -0400
changeset 299232 baee93983a1a83785879dc990d45030388e7854f
parent 299231 c69284da0cf87571ed792a4f6b9ddb7f6b436cab
child 299233 1f3bc3649264c8bf2dd5c19cf3790faa2fb7b1d1
push id77492
push userbzbarsky@mozilla.com
push dateFri, 27 May 2016 00:36:32 +0000
treeherdermozilla-inbound@1f3bc3649264 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssicking
bugs1214752
milestone49.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 1214752. Fix CORS preflights to provide a useful nsILoadContext, so they show up in our devtools network monitor properly. r=sicking
netwerk/protocol/http/nsCORSListenerProxy.cpp
--- a/netwerk/protocol/http/nsCORSListenerProxy.cpp
+++ b/netwerk/protocol/http/nsCORSListenerProxy.cpp
@@ -994,23 +994,25 @@ nsCORSListenerProxy::CheckPreflightNeede
 // doing the initial OPTIONS request for a CORS check
 class nsCORSPreflightListener final : public nsIStreamListener,
                                       public nsIInterfaceRequestor,
                                       public nsIChannelEventSink
 {
 public:
   nsCORSPreflightListener(nsIPrincipal* aReferrerPrincipal,
                           nsICorsPreflightCallback* aCallback,
+                          nsILoadContext* aLoadContext,
                           bool aWithCredentials,
                           const nsCString& aPreflightMethod,
                           const nsTArray<nsCString>& aPreflightHeaders)
    : mPreflightMethod(aPreflightMethod),
      mPreflightHeaders(aPreflightHeaders),
      mReferrerPrincipal(aReferrerPrincipal),
      mCallback(aCallback),
+     mLoadContext(aLoadContext),
      mWithCredentials(aWithCredentials)
   {
   }
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSIINTERFACEREQUESTOR
@@ -1022,16 +1024,17 @@ private:
   ~nsCORSPreflightListener() {}
 
   void AddResultToCache(nsIRequest* aRequest);
 
   nsCString mPreflightMethod;
   nsTArray<nsCString> mPreflightHeaders;
   nsCOMPtr<nsIPrincipal> mReferrerPrincipal;
   nsCOMPtr<nsICorsPreflightCallback> mCallback;
+  nsCOMPtr<nsILoadContext> mLoadContext;
   bool mWithCredentials;
 };
 
 NS_IMPL_ISUPPORTS(nsCORSPreflightListener, nsIStreamListener,
                   nsIRequestObserver, nsIInterfaceRequestor,
                   nsIChannelEventSink)
 
 void
@@ -1290,16 +1293,22 @@ nsCORSPreflightListener::CheckPreflightR
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCORSPreflightListener::GetInterface(const nsIID & aIID, void **aResult)
 {
+  if (aIID.Equals(NS_GET_IID(nsILoadContext)) && mLoadContext) {
+    nsCOMPtr<nsILoadContext> copy = mLoadContext;
+    copy.forget(aResult);
+    return NS_OK;
+  }
+
   return QueryInterface(aIID, aResult);
 }
 
 void
 nsCORSListenerProxy::RemoveFromCorsPreflightCache(nsIURI* aURI,
                                                   nsIPrincipal* aRequestingPrincipal)
 {
   MOZ_ASSERT(XRE_IsParentProcess());
@@ -1364,16 +1373,25 @@ nsCORSListenerProxy::StartCORSPreflight(
   nsCOMPtr<nsILoadInfo> loadInfo = static_cast<mozilla::LoadInfo*>
     (originalLoadInfo.get())->CloneForNewRequest();
   static_cast<mozilla::LoadInfo*>(loadInfo.get())->SetIsPreflight();
 
   nsCOMPtr<nsILoadGroup> loadGroup;
   rv = aRequestChannel->GetLoadGroup(getter_AddRefs(loadGroup));
   NS_ENSURE_SUCCESS(rv, rv);
 
+  // We want to give the preflight channel's notification callbacks the same
+  // load context as the original channel's notification callbacks had.  We
+  // don't worry about a load context provided via the loadgroup here, since
+  // they have the same loadgroup.
+  nsCOMPtr<nsIInterfaceRequestor> callbacks;
+  rv = aRequestChannel->GetNotificationCallbacks(getter_AddRefs(callbacks));
+  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsILoadContext> loadContext = do_GetInterface(callbacks);
+
   nsLoadFlags loadFlags;
   rv = aRequestChannel->GetLoadFlags(&loadFlags);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Preflight requests should never be intercepted by service workers and
   // are always anonymous.
   // NOTE: We ignore CORS checks on synthesized responses (see the CORS
   // preflights, then we need to extend the GetResponseSynthesized() check in
@@ -1421,18 +1439,18 @@ nsCORSListenerProxy::StartCORSPreflight(
     rv = preHttp->
       SetRequestHeader(NS_LITERAL_CSTRING("Access-Control-Request-Headers"),
                        headers, false);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   // Set up listener which will start the original channel
   RefPtr<nsCORSPreflightListener> preflightListener =
-    new nsCORSPreflightListener(principal, aCallback, withCredentials,
-                                method, preflightHeaders);
+    new nsCORSPreflightListener(principal, aCallback, loadContext,
+                                withCredentials, method, preflightHeaders);
 
   rv = preflightChannel->SetNotificationCallbacks(preflightListener);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Start preflight
   rv = preflightChannel->AsyncOpen2(preflightListener);
   NS_ENSURE_SUCCESS(rv, rv);