commit be96c4f788ab616d94457bcc4dd1d098b156d62c
Author: Arthur Edelstein <arthuredelstein(a)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);
};