author | Blake Kaplan <mrbkap@gmail.com> |
Tue, 28 Oct 2014 14:23:00 +0100 | |
changeset 239346 | 249b822b256a58be0c6b446188b85dbede247f03 |
parent 239345 | df77d22352254d84b0b4f3a57282651b979cf25f |
child 239347 | 6cd46e671a9da906757a04115d4768ce6e13b124 |
push id | 660 |
push user | raliiev@mozilla.com |
push date | Wed, 18 Feb 2015 20:30:48 +0000 |
treeherder | mozilla-release@49e493494178 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jduell |
bugs | 1049299 |
milestone | 36.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
|
--- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -10373,18 +10373,18 @@ nsDocShell::DoURILoad(nsIURI * aURI, } } //hack nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel)); nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal(do_QueryInterface(channel)); if (httpChannelInternal) { if (aForceAllowCookies) { - httpChannelInternal->SetForceAllowThirdPartyCookie(true); - } + httpChannelInternal->SetThirdPartyFlags(nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW); + } if (aFirstParty) { httpChannelInternal->SetDocumentURI(aURI); } else { httpChannelInternal->SetDocumentURI(aReferrerURI); } } nsCOMPtr<nsIWritablePropertyBag2> props(do_QueryInterface(channel));
--- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp @@ -1088,17 +1088,20 @@ Navigator::SendBeacon(const nsAString& a nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal(do_QueryInterface(channel)); nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil = do_GetService(THIRDPARTYUTIL_CONTRACTID); if (!httpChannelInternal) { aRv.Throw(NS_ERROR_DOM_BAD_URI); return false; } bool isForeign = true; thirdPartyUtil->IsThirdPartyWindow(mWindow, uri, &isForeign); - httpChannelInternal->SetForceAllowThirdPartyCookie(!isForeign); + uint32_t thirdPartyFlags = isForeign ? + 0 : + nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW; + httpChannelInternal->SetThirdPartyFlags(thirdPartyFlags); nsCString mimeType; if (!aData.IsNull()) { nsCOMPtr<nsIInputStream> in; if (aData.Value().IsString()) { nsCString stringData = NS_ConvertUTF16toUTF8(aData.Value().GetAsString()); nsCOMPtr<nsIStringInputStream> strStream = do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID, &rv);
--- a/dom/base/ThirdPartyUtil.cpp +++ b/dom/base/ThirdPartyUtil.cpp @@ -1,8 +1,10 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 sts=2 ts=8 et tw=80 : */ /* This Source Code Form is subject to the terms of the Mozilla Public * 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 "ThirdPartyUtil.h" #include "nsNetUtil.h" #include "nsIServiceManager.h" #include "nsIHttpChannelInternal.h" @@ -161,30 +163,57 @@ ThirdPartyUtil::IsThirdPartyChannel(nsIC nsIURI* aURI, bool* aResult) { NS_ENSURE_ARG(aChannel); NS_ASSERTION(aResult, "null outparam pointer"); nsresult rv; bool doForce = false; + bool checkWindowChain = true; + bool parentIsThird = false; nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal = do_QueryInterface(aChannel); if (httpChannelInternal) { - rv = httpChannelInternal->GetForceAllowThirdPartyCookie(&doForce); + uint32_t flags; + rv = httpChannelInternal->GetThirdPartyFlags(&flags); NS_ENSURE_SUCCESS(rv, rv); + doForce = (flags & nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW); + // If aURI was not supplied, and we're forcing, then we're by definition // not foreign. If aURI was supplied, we still want to check whether it's // foreign with respect to the channel URI. (The forcing only applies to // whatever window hierarchy exists above the channel.) if (doForce && !aURI) { *aResult = false; return NS_OK; } + + if (flags & nsIHttpChannelInternal::THIRD_PARTY_PARENT_IS_THIRD_PARTY) { + // Check that the two PARENT_IS_{THIRD,SAME}_PARTY are mutually exclusive. + MOZ_ASSERT(!(flags & nsIHttpChannelInternal::THIRD_PARTY_PARENT_IS_SAME_PARTY)); + + // If we're not forcing and we know that the window chain of the channel + // is third party, then we know now that we're third party. + if (!doForce) { + *aResult = true; + return NS_OK; + } + + checkWindowChain = false; + parentIsThird = true; + } else { + // In e10s, we can't check the parent chain in the parent, so we do so + // in the child and send the result to the parent. + // Note that we only check the window chain if neither + // THIRD_PARTY_PARENT_IS_* flag is set. + checkWindowChain = !(flags & nsIHttpChannelInternal::THIRD_PARTY_PARENT_IS_SAME_PARTY); + parentIsThird = false; + } } // Obtain the URI from the channel, and its base domain. nsCOMPtr<nsIURI> channelURI; aChannel->GetURI(getter_AddRefs(channelURI)); NS_ENSURE_TRUE(channelURI, NS_ERROR_INVALID_ARG); nsCString channelDomain; @@ -201,16 +230,22 @@ ThirdPartyUtil::IsThirdPartyChannel(nsIC // If it's foreign, or we're forcing, we're done. if (result || doForce) { *aResult = result; return NS_OK; } } + // If we've already computed this in the child process, we're done. + if (!checkWindowChain) { + *aResult = parentIsThird; + return NS_OK; + } + // Find the associated window and its parent window. nsCOMPtr<nsILoadContext> ctx; NS_QueryNotificationCallbacks(aChannel, ctx); if (!ctx) return NS_ERROR_INVALID_ARG; // If there is no window, the consumer kicking off the load didn't provide one // to the channel. This is limited to loads of certain types of resources. If // those loads require cookies, the forceAllowThirdPartyCookie property should
--- a/embedding/components/webbrowserpersist/nsWebBrowserPersist.cpp +++ b/embedding/components/webbrowserpersist/nsWebBrowserPersist.cpp @@ -1231,17 +1231,17 @@ nsresult nsWebBrowserPersist::SaveURIInt } } if (mPersistFlags & PERSIST_FLAGS_FORCE_ALLOW_COOKIES) { nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal = do_QueryInterface(inputChannel); if (httpChannelInternal) - httpChannelInternal->SetForceAllowThirdPartyCookie(true); + httpChannelInternal->SetThirdPartyFlags(nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW); } // Set the referrer, post data and headers if any nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(inputChannel)); if (httpChannel) { // Referrer if (aReferrer)
--- a/netwerk/ipc/NeckoChannelParams.ipdlh +++ b/netwerk/ipc/NeckoChannelParams.ipdlh @@ -37,17 +37,17 @@ struct HttpChannelOpenArgs RequestHeaderTuples requestHeaders; nsCString requestMethod; OptionalInputStreamParams uploadStream; bool uploadStreamHasHeaders; uint16_t priority; uint8_t redirectionLimit; bool allowPipelining; bool allowSTS; - bool forceAllowThirdPartyCookie; + uint32_t thirdPartyFlags; bool resumeAt; uint64_t startPos; nsCString entityID; bool chooseApplicationCache; nsCString appCacheClientID; bool allowSpdy; OptionalFileDescriptorSet fds; PrincipalInfo requestingPrincipalInfo;
--- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -51,17 +51,17 @@ HttpBaseChannel::HttpBaseChannel() , mApplyConversion(true) , mCanceled(false) , mIsPending(false) , mWasOpened(false) , mRequestObserversCalled(false) , mResponseHeadersModified(false) , mAllowPipelining(true) , mAllowSTS(true) - , mForceAllowThirdPartyCookie(false) + , mThirdPartyFlags(0) , mUploadStreamHasHeaders(false) , mInheritApplicationCache(true) , mChooseApplicationCache(false) , mLoadedFromApplicationCache(false) , mChannelIsForDownload(false) , mTracingEnabled(true) , mTimingEnabled(false) , mAllowSpdy(true) @@ -1424,28 +1424,48 @@ HttpBaseChannel::SetCookie(const char *a nsRefPtr<CookieNotifierRunnable> r = new CookieNotifierRunnable(this, aCookieHeader); NS_DispatchToMainThread(r); } return rv; } NS_IMETHODIMP +HttpBaseChannel::GetThirdPartyFlags(uint32_t *aFlags) +{ + *aFlags = mThirdPartyFlags; + return NS_OK; +} + +NS_IMETHODIMP +HttpBaseChannel::SetThirdPartyFlags(uint32_t aFlags) +{ + ENSURE_CALLED_BEFORE_ASYNC_OPEN(); + + mThirdPartyFlags = aFlags; + return NS_OK; +} + +NS_IMETHODIMP HttpBaseChannel::GetForceAllowThirdPartyCookie(bool *aForce) { - *aForce = mForceAllowThirdPartyCookie; + *aForce = !!(mThirdPartyFlags & nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW); return NS_OK; } NS_IMETHODIMP HttpBaseChannel::SetForceAllowThirdPartyCookie(bool aForce) { ENSURE_CALLED_BEFORE_ASYNC_OPEN(); - mForceAllowThirdPartyCookie = aForce; + if (aForce) + mThirdPartyFlags |= nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW; + else + mThirdPartyFlags &= ~nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW; + return NS_OK; } NS_IMETHODIMP HttpBaseChannel::GetCanceled(bool *aCanceled) { *aCanceled = mCanceled; return NS_OK; @@ -2035,19 +2055,18 @@ HttpBaseChannel::SetupReplacementChannel httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"), oldAcceptValue, false); } } nsCOMPtr<nsIHttpChannelInternal> httpInternal = do_QueryInterface(newChannel); if (httpInternal) { - // convey the mForceAllowThirdPartyCookie flag - httpInternal->SetForceAllowThirdPartyCookie(mForceAllowThirdPartyCookie); - // convey the spdy flag + // Convey third party cookie and spdy flags. + httpInternal->SetThirdPartyFlags(mThirdPartyFlags); httpInternal->SetAllowSpdy(mAllowSpdy); // update the DocumentURI indicator since we are being redirected. // if this was a top-level document channel, then the new channel // should have its mDocumentURI point to newURI; otherwise, we // just need to pass along our mDocumentURI to the new channel. if (newURI && (mURI == mDocumentURI)) httpInternal->SetDocumentURI(newURI);
--- a/netwerk/protocol/http/HttpBaseChannel.h +++ b/netwerk/protocol/http/HttpBaseChannel.h @@ -155,16 +155,18 @@ public: NS_IMETHOD RedirectTo(nsIURI *newURI); // nsIHttpChannelInternal NS_IMETHOD GetDocumentURI(nsIURI **aDocumentURI); NS_IMETHOD SetDocumentURI(nsIURI *aDocumentURI); NS_IMETHOD GetRequestVersion(uint32_t *major, uint32_t *minor); NS_IMETHOD GetResponseVersion(uint32_t *major, uint32_t *minor); NS_IMETHOD SetCookie(const char *aCookieHeader); + NS_IMETHOD GetThirdPartyFlags(uint32_t *aForce); + NS_IMETHOD SetThirdPartyFlags(uint32_t aForce); NS_IMETHOD GetForceAllowThirdPartyCookie(bool *aForce); NS_IMETHOD SetForceAllowThirdPartyCookie(bool aForce); NS_IMETHOD GetCanceled(bool *aCanceled); NS_IMETHOD GetChannelIsForDownload(bool *aChannelIsForDownload); NS_IMETHOD SetChannelIsForDownload(bool aChannelIsForDownload); NS_IMETHOD SetCacheKeysRedirectChain(nsTArray<nsCString> *cacheKeys); NS_IMETHOD GetLocalAddress(nsACString& addr); NS_IMETHOD GetLocalPort(int32_t* port); @@ -336,17 +338,17 @@ protected: uint32_t mCanceled : 1; uint32_t mIsPending : 1; uint32_t mWasOpened : 1; // if 1 all "http-on-{opening|modify|etc}-request" observers have been called uint32_t mRequestObserversCalled : 1; uint32_t mResponseHeadersModified : 1; uint32_t mAllowPipelining : 1; uint32_t mAllowSTS : 1; - uint32_t mForceAllowThirdPartyCookie : 1; + uint32_t mThirdPartyFlags : 3; uint32_t mUploadStreamHasHeaders : 1; uint32_t mInheritApplicationCache : 1; uint32_t mChooseApplicationCache : 1; uint32_t mLoadedFromApplicationCache : 1; uint32_t mChannelIsForDownload : 1; uint32_t mTracingEnabled : 1; // True if timing collection is enabled uint32_t mTimingEnabled : 1;
--- a/netwerk/protocol/http/HttpChannelChild.cpp +++ b/netwerk/protocol/http/HttpChannelChild.cpp @@ -26,16 +26,17 @@ #include "mozilla/ipc/URIUtils.h" #include "mozilla/ipc/BackgroundUtils.h" #include "mozilla/net/ChannelDiverterChild.h" #include "mozilla/net/DNS.h" #include "SerializedLoadContext.h" #include "nsInputStreamPump.h" #include "InterceptedChannel.h" #include "nsPerformance.h" +#include "mozIThirdPartyUtil.h" using namespace mozilla::dom; using namespace mozilla::ipc; namespace mozilla { namespace net { //----------------------------------------------------------------------------- @@ -1479,24 +1480,39 @@ HttpChannelChild::ContinueAsyncOpen() OptionalFileDescriptorSet optionalFDs; if (fdSet) { optionalFDs = fdSet; } else { optionalFDs = mozilla::void_t(); } + nsCOMPtr<mozIThirdPartyUtil> util(do_GetService(THIRDPARTYUTIL_CONTRACTID)); + if (util) { + bool thirdParty; + nsresult rv = util->IsThirdPartyChannel(this, nullptr, &thirdParty); + if (NS_FAILED(rv)) { + // If we couldn't compute whether this is a third-party load, assume that + // it is. + thirdParty = true; + } + + mThirdPartyFlags |= thirdParty ? + nsIHttpChannelInternal::THIRD_PARTY_PARENT_IS_THIRD_PARTY : + nsIHttpChannelInternal::THIRD_PARTY_PARENT_IS_SAME_PARTY; + } + openArgs.fds() = optionalFDs; openArgs.uploadStreamHasHeaders() = mUploadStreamHasHeaders; openArgs.priority() = mPriority; openArgs.redirectionLimit() = mRedirectionLimit; openArgs.allowPipelining() = mAllowPipelining; openArgs.allowSTS() = mAllowSTS; - openArgs.forceAllowThirdPartyCookie() = mForceAllowThirdPartyCookie; + openArgs.thirdPartyFlags() = mThirdPartyFlags; openArgs.resumeAt() = mSendResumeAt; openArgs.startPos() = mStartPos; openArgs.entityID() = mEntityID; openArgs.chooseApplicationCache() = mChooseApplicationCache; openArgs.appCacheClientID() = appCacheClientId; openArgs.allowSpdy() = mAllowSpdy; propagateLoadInfo(mLoadInfo, openArgs);
--- a/netwerk/protocol/http/HttpChannelParent.cpp +++ b/netwerk/protocol/http/HttpChannelParent.cpp @@ -96,18 +96,18 @@ HttpChannelParent::Init(const HttpChanne case HttpChannelCreationArgs::THttpChannelOpenArgs: { const HttpChannelOpenArgs& a = aArgs.get_HttpChannelOpenArgs(); return DoAsyncOpen(a.uri(), a.original(), a.doc(), a.referrer(), a.apiRedirectTo(), a.loadFlags(), a.requestHeaders(), a.requestMethod(), a.uploadStream(), a.uploadStreamHasHeaders(), a.priority(), a.redirectionLimit(), a.allowPipelining(), a.allowSTS(), - a.forceAllowThirdPartyCookie(), a.resumeAt(), - a.startPos(), a.entityID(), a.chooseApplicationCache(), + a.thirdPartyFlags(), a.resumeAt(), a.startPos(), + a.entityID(), a.chooseApplicationCache(), a.appCacheClientID(), a.allowSpdy(), a.fds(), a.requestingPrincipalInfo(), a.securityFlags(), a.contentPolicyType()); } case HttpChannelCreationArgs::THttpChannelConnectArgs: { const HttpChannelConnectArgs& cArgs = aArgs.get_HttpChannelConnectArgs(); return ConnectChannel(cArgs.channelId()); @@ -171,22 +171,22 @@ HttpChannelParent::DoAsyncOpen( const U const OptionalURIParams& aOriginalURI, const OptionalURIParams& aDocURI, const OptionalURIParams& aReferrerURI, const OptionalURIParams& aAPIRedirectToURI, const uint32_t& aLoadFlags, const RequestHeaderTuples& requestHeaders, const nsCString& requestMethod, const OptionalInputStreamParams& uploadStream, - const bool& uploadStreamHasHeaders, + const bool& uploadStreamHasHeaders, const uint16_t& priority, const uint8_t& redirectionLimit, - const bool& allowPipelining, - const bool& allowSTS, - const bool& forceAllowThirdPartyCookie, + const bool& allowPipelining, + const bool& allowSTS, + const uint32_t& thirdPartyFlags, const bool& doResumeAt, const uint64_t& startPos, const nsCString& entityID, const bool& chooseApplicationCache, const nsCString& appCacheClientID, const bool& allowSpdy, const OptionalFileDescriptorSet& aFds, const ipc::PrincipalInfo& aRequestingPrincipalInfo, @@ -299,17 +299,17 @@ HttpChannelParent::DoAsyncOpen( const U mChannel->SetUploadStreamHasHeaders(uploadStreamHasHeaders); } if (priority != nsISupportsPriority::PRIORITY_NORMAL) mChannel->SetPriority(priority); mChannel->SetRedirectionLimit(redirectionLimit); mChannel->SetAllowPipelining(allowPipelining); mChannel->SetAllowSTS(allowSTS); - mChannel->SetForceAllowThirdPartyCookie(forceAllowThirdPartyCookie); + mChannel->SetThirdPartyFlags(thirdPartyFlags); mChannel->SetAllowSpdy(allowSpdy); nsCOMPtr<nsIApplicationCacheChannel> appCacheChan = do_QueryObject(mChannel); nsCOMPtr<nsIApplicationCacheService> appCacheService = do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID); bool setChooseApplicationCache = chooseApplicationCache;
--- a/netwerk/protocol/http/HttpChannelParent.h +++ b/netwerk/protocol/http/HttpChannelParent.h @@ -94,17 +94,17 @@ protected: const RequestHeaderTuples& requestHeaders, const nsCString& requestMethod, const OptionalInputStreamParams& uploadStream, const bool& uploadStreamHasHeaders, const uint16_t& priority, const uint8_t& redirectionLimit, const bool& allowPipelining, const bool& allowSTS, - const bool& forceAllowThirdPartyCookie, + const uint32_t& thirdPartyFlags, const bool& doResumeAt, const uint64_t& startPos, const nsCString& entityID, const bool& chooseApplicationCache, const nsCString& appCacheClientID, const bool& allowSpdy, const OptionalFileDescriptorSet& aFds, const ipc::PrincipalInfo& aRequestingPrincipalInfo,
--- a/netwerk/protocol/http/nsIHttpChannelInternal.idl +++ b/netwerk/protocol/http/nsIHttpChannelInternal.idl @@ -33,17 +33,17 @@ interface nsIHttpUpgradeListener : nsISu in nsIAsyncOutputStream aSocketOut); }; /** * Dumping ground for http. This interface will never be frozen. If you are * 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(a95e45c1-b145-487c-b2a9-4e96e814a1b5)] +[scriptable, uuid(2677e555-8c48-4147-b883-5c2a673f65d5)] interface nsIHttpChannelInternal : nsISupports { /** * An http channel can own a reference to the document URI */ attribute nsIURI documentURI; /** @@ -73,18 +73,46 @@ interface nsIHttpChannelInternal : nsISu void setCookie(in string aCookieHeader); /** * Setup this channel as an application cache fallback channel. */ void setupFallbackChannel(in string aFallbackKey); /** - * Force relevant cookies to be sent with this load even if normally they - * wouldn't be. + * This flag is set to force relevant cookies to be sent with this load + * even if normally they wouldn't be. + */ + const unsigned long THIRD_PARTY_FORCE_ALLOW = 1 << 0; + + /** + * This flag is set in the parent if the child has already computed that + * it originates from a 3rd party frame (i.e. a 3rd party iframe). + */ + const unsigned long THIRD_PARTY_PARENT_IS_THIRD_PARTY = 1 << 1; + + /** + * This flag is set in the parent if the child has already computed that + * it is not a 3rd party request due to iframe parentage. However, if + * someone calls mozIThirdPartyUtil::IsThirdPartyChannel with a 3rd-party + * URI, the result would be true if the URI is third-party from this + * channel's URI. + */ + const unsigned long THIRD_PARTY_PARENT_IS_SAME_PARTY = 1 << 2; + + /** + * When set, these flags modify the algorithm used to decide whether to + * send 3rd party cookies for a given channel. + */ + attribute unsigned long thirdPartyFlags; + + /** + * This attribute was added before the "flags" above and is retained here + * for compatibility. When set to true, has the same effect as + * THIRD_PARTY_FORCE_ALLOW, described above. */ attribute boolean forceAllowThirdPartyCookie; /** * True iff the channel has been canceled. */ readonly attribute boolean canceled;