Bug 1111025 - Add newChanelChannelFromURIWithLoadInfo to nsIIOService (r=sicking)
authorChristoph Kerschbaumer <mozilla@christophkerschbaumer.com>
Fri, 12 Dec 2014 14:24:57 -0800
changeset 219869 adc247a722ef1f44b3f6d07eb86bfdc56d9210a7
parent 219868 f2f0d61c8acc217b57cfac70ed47ad6eba0c74fb
child 219870 b921743d876e978baa61b509bb52ce8b504d7d1e
push id10419
push usercbook@mozilla.com
push dateTue, 16 Dec 2014 12:45:27 +0000
treeherderfx-team@ec87657146eb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssicking
bugs1111025
milestone37.0a1
Bug 1111025 - Add newChanelChannelFromURIWithLoadInfo to nsIIOService (r=sicking)
netwerk/base/public/nsIIOService.idl
netwerk/base/src/nsIOService.cpp
netwerk/base/src/nsIOService.h
--- a/netwerk/base/public/nsIIOService.idl
+++ b/netwerk/base/public/nsIIOService.idl
@@ -6,27 +6,28 @@
 #include "nsISupports.idl"
 
 interface nsIProtocolHandler;
 interface nsIChannel;
 interface nsIURI;
 interface nsIFile;
 interface nsIDOMNode;
 interface nsIPrincipal;
+interface nsILoadInfo;
 
 /**
  * nsIIOService provides a set of network utility functions.  This interface
  * duplicates many of the nsIProtocolHandler methods in a protocol handler
  * independent way (e.g., NewURI inspects the scheme in order to delegate
  * creation of the new URI to the appropriate protocol handler).  nsIIOService
  * also provides a set of URL parsing utility functions.  These are provided
  * as a convenience to the programmer and in some cases to improve performance
  * by eliminating intermediate data structures and interfaces.
  */
-[scriptable, uuid(d8555f58-203a-465a-a33e-442ae4c6c4cf)]
+[scriptable, uuid(b1c3c61d-2df9-4240-ae16-0355b51a2770)]
 interface nsIIOService : nsISupports
 {
     /**
      * Returns a protocol handler for a given URI scheme.
      *
      * @param aScheme the URI scheme
      * @return reference to corresponding nsIProtocolHandler
      */
@@ -125,16 +126,22 @@ interface nsIIOService : nsISupports
     nsIChannel newChannelFromURI2(in nsIURI aURI,
                                   in nsIDOMNode aLoadingNode,
                                   in nsIPrincipal aLoadingPrincipal,
                                   in nsIPrincipal aTriggeringPrincipal,
                                   in unsigned long aSecurityFlags,
                                   in unsigned long aContentPolicyType);
 
     /**
+     * Equivalent to newChannelFromURI2(aURI, aLoadingNode, ...)
+     */
+    nsIChannel newChannelFromURIWithLoadInfo(in nsIURI aURI,
+                                             in nsILoadInfo aLoadInfo);
+
+    /**
      * Creates a channel for a given URI.
      *
      * @param aURI nsIURI from which to make a channel
      * @return reference to the new nsIChannel object
      */
     nsIChannel newChannelFromURI(in nsIURI aURI);
 
     /**
--- a/netwerk/base/src/nsIOService.cpp
+++ b/netwerk/base/src/nsIOService.cpp
@@ -590,37 +590,46 @@ nsIOService::NewChannelFromURI2(nsIURI* 
                                             aLoadingPrincipal,
                                             aTriggeringPrincipal,
                                             aSecurityFlags,
                                             aContentPolicyType,
                                             result);
 }
 
 NS_IMETHODIMP
+nsIOService::NewChannelFromURIWithLoadInfo(nsIURI* aURI,
+                                           nsILoadInfo* aLoadInfo,
+                                           nsIChannel** result)
+{
+  NS_ENSURE_ARG_POINTER(aLoadInfo);
+  return NewChannelFromURIWithProxyFlagsInternal(aURI,
+                                                 nullptr, // aProxyURI
+                                                 0,       // aProxyFlags
+                                                 aLoadInfo,
+                                                 result);
+}
+
+NS_IMETHODIMP
 nsIOService::NewChannelFromURI(nsIURI *aURI, nsIChannel **result)
 {
   return NewChannelFromURI2(aURI,
                             nullptr, // aLoadingNode
                             nullptr, // aLoadingPrincipal
                             nullptr, // aTriggeringPrincipal
                             nsILoadInfo::SEC_NORMAL,
                             nsIContentPolicy::TYPE_OTHER,
                             result);
 }
 
-NS_IMETHODIMP
-nsIOService::NewChannelFromURIWithProxyFlags2(nsIURI* aURI,
-                                              nsIURI* aProxyURI,
-                                              uint32_t aProxyFlags,
-                                              nsIDOMNode* aLoadingNode,
-                                              nsIPrincipal* aLoadingPrincipal,
-                                              nsIPrincipal* aTriggeringPrincipal,
-                                              uint32_t aSecurityFlags,
-                                              uint32_t aContentPolicyType,
-                                              nsIChannel** result)
+nsresult
+nsIOService::NewChannelFromURIWithProxyFlagsInternal(nsIURI* aURI,
+                                                     nsIURI* aProxyURI,
+                                                     uint32_t aProxyFlags,
+                                                     nsILoadInfo* aLoadInfo,
+                                                     nsIChannel** result)
 {
     nsresult rv;
     NS_ENSURE_ARG_POINTER(aURI);
 
     nsAutoCString scheme;
     rv = aURI->GetScheme(scheme);
     if (NS_FAILED(rv))
         return rv;
@@ -637,64 +646,42 @@ nsIOService::NewChannelFromURIWithProxyF
 
     // Ideally we are creating new channels by calling NewChannel2 (NewProxiedChannel2).
     // Keep in mind that Addons can implement their own Protocolhandlers, hence
     // NewChannel2() might *not* be implemented.
     // We do not want to break those addons, therefore we first try to create a channel
     // calling NewChannel2(); if that fails we fall back to creating a channel by calling
     // NewChannel();
 
-    nsCOMPtr<nsILoadInfo> loadInfo;
-    // Unfortunately not all callsites (see Bug 1087720, and 1099296) have been updated
-    // yet to call NewChannel2() instead of NewChannel(), hence those callsites do not
-    // provide the necessary loadinfo arguments yet.
-    // Since creating a new loadInfo requires 'aLoadingPrincipal' or 'aLoadingNode' we
-    // can branch on those arguments as an interim solution.
-    //
-    // BUG 1087720: Once that bug lands, we should have a loadInfo for all callers of
-    // NewChannelFromURIWithProxyFlags2() and should remove the *if* before creating a
-    // a new loadinfo.
-    if (aLoadingNode || aLoadingPrincipal) {
-      nsCOMPtr<nsINode> loadingNode(do_QueryInterface(aLoadingNode));
-      loadInfo = new mozilla::LoadInfo(aLoadingPrincipal,
-                                       aTriggeringPrincipal,
-                                       loadingNode,
-                                       aSecurityFlags,
-                                       aContentPolicyType);
-      if (!loadInfo) {
-        return NS_ERROR_UNEXPECTED;
-      }
-    }
-
     bool newChannel2Succeeded = true;
 
     nsCOMPtr<nsIProxiedProtocolHandler> pph = do_QueryInterface(handler);
     if (pph) {
         rv = pph->NewProxiedChannel2(aURI, nullptr, aProxyFlags, aProxyURI,
-                                     loadInfo, result);
+                                     aLoadInfo, result);
         // if calling NewProxiedChannel2() fails we try to fall back to
         // creating a new proxied channel by calling NewProxiedChannel().
         if (NS_FAILED(rv)) {
             newChannel2Succeeded = false;
             rv = pph->NewProxiedChannel(aURI, nullptr, aProxyFlags, aProxyURI,
                                         result);
         }
     }
     else {
-        rv = handler->NewChannel2(aURI, loadInfo, result);
+        rv = handler->NewChannel2(aURI, aLoadInfo, result);
         // if calling newChannel2() fails we try to fall back to
         // creating a new channel by calling NewChannel().
         if (NS_FAILED(rv)) {
             newChannel2Succeeded = false;
             rv = handler->NewChannel(aURI, result);
         }
     }
     NS_ENSURE_SUCCESS(rv, rv);
 
-    if ((aLoadingNode || aLoadingPrincipal) && newChannel2Succeeded) {
+    if (aLoadInfo && newChannel2Succeeded) {
       // Make sure that all the individual protocolhandlers attach
       // a loadInfo within it's implementation of ::newChannel2().
       // Once Bug 1087720 lands, we should remove the surrounding
       // if-clause here and always assert that we indeed have a
       // loadinfo on the newly created channel.
       nsCOMPtr<nsILoadInfo> loadInfo;
       (*result)->GetLoadInfo(getter_AddRefs(loadInfo));
       MOZ_ASSERT(loadInfo);
@@ -726,16 +713,57 @@ nsIOService::NewChannelFromURIWithProxyF
             gHasWarnedUploadChannel2 = true;
         }
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
+nsIOService::NewChannelFromURIWithProxyFlags2(nsIURI* aURI,
+                                              nsIURI* aProxyURI,
+                                              uint32_t aProxyFlags,
+                                              nsIDOMNode* aLoadingNode,
+                                              nsIPrincipal* aLoadingPrincipal,
+                                              nsIPrincipal* aTriggeringPrincipal,
+                                              uint32_t aSecurityFlags,
+                                              uint32_t aContentPolicyType,
+                                              nsIChannel** result)
+{
+    // Ideally all callers of NewChannelFromURIWithProxyFlags2 provide the
+    // necessary arguments to create a loadinfo. Keep in mind that addons
+    // might still call NewChannelFromURIWithProxyFlags() which forwards
+    // its calls to NewChannelFromURIWithProxyFlags2 using *null* values
+    // as the arguments for aLoadingNode, aLoadingPrincipal, and also
+    // aTriggeringPrincipal.
+    // We do not want to break those addons, hence we only create a Loadinfo
+    // if 'aLoadingNode' or 'aLoadingPrincipal' are provided. Note, that
+    // either aLoadingNode or aLoadingPrincipal is required to succesfully
+    // create a LoadInfo object.
+    nsCOMPtr<nsILoadInfo> loadInfo;
+
+    if (aLoadingNode || aLoadingPrincipal) {
+      nsCOMPtr<nsINode> loadingNode(do_QueryInterface(aLoadingNode));
+      loadInfo = new mozilla::LoadInfo(aLoadingPrincipal,
+                                       aTriggeringPrincipal,
+                                       loadingNode,
+                                       aSecurityFlags,
+                                       aContentPolicyType);
+      if (!loadInfo) {
+        return NS_ERROR_UNEXPECTED;
+      }
+    }
+    return NewChannelFromURIWithProxyFlagsInternal(aURI,
+                                                   aProxyURI,
+                                                   aProxyFlags,
+                                                   loadInfo,
+                                                   result);
+}
+
+NS_IMETHODIMP
 nsIOService::NewChannelFromURIWithProxyFlags(nsIURI *aURI,
                                              nsIURI *aProxyURI,
                                              uint32_t aProxyFlags,
                                              nsIChannel **result)
 {
   return NewChannelFromURIWithProxyFlags2(aURI,
                                           aProxyURI,
                                           aProxyFlags,
--- a/netwerk/base/src/nsIOService.h
+++ b/netwerk/base/src/nsIOService.h
@@ -112,16 +112,21 @@ private:
     void LookupProxyInfo(nsIURI *aURI, nsIURI *aProxyURI, uint32_t aProxyFlags,
                          nsCString *aScheme, nsIProxyInfo **outPI);
 
     // notify content processes of offline status
     // 'status' must be a nsIAppOfflineInfo mode constant.
     void NotifyAppOfflineStatus(uint32_t appId, int32_t status);
     static PLDHashOperator EnumerateWifiAppsChangingState(const unsigned int &, int32_t, void*);
 
+    nsresult NewChannelFromURIWithProxyFlagsInternal(nsIURI* aURI,
+                                                     nsIURI* aProxyURI,
+                                                     uint32_t aProxyFlags,
+                                                     nsILoadInfo* aLoadInfo,
+                                                     nsIChannel** result);
 private:
     bool                                 mOffline;
     bool                                 mOfflineForProfileChange;
     bool                                 mManageOfflineStatus;
 
     // Used to handle SetOffline() reentrancy.  See the comment in
     // SetOffline() for more details.
     bool                                 mSettingOffline;