commit be96c4f788ab616d94457bcc4dd1d098b156d62c Author: Arthur Edelstein arthuredelstein@gmail.com Date: Mon Jun 6 00:56:09 2016 -0700
Bug 16998: Isolate link rel=preconnect to first party --- dom/base/nsDocument.cpp | 8 +++++-- netwerk/base/nsIOService.cpp | 41 +++++++++++++++++++++++++++++---- netwerk/base/nsIOService.h | 1 + netwerk/base/nsISpeculativeConnect.idl | 11 ++++++++- netwerk/ipc/NeckoParent.cpp | 7 +++--- netwerk/ipc/NeckoParent.h | 3 ++- netwerk/ipc/PNecko.ipdl | 2 +- netwerk/protocol/http/nsHttpHandler.cpp | 27 ++++++++++++++++++---- netwerk/protocol/http/nsHttpHandler.h | 1 + 9 files changed, 84 insertions(+), 17 deletions(-)
diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 586e199..e7077a9 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -246,6 +246,8 @@
#include "nsISpeculativeConnect.h"
+#include "ThirdPartyUtil.h" + #ifdef MOZ_MEDIA_NAVIGATOR #include "mozilla/MediaManager.h" #endif // MOZ_MEDIA_NAVIGATOR @@ -9733,10 +9735,12 @@ nsDocument::MaybePreconnect(nsIURI* aOrigURI, mozilla::CORSMode aCORSMode) return; }
+ nsCString firstPartyHost; + ThirdPartyUtil::GetFirstPartyHost(this, firstPartyHost); if (aCORSMode == CORS_ANONYMOUS) { - speculator->SpeculativeAnonymousConnect(uri, nullptr); + speculator->SpeculativeAnonymousConnectIsolated(uri, firstPartyHost, nullptr); } else { - speculator->SpeculativeConnect(uri, nullptr); + speculator->SpeculativeConnectIsolated(uri, firstPartyHost, nullptr); } }
diff --git a/netwerk/base/nsIOService.cpp b/netwerk/base/nsIOService.cpp index ad86c95..a864d0e 100644 --- a/netwerk/base/nsIOService.cpp +++ b/netwerk/base/nsIOService.cpp @@ -51,6 +51,7 @@ #include "ClosingService.h" #include "ReferrerPolicy.h" #include "nsContentSecurityManager.h" +#include "ThirdPartyUtil.h"
#ifdef MOZ_WIDGET_GONK #include "nsINetworkManager.h" @@ -1822,10 +1823,14 @@ IOServiceProxyCallback::OnProxyAvailable(nsICancelable *request, nsIChannel *cha
nsLoadFlags loadFlags = 0; channel->GetLoadFlags(&loadFlags); + + nsCString firstPartyHost; + ThirdPartyUtil::GetFirstPartyHost(channel, firstPartyHost); + if (loadFlags & nsIRequest::LOAD_ANONYMOUS) { - speculativeHandler->SpeculativeAnonymousConnect(uri, mCallbacks); + speculativeHandler->SpeculativeAnonymousConnectIsolated(uri, firstPartyHost, mCallbacks); } else { - speculativeHandler->SpeculativeConnect(uri, mCallbacks); + speculativeHandler->SpeculativeConnectIsolated(uri, firstPartyHost, mCallbacks); }
return NS_OK; @@ -1833,6 +1838,7 @@ IOServiceProxyCallback::OnProxyAvailable(nsICancelable *request, nsIChannel *cha
nsresult nsIOService::SpeculativeConnectInternal(nsIURI *aURI, + const nsACString& aIsolationKey, nsIInterfaceRequestor *aCallbacks, bool aAnonymous) { @@ -1867,6 +1873,17 @@ nsIOService::SpeculativeConnectInternal(nsIURI *aURI, getter_AddRefs(channel)); NS_ENSURE_SUCCESS(rv, rv);
+ // If we have an isolation key, use it as the document URI for this channel. + if (!aIsolationKey.IsEmpty()) { + nsCOMPtr<nsIHttpChannelInternal> channelInternal(do_QueryInterface(channel)); + if (channelInternal) { + nsCString documentURISpec("https://"); + documentURISpec.Append(aIsolationKey); + nsCOMPtr<nsIURI> documentURI; + /* nsresult rv = */ NS_NewURI(getter_AddRefs(documentURI), documentURISpec); + channelInternal->SetDocumentURI(documentURI); + } + } if (aAnonymous) { nsLoadFlags loadFlags = 0; channel->GetLoadFlags(&loadFlags); @@ -1885,17 +1902,33 @@ nsIOService::SpeculativeConnectInternal(nsIURI *aURI, }
NS_IMETHODIMP +nsIOService::SpeculativeConnectIsolated(nsIURI *aURI, + const nsACString& aIsolationKey, + nsIInterfaceRequestor *aCallbacks) +{ + return SpeculativeConnectInternal(aURI, aIsolationKey, aCallbacks, false); +} + +NS_IMETHODIMP nsIOService::SpeculativeConnect(nsIURI *aURI, nsIInterfaceRequestor *aCallbacks) { - return SpeculativeConnectInternal(aURI, aCallbacks, false); + return SpeculativeConnectInternal(aURI, EmptyCString(), aCallbacks, false); +} + +NS_IMETHODIMP +nsIOService::SpeculativeAnonymousConnectIsolated(nsIURI *aURI, + const nsACString& aIsolationKey, + nsIInterfaceRequestor *aCallbacks) +{ + return SpeculativeConnectInternal(aURI, aIsolationKey, aCallbacks, true); }
NS_IMETHODIMP nsIOService::SpeculativeAnonymousConnect(nsIURI *aURI, nsIInterfaceRequestor *aCallbacks) { - return SpeculativeConnectInternal(aURI, aCallbacks, true); + return SpeculativeConnectInternal(aURI, EmptyCString(), aCallbacks, true); }
void diff --git a/netwerk/base/nsIOService.h b/netwerk/base/nsIOService.h index e948ffd..308cee7 100644 --- a/netwerk/base/nsIOService.h +++ b/netwerk/base/nsIOService.h @@ -133,6 +133,7 @@ private: nsIChannel** result);
nsresult SpeculativeConnectInternal(nsIURI *aURI, + const nsACString& aIsolationKey, nsIInterfaceRequestor *aCallbacks, bool aAnonymous);
diff --git a/netwerk/base/nsISpeculativeConnect.idl b/netwerk/base/nsISpeculativeConnect.idl index 15d63e1..eed9570 100644 --- a/netwerk/base/nsISpeculativeConnect.idl +++ b/netwerk/base/nsISpeculativeConnect.idl @@ -8,7 +8,7 @@ interface nsIURI; interface nsIInterfaceRequestor;
-[scriptable, uuid(d74a17ac-5b8a-4824-a309-b1f04a3c4aed)] +[scriptable, uuid(60cf321d-9f09-403a-b8b6-db221e6ca3a1)] interface nsISpeculativeConnect : nsISupports { /** @@ -21,6 +21,7 @@ interface nsISpeculativeConnect : nsISupports * to actually open the new channel. * * @param aURI the URI of the hinted transaction + * @param aIsolationKey the isolation key for the connection * @param aCallbacks any security callbacks for use with SSL for interfaces * such as nsIBadCertListener. May be null. * @@ -30,6 +31,14 @@ interface nsISpeculativeConnect : nsISupports
void speculativeAnonymousConnect(in nsIURI aURI, in nsIInterfaceRequestor aCallbacks); + + void speculativeConnectIsolated(in nsIURI aURI, + in AUTF8String aIsolationKey, + in nsIInterfaceRequestor aCallbacks); + + void speculativeAnonymousConnectIsolated(in nsIURI aURI, + in AUTF8String aIsolationKey, + in nsIInterfaceRequestor aCallbacks); };
/** diff --git a/netwerk/ipc/NeckoParent.cpp b/netwerk/ipc/NeckoParent.cpp index 796e78f..fa4911b 100644 --- a/netwerk/ipc/NeckoParent.cpp +++ b/netwerk/ipc/NeckoParent.cpp @@ -728,15 +728,16 @@ NeckoParent::DeallocPRemoteOpenFileParent(PRemoteOpenFileParent* actor) }
bool -NeckoParent::RecvSpeculativeConnect(const URIParams& aURI, const bool& aAnonymous) +NeckoParent::RecvSpeculativeConnect(const URIParams& aURI, const bool& aAnonymous, + const nsCString& aIsolationKey) { nsCOMPtr<nsISpeculativeConnect> speculator(gIOService); nsCOMPtr<nsIURI> uri = DeserializeURI(aURI); if (uri && speculator) { if (aAnonymous) { - speculator->SpeculativeAnonymousConnect(uri, nullptr); + speculator->SpeculativeAnonymousConnectIsolated(uri, aIsolationKey, nullptr); } else { - speculator->SpeculativeConnect(uri, nullptr); + speculator->SpeculativeConnectIsolated(uri, aIsolationKey, nullptr); }
} diff --git a/netwerk/ipc/NeckoParent.h b/netwerk/ipc/NeckoParent.h index 508ab6f..900328c 100644 --- a/netwerk/ipc/NeckoParent.h +++ b/netwerk/ipc/NeckoParent.h @@ -167,7 +167,8 @@ protected: const uint32_t& flags, const nsCString& aNetworkInterface) override; virtual bool DeallocPDNSRequestParent(PDNSRequestParent*) override; - virtual bool RecvSpeculativeConnect(const URIParams& aURI, const bool& aAnonymous) override; + virtual bool RecvSpeculativeConnect(const URIParams& aURI, const bool& aAnonymous, + const nsCString& aFirstPartyHost) override; virtual bool RecvHTMLDNSPrefetch(const nsString& hostname, const uint16_t& flags) override; virtual bool RecvCancelHTMLDNSPrefetch(const nsString& hostname, diff --git a/netwerk/ipc/PNecko.ipdl b/netwerk/ipc/PNecko.ipdl index 2e1f2f5..0d0c7f8 100644 --- a/netwerk/ipc/PNecko.ipdl +++ b/netwerk/ipc/PNecko.ipdl @@ -89,7 +89,7 @@ parent: URIParams fileuri, OptionalURIParams appuri);
- SpeculativeConnect(URIParams uri, bool anonymous); + SpeculativeConnect(URIParams uri, bool anonymous, nsCString isolationKey); HTMLDNSPrefetch(nsString hostname, uint16_t flags); CancelHTMLDNSPrefetch(nsString hostname, uint16_t flags, nsresult reason);
diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp index e425c22..97461fe 100644 --- a/netwerk/protocol/http/nsHttpHandler.cpp +++ b/netwerk/protocol/http/nsHttpHandler.cpp @@ -2126,13 +2126,15 @@ nsHttpHandler::Observe(nsISupports *subject,
nsresult nsHttpHandler::SpeculativeConnectInternal(nsIURI *aURI, + const nsACString& aIsolationKey, nsIInterfaceRequestor *aCallbacks, bool anonymous) { + nsCString isolationKey(aIsolationKey); if (IsNeckoChild()) { ipc::URIParams params; SerializeURI(aURI, params); - gNeckoChild->SendSpeculativeConnect(params, anonymous); + gNeckoChild->SendSpeculativeConnect(params, anonymous, isolationKey); return NS_OK; }
@@ -2205,26 +2207,41 @@ nsHttpHandler::SpeculativeConnectInternal(nsIURI *aURI, nsAutoCString username; aURI->GetUsername(username);
- // TODO: Fix isolation for speculative connect. nsHttpConnectionInfo *ci = - new nsHttpConnectionInfo(host, port, EmptyCString(), username, nullptr, EmptyCString(), usingSSL); + new nsHttpConnectionInfo(host, port, EmptyCString(), username, nullptr, aIsolationKey, usingSSL); ci->SetAnonymous(anonymous);
return SpeculativeConnect(ci, aCallbacks); }
NS_IMETHODIMP +nsHttpHandler::SpeculativeConnectIsolated(nsIURI *aURI, + const nsACString& aIsolationKey, + nsIInterfaceRequestor *aCallbacks) +{ + return SpeculativeConnectInternal(aURI, aIsolationKey, aCallbacks, false); +} + +NS_IMETHODIMP nsHttpHandler::SpeculativeConnect(nsIURI *aURI, nsIInterfaceRequestor *aCallbacks) { - return SpeculativeConnectInternal(aURI, aCallbacks, false); + return SpeculativeConnectInternal(aURI, EmptyCString(), aCallbacks, false); +} + +NS_IMETHODIMP +nsHttpHandler::SpeculativeAnonymousConnectIsolated(nsIURI *aURI, + const nsACString& aIsolationKey, + nsIInterfaceRequestor *aCallbacks) +{ + return SpeculativeConnectInternal(aURI, aIsolationKey, aCallbacks, true); }
NS_IMETHODIMP nsHttpHandler::SpeculativeAnonymousConnect(nsIURI *aURI, nsIInterfaceRequestor *aCallbacks) { - return SpeculativeConnectInternal(aURI, aCallbacks, true); + return SpeculativeConnectInternal(aURI, EmptyCString(), aCallbacks, true); }
void diff --git a/netwerk/protocol/http/nsHttpHandler.h b/netwerk/protocol/http/nsHttpHandler.h index 1205dad..cf15775 100644 --- a/netwerk/protocol/http/nsHttpHandler.h +++ b/netwerk/protocol/http/nsHttpHandler.h @@ -596,6 +596,7 @@ private:
private: nsresult SpeculativeConnectInternal(nsIURI *aURI, + const nsACString& aIsolationKey, nsIInterfaceRequestor *aCallbacks, bool anonymous); };