[tor-commits] [tor-browser/tor-browser-31.2.0esr-4.5-1] Bug #3455.1: Allow proxy settings to be set per URL bar domain.

mikeperry at torproject.org mikeperry at torproject.org
Thu Oct 30 20:48:36 UTC 2014


commit 08991021207bcc7c982fa5ae5a9984a12ec7bf5f
Author: Arthur Edelstein <arthuredelstein at gmail.com>
Date:   Tue Oct 21 02:15:25 2014 -0700

    Bug #3455.1: Allow proxy settings to be set per URL bar domain.
---
 dom/plugins/base/moz.build                         |    1 +
 dom/plugins/base/nsPluginHost.cpp                  |   27 ++--
 netwerk/base/public/nsIProtocolProxyCallback.idl   |   10 +-
 netwerk/base/public/nsIProtocolProxyFilter.idl     |   34 ++++-
 netwerk/base/public/nsIProtocolProxyService.idl    |   32 +++-
 netwerk/base/public/nsIProtocolProxyService2.idl   |   13 +-
 netwerk/base/src/nsIOService.cpp                   |   18 ++-
 netwerk/base/src/nsPACMan.cpp                      |    9 +-
 netwerk/base/src/nsPACMan.h                        |   10 +-
 netwerk/base/src/nsProtocolProxyService.cpp        |  157 +++++++++++++-------
 netwerk/base/src/nsProtocolProxyService.h          |   49 ++++--
 netwerk/protocol/ftp/nsFtpConnectionThread.cpp     |   11 +-
 netwerk/protocol/http/HttpBaseChannel.cpp          |   10 ++
 netwerk/protocol/http/HttpBaseChannel.h            |    1 +
 netwerk/protocol/http/nsHttpChannel.cpp            |    6 +-
 netwerk/protocol/http/nsIHttpChannel.idl           |    6 +
 .../protocol/viewsource/nsViewSourceChannel.cpp    |    6 +
 netwerk/protocol/websocket/WebSocketChannel.cpp    |    4 +-
 18 files changed, 281 insertions(+), 123 deletions(-)

diff --git a/dom/plugins/base/moz.build b/dom/plugins/base/moz.build
index ded5fb5..25bae79 100644
--- a/dom/plugins/base/moz.build
+++ b/dom/plugins/base/moz.build
@@ -103,6 +103,7 @@ LOCAL_INCLUDES += [
     '/gfx/skia/include/core',
     '/layout/generic',
     '/layout/xul',
+    '/netwerk/base/src',
     '/widget/android',
     '/widget/xpwidgets',
     '/xpcom/base',
diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp
index bc6bf72..1efe59f 100644
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -30,7 +30,7 @@
 #include "nsIURL.h"
 #include "nsTArray.h"
 #include "nsReadableUtils.h"
-#include "nsIProtocolProxyService2.h"
+#include "nsProtocolProxyService.h"
 #include "nsIStreamConverterService.h"
 #include "nsIFile.h"
 #if defined(XP_MACOSX)
@@ -583,32 +583,29 @@ nsresult nsPluginHost::FindProxyForURL(const char* url, char* *result)
   }
   nsresult res;
 
-  nsCOMPtr<nsIURI> uriIn;
-  nsCOMPtr<nsIProtocolProxyService> proxyService;
-  nsCOMPtr<nsIProtocolProxyService2> proxyService2;
-  nsCOMPtr<nsIIOService> ioService;
-
-  proxyService = do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &res);
+  nsCOMPtr<nsIProtocolProxyService> proxyService =
+    do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &res);
   if (NS_FAILED(res) || !proxyService)
     return res;
 
-  proxyService2 = do_QueryInterface(proxyService, &res);
-  if (NS_FAILED(res) || !proxyService2)
-    return res;
+  nsRefPtr<nsProtocolProxyService> rawProxyService = do_QueryObject(proxyService);
+  if (!rawProxyService)
+    return NS_ERROR_FAILURE;
 
-  ioService = do_GetService(NS_IOSERVICE_CONTRACTID, &res);
+  nsCOMPtr<nsIIOService> ioService = do_GetService(NS_IOSERVICE_CONTRACTID, &res);
   if (NS_FAILED(res) || !ioService)
     return res;
 
-  // make an nsURI from the argument url
-  res = ioService->NewURI(nsDependentCString(url), nullptr, nullptr, getter_AddRefs(uriIn));
+  // make a temporary channel from the argument url
+  nsCOMPtr<nsIChannel> tempChannel;
+  res = ioService->NewChannel(nsDependentCString(url), nullptr, nullptr, getter_AddRefs(tempChannel));
   if (NS_FAILED(res))
     return res;
 
   nsCOMPtr<nsIProxyInfo> pi;
 
-  // Remove this with bug 778201
-  res = proxyService2->DeprecatedBlockingResolve(uriIn, 0, getter_AddRefs(pi));
+  // Remove this deprecated call in the future (see Bug 778201):
+  res = rawProxyService->DeprecatedBlockingResolve(tempChannel, 0, getter_AddRefs(pi));
   if (NS_FAILED(res))
     return res;
 
diff --git a/netwerk/base/public/nsIProtocolProxyCallback.idl b/netwerk/base/public/nsIProtocolProxyCallback.idl
index ca1ab51..96c2181 100644
--- a/netwerk/base/public/nsIProtocolProxyCallback.idl
+++ b/netwerk/base/public/nsIProtocolProxyCallback.idl
@@ -6,7 +6,7 @@
 
 #include "nsISupports.idl"
 
-interface nsIURI;
+interface nsIChannel;
 interface nsIProxyInfo;
 interface nsICancelable;
 
@@ -14,7 +14,7 @@ interface nsICancelable;
  * This interface serves as a closure for nsIProtocolProxyService's
  * asyncResolve method.
  */
-[scriptable, uuid(a9967200-f95e-45c2-beb3-9b060d874bfd)]
+[scriptable, uuid(fbb6eff6-0cc2-4d99-8d6f-0a12b462bdeb)]
 interface nsIProtocolProxyCallback : nsISupports
 {
   /**
@@ -23,8 +23,8 @@ interface nsIProtocolProxyCallback : nsISupports
    *
    * @param aRequest
    *        The value returned from asyncResolve.
-   * @param aURI
-   *        The URI passed to asyncResolve.
+   * @param aChannel
+   *        The channel passed to asyncResolve.
    * @param aProxyInfo
    *        The resulting proxy info or null if there is no associated proxy
    *        info for aURI.  As with the result of nsIProtocolProxyService's
@@ -36,7 +36,7 @@ interface nsIProtocolProxyCallback : nsISupports
    *        indicates the reason for the failure and aProxyInfo will be null.
    */
   void onProxyAvailable(in nsICancelable aRequest,
-                        in nsIURI aURI,
+                        in nsIChannel aChannel,
                         in nsIProxyInfo aProxyInfo,
                         in nsresult aStatus);
 };
diff --git a/netwerk/base/public/nsIProtocolProxyFilter.idl b/netwerk/base/public/nsIProtocolProxyFilter.idl
index 8ad6ca4..8798a49 100644
--- a/netwerk/base/public/nsIProtocolProxyFilter.idl
+++ b/netwerk/base/public/nsIProtocolProxyFilter.idl
@@ -6,6 +6,7 @@
 
 #include "nsISupports.idl"
 
+interface nsIChannel;
 interface nsIProtocolProxyService;
 interface nsIProxyInfo;
 interface nsIURI;
@@ -13,7 +14,7 @@ interface nsIURI;
 /**
  * This interface is used to apply filters to the proxies selected for a given
  * URI.  Use nsIProtocolProxyService::registerFilter to hook up instances of
- * this interface.
+ * this interface. See also nsIProtocolProxyChannelFilter.
  */
 [scriptable, uuid(f424abd3-32b4-456c-9f45-b7e3376cb0d1)]
 interface nsIProtocolProxyFilter : nsISupports
@@ -40,3 +41,34 @@ interface nsIProtocolProxyFilter : nsISupports
   nsIProxyInfo applyFilter(in nsIProtocolProxyService aProxyService,
                            in nsIURI aURI, in nsIProxyInfo aProxy);
 };
+
+/**
+ * This interface is used to apply filters to the proxies selected for a given
+ * channel.  Use nsIProtocolProxyService::registerChannelFilter to hook up instances of
+ * this interface. See also nsIProtocolProxyFilter.
+ */
+[scriptable, uuid(245b0880-82c5-4e6e-be6d-bc586aa55a90)]
+interface nsIProtocolProxyChannelFilter : nsISupports
+{
+  /**
+   * This method is called to apply proxy filter rules for the given channel
+   * and proxy object (or list of proxy objects).
+   *
+   * @param aProxyService
+   *        A reference to the Protocol Proxy Service.  This is passed so that
+   *        implementations may easily access methods such as newProxyInfo.
+   * @param aChannel
+   *        The channel for which these proxy settings apply.
+   * @param aProxy
+   *        The proxy (or list of proxies) that would be used by default for
+   *        the given channel. This may be null.
+   *
+   * @return The proxy (or list of proxies) that should be used in place of
+   *         aProxy. This can be just be aProxy if the filter chooses not to
+   *         modify the proxy. It can also be null to indicate that a direct
+   *         connection should be used.  Use aProxyService.newProxyInfo to
+   *         construct nsIProxyInfo objects.
+   */
+  nsIProxyInfo applyFilter(in nsIProtocolProxyService aProxyService,
+                           in nsIChannel aChannel, in nsIProxyInfo aProxy);
+};
diff --git a/netwerk/base/public/nsIProtocolProxyService.idl b/netwerk/base/public/nsIProtocolProxyService.idl
index 526eab8..9365658 100644
--- a/netwerk/base/public/nsIProtocolProxyService.idl
+++ b/netwerk/base/public/nsIProtocolProxyService.idl
@@ -9,6 +9,7 @@
 interface nsICancelable;
 interface nsIProtocolProxyCallback;
 interface nsIProtocolProxyFilter;
+interface nsIProtocolProxyChannelFilter;
 interface nsIProxyInfo;
 interface nsIChannel;
 interface nsIURI;
@@ -17,7 +18,7 @@ interface nsIURI;
  * nsIProtocolProxyService provides methods to access information about
  * various network proxies.
  */
-[scriptable, uuid(e77c642b-026f-41ce-9b23-f829a6e3f300)]
+[scriptable, uuid(ab363090-c331-489f-aabb-7fe4481795b8)]
 interface nsIProtocolProxyService : nsISupports
 {
     /** Flag 1 << 0 is unused **/
@@ -64,11 +65,11 @@ interface nsIProtocolProxyService : nsISupports
 
     /**
      * This method returns via callback a nsIProxyInfo instance that identifies
-     * a proxy to be used for loading the given URI.  Otherwise, this method returns
+     * a proxy to be used for the given channel.  Otherwise, this method returns
      * null indicating that a direct connection should be used.
      *
-     * @param aURI
-     *        The URI to test.
+     * @param aChannel
+     *        The channel for which a proxy is to be found.
      * @param aFlags
      *        A bit-wise combination of the RESOLVE_ flags defined above.  Pass
      *        0 to specify the default behavior.  Any additional bits that do
@@ -94,7 +95,7 @@ interface nsIProtocolProxyService : nsISupports
      *
      * @see nsIProxiedProtocolHandler::newProxiedChannel 
      */
-    nsICancelable asyncResolve(in nsIURI aURI, in unsigned long aFlags,
+    nsICancelable asyncResolve(in nsIChannel aChannel, in unsigned long aFlags,
                                in nsIProtocolProxyCallback aCallback);
 
     /**
@@ -191,6 +192,18 @@ interface nsIProtocolProxyService : nsISupports
                         in unsigned long aPosition);
 
     /**
+     * Similar to registerFilter, but accepts an nsIProtocolProxyChannelFilter,
+     * which selects proxies according to channel rather than URI.
+     *
+     * @param aFilter
+     *        The nsIProtocolProxyChannelFilter instance to be registered.
+     * @param aPosition
+     *        The position of the filter.
+     */
+    void registerChannelFilter(in nsIProtocolProxyChannelFilter aFilter,
+                               in unsigned long aPosition);
+
+    /**
      * This method may be used to unregister a proxy filter instance.  All
      * filters will be automatically unregistered at XPCOM shutdown.
      *
@@ -199,6 +212,15 @@ interface nsIProtocolProxyService : nsISupports
      */
     void unregisterFilter(in nsIProtocolProxyFilter aFilter);
 
+    /**
+     * This method may be used to unregister a proxy channel filter instance.  All
+     * filters will be automatically unregistered at XPCOM shutdown.
+     *
+     * @param aFilter
+     *        The nsIProtocolProxyChannelFilter instance to be unregistered.
+     */
+    void unregisterChannelFilter(in nsIProtocolProxyChannelFilter aFilter);
+
      /**
       * These values correspond to the possible integer values for the
       * network.proxy.type preference.
diff --git a/netwerk/base/public/nsIProtocolProxyService2.idl b/netwerk/base/public/nsIProtocolProxyService2.idl
index cb39a33..9e4f548 100644
--- a/netwerk/base/public/nsIProtocolProxyService2.idl
+++ b/netwerk/base/public/nsIProtocolProxyService2.idl
@@ -9,7 +9,7 @@
 /**
  * An extension of nsIProtocolProxyService
  */
-[scriptable, uuid(bb52e571-4a0e-4363-83d0-52034910dd14)]
+[scriptable, uuid(b2e5b2c0-e21e-4845-b336-be6d60a38951)]
 interface nsIProtocolProxyService2 : nsIProtocolProxyService
 {
   /**
@@ -18,21 +18,12 @@ interface nsIProtocolProxyService2 : nsIProtocolProxyService
    */
   void reloadPAC();
 
-  /**
-   * This exists so Java(tm) can migrate to an asynchronous interface.
-   * Do not use this unless you are the plugin interface, and even then you
-   * ought to feel horribly guilty because you will create main thread jank.
-   *
-   * No documentation - it is deprecated!
-   **/
-  nsIProxyInfo deprecatedBlockingResolve(in nsIURI aURI, in unsigned long aFlags);
-
     /**
      * This method is identical to asyncResolve() except it may execute the
      * callback function immediately (i.e from the stack of asyncResolve2()) if
      * it is immediately ready to run. The nsICancelable return value will be
      * null in that case.
      */
-  nsICancelable asyncResolve2(in nsIURI aURI, in unsigned long aFlags,
+  nsICancelable asyncResolve2(in nsIChannel aChannel, in unsigned long aFlags,
                               in nsIProtocolProxyCallback aCallback);
 };
diff --git a/netwerk/base/src/nsIOService.cpp b/netwerk/base/src/nsIOService.cpp
index b64e7d3..99efa57 100644
--- a/netwerk/base/src/nsIOService.cpp
+++ b/netwerk/base/src/nsIOService.cpp
@@ -1197,7 +1197,7 @@ private:
 NS_IMPL_ISUPPORTS(IOServiceProxyCallback, nsIProtocolProxyCallback)
 
 NS_IMETHODIMP
-IOServiceProxyCallback::OnProxyAvailable(nsICancelable *request, nsIURI *aURI,
+IOServiceProxyCallback::OnProxyAvailable(nsICancelable *request, nsIChannel *channel,
                                          nsIProxyInfo *pi, nsresult status)
 {
     // Checking proxy status for speculative connect
@@ -1209,8 +1209,13 @@ IOServiceProxyCallback::OnProxyAvailable(nsICancelable *request, nsIURI *aURI,
         return NS_OK;
     }
 
+    nsCOMPtr<nsIURI> uri;
+    nsresult rv = channel->GetURI(getter_AddRefs(uri));
+    if (NS_FAILED(rv))
+        return NS_OK;
+
     nsAutoCString scheme;
-    nsresult rv = aURI->GetScheme(scheme);
+    rv = uri->GetScheme(scheme);
     if (NS_FAILED(rv))
         return NS_OK;
 
@@ -1225,7 +1230,7 @@ IOServiceProxyCallback::OnProxyAvailable(nsICancelable *request, nsIURI *aURI,
     if (!speculativeHandler)
         return NS_OK;
 
-    speculativeHandler->SpeculativeConnect(aURI,
+    speculativeHandler->SpeculativeConnect(uri,
                                            mCallbacks);
     return NS_OK;
 }
@@ -1243,8 +1248,13 @@ nsIOService::SpeculativeConnect(nsIURI *aURI,
     if (NS_FAILED(rv))
         return rv;
 
+    nsCOMPtr<nsIChannel> channel;
+    rv = NewChannelFromURI(aURI, getter_AddRefs(channel));
+    if (NS_FAILED(rv))
+        return rv;
+
     nsCOMPtr<nsICancelable> cancelable;
     nsRefPtr<IOServiceProxyCallback> callback =
         new IOServiceProxyCallback(aCallbacks, this);
-    return pps->AsyncResolve(aURI, 0, callback, getter_AddRefs(cancelable));
+    return pps->AsyncResolve(channel, 0, callback, getter_AddRefs(cancelable));
 }
diff --git a/netwerk/base/src/nsPACMan.cpp b/netwerk/base/src/nsPACMan.cpp
index 81bc17e..e8b0b2d 100644
--- a/netwerk/base/src/nsPACMan.cpp
+++ b/netwerk/base/src/nsPACMan.cpp
@@ -320,8 +320,8 @@ nsPACMan::Shutdown()
 }
 
 nsresult
-nsPACMan::AsyncGetProxyForURI(nsIURI *uri, nsPACManCallback *callback,
-                              bool mainThreadResponse)
+nsPACMan::AsyncGetProxyForChannel(nsIChannel *channel, nsPACManCallback *callback,
+                                  bool mainThreadResponse)
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "wrong thread");
   if (mShutdown)
@@ -332,6 +332,11 @@ nsPACMan::AsyncGetProxyForURI(nsIURI *uri, nsPACManCallback *callback,
       TimeStamp::Now() > mScheduledReload)
     LoadPACFromURI(EmptyCString());
 
+  nsCOMPtr<nsIURI> uri;
+  nsresult rv = channel->GetURI(getter_AddRefs(uri));
+  if (NS_FAILED(rv))
+    return rv;
+
   nsRefPtr<PendingPACQuery> query =
     new PendingPACQuery(this, uri, callback, mainThreadResponse);
 
diff --git a/netwerk/base/src/nsPACMan.h b/netwerk/base/src/nsPACMan.h
index 410ae5641..6f95d97 100644
--- a/netwerk/base/src/nsPACMan.h
+++ b/netwerk/base/src/nsPACMan.h
@@ -27,13 +27,13 @@ class nsIThread;
 class WaitForThreadShutdown;
 
 /**
- * This class defines a callback interface used by AsyncGetProxyForURI.
+ * This class defines a callback interface used by AsyncGetProxyForChannel.
  */
 class NS_NO_VTABLE nsPACManCallback : public nsISupports
 {
 public:
   /**
-   * This method is invoked on the same thread that called AsyncGetProxyForURI.
+   * This method is invoked on the same thread that called AsyncGetProxyForChannel.
    *
    * @param status
    *        This parameter indicates whether or not the PAC query succeeded.
@@ -101,14 +101,14 @@ public:
    * will queue up the request, and complete it once the PAC file has been
    * loaded.
    * 
-   * @param uri
-   *        The URI to query.
+   * @param channel
+   *        The channel to query.
    * @param callback
    *        The callback to run once the PAC result is available.
    * @param mustCallbackOnMainThread
    *        If set to false the callback can be made from the PAC thread
    */
-  nsresult AsyncGetProxyForURI(nsIURI *uri, nsPACManCallback *callback,
+  nsresult AsyncGetProxyForChannel(nsIChannel *channel, nsPACManCallback *callback,
                                bool mustCallbackOnMainThread);
 
   /**
diff --git a/netwerk/base/src/nsProtocolProxyService.cpp b/netwerk/base/src/nsProtocolProxyService.cpp
index 98ea68b..3878c58d 100644
--- a/netwerk/base/src/nsProtocolProxyService.cpp
+++ b/netwerk/base/src/nsProtocolProxyService.cpp
@@ -14,6 +14,7 @@
 #include "nsIObserverService.h"
 #include "nsIProtocolHandler.h"
 #include "nsIProtocolProxyCallback.h"
+#include "nsIChannel.h"
 #include "nsICancelable.h"
 #include "nsIDNSService.h"
 #include "nsPIDNSService.h"
@@ -67,7 +68,7 @@ struct nsProtocolInfo {
 //----------------------------------------------------------------------------
 
 // The nsPACManCallback portion of this implementation should be run
-// on the main thread - so call nsPACMan::AsyncGetProxyForURI() with
+// on the main thread - so call nsPACMan::AsyncGetProxyForChannel() with
 // a true mainThreadResponse parameter.
 class nsAsyncResolveRequest MOZ_FINAL : public nsIRunnable
                                       , public nsPACManCallback
@@ -76,7 +77,7 @@ class nsAsyncResolveRequest MOZ_FINAL : public nsIRunnable
 public:
     NS_DECL_THREADSAFE_ISUPPORTS
 
-    nsAsyncResolveRequest(nsProtocolProxyService *pps, nsIURI *uri,
+    nsAsyncResolveRequest(nsProtocolProxyService *pps, nsIChannel *channel,
                           uint32_t aResolveFlags,
                           nsIProtocolProxyCallback *callback)
         : mStatus(NS_OK)
@@ -84,7 +85,7 @@ public:
         , mResolveFlags(aResolveFlags)
         , mPPS(pps)
         , mXPComPPS(pps)
-        , mURI(uri)
+        , mChannel(channel)
         , mCallback(callback)
     {
         NS_ASSERTION(mCallback, "null callback");
@@ -100,9 +101,9 @@ public:
             nsCOMPtr<nsIThread> mainThread;
             NS_GetMainThread(getter_AddRefs(mainThread));
 
-            if (mURI) {
-                nsIURI *forgettable;
-                mURI.forget(&forgettable);
+            if (mChannel) {
+                nsIChannel *forgettable;
+                mChannel.forget(&forgettable);
                 NS_ProxyRelease(mainThread, forgettable, false);
             }
 
@@ -207,19 +208,21 @@ private:
         if (NS_SUCCEEDED(mStatus) && !mProxyInfo && !mPACString.IsEmpty()) {
             mPPS->ProcessPACString(mPACString, mResolveFlags,
                                    getter_AddRefs(mProxyInfo));
+            nsCOMPtr<nsIURI> uri;
+            mChannel->GetURI(getter_AddRefs(uri));
 
             // Now apply proxy filters
             nsProtocolInfo info;
-            mStatus = mPPS->GetProtocolInfo(mURI, &info);
+            mStatus = mPPS->GetProtocolInfo(uri, &info);
             if (NS_SUCCEEDED(mStatus))
-                mPPS->ApplyFilters(mURI, info, mProxyInfo);
+                mPPS->ApplyFilters(mChannel, info, mProxyInfo);
             else
                 mProxyInfo = nullptr;
 
             LOG(("pac thread callback %s\n", mPACString.get()));
             if (NS_SUCCEEDED(mStatus))
                 mPPS->MaybeDisableDNSPrefetch(mProxyInfo);
-            mCallback->OnProxyAvailable(this, mURI, mProxyInfo, mStatus);
+            mCallback->OnProxyAvailable(this, mChannel, mProxyInfo, mStatus);
         }
         else if (NS_SUCCEEDED(mStatus) && !mPACURL.IsEmpty()) {
             LOG(("pac thread callback indicates new pac file load\n"));
@@ -229,12 +232,12 @@ private:
             if (NS_SUCCEEDED(rv)) {
                 // now that the load is triggered, we can resubmit the query
                 nsRefPtr<nsAsyncResolveRequest> newRequest =
-                    new nsAsyncResolveRequest(mPPS, mURI, mResolveFlags, mCallback);
-                rv = mPPS->mPACMan->AsyncGetProxyForURI(mURI, newRequest, true);
+                    new nsAsyncResolveRequest(mPPS, mChannel, mResolveFlags, mCallback);
+                rv = mPPS->mPACMan->AsyncGetProxyForChannel(mChannel, newRequest, true);
             }
 
             if (NS_FAILED(rv))
-                mCallback->OnProxyAvailable(this, mURI, nullptr, rv);
+                mCallback->OnProxyAvailable(this, mChannel, nullptr, rv);
 
             // do not call onproxyavailable() in SUCCESS case - the newRequest will
             // take care of that
@@ -243,7 +246,7 @@ private:
             LOG(("pac thread callback did not provide information %X\n", mStatus));
             if (NS_SUCCEEDED(mStatus))
                 mPPS->MaybeDisableDNSPrefetch(mProxyInfo);
-            mCallback->OnProxyAvailable(this, mURI, mProxyInfo, mStatus);
+            mCallback->OnProxyAvailable(this, mChannel, mProxyInfo, mStatus);
         }
 
         // We are on the main thread now and don't need these any more so
@@ -252,7 +255,7 @@ private:
         mCallback = nullptr;  // in case the callback holds an owning ref to us
         mPPS = nullptr;
         mXPComPPS = nullptr;
-        mURI = nullptr;
+        mChannel = nullptr;
         mProxyInfo = nullptr;
     }
 
@@ -266,7 +269,7 @@ private:
 
     nsProtocolProxyService            *mPPS;
     nsCOMPtr<nsIProtocolProxyService>  mXPComPPS;
-    nsCOMPtr<nsIURI>                   mURI;
+    nsCOMPtr<nsIChannel>               mChannel;
     nsCOMPtr<nsIProtocolProxyCallback> mCallback;
     nsCOMPtr<nsIProxyInfo>             mProxyInfo;
 };
@@ -964,7 +967,7 @@ nsProtocolProxyService::ReloadPAC()
 // The nsPACManCallback portion of this implementation should be run
 // off the main thread, because it uses a condvar for signaling and
 // the main thread is blocking on that condvar -
-//  so call nsPACMan::AsyncGetProxyForURI() with
+//  so call nsPACMan::AsyncGetProxyForChannel() with
 // a false mainThreadResponse parameter.
 class nsAsyncBridgeRequest MOZ_FINAL  : public nsPACManCallback
 {
@@ -1010,16 +1013,19 @@ private:
 };
 NS_IMPL_ISUPPORTS0(nsAsyncBridgeRequest)
 
-// nsIProtocolProxyService2
+// nsProtocolProxyService
 NS_IMETHODIMP
-nsProtocolProxyService::DeprecatedBlockingResolve(nsIURI *aURI,
+nsProtocolProxyService::DeprecatedBlockingResolve(nsIChannel *aChannel,
                                                   uint32_t aFlags,
                                                   nsIProxyInfo **retval)
 {
-    NS_ENSURE_ARG_POINTER(aURI);
+    NS_ENSURE_ARG_POINTER(aChannel);
+
+    nsCOMPtr<nsIURI> uri;
+    aChannel->GetURI(getter_AddRefs(uri));
 
     nsProtocolInfo info;
-    nsresult rv = GetProtocolInfo(aURI, &info);
+    nsresult rv = GetProtocolInfo(uri, &info);
     if (NS_FAILED(rv))
         return rv;
 
@@ -1030,12 +1036,12 @@ nsProtocolProxyService::DeprecatedBlockingResolve(nsIURI *aURI,
     // but if neither of them are in use, we can just do the work
     // right here and directly invoke the callback
 
-    rv = Resolve_Internal(aURI, info, aFlags, &usePACThread, getter_AddRefs(pi));
+    rv = Resolve_Internal(aChannel, info, aFlags, &usePACThread, getter_AddRefs(pi));
     if (NS_FAILED(rv))
         return rv;
 
     if (!usePACThread || !mPACMan) {
-        ApplyFilters(aURI, info, pi);
+        ApplyFilters(aChannel, info, pi);
         pi.forget(retval);
         return NS_OK;
     }
@@ -1044,7 +1050,7 @@ nsProtocolProxyService::DeprecatedBlockingResolve(nsIURI *aURI,
     // code, but block this thread on that completion.
     nsRefPtr<nsAsyncBridgeRequest> ctx = new nsAsyncBridgeRequest();
     ctx->Lock();
-    if (NS_SUCCEEDED(mPACMan->AsyncGetProxyForURI(aURI, ctx, false))) {
+    if (NS_SUCCEEDED(mPACMan->AsyncGetProxyForChannel(aChannel, ctx, false))) {
         // this can really block the main thread, so cap it at 3 seconds
        ctx->Wait();
     }
@@ -1060,7 +1066,7 @@ nsProtocolProxyService::DeprecatedBlockingResolve(nsIURI *aURI,
     if (!ctx->mPACString.IsEmpty()) {
         LOG(("sync pac thread callback %s\n", ctx->mPACString.get()));
         ProcessPACString(ctx->mPACString, 0, getter_AddRefs(pi));
-        ApplyFilters(aURI, info, pi);
+        ApplyFilters(aChannel, info, pi);
         pi.forget(retval);
         return NS_OK;
     }
@@ -1084,17 +1090,20 @@ nsProtocolProxyService::DeprecatedBlockingResolve(nsIURI *aURI,
 }
 
 nsresult
-nsProtocolProxyService::AsyncResolveInternal(nsIURI *uri, uint32_t flags,
+nsProtocolProxyService::AsyncResolveInternal(nsIChannel *channel, uint32_t flags,
                                              nsIProtocolProxyCallback *callback,
                                              nsICancelable **result,
                                              bool isSyncOK)
 {
-    NS_ENSURE_ARG_POINTER(uri);
+    NS_ENSURE_ARG_POINTER(channel);
     NS_ENSURE_ARG_POINTER(callback);
 
+    nsCOMPtr<nsIURI> uri;
+    channel->GetURI(getter_AddRefs(uri));
+
     *result = nullptr;
     nsRefPtr<nsAsyncResolveRequest> ctx =
-        new nsAsyncResolveRequest(this, uri, flags, callback);
+        new nsAsyncResolveRequest(this, channel, flags, callback);
 
     nsProtocolInfo info;
     nsresult rv = GetProtocolInfo(uri, &info);
@@ -1108,13 +1117,13 @@ nsProtocolProxyService::AsyncResolveInternal(nsIURI *uri, uint32_t flags,
     // but if neither of them are in use, we can just do the work
     // right here and directly invoke the callback
 
-    rv = Resolve_Internal(uri, info, flags, &usePACThread, getter_AddRefs(pi));
+    rv = Resolve_Internal(channel, info, flags, &usePACThread, getter_AddRefs(pi));
     if (NS_FAILED(rv))
         return rv;
 
     if (!usePACThread || !mPACMan) {
         // we can do it locally
-        ApplyFilters(uri, info, pi);
+        ApplyFilters(channel, info, pi);
         ctx->SetResult(NS_OK, pi);
         if (isSyncOK) {
             ctx->Run();
@@ -1129,7 +1138,7 @@ nsProtocolProxyService::AsyncResolveInternal(nsIURI *uri, uint32_t flags,
 
     // else kick off a PAC thread query
 
-    rv = mPACMan->AsyncGetProxyForURI(uri, ctx, true);
+    rv = mPACMan->AsyncGetProxyForChannel(channel, ctx, true);
     if (NS_SUCCEEDED(rv))
         ctx.forget(result);
     return rv;
@@ -1137,19 +1146,19 @@ nsProtocolProxyService::AsyncResolveInternal(nsIURI *uri, uint32_t flags,
 
 // nsIProtocolProxyService
 NS_IMETHODIMP
-nsProtocolProxyService::AsyncResolve2(nsIURI *uri, uint32_t flags,
+nsProtocolProxyService::AsyncResolve2(nsIChannel *channel, uint32_t flags,
                                       nsIProtocolProxyCallback *callback,
                                       nsICancelable **result)
 {
-    return AsyncResolveInternal(uri, flags, callback, result, true);
+    return AsyncResolveInternal(channel, flags, callback, result, true);
 }
 
 NS_IMETHODIMP
-nsProtocolProxyService::AsyncResolve(nsIURI *uri, uint32_t flags,
+nsProtocolProxyService::AsyncResolve(nsIChannel *channel, uint32_t flags,
                                      nsIProtocolProxyCallback *callback,
                                      nsICancelable **result)
 {
-    return AsyncResolveInternal(uri, flags, callback, result, false);
+    return AsyncResolveInternal(channel, flags, callback, result, false);
 }
 
 NS_IMETHODIMP
@@ -1221,16 +1230,9 @@ nsProtocolProxyService::GetFailoverForProxy(nsIProxyInfo  *aProxy,
     return NS_OK;
 }
 
-NS_IMETHODIMP
-nsProtocolProxyService::RegisterFilter(nsIProtocolProxyFilter *filter,
-                                       uint32_t position)
+nsresult
+nsProtocolProxyService::InsertFilterLink(FilterLink *link, uint32_t position)
 {
-    UnregisterFilter(filter);  // remove this filter if we already have it
-
-    FilterLink *link = new FilterLink(position, filter);
-    if (!link)
-        return NS_ERROR_OUT_OF_MEMORY;
-
     if (!mFilters) {
         mFilters = link;
         return NS_OK;
@@ -1258,11 +1260,32 @@ nsProtocolProxyService::RegisterFilter(nsIProtocolProxyFilter *filter,
 }
 
 NS_IMETHODIMP
-nsProtocolProxyService::UnregisterFilter(nsIProtocolProxyFilter *filter)
+nsProtocolProxyService::RegisterFilter(nsIProtocolProxyFilter *filter,
+                                       uint32_t position)
 {
-    // QI to nsISupports so we can safely test object identity.
-    nsCOMPtr<nsISupports> givenObject = do_QueryInterface(filter);
+    UnregisterFilter(filter); // remove this filter if we already have it
+
+    FilterLink *link = new FilterLink(position, filter);
+    if (!link)
+        return NS_ERROR_OUT_OF_MEMORY;
+    return InsertFilterLink(link, position);
+}
 
+NS_IMETHODIMP
+nsProtocolProxyService::RegisterChannelFilter(nsIProtocolProxyChannelFilter *channelFilter,
+                                              uint32_t position)
+{
+    UnregisterChannelFilter(channelFilter);  // remove this filter if we already have it
+
+    FilterLink *link = new FilterLink(position, channelFilter);
+    if (!link)
+        return NS_ERROR_OUT_OF_MEMORY;
+    return InsertFilterLink(link, position);
+}
+
+nsresult
+nsProtocolProxyService::RemoveFilterLink(nsISupports* givenObject)
+{
     FilterLink *last = nullptr;
     for (FilterLink *iter = mFilters; iter; iter = iter->next) {
         nsCOMPtr<nsISupports> object = do_QueryInterface(iter->filter);
@@ -1283,6 +1306,20 @@ nsProtocolProxyService::UnregisterFilter(nsIProtocolProxyFilter *filter)
 }
 
 NS_IMETHODIMP
+nsProtocolProxyService::UnregisterFilter(nsIProtocolProxyFilter *filter) {
+    // QI to nsISupports so we can safely test object identity.
+    nsCOMPtr<nsISupports> givenObject = do_QueryInterface(filter);
+    return RemoveFilterLink(givenObject);
+}
+
+NS_IMETHODIMP
+nsProtocolProxyService::UnregisterChannelFilter(nsIProtocolProxyChannelFilter *channelFilter) {
+    // QI to nsISupports so we can safely test object identity.
+    nsCOMPtr<nsISupports> givenObject = do_QueryInterface(channelFilter);
+    return RemoveFilterLink(givenObject);
+}
+
+NS_IMETHODIMP
 nsProtocolProxyService::GetProxyConfigType(uint32_t* aProxyConfigType)
 {
   *aProxyConfigType = mProxyConfig;
@@ -1489,13 +1526,13 @@ nsProtocolProxyService::NewProxyInfo_Internal(const char *aType,
 }
 
 nsresult
-nsProtocolProxyService::Resolve_Internal(nsIURI *uri,
+nsProtocolProxyService::Resolve_Internal(nsIChannel *channel,
                                          const nsProtocolInfo &info,
                                          uint32_t flags,
                                          bool *usePACThread,
                                          nsIProxyInfo **result)
 {
-    NS_ENSURE_ARG_POINTER(uri);
+    NS_ENSURE_ARG_POINTER(channel);
     nsresult rv = SetupPACThread();
     if (NS_FAILED(rv))
         return rv;
@@ -1506,6 +1543,9 @@ nsProtocolProxyService::Resolve_Internal(nsIURI *uri,
     if (!(info.flags & nsIProtocolHandler::ALLOWS_PROXY))
         return NS_OK;  // Can't proxy this (filters may not override)
 
+    nsCOMPtr<nsIURI> uri;
+    channel->GetURI(getter_AddRefs(uri));
+
     // See bug #586908.
     // Avoid endless loop if |uri| is the current PAC-URI. Returning OK
     // here means that we will not use a proxy for this connection.
@@ -1675,7 +1715,7 @@ nsProtocolProxyService::MaybeDisableDNSPrefetch(nsIProxyInfo *aProxy)
 }
 
 void
-nsProtocolProxyService::ApplyFilters(nsIURI *uri, const nsProtocolInfo &info,
+nsProtocolProxyService::ApplyFilters(nsIChannel *channel, const nsProtocolInfo &info,
                                      nsIProxyInfo **list)
 {
     if (!(info.flags & nsIProtocolHandler::ALLOWS_PROXY))
@@ -1690,9 +1730,22 @@ nsProtocolProxyService::ApplyFilters(nsIURI *uri, const nsProtocolInfo &info,
 
     for (FilterLink *iter = mFilters; iter; iter = iter->next) {
         PruneProxyInfo(info, list);
-
-        rv = iter->filter->ApplyFilter(this, uri, *list,
-                                       getter_AddRefs(result));
+        if (!!iter->filter) {
+          nsCOMPtr<nsIURI> uri;
+          channel->GetURI(getter_AddRefs(uri));
+          if (!!uri) {
+            nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
+            nsCOMPtr<nsIURI> proxyURI = nullptr;
+            if (!!httpChannel) {
+              httpChannel->GetProxyURI(getter_AddRefs(proxyURI));
+            }
+            rv = iter->filter->ApplyFilter(this, proxyURI ? proxyURI : uri, *list,
+                                           getter_AddRefs(result));
+          }
+        } else if (!!iter->channelFilter) {
+          rv = iter->channelFilter->ApplyFilter(this, channel, *list,
+                                                getter_AddRefs(result));
+        }
         if (NS_FAILED(rv))
             continue;
         result.swap(*list);
diff --git a/netwerk/base/src/nsProtocolProxyService.h b/netwerk/base/src/nsProtocolProxyService.h
index 4108e30..9ef68b9 100644
--- a/netwerk/base/src/nsProtocolProxyService.h
+++ b/netwerk/base/src/nsProtocolProxyService.h
@@ -27,6 +27,12 @@ class nsIPrefBranch;
 class nsISystemProxySettings;
 class nsPACMan;
 
+// CID for the nsProtocolProxyService class
+// 091eedd8-8bae-4fe3-ad62-0c87351e640d
+#define NS_PROTOCOL_PROXY_SERVICE_IMPL_CID        \
+{ 0x091eedd8, 0x8bae, 0x4fe3, \
+        { 0xad, 0x62, 0x0c, 0x87, 0x35, 0x1e, 0x64, 0x0d } }
+
 class nsProtocolProxyService MOZ_FINAL : public nsIProtocolProxyService2
                                        , public nsIObserver
 {
@@ -36,9 +42,14 @@ public:
     NS_DECL_NSIPROTOCOLPROXYSERVICE
     NS_DECL_NSIOBSERVER
 
+    NS_DECLARE_STATIC_IID_ACCESSOR(NS_PROTOCOL_PROXY_SERVICE_IMPL_CID)
+
     nsProtocolProxyService() NS_HIDDEN;
 
     NS_HIDDEN_(nsresult) Init();
+    nsresult DeprecatedBlockingResolve(nsIChannel *aChannel,
+                                       uint32_t aFlags,
+                                       nsIProxyInfo **retval);
 
 protected:
     friend class nsAsyncResolveRequest;
@@ -192,8 +203,8 @@ protected:
      * caller with either the proxy info result or a flag to instruct the
      * caller to use PAC instead.
      *
-     * @param uri
-     *        The URI to test.
+     * @param channel
+     *        The channel to test.
      * @param info
      *        Information about the URI's protocol.
      * @param flags
@@ -204,7 +215,7 @@ protected:
      * @param result
      *        The resulting proxy info or null.
      */
-    NS_HIDDEN_(nsresult) Resolve_Internal(nsIURI *uri,
+    NS_HIDDEN_(nsresult) Resolve_Internal(nsIChannel *channel,
                                           const nsProtocolInfo &info,
                                           uint32_t flags,
                                           bool *usePAC, 
@@ -214,26 +225,26 @@ protected:
      * This method applies the registered filters to the given proxy info
      * list, and returns a possibly modified list.
      *
-     * @param uri
-     *        The URI corresponding to this proxy info list.
+     * @param channel
+     *        The channel corresponding to this proxy info list.
      * @param info
      *        Information about the URI's protocol.
      * @param proxyInfo
      *        The proxy info list to be modified.  This is an inout param.
      */
-    NS_HIDDEN_(void) ApplyFilters(nsIURI *uri, const nsProtocolInfo &info,
+    NS_HIDDEN_(void) ApplyFilters(nsIChannel *channel, const nsProtocolInfo &info,
                                   nsIProxyInfo **proxyInfo);
 
     /**
      * This method is a simple wrapper around ApplyFilters that takes the
      * proxy info list inout param as a nsCOMPtr.
      */
-    inline void ApplyFilters(nsIURI *uri, const nsProtocolInfo &info,
+    inline void ApplyFilters(nsIChannel *channel, const nsProtocolInfo &info,
                              nsCOMPtr<nsIProxyInfo> &proxyInfo)
     {
       nsIProxyInfo *pi = nullptr;
       proxyInfo.swap(pi);
-      ApplyFilters(uri, info, &pi);
+      ApplyFilters(channel, info, &pi);
       proxyInfo.swap(pi);
     }
 
@@ -317,19 +328,27 @@ protected:
         }
     };
 
-    // This structure is allocated for each registered nsIProtocolProxyFilter.
+    // An instance of this struct is allocated for each registered
+    // nsIProtocolProxyFilter and each nsIProtocolProxyChannelFilter.
     struct FilterLink {
       struct FilterLink                *next;
       uint32_t                          position;
-      nsCOMPtr<nsIProtocolProxyFilter>  filter;
-
+      nsCOMPtr<nsIProtocolProxyFilter> filter;
+      nsCOMPtr<nsIProtocolProxyChannelFilter> channelFilter;
       FilterLink(uint32_t p, nsIProtocolProxyFilter *f)
-        : next(nullptr), position(p), filter(f) {}
-
+        : next(nullptr), position(p), filter(f), channelFilter(nullptr) {}
+      FilterLink(uint32_t p, nsIProtocolProxyChannelFilter *cf)
+        : next(nullptr), position(p), filter(nullptr), channelFilter(cf) {}
       // Chain deletion to simplify cleaning up the filter links
       ~FilterLink() { if (next) delete next; }
     };
 
+private:
+    // Private methods to insert and remove FilterLinks from the FilterLink chain.
+    nsresult InsertFilterLink(FilterLink *link, uint32_t position);
+    nsresult RemoveFilterLink(nsISupports *givenObject);
+
+protected:
     // Indicates if local hosts (plain hostnames, no dots) should use the proxy
     bool mFilterLocalHosts;
 
@@ -364,11 +383,13 @@ protected:
     int32_t                      mFailedProxyTimeout;
 
 private:
-    nsresult AsyncResolveInternal(nsIURI *uri, uint32_t flags,
+    nsresult AsyncResolveInternal(nsIChannel *channel, uint32_t flags,
                                   nsIProtocolProxyCallback *callback,
                                   nsICancelable **result,
                                   bool isSyncOK);
 
 };
 
+NS_DEFINE_STATIC_IID_ACCESSOR(nsProtocolProxyService, NS_PROTOCOL_PROXY_SERVICE_IMPL_CID)
+
 #endif // !nsProtocolProxyService_h__
diff --git a/netwerk/protocol/ftp/nsFtpConnectionThread.cpp b/netwerk/protocol/ftp/nsFtpConnectionThread.cpp
index 6d8d9f1..5073dbb 100644
--- a/netwerk/protocol/ftp/nsFtpConnectionThread.cpp
+++ b/netwerk/protocol/ftp/nsFtpConnectionThread.cpp
@@ -1872,7 +1872,7 @@ nsFtpState::Init(nsFtpChannel *channel)
         do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID);
 
     if (pps && !mChannel->ProxyInfo()) {
-        pps->AsyncResolve(mChannel->URI(), 0, this,
+        pps->AsyncResolve(mChannel, 0, this,
                           getter_AddRefs(mProxyRequest));
     }
 
@@ -2358,7 +2358,7 @@ nsFtpState::CloseWithStatus(nsresult status)
 }
 
 static nsresult
-CreateHTTPProxiedChannel(nsIURI *uri, nsIProxyInfo *pi, nsIChannel **newChannel)
+CreateHTTPProxiedChannel(nsIChannel *channel, nsIProxyInfo *pi, nsIChannel **newChannel)
 {
     nsresult rv;
     nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
@@ -2374,11 +2374,14 @@ CreateHTTPProxiedChannel(nsIURI *uri, nsIProxyInfo *pi, nsIChannel **newChannel)
     if (NS_FAILED(rv))
         return rv;
 
+    nsCOMPtr<nsIURI> uri;
+    channel->GetURI(getter_AddRefs(uri));
+
     return pph->NewProxiedChannel(uri, pi, 0, nullptr, newChannel);
 }
 
 NS_IMETHODIMP
-nsFtpState::OnProxyAvailable(nsICancelable *request, nsIURI *uri,
+nsFtpState::OnProxyAvailable(nsICancelable *request, nsIChannel *channel,
                              nsIProxyInfo *pi, nsresult status)
 {
   mProxyRequest = nullptr;
@@ -2395,7 +2398,7 @@ nsFtpState::OnProxyAvailable(nsICancelable *request, nsIURI *uri,
         LOG(("FTP:(%p) Configured to use a HTTP proxy channel\n", this));
 
         nsCOMPtr<nsIChannel> newChannel;
-        if (NS_SUCCEEDED(CreateHTTPProxiedChannel(uri, pi,
+        if (NS_SUCCEEDED(CreateHTTPProxiedChannel(channel, pi,
                                                   getter_AddRefs(newChannel))) &&
             NS_SUCCEEDED(mChannel->Redirect(newChannel,
                                             nsIChannelEventSink::REDIRECT_INTERNAL,
diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp
index 40123da..64b202a 100644
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -68,6 +68,7 @@ HttpBaseChannel::HttpBaseChannel()
   , mContentDispositionHint(UINT32_MAX)
   , mHttpHandler(gHttpHandler)
   , mRedirectCount(0)
+  , mProxyURI(nullptr)
 {
   LOG(("Creating HttpBaseChannel @%x\n", this));
 
@@ -1075,6 +1076,15 @@ HttpBaseChannel::SetReferrer(nsIURI *referrer)
 }
 
 NS_IMETHODIMP
+HttpBaseChannel::GetProxyURI(nsIURI** proxyURI)
+{
+  NS_ENSURE_ARG_POINTER(proxyURI);
+  *proxyURI = mProxyURI;
+  NS_IF_ADDREF(*proxyURI);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 HttpBaseChannel::GetRequestHeader(const nsACString& aHeader,
                                   nsACString& aValue)
 {
diff --git a/netwerk/protocol/http/HttpBaseChannel.h b/netwerk/protocol/http/HttpBaseChannel.h
index e177a39..abaf789 100644
--- a/netwerk/protocol/http/HttpBaseChannel.h
+++ b/netwerk/protocol/http/HttpBaseChannel.h
@@ -115,6 +115,7 @@ public:
   NS_IMETHOD SetRequestMethod(const nsACString& aMethod);
   NS_IMETHOD GetReferrer(nsIURI **referrer);
   NS_IMETHOD SetReferrer(nsIURI *referrer);
+  NS_IMETHOD GetProxyURI(nsIURI **proxyURI);
   NS_IMETHOD GetRequestHeader(const nsACString& aHeader, nsACString& aValue);
   NS_IMETHOD SetRequestHeader(const nsACString& aHeader,
                               const nsACString& aValue, bool aMerge);
diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp
index 6449769..41ef8bb 100644
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -1823,10 +1823,10 @@ nsHttpChannel::ResolveProxy()
     // then it is ok to use that version.
     nsCOMPtr<nsIProtocolProxyService2> pps2 = do_QueryInterface(pps);
     if (pps2) {
-        rv = pps2->AsyncResolve2(mProxyURI ? mProxyURI : mURI, mProxyResolveFlags,
+        rv = pps2->AsyncResolve2(this, mProxyResolveFlags,
                                  this, getter_AddRefs(mProxyRequest));
     } else {
-        rv = pps->AsyncResolve(mProxyURI ? mProxyURI : mURI, mProxyResolveFlags,
+        rv = pps->AsyncResolve(this, mProxyResolveFlags,
                                this, getter_AddRefs(mProxyRequest));
     }
 
@@ -4707,7 +4707,7 @@ nsHttpChannel::SetPriority(int32_t value)
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
-nsHttpChannel::OnProxyAvailable(nsICancelable *request, nsIURI *uri,
+nsHttpChannel::OnProxyAvailable(nsICancelable *request, nsIChannel *channel,
                                 nsIProxyInfo *pi, nsresult status)
 {
     LOG(("nsHttpChannel::OnProxyAvailable [this=%p pi=%p status=%x mStatus=%x]\n",
diff --git a/netwerk/protocol/http/nsIHttpChannel.idl b/netwerk/protocol/http/nsIHttpChannel.idl
index abb2ee4..24df18b 100644
--- a/netwerk/protocol/http/nsIHttpChannel.idl
+++ b/netwerk/protocol/http/nsIHttpChannel.idl
@@ -56,6 +56,12 @@ interface nsIHttpChannel : nsIChannel
     attribute nsIURI referrer;
 
     /**
+     * Read the proxy URI, which, if non-null, will be used to resolve
+     * proxies for this channel.
+     */
+    readonly attribute nsIURI proxyURI;
+
+    /**
      * Get the value of a particular request header.
      *
      * @param aHeader
diff --git a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
index f92c36e..350c920 100644
--- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
+++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
@@ -115,6 +115,12 @@ nsViewSourceChannel::GetName(nsACString &result)
 }
 
 NS_IMETHODIMP
+nsViewSourceChannel::GetProxyURI(nsIURI** proxyURI)
+{
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
 nsViewSourceChannel::IsPending(bool *result)
 {
     NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
diff --git a/netwerk/protocol/websocket/WebSocketChannel.cpp b/netwerk/protocol/websocket/WebSocketChannel.cpp
index 90f023c..5e14f97 100644
--- a/netwerk/protocol/websocket/WebSocketChannel.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
@@ -2292,7 +2292,7 @@ WebSocketChannel::ApplyForAdmission()
 
   MOZ_ASSERT(!mCancelable);
 
-  return pps->AsyncResolve(mURI,
+  return pps->AsyncResolve(mHttpChannel,
                            nsIProtocolProxyService::RESOLVE_PREFER_HTTPS_PROXY |
                            nsIProtocolProxyService::RESOLVE_ALWAYS_TUNNEL,
                            this, getter_AddRefs(mCancelable));
@@ -2406,7 +2406,7 @@ WebSocketChannel::OnLookupComplete(nsICancelable *aRequest,
 
 // nsIProtocolProxyCallback
 NS_IMETHODIMP
-WebSocketChannel::OnProxyAvailable(nsICancelable *aRequest, nsIURI *aURI,
+WebSocketChannel::OnProxyAvailable(nsICancelable *aRequest, nsIChannel *aChannel,
                                    nsIProxyInfo *pi, nsresult status)
 {
   if (mStopped) {





More information about the tor-commits mailing list