Bug 1162243 - add anonymous speculative connections r=hurley
authorPatrick McManus <mcmanus@ducksong.com>
Tue, 05 May 2015 21:15:36 -0400
changeset 242896 3c8a74e0291d62da8d5a6017baa5eed33addb3a8
parent 242895 7b11fc3efb145d63e7d2ab7931a0f0282ae54063
child 242897 534fd8feaf8ff9b1c2365eef442c5819f2e006d9
push id28713
push userkwierso@gmail.com
push dateFri, 08 May 2015 17:06:43 +0000
treeherdermozilla-central@fd5e9b7eec13 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershurley
bugs1162243
milestone40.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 1162243 - add anonymous speculative connections r=hurley
netwerk/base/nsIOService.cpp
netwerk/base/nsIOService.h
netwerk/base/nsISpeculativeConnect.idl
netwerk/ipc/NeckoParent.cpp
netwerk/ipc/NeckoParent.h
netwerk/ipc/PNecko.ipdl
netwerk/protocol/http/nsHttpHandler.cpp
netwerk/protocol/http/nsHttpHandler.h
--- a/netwerk/base/nsIOService.cpp
+++ b/netwerk/base/nsIOService.cpp
@@ -1635,24 +1635,31 @@ IOServiceProxyCallback::OnProxyAvailable
     if (NS_FAILED(rv))
         return NS_OK;
 
     nsCOMPtr<nsISpeculativeConnect> speculativeHandler =
         do_QueryInterface(handler);
     if (!speculativeHandler)
         return NS_OK;
 
-    speculativeHandler->SpeculativeConnect(uri,
-                                           mCallbacks);
+    nsLoadFlags loadFlags = 0;
+    channel->GetLoadFlags(&loadFlags);
+    if (loadFlags & nsIRequest::LOAD_ANONYMOUS) {
+        speculativeHandler->SpeculativeAnonymousConnect(uri, mCallbacks);
+    } else {
+        speculativeHandler->SpeculativeConnect(uri, mCallbacks);
+    }
+
     return NS_OK;
 }
 
-NS_IMETHODIMP
-nsIOService::SpeculativeConnect(nsIURI *aURI,
-                                nsIInterfaceRequestor *aCallbacks)
+nsresult
+nsIOService::SpeculativeConnectInternal(nsIURI *aURI,
+                                        nsIInterfaceRequestor *aCallbacks,
+                                        bool aAnonymous)
 {
     // Check for proxy information. If there is a proxy configured then a
     // speculative connect should not be performed because the potential
     // reward is slim with tcp peers closely located to the browser.
     nsresult rv;
     nsCOMPtr<nsIProtocolProxyService> pps =
             do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -1673,29 +1680,49 @@ nsIOService::SpeculativeConnect(nsIURI *
     nsCOMPtr<nsIChannel> channel;
     rv = NewChannelFromURI2(aURI,
                             nullptr, // aLoadingNode,
                             systemPrincipal,
                             nullptr, //aTriggeringPrincipal,
                             nsILoadInfo::SEC_NORMAL,
                             nsIContentPolicy::TYPE_OTHER,
                             getter_AddRefs(channel));
+    NS_ENSURE_SUCCESS(rv, rv);
 
-    NS_ENSURE_SUCCESS(rv, rv);
+    if (aAnonymous) {
+        nsLoadFlags loadFlags = 0;
+        channel->GetLoadFlags(&loadFlags);
+        loadFlags |= nsIRequest::LOAD_ANONYMOUS;
+        channel->SetLoadFlags(loadFlags);
+    }
 
     nsCOMPtr<nsICancelable> cancelable;
     nsRefPtr<IOServiceProxyCallback> callback =
         new IOServiceProxyCallback(aCallbacks, this);
     nsCOMPtr<nsIProtocolProxyService2> pps2 = do_QueryInterface(pps);
     if (pps2) {
         return pps2->AsyncResolve2(channel, 0, callback, getter_AddRefs(cancelable));
     }
     return pps->AsyncResolve(channel, 0, callback, getter_AddRefs(cancelable));
 }
 
+NS_IMETHODIMP
+nsIOService::SpeculativeConnect(nsIURI *aURI,
+                                nsIInterfaceRequestor *aCallbacks)
+{
+    return SpeculativeConnectInternal(aURI, aCallbacks, false);
+}
+
+NS_IMETHODIMP
+nsIOService::SpeculativeAnonymousConnect(nsIURI *aURI,
+                                         nsIInterfaceRequestor *aCallbacks)
+{
+    return SpeculativeConnectInternal(aURI, aCallbacks, true);
+}
+
 void
 nsIOService::NotifyAppOfflineStatus(uint32_t appId, int32_t state)
 {
     MOZ_RELEASE_ASSERT(NS_IsMainThread(),
             "Should be called on the main thread");
 
     nsCOMPtr<nsIObserverService> observerService =
         mozilla::services::GetObserverService();
--- a/netwerk/base/nsIOService.h
+++ b/netwerk/base/nsIOService.h
@@ -117,16 +117,21 @@ private:
     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);
+
+    nsresult SpeculativeConnectInternal(nsIURI *aURI,
+                                        nsIInterfaceRequestor *aCallbacks,
+                                        bool aAnonymous);
+
 private:
     bool                                 mOffline;
     bool                                 mOfflineForProfileChange;
     bool                                 mManageLinkStatus;
     bool                                 mConnectivity;
     // If true, the connectivity state will be mirrored by IOService.offline
     // meaning if !mConnectivity, GetOffline() will return true
     bool                                 mOfflineMirrorsConnectivity;
--- a/netwerk/base/nsISpeculativeConnect.idl
+++ b/netwerk/base/nsISpeculativeConnect.idl
@@ -3,17 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 interface nsIURI;
 interface nsIInterfaceRequestor;
 
-[scriptable, uuid(fa580a8d-f4a4-47c5-8ade-4f9786e8d1de)]
+[scriptable, uuid(d74a17ac-5b8a-4824-a309-b1f04a3c4aed)]
 interface nsISpeculativeConnect : nsISupports
 {
     /**
      * Called as a hint to indicate a new transaction for the URI is likely coming
      * soon. The implementer may use this information to start a TCP
      * and/or SSL level handshake for that resource immediately so that it is
      * ready and/or progressed when the transaction is actually submitted.
      *
@@ -23,16 +23,18 @@ interface nsISpeculativeConnect : nsISup
      * @param aURI the URI of the hinted transaction
      * @param aCallbacks any security callbacks for use with SSL for interfaces
      *        such as nsIBadCertListener. May be null.
      *
      */
     void speculativeConnect(in nsIURI aURI,
                             in nsIInterfaceRequestor aCallbacks);
 
+    void speculativeAnonymousConnect(in nsIURI aURI,
+                                     in nsIInterfaceRequestor aCallbacks);
 };
 
 /**
  * This is used to override the default values for various values (documented
  * inline) to determine whether or not to actually make a speculative
  * connection.
  */
 [builtinclass, uuid(f6a0d1e5-369f-4abc-81ae-d370d36e4006)]
--- a/netwerk/ipc/NeckoParent.cpp
+++ b/netwerk/ipc/NeckoParent.cpp
@@ -691,22 +691,27 @@ NeckoParent::RecvPRemoteOpenFileConstruc
 bool
 NeckoParent::DeallocPRemoteOpenFileParent(PRemoteOpenFileParent* actor)
 {
   delete actor;
   return true;
 }
 
 bool
-NeckoParent::RecvSpeculativeConnect(const URIParams &aURI)
+NeckoParent::RecvSpeculativeConnect(const URIParams& aURI, const bool& aAnonymous)
 {
   nsCOMPtr<nsISpeculativeConnect> speculator(gIOService);
   nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
   if (uri && speculator) {
-    speculator->SpeculativeConnect(uri, nullptr);
+    if (aAnonymous) {
+      speculator->SpeculativeAnonymousConnect(uri, nullptr);
+    } else {
+      speculator->SpeculativeConnect(uri, nullptr);
+    }
+
   }
   return true;
 }
 
 bool
 NeckoParent::RecvHTMLDNSPrefetch(const nsString& hostname,
                                  const uint16_t& flags)
 {
--- a/netwerk/ipc/NeckoParent.h
+++ b/netwerk/ipc/NeckoParent.h
@@ -158,17 +158,17 @@ protected:
   virtual PDNSRequestParent* AllocPDNSRequestParent(const nsCString& aHost,
                                                     const uint32_t& aFlags,
                                                     const nsCString& aNetworkInterface) override;
   virtual bool RecvPDNSRequestConstructor(PDNSRequestParent* actor,
                                           const nsCString& hostName,
                                           const uint32_t& flags,
                                           const nsCString& aNetworkInterface) override;
   virtual bool DeallocPDNSRequestParent(PDNSRequestParent*) override;
-  virtual bool RecvSpeculativeConnect(const URIParams& aURI) override;
+  virtual bool RecvSpeculativeConnect(const URIParams& aURI, const bool& aAnonymous) override;
   virtual bool RecvHTMLDNSPrefetch(const nsString& hostname,
                                    const uint16_t& flags) override;
   virtual bool RecvCancelHTMLDNSPrefetch(const nsString& hostname,
                                          const uint16_t& flags,
                                          const nsresult& reason) override;
 
   virtual mozilla::ipc::IProtocol*
   CloneProtocol(Channel* aChannel,
--- a/netwerk/ipc/PNecko.ipdl
+++ b/netwerk/ipc/PNecko.ipdl
@@ -71,17 +71,17 @@ parent:
   PUDPSocket(Principal principal, nsCString filter);
 
   PDNSRequest(nsCString hostName, uint32_t flags, nsCString networkInterface);
 
   PRemoteOpenFile(SerializedLoadContext loadContext,
                   URIParams fileuri,
                   OptionalURIParams appuri);
 
-  SpeculativeConnect(URIParams uri);
+  SpeculativeConnect(URIParams uri, bool anonymous);
   HTMLDNSPrefetch(nsString hostname, uint16_t flags);
   CancelHTMLDNSPrefetch(nsString hostname, uint16_t flags, nsresult reason);
 
   /**
    * channelId is used to establish a connection between redirect channels in
    * the parent and the child when we're redirecting to a data: URI.
    */
   PDataChannel(uint32_t channelId);
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -2017,24 +2017,25 @@ nsHttpHandler::Observe(nsISupports *subj
         }
     }
 
     return NS_OK;
 }
 
 // nsISpeculativeConnect
 
-NS_IMETHODIMP
-nsHttpHandler::SpeculativeConnect(nsIURI *aURI,
-                                  nsIInterfaceRequestor *aCallbacks)
+nsresult
+nsHttpHandler::SpeculativeConnectInternal(nsIURI *aURI,
+                                          nsIInterfaceRequestor *aCallbacks,
+                                          bool anonymous)
 {
     if (IsNeckoChild()) {
         ipc::URIParams params;
         SerializeURI(aURI, params);
-        gNeckoChild->SendSpeculativeConnect(params);
+        gNeckoChild->SendSpeculativeConnect(params, anonymous);
         return NS_OK;
     }
 
     if (!mHandlerActive)
         return NS_OK;
 
     nsISiteSecurityService* sss = gHttpHandler->GetSSService();
     bool isStsHost = false;
@@ -2087,20 +2088,35 @@ nsHttpHandler::SpeculativeConnect(nsIURI
     if (NS_FAILED(rv))
         return rv;
 
     nsAutoCString username;
     aURI->GetUsername(username);
 
     nsHttpConnectionInfo *ci =
         new nsHttpConnectionInfo(host, port, EmptyCString(), username, nullptr, usingSSL);
+    ci->SetAnonymous(anonymous);
 
     return SpeculativeConnect(ci, aCallbacks);
 }
 
+NS_IMETHODIMP
+nsHttpHandler::SpeculativeConnect(nsIURI *aURI,
+                                  nsIInterfaceRequestor *aCallbacks)
+{
+    return SpeculativeConnectInternal(aURI, aCallbacks, false);
+}
+
+NS_IMETHODIMP
+nsHttpHandler::SpeculativeAnonymousConnect(nsIURI *aURI,
+                                           nsIInterfaceRequestor *aCallbacks)
+{
+    return SpeculativeConnectInternal(aURI, aCallbacks, true);
+}
+
 void
 nsHttpHandler::TickleWifi(nsIInterfaceRequestor *cb)
 {
     if (!cb || !mWifiTickler)
         return;
 
     // If B2G requires a similar mechanism nsINetworkManager, currently only avail
     // on B2G, contains the necessary information on wifi and gateway
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -560,16 +560,21 @@ public:
     void SetRequestTokenBucket(EventTokenBucket *aTokenBucket)
     {
         mRequestTokenBucket = aTokenBucket;
     }
 
 private:
     nsRefPtr<Tickler> mWifiTickler;
     void TickleWifi(nsIInterfaceRequestor *cb);
+
+private:
+    nsresult SpeculativeConnectInternal(nsIURI *aURI,
+                                        nsIInterfaceRequestor *aCallbacks,
+                                        bool anonymous);
 };
 
 extern nsHttpHandler *gHttpHandler;
 
 //-----------------------------------------------------------------------------
 // nsHttpsHandler - thin wrapper to distinguish the HTTP handler from the
 //                  HTTPS handler (even though they share the same impl).
 //-----------------------------------------------------------------------------