Bug 437174 - Disabling 3rd party cookies breaks sending cookies for

channels with no docshell.  r+sr=bzbarsky.
  Added forceAllowThirdPartyCookie to nsIHttpChannelInternal.
  Added LOAD_FLAGS_FORCE_ALLOW_COOKIES to nsIWebNavigation.
  Added PERSIST_FLAGS_FORCE_ALLOW_COOKIES to nsIWebBrowserPersist.

--HG--
extra : rebase_source : 0ea11e1ed53d75152f57ffed74f44fc749a7a567
This commit is contained in:
Mark Smith 2009-06-16 10:30:25 -04:00
parent b4d60fb950
commit bb426c0819
12 changed files with 93 additions and 12 deletions

View File

@ -43,6 +43,8 @@
# Ehsan Akhgari <ehsan.akhgari@gmail.com>
# Dan Mosedale <dmose@mozilla.org>
# Justin Dolske <dolske@mozilla.com>
# Kathleen Brade <brade@pearlcrescent.com>
# Mark Smith <mcs@pearlcrescent.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
@ -946,8 +948,11 @@ nsContextMenu.prototype = {
channel.notificationCallbacks = new callbacks();
channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE |
Ci.nsIChannel.LOAD_CALL_CONTENT_SNIFFERS;
if (channel instanceof Ci.nsIHttpChannel)
if (channel instanceof Ci.nsIHttpChannel) {
channel.referrer = doc.documentURIObject;
if (channel instanceof Ci.nsIHttpChannelInternal)
channel.forceAllowThirdPartyCookie = true;
}
// fallback to the old way if we don't see the headers quickly
var timeToWait =

View File

@ -1336,6 +1336,9 @@ nsDocShell::LoadURI(nsIURI * aURI,
if (aLoadFlags & LOAD_FLAGS_BYPASS_CLASSIFIER)
flags |= INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER;
if (aLoadFlags & LOAD_FLAGS_FORCE_ALLOW_COOKIES)
flags |= INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES;
return InternalLoad(aURI,
referrer,
owner,
@ -8018,7 +8021,8 @@ nsDocShell::InternalLoad(nsIURI * aURI,
owner, aTypeHint, aPostData, aHeadersData, aFirstParty,
aDocShell, getter_AddRefs(req),
(aFlags & INTERNAL_LOAD_FLAGS_FIRST_LOAD) != 0,
(aFlags & INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER) != 0);
(aFlags & INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER) != 0,
(aFlags & INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES) != 0);
if (req && aRequest)
NS_ADDREF(*aRequest = req);
@ -8105,7 +8109,8 @@ nsDocShell::DoURILoad(nsIURI * aURI,
nsIDocShell ** aDocShell,
nsIRequest ** aRequest,
PRBool aIsNewWindowTarget,
PRBool aBypassClassifier)
PRBool aBypassClassifier,
PRBool aForceAllowCookies)
{
nsresult rv;
nsCOMPtr<nsIURILoader> uriLoader;
@ -8179,6 +8184,9 @@ nsDocShell::DoURILoad(nsIURI * aURI,
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal(do_QueryInterface(channel));
if (httpChannelInternal) {
if (aForceAllowCookies) {
httpChannelInternal->SetForceAllowThirdPartyCookie(PR_TRUE);
}
if (aFirstParty) {
httpChannelInternal->SetDocumentURI(aURI);
} else {

View File

@ -347,7 +347,8 @@ protected:
nsIDocShell ** aDocShell,
nsIRequest ** aRequest,
PRBool aIsNewWindowTarget,
PRBool aBypassClassifier);
PRBool aBypassClassifier,
PRBool aForceAllowCookies);
NS_IMETHOD AddHeadersToChannel(nsIInputStream * aHeadersData,
nsIChannel * aChannel);
virtual nsresult DoChannelLoad(nsIChannel * aChannel,

View File

@ -131,6 +131,7 @@ interface nsIDocShell : nsISupports
const long INTERNAL_LOAD_FLAGS_FIRST_LOAD = 0x8;
const long INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER = 0x10;
const long INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES = 0x20;
/**
* Loads the given URI. This method is identical to loadURI(...) except

View File

@ -210,6 +210,12 @@ interface nsIWebNavigation : nsISupports
*/
const unsigned long LOAD_FLAGS_BYPASS_CLASSIFIER = 0x10000;
/**
* Force relevant cookies to be sent with this load even if normally they
* wouldn't be.
*/
const unsigned long LOAD_FLAGS_FORCE_ALLOW_COOKIES = 0x20000;
/**
* Loads a given URI. This will give priority to loading the requested URI
* in the object implementing this interface. If it can't be loaded here

View File

@ -100,6 +100,11 @@ interface nsIWebBrowserPersist : nsICancelable
*/
const unsigned long PERSIST_FLAGS_APPEND_TO_FILE = 32768;
/**
* Force relevant cookies to be sent with this load even if normally they
* wouldn't be.
*/
const unsigned long PERSIST_FLAGS_FORCE_ALLOW_COOKIES = 65536;
/**
* Flags governing how data is fetched and saved from the network.

View File

@ -52,6 +52,7 @@
#include "nsIStorageStream.h"
#include "nsISeekableStream.h"
#include "nsIHttpChannel.h"
#include "nsIHttpChannelInternal.h"
#include "nsIEncodedChannel.h"
#include "nsIUploadChannel.h"
#include "nsICachingChannel.h"
@ -1262,6 +1263,14 @@ nsresult nsWebBrowserPersist::SaveURIInternal(
}
}
if (mPersistFlags & PERSIST_FLAGS_FORCE_ALLOW_COOKIES)
{
nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal =
do_QueryInterface(inputChannel);
if (httpChannelInternal)
httpChannelInternal->SetForceAllowThirdPartyCookie(PR_TRUE);
}
// Set the referrer, post data and headers if any
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(inputChannel));
if (httpChannel)

View File

@ -24,6 +24,8 @@
* Darin Fisher <darin@meer.net>
* Daniel Witte <dwitte@stanford.edu>
* Ehsan Akhgari <ehsan.akhgari@gmail.com>
* Kathleen Brade <brade@pearlcrescent.com>
* Mark Smith <mcs@pearlcrescent.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -53,6 +55,7 @@
#include "nsIDocShell.h"
#include "nsIWebNavigation.h"
#include "nsIChannel.h"
#include "nsIHttpChannelInternal.h"
#include "nsIDOMWindow.h"
#include "nsIDOMDocument.h"
#include "nsIPrincipal.h"
@ -428,17 +431,20 @@ nsCookiePermission::GetOriginatingURI(nsIChannel *aChannel,
*
* 1) no channel.
*
* 2) a channel, but no window. this can occur when the consumer kicking
* 2) a channel with the "force allow third party cookies" option set.
* since we may not have a window, we return the channel URI in this case.
*
* 3) a channel, but no window. this can occur when the consumer kicking
* off the load doesn't provide one to the channel, and should be limited
* to loads of certain types of resources.
*
* 3) a window equal to the top window of same type, with the channel its
* 4) a window equal to the top window of same type, with the channel its
* document channel. this covers the case of a freshly kicked-off load
* (e.g. the user typing something in the location bar, or clicking on a
* bookmark), where the window's URI hasn't yet been set, and will be
* bogus. we return the channel URI in this case.
*
* 4) Anything else. this covers most cases for an ordinary page load from
* 5) Anything else. this covers most cases for an ordinary page load from
* the location bar, and will catch nested frames within a page, image
* loads, etc. we return the URI of the root window's document's principal
* in this case.
@ -450,6 +456,22 @@ nsCookiePermission::GetOriginatingURI(nsIChannel *aChannel,
if (!aChannel)
return NS_ERROR_NULL_POINTER;
// case 2)
nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal = do_QueryInterface(aChannel);
if (httpChannelInternal)
{
PRBool doForce = PR_FALSE;
if (NS_SUCCEEDED(httpChannelInternal->GetForceAllowThirdPartyCookie(&doForce)) && doForce)
{
// return the channel's URI (we may not have a window)
aChannel->GetURI(aURI);
if (!*aURI)
return NS_ERROR_NULL_POINTER;
return NS_OK;
}
}
// find the associated window and its top window
nsCOMPtr<nsILoadContext> ctx;
NS_QueryNotificationCallbacks(aChannel, ctx);
@ -459,11 +481,11 @@ nsCookiePermission::GetOriginatingURI(nsIChannel *aChannel,
ctx->GetAssociatedWindow(getter_AddRefs(ourWin));
}
// case 2)
// case 3)
if (!topWin)
return NS_ERROR_INVALID_ARG;
// case 3)
// case 4)
if (ourWin == topWin) {
// Check whether this is the document channel for this window (representing
// a load of a new page). This is a bit of a nasty hack, but we will
@ -481,7 +503,7 @@ nsCookiePermission::GetOriginatingURI(nsIChannel *aChannel,
}
}
// case 4) - get the originating URI from the top window's principal
// case 5) - get the originating URI from the top window's principal
nsCOMPtr<nsIScriptObjectPrincipal> scriptObjPrin = do_QueryInterface(topWin);
NS_ENSURE_TRUE(scriptObjPrin, NS_ERROR_UNEXPECTED);

View File

@ -45,7 +45,7 @@ interface nsIProxyInfo;
* 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(3ce040fb-3933-462a-8d62-80b78fbd0809)]
[scriptable, uuid(0eb66361-faaa-4e52-8c7e-6c25f11f8e3c)]
interface nsIHttpChannelInternal : nsISupports
{
/**
@ -78,4 +78,9 @@ interface nsIHttpChannelInternal : nsISupports
*/
void setupFallbackChannel(in string aFallbackKey);
/**
* Force relevant cookies to be sent with this load even if normally they
* wouldn't be.
*/
attribute boolean forceAllowThirdPartyCookie;
};

View File

@ -135,6 +135,7 @@ nsHttpChannel::nsHttpChannel()
, mChooseApplicationCache(PR_FALSE)
, mLoadedFromApplicationCache(PR_FALSE)
, mTracingEnabled(PR_TRUE)
, mForceAllowThirdPartyCookie(PR_FALSE)
{
LOG(("Creating nsHttpChannel @%x\n", this));
@ -4727,6 +4728,20 @@ nsHttpChannel::SetDocumentURI(nsIURI *aDocumentURI)
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::GetForceAllowThirdPartyCookie(PRBool *aForceAllowThirdPartyCookie)
{
*aForceAllowThirdPartyCookie = mForceAllowThirdPartyCookie;
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::SetForceAllowThirdPartyCookie(PRBool aForceAllowThirdPartyCookie)
{
mForceAllowThirdPartyCookie = aForceAllowThirdPartyCookie;
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::GetRequestVersion(PRUint32 *major, PRUint32 *minor)
{

View File

@ -343,6 +343,7 @@ private:
PRUint32 mChooseApplicationCache : 1;
PRUint32 mLoadedFromApplicationCache : 1;
PRUint32 mTracingEnabled : 1;
PRUint32 mForceAllowThirdPartyCookie : 1;
class nsContentEncodings : public nsIUTF8StringEnumerator
{

View File

@ -24,6 +24,8 @@
# Fredrik Holmqvist <thesuckiestemail@yahoo.se>
# Asaf Romano <mozilla.mano@sent.com>
# Ehsan Akhgari <ehsan.akhgari@gmail.com>
# Kathleen Brade <brade@pearlcrescent.com>
# Mark Smith <mcs@pearlcrescent.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
@ -391,7 +393,8 @@ function internalPersist(persistArgs)
// Calculate persist flags.
const nsIWBP = Components.interfaces.nsIWebBrowserPersist;
const flags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
const flags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
nsIWBP.PERSIST_FLAGS_FORCE_ALLOW_COOKIES;
if (persistArgs.bypassCache)
persist.persistFlags = flags | nsIWBP.PERSIST_FLAGS_BYPASS_CACHE;
else