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 340258 baee93983a1a83785879dc990d45030388e7854f
parent 340257 c69284da0cf87571ed792a4f6b9ddb7f6b436cab
child 340259 1f3bc3649264c8bf2dd5c19cf3790faa2fb7b1d1
push id1183
push userraliiev@mozilla.com
push dateMon, 05 Sep 2016 20:01:49 +0000
treeherdermozilla-release@3148731bed45 [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);