Bug 1120487 - Implement shim before moving security checks into AsyncOpen, ioservice changes (r=sicking,sworkman)
authorChristoph Kerschbaumer <mozilla@christophkerschbaumer.com>
Fri, 29 May 2015 10:41:41 -0700
changeset 246426 4819768c871f5f64c5e2a984c7794f5385bc2977
parent 246425 b06b05456f754ecda71bb11a24c3b00e6a30a65d
child 246427 042c4e999e203ed2b2bd2592a85ab46d80d63354
push id28830
push usercbook@mozilla.com
push dateMon, 01 Jun 2015 13:02:44 +0000
treeherdermozilla-central@39c85ec2d644 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssicking, sworkman
bugs1120487
milestone41.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 1120487 - Implement shim before moving security checks into AsyncOpen, ioservice changes (r=sicking,sworkman)
netwerk/base/nsIOService.cpp
--- a/netwerk/base/nsIOService.cpp
+++ b/netwerk/base/nsIOService.cpp
@@ -17,16 +17,17 @@
 #include "nsIObserverService.h"
 #include "nsIPrefService.h"
 #include "nsXPCOM.h"
 #include "nsIProxiedProtocolHandler.h"
 #include "nsIProxyInfo.h"
 #include "nsEscape.h"
 #include "nsNetCID.h"
 #include "nsCRT.h"
+#include "nsSecCheckWrapChannel.h"
 #include "nsSimpleNestedURI.h"
 #include "nsNetUtil.h"
 #include "nsTArray.h"
 #include "nsIConsoleService.h"
 #include "nsIUploadChannel2.h"
 #include "nsXULAppAPI.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIProtocolProxyCallback.h"
@@ -656,86 +657,87 @@ nsIOService::NewChannelFromURIWithProxyF
     rv = handler->GetProtocolFlags(&protoFlags);
     if (NS_FAILED(rv))
         return rv;
 
     // 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();
-
-    bool newChannel2Succeeded = true;
-
+    // calling NewChannel2(); if that fails:
+    // * we fall back to creating a channel by calling NewChannel()
+    // * wrap the addon channel
+    // * and attach the loadInfo to the channel wrapper
+    nsCOMPtr<nsIChannel> channel;
     nsCOMPtr<nsIProxiedProtocolHandler> pph = do_QueryInterface(handler);
     if (pph) {
         rv = pph->NewProxiedChannel2(aURI, nullptr, aProxyFlags, aProxyURI,
-                                     aLoadInfo, result);
+                                     aLoadInfo, getter_AddRefs(channel));
         // 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);
+                                        getter_AddRefs(channel));
+            NS_ENSURE_SUCCESS(rv, rv);
+            // we have to wrap that channel
+            channel = new nsSecCheckWrapChannel(channel, aLoadInfo);
         }
     }
     else {
-        rv = handler->NewChannel2(aURI, aLoadInfo, result);
+        rv = handler->NewChannel2(aURI, aLoadInfo, getter_AddRefs(channel));
         // 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);
+            rv = handler->NewChannel(aURI, getter_AddRefs(channel));
+            NS_ENSURE_SUCCESS(rv, rv);
+            // we have to wrap that channel
+            channel = new nsSecCheckWrapChannel(channel, aLoadInfo);
         }
     }
-    NS_ENSURE_SUCCESS(rv, rv);
 
-    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.
+    // Make sure that all the individual protocolhandlers attach a loadInfo.
+    if (aLoadInfo) {
+      // make sure we have the same instance of loadInfo on the newly created channel
       nsCOMPtr<nsILoadInfo> loadInfo;
-      (*result)->GetLoadInfo(getter_AddRefs(loadInfo));
-      // make sure we have the same instance of loadInfo on the newly created channel
+      channel->GetLoadInfo(getter_AddRefs(loadInfo));
+
       if (aLoadInfo != loadInfo) {
         MOZ_ASSERT(false, "newly created channel must have a loadinfo attached");
         return NS_ERROR_UNEXPECTED;
       }
 
       // If we're sandboxed, make sure to clear any owner the channel
       // might already have.
       if (loadInfo->GetLoadingSandboxed()) {
-        (*result)->SetOwner(nullptr);
+        channel->SetOwner(nullptr);
       }
     }
 
     // Some extensions override the http protocol handler and provide their own
     // implementation. The channels returned from that implementation doesn't
     // seem to always implement the nsIUploadChannel2 interface, presumably
     // because it's a new interface.
     // Eventually we should remove this and simply require that http channels
     // implement the new interface.
     // See bug 529041
     if (!gHasWarnedUploadChannel2 && scheme.EqualsLiteral("http")) {
-        nsCOMPtr<nsIUploadChannel2> uploadChannel2 = do_QueryInterface(*result);
+        nsCOMPtr<nsIUploadChannel2> uploadChannel2 = do_QueryInterface(channel);
         if (!uploadChannel2) {
             nsCOMPtr<nsIConsoleService> consoleService =
                 do_GetService(NS_CONSOLESERVICE_CONTRACTID);
             if (consoleService) {
                 consoleService->LogStringMessage(NS_LITERAL_STRING(
                     "Http channel implementation doesn't support nsIUploadChannel2. An extension has supplied a non-functional http protocol handler. This will break behavior and in future releases not work at all."
                                                                    ).get());
             }
             gHasWarnedUploadChannel2 = true;
         }
     }
 
+    channel.forget(result);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsIOService::NewChannelFromURIWithProxyFlags2(nsIURI* aURI,
                                               nsIURI* aProxyURI,
                                               uint32_t aProxyFlags,
                                               nsIDOMNode* aLoadingNode,