Bug 1088183: Propagate the top window URI to the parent http channel through HttpChannelOpenArgs (a=kwierso,r=jduell,mrbkap)

This commit is contained in:
Monica Chew 2014-10-29 17:22:22 -07:00
parent 89bf044895
commit 8ab9fc8100
11 changed files with 95 additions and 13 deletions

View File

@ -12,10 +12,19 @@
#include "nsILoadContext.h"
#include "nsIPrincipal.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsIURI.h"
#include "nsThreadUtils.h"
#include "prlog.h"
NS_IMPL_ISUPPORTS(ThirdPartyUtil, mozIThirdPartyUtil)
//
// NSPR_LOG_MODULES=thirdPartyUtil:5
//
static PRLogModuleInfo *gThirdPartyLog;
#undef LOG
#define LOG(args) PR_LOG(gThirdPartyLog, PR_LOG_DEBUG, args)
nsresult
ThirdPartyUtil::Init()
{
@ -23,6 +32,10 @@ ThirdPartyUtil::Init()
nsresult rv;
mTLDService = do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv);
if (!gThirdPartyLog)
gThirdPartyLog = PR_NewLogModule("thirdPartyUtil");
return rv;
}
@ -62,7 +75,11 @@ ThirdPartyUtil::GetURIFromWindow(nsIDOMWindow* aWin, nsIURI** result)
return NS_ERROR_INVALID_ARG;
}
nsCOMPtr<nsIURI> uri;
if (prin->GetIsNullPrincipal()) {
LOG(("ThirdPartyUtil::GetURIFromWindow can't use null principal\n"));
return NS_ERROR_INVALID_ARG;
}
rv = prin->GetURI(result);
return rv;
}

View File

@ -14,6 +14,7 @@
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsIDOMWindow.h"
#include "nsIHttpChannelInternal.h"
#include "nsIIOService.h"
#include "nsIPermissionManager.h"
#include "nsIProtocolHandler.h"
@ -76,20 +77,24 @@ nsChannelClassifier::ShouldEnableTrackingProtection(nsIChannel *aChannel,
return NS_OK;
}
nsCOMPtr<nsIDOMWindow> win;
rv = thirdPartyUtil->GetTopWindowForChannel(aChannel, getter_AddRefs(win));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> uri;
rv = thirdPartyUtil->GetURIFromWindow(win, getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIIOService> ios = do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIHttpChannelInternal> chan = do_QueryInterface(aChannel, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> uri;
rv = chan->GetTopWindowURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
if (!uri) {
LOG(("nsChannelClassifier[%p]: No window URI\n", this));
}
const char ALLOWLIST_EXAMPLE_PREF[] = "channelclassifier.allowlist_example";
if (!uri && Preferences::GetBool(ALLOWLIST_EXAMPLE_PREF, false)) {
LOG(("nsChannelClassifier[%p]: Allowlisting test domain", this));
LOG(("nsChannelClassifier[%p]: Allowlisting test domain\n", this));
rv = ios->NewURI(NS_LITERAL_CSTRING("http://allowlisted.example.com"),
nullptr, nullptr, getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
@ -141,7 +146,13 @@ nsChannelClassifier::ShouldEnableTrackingProtection(nsIChannel *aChannel,
}
// Tracking protection will be disabled so update the security state
// of the document and fire a secure change event.
// of the document and fire a secure change event. If we can't get the
// window for the channel, then the shield won't show up so we can't send
// and event to the securityUI anyway.
nsCOMPtr<nsIDOMWindow> win;
rv = thirdPartyUtil->GetTopWindowForChannel(aChannel, getter_AddRefs(win));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsPIDOMWindow> pwin = do_QueryInterface(win, &rv);
NS_ENSURE_SUCCESS(rv, NS_OK);
nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell();

View File

@ -33,6 +33,7 @@ struct HttpChannelOpenArgs
OptionalURIParams doc;
OptionalURIParams referrer;
OptionalURIParams apiRedirectTo;
OptionalURIParams topWindowURI;
uint32_t loadFlags;
RequestHeaderTuples requestHeaders;
nsCString requestMethod;

View File

@ -35,6 +35,7 @@
#include "nsPIDOMWindow.h"
#include "nsPerformance.h"
#include "nsINetworkInterceptController.h"
#include "mozIThirdPartyUtil.h"
#include <algorithm>
@ -1331,6 +1332,36 @@ HttpBaseChannel::RedirectTo(nsIURI *newURI)
// HttpBaseChannel::nsIHttpChannelInternal
//-----------------------------------------------------------------------------
NS_IMETHODIMP
HttpBaseChannel::GetTopWindowURI(nsIURI **aTopWindowURI)
{
nsresult rv = NS_OK;
nsCOMPtr<mozIThirdPartyUtil> util;
// Only compute the top window URI once. In e10s, this must be computed in the
// child. The parent gets the top window URI through HttpChannelOpenArgs.
if (!mTopWindowURI) {
util = do_GetService(THIRDPARTYUTIL_CONTRACTID);
if (!util) {
return NS_ERROR_NOT_AVAILABLE;
}
nsCOMPtr<nsIDOMWindow> win;
nsresult rv = util->GetTopWindowForChannel(this, getter_AddRefs(win));
if (NS_SUCCEEDED(rv)) {
rv = util->GetURIFromWindow(win, getter_AddRefs(mTopWindowURI));
#if DEBUG
if (mTopWindowURI) {
nsCString spec;
rv = mTopWindowURI->GetSpec(spec);
LOG(("HttpChannelBase::Setting topwindow URI spec %s [this=%p]\n",
spec.get(), this));
}
#endif
}
}
NS_IF_ADDREF(*aTopWindowURI = mTopWindowURI);
return rv;
}
NS_IMETHODIMP
HttpBaseChannel::GetDocumentURI(nsIURI **aDocumentURI)
{

View File

@ -187,6 +187,7 @@ public:
NS_IMETHOD ForcePending(bool aForcePending);
NS_IMETHOD GetLastModifiedTime(PRTime* lastModifiedTime);
NS_IMETHOD ForceNoIntercept();
NS_IMETHOD GetTopWindowURI(nsIURI **aTopWindowURI);
inline void CleanRedirectCacheChainIfNecessary()
{
@ -407,6 +408,7 @@ protected:
nsCOMPtr<nsIPrincipal> mPrincipal;
bool mForcePending;
nsCOMPtr<nsIURI> mTopWindowURI;
};
// Share some code while working around C++'s absurd inability to handle casting

View File

@ -1493,8 +1493,12 @@ HttpChannelChild::ContinueAsyncOpen()
mThirdPartyFlags |= thirdParty ?
nsIHttpChannelInternal::THIRD_PARTY_PARENT_IS_THIRD_PARTY :
nsIHttpChannelInternal::THIRD_PARTY_PARENT_IS_SAME_PARTY;
nsCOMPtr<nsIURI> uri;
GetTopWindowURI(getter_AddRefs(uri));
}
SerializeURI(mTopWindowURI, openArgs.topWindowURI());
openArgs.fds() = optionalFDs;
openArgs.uploadStreamHasHeaders() = mUploadStreamHasHeaders;

View File

@ -97,7 +97,8 @@ HttpChannelParent::Init(const HttpChannelCreationArgs& aArgs)
{
const HttpChannelOpenArgs& a = aArgs.get_HttpChannelOpenArgs();
return DoAsyncOpen(a.uri(), a.original(), a.doc(), a.referrer(),
a.apiRedirectTo(), a.loadFlags(), a.requestHeaders(),
a.apiRedirectTo(), a.topWindowURI(),
a.loadFlags(), a.requestHeaders(),
a.requestMethod(), a.uploadStream(),
a.uploadStreamHasHeaders(), a.priority(),
a.redirectionLimit(), a.allowPipelining(), a.allowSTS(),
@ -172,6 +173,7 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
const OptionalURIParams& aDocURI,
const OptionalURIParams& aReferrerURI,
const OptionalURIParams& aAPIRedirectToURI,
const OptionalURIParams& aTopWindowURI,
const uint32_t& aLoadFlags,
const RequestHeaderTuples& requestHeaders,
const nsCString& requestMethod,
@ -203,6 +205,7 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
nsCOMPtr<nsIURI> docUri = DeserializeURI(aDocURI);
nsCOMPtr<nsIURI> referrerUri = DeserializeURI(aReferrerURI);
nsCOMPtr<nsIURI> apiRedirectToUri = DeserializeURI(aAPIRedirectToURI);
nsCOMPtr<nsIURI> topWindowUri = DeserializeURI(aTopWindowURI);
nsCString uriSpec;
uri->GetSpec(uriSpec);
@ -266,6 +269,8 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
mChannel->SetReferrerInternal(referrerUri);
if (apiRedirectToUri)
mChannel->RedirectTo(apiRedirectToUri);
if (topWindowUri)
mChannel->SetTopWindowURI(topWindowUri);
if (loadFlags != nsIRequest::LOAD_NORMAL)
mChannel->SetLoadFlags(loadFlags);

View File

@ -91,6 +91,7 @@ protected:
const OptionalURIParams& docUri,
const OptionalURIParams& referrerUri,
const OptionalURIParams& internalRedirectUri,
const OptionalURIParams& topWindowUri,
const uint32_t& loadFlags,
const RequestHeaderTuples& requestHeaders,
const nsCString& requestMethod,

View File

@ -4958,7 +4958,7 @@ nsHttpChannel::SetupFallbackChannel(const char *aFallbackKey)
{
ENSURE_CALLED_BEFORE_CONNECT();
LOG(("nsHttpChannel::SetupFallbackChannel [this=%p, key=%s]",
LOG(("nsHttpChannel::SetupFallbackChannel [this=%p, key=%s]\n",
this, aFallbackKey));
mFallbackChannel = true;
mFallbackKey = aFallbackKey;

View File

@ -151,6 +151,11 @@ public: /* internal necko use only */
return NS_OK;
}
nsresult SetTopWindowURI(nsIURI* aTopWindowURI) {
mTopWindowURI = aTopWindowURI;
return NS_OK;
}
nsresult OpenCacheEntry(bool usingSSL);
nsresult ContinueConnect();

View File

@ -38,7 +38,7 @@ interface nsIHttpUpgradeListener : nsISupports
* using any feature exposed by this interface, be aware that this interface
* will change and you will be broken. You have been warned.
*/
[scriptable, uuid(2677e555-8c48-4147-b883-5c2a673f65d5)]
[scriptable, uuid(62a8d6e2-3418-4c6f-9d90-88573838f6dd)]
interface nsIHttpChannelInternal : nsISupports
{
/**
@ -235,4 +235,9 @@ interface nsIHttpChannelInternal : nsISupports
* interception and proceed immediately to the network/cache.
*/
void forceNoIntercept();
/**
* The URI of the top-level window that's associated with this channel.
*/
readonly attribute nsIURI topWindowURI;
};