Bug 437174 - Disabling 3rd party cookies breaks sending cookies for
authorMark Smith <mcs@pearlcrescent.com>
Tue, 16 Jun 2009 10:30:25 -0400
changeset 29288 c913f5afe23a64c86a404b26ea3e7a6e5442f7a7
parent 29287 f8b0823d8b845294574e311cd7316673e89a9df4
child 29289 5aa91f894d3ad345625724c2d448a92717179144
push id7544
push usermcs@pearlcrescent.com
push dateWed, 17 Jun 2009 12:48:11 +0000
treeherdermozilla-central@c913f5afe23a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs437174
milestone1.9.2a1pre
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.
browser/base/content/nsContextMenu.js
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
docshell/base/nsIDocShell.idl
docshell/base/nsIWebNavigation.idl
embedding/components/webbrowserpersist/public/nsIWebBrowserPersist.idl
embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp
extensions/cookie/nsCookiePermission.cpp
netwerk/protocol/http/public/nsIHttpChannelInternal.idl
netwerk/protocol/http/src/nsHttpChannel.cpp
netwerk/protocol/http/src/nsHttpChannel.h
toolkit/content/contentAreaUtils.js
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -38,16 +38,18 @@
 #   Joe Hughes <joe@retrovirus.com>
 #   Pamela Greene <pamg.bugs@gmail.com>
 #   Michael Ventnor <ventnors_dogs234@yahoo.com.au>
 #   Simon B├╝nzli <zeniko@gmail.com>
 #   Gijs Kruitbosch <gijskruitbosch@gmail.com>
 #   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
 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
@@ -941,18 +943,21 @@ nsContextMenu.prototype = {
 
     // set up a channel to do the saving
     var ioService = Cc["@mozilla.org/network/io-service;1"].
                     getService(Ci.nsIIOService);
     var channel = ioService.newChannelFromURI(this.getLinkURI());
     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 = 
       gPrefService.getIntPref("browser.download.saveLinkAsFilenameTimeout");
     var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
     timer.initWithCallback(new timerCallback(), timeToWait,
                            timer.TYPE_ONE_SHOT);
 
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -1331,16 +1331,19 @@ nsDocShell::LoadURI(nsIURI * aURI,
         flags |= INTERNAL_LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
 
     if (aLoadFlags & LOAD_FLAGS_FIRST_LOAD)
         flags |= INTERNAL_LOAD_FLAGS_FIRST_LOAD;
 
     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,
                         flags,
                         target.get(),
                         nsnull,         // No type hint
                         postStream,
                         headersStream,
@@ -8013,17 +8016,18 @@ nsDocShell::InternalLoad(nsIURI * aURI,
     }
 
     nsCOMPtr<nsIRequest> req;
     rv = DoURILoad(aURI, aReferrer,
                    !(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER),
                    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);
 
     if (NS_FAILED(rv)) {
         nsCOMPtr<nsIChannel> chan(do_QueryInterface(req));
         DisplayLoadError(rv, aURI, nsnull, chan);
     }
 
@@ -8100,17 +8104,18 @@ nsDocShell::DoURILoad(nsIURI * aURI,
                       nsISupports * aOwner,
                       const char * aTypeHint,
                       nsIInputStream * aPostData,
                       nsIInputStream * aHeadersData,
                       PRBool aFirstParty,
                       nsIDocShell ** aDocShell,
                       nsIRequest ** aRequest,
                       PRBool aIsNewWindowTarget,
-                      PRBool aBypassClassifier)
+                      PRBool aBypassClassifier,
+                      PRBool aForceAllowCookies)
 {
     nsresult rv;
     nsCOMPtr<nsIURILoader> uriLoader;
 
     uriLoader = do_GetService(NS_URI_LOADER_CONTRACTID, &rv);
     if (NS_FAILED(rv)) return rv;
 
     nsLoadFlags loadFlags = nsIRequest::LOAD_NORMAL;
@@ -8174,16 +8179,19 @@ nsDocShell::DoURILoad(nsIURI * aURI,
     else {
         mContentTypeHint.Truncate();
     }
     
     //hack
     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 {
         httpChannelInternal->SetDocumentURI(aReferrerURI);
       }
     }
 
     nsCOMPtr<nsIWritablePropertyBag2> props(do_QueryInterface(channel));
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -342,17 +342,18 @@ protected:
                                nsISupports * aOwner,
                                const char * aTypeHint,
                                nsIInputStream * aPostData,
                                nsIInputStream * aHeadersData,
                                PRBool firstParty,
                                nsIDocShell ** aDocShell,
                                nsIRequest ** aRequest,
                                PRBool aIsNewWindowTarget,
-                               PRBool aBypassClassifier);
+                               PRBool aBypassClassifier,
+                               PRBool aForceAllowCookies);
     NS_IMETHOD AddHeadersToChannel(nsIInputStream * aHeadersData, 
                                   nsIChannel * aChannel);
     virtual nsresult DoChannelLoad(nsIChannel * aChannel,
                                    nsIURILoader * aURILoader,
                                    PRBool aBypassClassifier);
 
     // Check the channel load against the URI classifier service (if it
     // exists).  The channel will be suspended until the classification is
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -126,16 +126,17 @@ interface nsIDocShell : nsISupports
   const long INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER      = 0x2;
   const long INTERNAL_LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP = 0x4;
 
   // This flag marks the first load in this object
   // @see nsIWebNavigation::LOAD_FLAGS_FIRST_LOAD
   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
    * that its parameter list is broken out instead of being packaged inside
    * of an nsIDocShellLoadInfo object...
    *
    * @param aURI            - The URI to load.
    * @param aReferrer       - Referring URI
--- a/docshell/base/nsIWebNavigation.idl
+++ b/docshell/base/nsIWebNavigation.idl
@@ -206,16 +206,22 @@ interface nsIWebNavigation : nsISupports
 
   /**
    * This flag specifies that the URI classifier should not be checked for
    * this load.  This flag must not be passed to Reload.
    */
   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
    * however, the URI dispatcher will go through its normal process of content
    * loading.
    *
    * @param aURI
    *        The URI string to load.  For HTTP and FTP URLs and possibly others,
    *        characters above U+007F will be converted to UTF-8 and then URL-
--- a/embedding/components/webbrowserpersist/public/nsIWebBrowserPersist.idl
+++ b/embedding/components/webbrowserpersist/public/nsIWebBrowserPersist.idl
@@ -95,16 +95,21 @@ interface nsIWebBrowserPersist : nsICanc
    */
   const unsigned long PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION = 16384;
   /**
    * Append the downloaded data to the target file.
    * This can only be used when persisting to a local file.
    */
   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. 
    * It is best to set this value explicitly unless you are prepared
    * to accept the default values.
    */
   attribute unsigned long persistFlags;
     
--- a/embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp
+++ b/embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp
@@ -47,16 +47,17 @@
 #endif
 
 #include "nsNetUtil.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIComponentRegistrar.h"
 #include "nsIStorageStream.h"
 #include "nsISeekableStream.h"
 #include "nsIHttpChannel.h"
+#include "nsIHttpChannelInternal.h"
 #include "nsIEncodedChannel.h"
 #include "nsIUploadChannel.h"
 #include "nsICachingChannel.h"
 #include "nsEscape.h"
 #include "nsUnicharUtils.h"
 #include "nsIStringEnumerator.h"
 #include "nsCRT.h"
 #include "nsSupportsArray.h"
@@ -1257,16 +1258,24 @@ nsresult nsWebBrowserPersist::SaveURIInt
     {
         nsCOMPtr<nsIEncodedChannel> encodedChannel(do_QueryInterface(inputChannel));
         if (encodedChannel)
         {
             encodedChannel->SetApplyConversion(PR_FALSE);
         }
     }
 
+    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)
     {
         // Referrer
         if (aReferrer)
         {
             httpChannel->SetReferrer(aReferrer);
--- a/extensions/cookie/nsCookiePermission.cpp
+++ b/extensions/cookie/nsCookiePermission.cpp
@@ -19,16 +19,18 @@
  * Michiel van Leeuwen (mvl@exedo.nl).
  * Portions created by the Initial Developer are Copyright (C) 2003
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   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
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -48,16 +50,17 @@
 #include "nsNetUtil.h"
 #include "nsIURI.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsIPrefBranch2.h"
 #include "nsIDocShell.h"
 #include "nsIWebNavigation.h"
 #include "nsIChannel.h"
+#include "nsIHttpChannelInternal.h"
 #include "nsIDOMWindow.h"
 #include "nsIDOMDocument.h"
 #include "nsIPrincipal.h"
 #include "nsString.h"
 #include "nsCRT.h"
 #include "nsILoadContext.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsNetCID.h"
@@ -423,52 +426,71 @@ nsCookiePermission::GetOriginatingURI(ns
                                       nsIURI     **aURI)
 {
   /* to find the originating URI, we use the loadgroup of the channel to obtain
    * the window owning the load, and from there, we find the top same-type
    * window and its URI. there are several possible cases:
    *
    * 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.
    */
 
   *aURI = nsnull;
 
   // case 1)
   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);
   nsCOMPtr<nsIDOMWindow> topWin, ourWin;
   if (ctx) {
     ctx->GetTopWindow(getter_AddRefs(topWin));
     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
     // hopefully flag these channels better later.
     nsLoadFlags flags;
     aChannel->GetLoadFlags(&flags);
 
     if (flags & nsIChannel::LOAD_DOCUMENT_URI) {
@@ -476,17 +498,17 @@ nsCookiePermission::GetOriginatingURI(ns
       aChannel->GetURI(aURI);
       if (!*aURI)
         return NS_ERROR_NULL_POINTER;
 
       return NS_OK;
     }
   }
 
-  // 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);
 
   nsIPrincipal* prin = scriptObjPrin->GetPrincipal();
   NS_ENSURE_TRUE(prin, NS_ERROR_UNEXPECTED);
   
   prin->GetURI(aURI);
 
--- a/netwerk/protocol/http/public/nsIHttpChannelInternal.idl
+++ b/netwerk/protocol/http/public/nsIHttpChannelInternal.idl
@@ -40,17 +40,17 @@
 interface nsIURI;
 interface nsIProxyInfo;
 
 /** 
  * 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(3ce040fb-3933-462a-8d62-80b78fbd0809)]
+[scriptable, uuid(0eb66361-faaa-4e52-8c7e-6c25f11f8e3c)]
 interface nsIHttpChannelInternal : nsISupports
 {
     /**
      * An http channel can own a reference to the document URI
      */
     attribute nsIURI documentURI;
 
     /**
@@ -73,9 +73,14 @@ 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.
+     */
+    attribute boolean forceAllowThirdPartyCookie;
 };
--- a/netwerk/protocol/http/src/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/src/nsHttpChannel.cpp
@@ -130,16 +130,17 @@ nsHttpChannel::nsHttpChannel()
     , mInitedCacheEntry(PR_FALSE)
     , mCacheForOfflineUse(PR_FALSE)
     , mCachingOpportunistically(PR_FALSE)
     , mFallbackChannel(PR_FALSE)
     , mInheritApplicationCache(PR_TRUE)
     , mChooseApplicationCache(PR_FALSE)
     , mLoadedFromApplicationCache(PR_FALSE)
     , mTracingEnabled(PR_TRUE)
+    , mForceAllowThirdPartyCookie(PR_FALSE)
 {
     LOG(("Creating nsHttpChannel @%x\n", this));
 
     // grab a reference to the handler to ensure that it doesn't go away.
     nsHttpHandler *handler = gHttpHandler;
     NS_ADDREF(handler);
 }
 
@@ -4723,16 +4724,30 @@ nsHttpChannel::GetDocumentURI(nsIURI **a
 NS_IMETHODIMP
 nsHttpChannel::SetDocumentURI(nsIURI *aDocumentURI)
 {
     mDocumentURI = 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)
 {
   int version = mRequestHead.Version();
 
   if (major) { *major = version / 10; }
   if (minor) { *minor = version % 10; }
 
   return NS_OK;
--- a/netwerk/protocol/http/src/nsHttpChannel.h
+++ b/netwerk/protocol/http/src/nsHttpChannel.h
@@ -338,16 +338,17 @@ private:
     PRUint32                          mCachingOpportunistically : 1;
     // True if we are loading a fallback cache entry from the
     // application cache.
     PRUint32                          mFallbackChannel          : 1;
     PRUint32                          mInheritApplicationCache  : 1;
     PRUint32                          mChooseApplicationCache   : 1;
     PRUint32                          mLoadedFromApplicationCache : 1;
     PRUint32                          mTracingEnabled           : 1;
+    PRUint32                          mForceAllowThirdPartyCookie : 1;
 
     class nsContentEncodings : public nsIUTF8StringEnumerator
     {
     public:
         NS_DECL_ISUPPORTS
         NS_DECL_NSIUTF8STRINGENUMERATOR
 
         nsContentEncodings(nsIHttpChannel* aChannel, const char* aEncodingHeader);
--- a/toolkit/content/contentAreaUtils.js
+++ b/toolkit/content/contentAreaUtils.js
@@ -19,16 +19,18 @@
 # Portions created by the Initial Developer are Copyright (C) 1998
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
 #   Ben Goodger <ben@netscape.com> (Save File)
 #   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
 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
@@ -386,17 +388,18 @@ function internalSave(aURL, aDocument, a
  *        If true, the document will always be refetched from the server
  */
 function internalPersist(persistArgs)
 {
   var persist = makeWebBrowserPersist();
 
   // 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
     persist.persistFlags = flags | nsIWBP.PERSIST_FLAGS_FROM_CACHE;
 
   // Leave it to WebBrowserPersist to discover the encoding type (or lack thereof):
   persist.persistFlags |= nsIWBP.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;