--- a/extensions/cookie/nsCookieModule.cpp
+++ b/extensions/cookie/nsCookieModule.cpp
@@ -44,17 +44,17 @@
#include "nsICategoryManager.h"
#include "nsCookiePromptService.h"
#include "nsCookiePermission.h"
#include "nsXPIDLString.h"
// Define the constructor function for the objects
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPermissionManager, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPopupWindowManager, Init)
-NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsCookiePermission, Init)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsCookiePermission)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsCookiePromptService)
// The list of components we register
static const nsModuleComponentInfo components[] = {
{ "PermissionManager",
NS_PERMISSIONMANAGER_CID,
NS_PERMISSIONMANAGER_CONTRACTID,
nsPermissionManagerConstructor
--- a/extensions/cookie/nsCookiePermission.cpp
+++ b/extensions/cookie/nsCookiePermission.cpp
@@ -106,22 +106,25 @@ IsFromMailNews(nsIURI *aURI)
return PR_FALSE;
}
#endif
NS_IMPL_ISUPPORTS2(nsCookiePermission,
nsICookiePermission,
nsIObserver)
-nsresult
+bool
nsCookiePermission::Init()
{
+ // Initialize nsIPermissionManager and fetch relevant prefs. This is only
+ // required for some methods on nsICookiePermission, so it should be done
+ // lazily.
nsresult rv;
mPermMgr = do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv);
- if (NS_FAILED(rv)) return rv;
+ if (NS_FAILED(rv)) return false;
// failure to access the pref service is non-fatal...
nsCOMPtr<nsIPrefBranch2> prefBranch =
do_GetService(NS_PREFSERVICE_CONTRACTID);
if (prefBranch) {
prefBranch->AddObserver(kCookiesLifetimePolicy, this, PR_FALSE);
prefBranch->AddObserver(kCookiesLifetimeDays, this, PR_FALSE);
prefBranch->AddObserver(kCookiesAlwaysAcceptSession, this, PR_FALSE);
@@ -150,17 +153,17 @@ nsCookiePermission::Init()
prefBranch->SetIntPref(kCookiesLifetimePolicy, ACCEPT_FOR_N_DAYS);
else
prefBranch->SetIntPref(kCookiesLifetimePolicy, ACCEPT_SESSION);
}
prefBranch->SetBoolPref(kCookiesPrefsMigrated, PR_TRUE);
}
}
- return NS_OK;
+ return true;
}
void
nsCookiePermission::PrefChanged(nsIPrefBranch *aPrefBranch,
const char *aPref)
{
PRInt32 val;
@@ -179,16 +182,20 @@ nsCookiePermission::PrefChanged(nsIPrefB
NS_SUCCEEDED(aPrefBranch->GetBoolPref(kCookiesAlwaysAcceptSession, &val)))
mCookiesAlwaysAcceptSession = val;
}
NS_IMETHODIMP
nsCookiePermission::SetAccess(nsIURI *aURI,
nsCookieAccess aAccess)
{
+ // Lazily initialize ourselves
+ if (!EnsureInitialized())
+ return NS_ERROR_UNEXPECTED;
+
//
// NOTE: nsCookieAccess values conveniently match up with
// the permission codes used by nsIPermissionManager.
// this is nice because it avoids conversion code.
//
return mPermMgr->Add(aURI, kPermissionType, aAccess,
nsIPermissionManager::EXPIRE_NEVER, 0);
}
@@ -201,17 +208,21 @@ nsCookiePermission::CanAccess(nsIURI
#ifdef MOZ_MAIL_NEWS
// If this URI is a mailnews one (e.g. imap etc), don't allow cookies for
// it.
if (IsFromMailNews(aURI)) {
*aResult = ACCESS_DENY;
return NS_OK;
}
#endif // MOZ_MAIL_NEWS
-
+
+ // Lazily initialize ourselves
+ if (!EnsureInitialized())
+ return NS_ERROR_UNEXPECTED;
+
// finally, check with permission manager...
nsresult rv = mPermMgr->TestPermission(aURI, kPermissionType, (PRUint32 *) aResult);
if (NS_SUCCEEDED(rv)) {
switch (*aResult) {
// if we have one of the publicly-available values, just return it
case nsIPermissionManager::UNKNOWN_ACTION: // ACCESS_DEFAULT
case nsIPermissionManager::ALLOW_ACTION: // ACCESS_ALLOW
case nsIPermissionManager::DENY_ACTION: // ACCESS_DENY
@@ -239,16 +250,20 @@ nsCookiePermission::CanSetCookie(nsIURI
PRBool *aIsSession,
PRInt64 *aExpiry,
PRBool *aResult)
{
NS_ASSERTION(aURI, "null uri");
*aResult = kDefaultPolicy;
+ // Lazily initialize ourselves
+ if (!EnsureInitialized())
+ return NS_ERROR_UNEXPECTED;
+
PRUint32 perm;
mPermMgr->TestPermission(aURI, kPermissionType, &perm);
switch (perm) {
case nsICookiePermission::ACCESS_SESSION:
*aIsSession = PR_TRUE;
case nsIPermissionManager::ALLOW_ACTION: // ACCESS_ALLOW
*aResult = PR_TRUE;
@@ -502,17 +517,17 @@ nsCookiePermission::Observe(nsISupports
NS_ASSERTION(!nsCRT::strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic),
"unexpected topic - we only deal with pref changes!");
if (prefBranch)
PrefChanged(prefBranch, NS_LossyConvertUTF16toASCII(aData).get());
return NS_OK;
}
-PRBool
+bool
nsCookiePermission::InPrivateBrowsing()
{
PRBool inPrivateBrowsingMode = PR_FALSE;
if (!mPBService)
mPBService = do_GetService(NS_PRIVATE_BROWSING_SERVICE_CONTRACTID);
if (mPBService)
mPBService->GetPrivateBrowsingEnabled(&inPrivateBrowsingMode);
return inPrivateBrowsingMode;
--- a/extensions/cookie/nsCookiePermission.h
+++ b/extensions/cookie/nsCookiePermission.h
@@ -57,21 +57,22 @@ public:
nsCookiePermission()
: mCookiesLifetimeSec(LL_MAXINT)
, mCookiesLifetimePolicy(0) // ACCEPT_NORMALLY
, mCookiesAlwaysAcceptSession(PR_FALSE)
{}
virtual ~nsCookiePermission() {}
- nsresult Init();
- void PrefChanged(nsIPrefBranch *, const char *);
+ bool Init();
+ void PrefChanged(nsIPrefBranch *, const char *);
private:
- PRBool InPrivateBrowsing();
+ bool EnsureInitialized() { return mPermMgr != NULL || Init(); };
+ bool InPrivateBrowsing();
nsCOMPtr<nsIPermissionManager> mPermMgr;
nsCOMPtr<nsIPrivateBrowsingService> mPBService;
PRInt64 mCookiesLifetimeSec; // lifetime limit specified in seconds
PRUint8 mCookiesLifetimePolicy; // pref for how long cookies are stored
PRPackedBool mCookiesAlwaysAcceptSession; // don't prompt for session cookies
};
--- a/ipc/ipdl/Makefile.in
+++ b/ipc/ipdl/Makefile.in
@@ -53,16 +53,17 @@ EXPORT_LIBRARY = 1
##-----------------------------------------------------------------------------
## When you add IPDL files to a source directory, list the directory here.
##
IPDLDIRS = \
dom/plugins \
dom/ipc \
netwerk/ipc \
netwerk/protocol/http/src \
+ netwerk/cookie/src \
ipc/ipdl/test/cxx \
ipc/testshell \
js/src/ipc \
$(NULL)
##-----------------------------------------------------------------------------
ifdef MOZ_IPDL_TESTS
DIRS += test
--- a/netwerk/build/nsNetModule.cpp
+++ b/netwerk/build/nsNetModule.cpp
@@ -170,20 +170,20 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsDirInde
#include "nsStreamListenerTee.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsStreamListenerTee)
///////////////////////////////////////////////////////////////////////////////
#ifdef NECKO_COOKIES
#include "nsCookieService.h"
-NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsCookieService, nsCookieService::GetSingleton)
+NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsICookieService,
+ nsCookieService::GetXPCOMSingleton)
#endif
-
///////////////////////////////////////////////////////////////////////////////
#ifdef NECKO_WIFI
#include "nsWifiMonitor.h"
#undef LOG
#undef LOG_ENABLED
NS_GENERIC_FACTORY_CONSTRUCTOR(nsWifiMonitor)
@@ -1106,23 +1106,23 @@ static const nsModuleComponentInfo gNetM
nsApplicationCacheNamespaceConstructor
},
#endif
#ifdef NECKO_COOKIES
{ NS_COOKIEMANAGER_CLASSNAME,
NS_COOKIEMANAGER_CID,
NS_COOKIEMANAGER_CONTRACTID,
- nsCookieServiceConstructor
+ nsICookieServiceConstructor
},
{ NS_COOKIESERVICE_CLASSNAME,
NS_COOKIESERVICE_CID,
NS_COOKIESERVICE_CONTRACTID,
- nsCookieServiceConstructor
+ nsICookieServiceConstructor
},
#endif
#ifdef NECKO_WIFI
{
NS_WIFI_MONITOR_CLASSNAME,
NS_WIFI_MONITOR_COMPONENT_CID,
NS_WIFI_MONITOR_CONTRACTID,
new file mode 100644
--- /dev/null
+++ b/netwerk/cookie/src/CookieServiceChild.cpp
@@ -0,0 +1,203 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation <http://www.mozilla.org/>.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Daniel Witte <dwitte@mozilla.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
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "mozilla/net/CookieServiceChild.h"
+#include "mozilla/net/NeckoChild.h"
+#include "nsIURI.h"
+
+namespace mozilla {
+namespace net {
+
+static CookieServiceChild *gCookieService;
+
+CookieServiceChild*
+CookieServiceChild::GetSingleton()
+{
+ if (!gCookieService)
+ gCookieService = new CookieServiceChild();
+
+ NS_ADDREF(gCookieService);
+ return gCookieService;
+}
+
+NS_IMPL_ISUPPORTS1(CookieServiceChild, nsICookieService)
+
+CookieServiceChild::CookieServiceChild()
+{
+ NS_ASSERTION(IsNeckoChild(), "not a child process");
+
+ // This corresponds to Release() in DeallocPCookieService.
+ NS_ADDREF_THIS();
+
+ // Create a child PCookieService actor.
+ NeckoChild::InitNeckoChild();
+ gNeckoChild->SendPCookieServiceConstructor(this);
+
+ mPermissionService = do_GetService(NS_COOKIEPERMISSION_CONTRACTID);
+ if (!mPermissionService)
+ NS_WARNING("couldn't get nsICookiePermission in child");
+}
+
+CookieServiceChild::~CookieServiceChild()
+{
+ gCookieService = nsnull;
+}
+
+void
+CookieServiceChild::SerializeURIs(nsIURI *aHostURI,
+ nsIChannel *aChannel,
+ nsCString &aHostSpec,
+ nsCString &aHostCharset,
+ nsCString &aOriginatingSpec,
+ nsCString &aOriginatingCharset)
+{
+ // Serialize the host URI.
+ // TODO: The cookieservice deals exclusively with ASCII hosts, but not paths.
+ // We should fix that, and then we can just serialize the spec as ASCII here.
+ aHostURI->GetSpec(aHostSpec);
+ aHostURI->GetOriginCharset(aHostCharset);
+
+ // Determine and serialize the originating URI. Failure is acceptable.
+ if (!mPermissionService) {
+ NS_WARNING("nsICookiePermission unavailable! Cookie may be rejected");
+ return;
+ }
+
+ nsCOMPtr<nsIURI> originatingURI;
+ mPermissionService->GetOriginatingURI(aChannel,
+ getter_AddRefs(originatingURI));
+ if (originatingURI) {
+ originatingURI->GetSpec(aOriginatingSpec);
+ originatingURI->GetOriginCharset(aOriginatingSpec);
+ }
+}
+
+nsresult
+CookieServiceChild::GetCookieStringInternal(nsIURI *aHostURI,
+ nsIChannel *aChannel,
+ char **aCookieString,
+ bool aFromHttp)
+{
+ NS_ENSURE_ARG(aHostURI);
+ NS_ENSURE_ARG_POINTER(aCookieString);
+
+ *aCookieString = NULL;
+
+ nsCAutoString hostSpec, hostCharset, originatingSpec, originatingCharset;
+ SerializeURIs(aHostURI, aChannel, hostSpec, hostCharset,
+ originatingSpec, originatingCharset);
+
+ // Synchronously call the parent.
+ nsCAutoString result;
+ SendGetCookieString(hostSpec, hostCharset,
+ originatingSpec, originatingCharset,
+ aFromHttp, &result);
+ if (!result.IsEmpty())
+ *aCookieString = ToNewCString(result);
+
+ return NS_OK;
+}
+
+nsresult
+CookieServiceChild::SetCookieStringInternal(nsIURI *aHostURI,
+ nsIChannel *aChannel,
+ const char *aCookieString,
+ const char *aServerTime,
+ bool aFromHttp)
+{
+ NS_ENSURE_ARG(aHostURI);
+ NS_ENSURE_ARG_POINTER(aCookieString);
+
+ nsCAutoString hostSpec, hostCharset, originatingSpec, originatingCharset;
+ SerializeURIs(aHostURI, aChannel, hostSpec, hostCharset,
+ originatingSpec, originatingCharset);
+
+ nsDependentCString cookieString(aCookieString);
+ nsDependentCString serverTime;
+ if (aServerTime)
+ serverTime.Rebind(aServerTime);
+
+ // Synchronously call the parent.
+ SendSetCookieString(hostSpec, hostCharset,
+ originatingSpec, originatingCharset,
+ cookieString, serverTime, aFromHttp);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+CookieServiceChild::GetCookieString(nsIURI *aHostURI,
+ nsIChannel *aChannel,
+ char **aCookieString)
+{
+ return GetCookieStringInternal(aHostURI, aChannel, aCookieString, false);
+}
+
+NS_IMETHODIMP
+CookieServiceChild::GetCookieStringFromHttp(nsIURI *aHostURI,
+ nsIURI *aFirstURI,
+ nsIChannel *aChannel,
+ char **aCookieString)
+{
+ return GetCookieStringInternal(aHostURI, aChannel, aCookieString, true);
+}
+
+NS_IMETHODIMP
+CookieServiceChild::SetCookieString(nsIURI *aHostURI,
+ nsIPrompt *aPrompt,
+ const char *aCookieString,
+ nsIChannel *aChannel)
+{
+ return SetCookieStringInternal(aHostURI, aChannel, aCookieString,
+ nsnull, false);
+}
+
+NS_IMETHODIMP
+CookieServiceChild::SetCookieStringFromHttp(nsIURI *aHostURI,
+ nsIURI *aFirstURI,
+ nsIPrompt *aPrompt,
+ const char *aCookieString,
+ const char *aServerTime,
+ nsIChannel *aChannel)
+{
+ return SetCookieStringInternal(aHostURI, aChannel, aCookieString,
+ aServerTime, true);
+}
+
+}
+}
+
new file mode 100644
--- /dev/null
+++ b/netwerk/cookie/src/CookieServiceChild.h
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation <http://www.mozilla.org/>.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Daniel Witte <dwitte@mozilla.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
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_net_CookieServiceChild_h__
+#define mozilla_net_CookieServiceChild_h__
+
+#include "mozilla/net/PCookieServiceChild.h"
+#include "nsICookieService.h"
+#include "nsICookiePermission.h"
+
+namespace mozilla {
+namespace net {
+
+class CookieServiceChild : public PCookieServiceChild
+ , public nsICookieService
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSICOOKIESERVICE
+
+ CookieServiceChild();
+ virtual ~CookieServiceChild();
+
+ static CookieServiceChild* GetSingleton();
+
+protected:
+ void SerializeURIs(nsIURI *aHostURI,
+ nsIChannel *aChannel,
+ nsCString &aHostSpec,
+ nsCString &aHostCharset,
+ nsCString &aOriginatingSpec,
+ nsCString &aOriginatingCharset);
+
+ nsresult GetCookieStringInternal(nsIURI *aHostURI,
+ nsIChannel *aChannel,
+ char **aCookieString,
+ bool aFromHttp);
+
+ nsresult SetCookieStringInternal(nsIURI *aHostURI,
+ nsIChannel *aChannel,
+ const char *aCookieString,
+ const char *aServerTime,
+ bool aFromHttp);
+
+ nsCOMPtr<nsICookiePermission> mPermissionService;
+};
+
+}
+}
+
+#endif // mozilla_net_CookieServiceChild_h__
+
new file mode 100644
--- /dev/null
+++ b/netwerk/cookie/src/CookieServiceParent.cpp
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation <http://www.mozilla.org/>.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Daniel Witte <dwitte@mozilla.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
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "mozilla/net/CookieServiceParent.h"
+#include "nsCookieService.h"
+#include "nsNetUtil.h"
+
+namespace mozilla {
+namespace net {
+
+CookieServiceParent::CookieServiceParent()
+{
+ // Instantiate the cookieservice via the service manager, so it sticks around
+ // until shutdown.
+ nsCOMPtr<nsICookieService> cs = do_GetService(NS_COOKIESERVICE_CONTRACTID);
+
+ // Get the nsCookieService instance directly, so we can call internal methods.
+ mCookieService =
+ already_AddRefed<nsCookieService>(nsCookieService::GetSingleton());
+ NS_ASSERTION(mCookieService, "couldn't get nsICookieService");
+
+ mIOService = do_GetService(NS_IOSERVICE_CONTRACTID);
+ NS_ASSERTION(mIOService, "couldn't get nsIIOService");
+}
+
+CookieServiceParent::~CookieServiceParent()
+{
+}
+
+bool
+CookieServiceParent::RecvGetCookieString(const nsCString& aHostSpec,
+ const nsCString& aHostCharset,
+ const nsCString& aOriginatingSpec,
+ const nsCString& aOriginatingCharset,
+ const bool& aFromHttp,
+ nsCString* aResult)
+{
+ if (!mCookieService)
+ return true;
+
+ // Deserialize URIs. Having a host URI is mandatory and should always be
+ // provided by the child; thus we consider failure fatal.
+ nsCOMPtr<nsIURI> hostURI, originatingURI;
+ NS_NewURI(getter_AddRefs(hostURI),
+ aHostSpec, aHostCharset.get(),
+ nsnull, mIOService);
+ NS_NewURI(getter_AddRefs(originatingURI),
+ aOriginatingSpec, aOriginatingCharset.get(),
+ nsnull, mIOService);
+ if (!hostURI)
+ return false;
+
+ mCookieService->GetCookieInternal(hostURI, originatingURI,
+ aFromHttp, *aResult);
+ return true;
+}
+
+bool
+CookieServiceParent::RecvSetCookieString(const nsCString& aHostSpec,
+ const nsCString& aHostCharset,
+ const nsCString& aOriginatingSpec,
+ const nsCString& aOriginatingCharset,
+ const nsCString& aCookieString,
+ const nsCString& aServerTime,
+ const bool& aFromHttp)
+{
+ if (!mCookieService)
+ return true;
+
+ // Deserialize URIs. Having a host URI is mandatory and should always be
+ // provided by the child; thus we consider failure fatal.
+ nsCOMPtr<nsIURI> hostURI, originatingURI;
+ NS_NewURI(getter_AddRefs(hostURI),
+ aHostSpec, aHostCharset.get(),
+ nsnull, mIOService);
+ NS_NewURI(getter_AddRefs(originatingURI),
+ aOriginatingSpec, aOriginatingCharset.get(),
+ nsnull, mIOService);
+ if (!hostURI)
+ return false;
+
+ mCookieService->SetCookieStringInternal(hostURI, originatingURI,
+ aCookieString, aServerTime,
+ aFromHttp);
+ return true;
+}
+
+}
+}
+
new file mode 100644
--- /dev/null
+++ b/netwerk/cookie/src/CookieServiceParent.h
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation <http://www.mozilla.org/>.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Daniel Witte <dwitte@mozilla.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
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_net_CookieServiceParent_h
+#define mozilla_net_CookieServiceParent_h
+
+#include "mozilla/net/PCookieServiceParent.h"
+
+class nsCookieService;
+class nsIIOService;
+
+namespace mozilla {
+namespace net {
+
+class CookieServiceParent : public PCookieServiceParent
+{
+public:
+ CookieServiceParent();
+ virtual ~CookieServiceParent();
+
+protected:
+ virtual bool RecvGetCookieString(const nsCString& aHostSpec,
+ const nsCString& aHostCharset,
+ const nsCString& aOriginatingSpec,
+ const nsCString& aOriginatingCharset,
+ const bool& aFromHttp,
+ nsCString* aResult);
+
+ virtual bool RecvSetCookieString(const nsCString& aHostSpec,
+ const nsCString& aHostCharset,
+ const nsCString& aOriginatingSpec,
+ const nsCString& aOriginatingCharset,
+ const nsCString& aCookieString,
+ const nsCString& aServerTime,
+ const bool& aFromHttp);
+
+ nsRefPtr<nsCookieService> mCookieService;
+ nsCOMPtr<nsIIOService> mIOService;
+};
+
+}
+}
+
+#endif // mozilla_net_CookieServiceParent_h
+
--- a/netwerk/cookie/src/Makefile.in
+++ b/netwerk/cookie/src/Makefile.in
@@ -41,17 +41,32 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = necko
LIBRARY_NAME = neckocookie_s
FORCE_STATIC_LIB = 1
LIBXUL_LIBRARY = 1
-
CPPSRCS = \
nsCookie.cpp \
nsCookieService.cpp \
$(NULL)
+ifdef MOZ_IPC
+EXPORTS_NAMESPACES = mozilla/net
+
+EXPORTS_mozilla/net = \
+ CookieServiceParent.h \
+ CookieServiceChild.h \
+ $(NULL)
+
+CPPSRCS += \
+ CookieServiceParent.cpp \
+ CookieServiceChild.cpp \
+ $(NULL)
+endif
+
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk
DEFINES += -DIMPL_NS_NET
new file mode 100644
--- /dev/null
+++ b/netwerk/cookie/src/PCookieService.ipdl
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Daniel Witte <dwitte@mozilla.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
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+include protocol "PNecko.ipdl";
+
+namespace mozilla {
+namespace net {
+
+sync protocol PCookieService
+{
+ manager PNecko;
+
+parent:
+ sync GetCookieString(nsCString hostSpec,
+ nsCString hostCharset,
+ nsCString originatingSpec,
+ nsCString originatingCharset,
+ bool fromHttp)
+ returns (nsCString result);
+
+ SetCookieString(nsCString hostSpec,
+ nsCString hostCharset,
+ nsCString originatingSpec,
+ nsCString originatingCharset,
+ nsCString cookieString,
+ nsCString serverTime,
+ bool fromHttp);
+
+ __delete__();
+};
+
+}
+}
+
new file mode 100644
--- /dev/null
+++ b/netwerk/cookie/src/ipdl.mk
@@ -0,0 +1,41 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla Firefox.
+#
+# The Initial Developer of the Original Code is
+# The Mozilla Foundation <http://www.mozilla.org/>.
+# Portions created by the Initial Developer are Copyright (C) 2010
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Daniel Witte <dwitte@mozilla.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
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+IPDLSRCS = \
+ PCookieService.ipdl \
+ $(NULL)
+
--- a/netwerk/cookie/src/nsCookieService.cpp
+++ b/netwerk/cookie/src/nsCookieService.cpp
@@ -34,16 +34,21 @@
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
+#ifdef MOZ_IPC
+#include "mozilla/net/CookieServiceChild.h"
+#include "mozilla/net/NeckoCommon.h"
+#endif
+
#include "nsCookieService.h"
#include "nsIServiceManager.h"
#include "nsIIOService.h"
#include "nsIPrefBranch.h"
#include "nsIPrefBranch2.h"
#include "nsIPrefService.h"
#include "nsICookiePermission.h"
@@ -68,16 +73,18 @@
#include "prprf.h"
#include "nsNetUtil.h"
#include "nsNetCID.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsIPrivateBrowsingService.h"
#include "nsNetCID.h"
#include "mozilla/storage.h"
+using namespace mozilla::net;
+
/******************************************************************************
* nsCookieService impl:
* useful types & constants
******************************************************************************/
// XXX_hack. See bug 178993.
// This is a hack to hide HttpOnly cookies from older browsers
static const char kHttpOnlyPrefix[] = "#HttpOnly_";
@@ -462,21 +469,36 @@ static RemoveCookieDBListener sRemoveCoo
} // anonymous namespace
/******************************************************************************
* nsCookieService impl:
* singleton instance ctor/dtor methods
******************************************************************************/
-nsCookieService *nsCookieService::gCookieService = nsnull;
+static nsCookieService *gCookieService;
+
+nsICookieService*
+nsCookieService::GetXPCOMSingleton()
+{
+#ifdef MOZ_IPC
+ if (IsNeckoChild())
+ return CookieServiceChild::GetSingleton();
+#endif
+
+ return GetSingleton();
+}
nsCookieService*
nsCookieService::GetSingleton()
{
+#ifdef MOZ_IPC
+ NS_ASSERTION(!IsNeckoChild(), "not a parent process");
+#endif
+
if (gCookieService) {
NS_ADDREF(gCookieService);
return gCookieService;
}
// Create a new singleton nsCookieService.
// We AddRef only once since XPCOM has rules about the ordering of module
// teardowns - by the time our module destructor is called, it's too late to
@@ -881,133 +903,159 @@ nsCookieService::Observe(nsISupports
return NS_OK;
}
NS_IMETHODIMP
nsCookieService::GetCookieString(nsIURI *aHostURI,
nsIChannel *aChannel,
char **aCookie)
{
- GetCookieInternal(aHostURI, aChannel, PR_FALSE, aCookie);
-
+ NS_ENSURE_ARG(aHostURI);
+ NS_ENSURE_ARG(aCookie);
+
+ nsCOMPtr<nsIURI> originatingURI;
+ GetOriginatingURI(aChannel, getter_AddRefs(originatingURI));
+
+ nsCAutoString result;
+ GetCookieInternal(aHostURI, originatingURI, PR_FALSE, result);
+ *aCookie = result.IsEmpty() ? nsnull : ToNewCString(result);
return NS_OK;
}
NS_IMETHODIMP
nsCookieService::GetCookieStringFromHttp(nsIURI *aHostURI,
nsIURI *aFirstURI,
nsIChannel *aChannel,
char **aCookie)
{
- GetCookieInternal(aHostURI, aChannel, PR_TRUE, aCookie);
-
+ NS_ENSURE_ARG(aHostURI);
+ NS_ENSURE_ARG(aCookie);
+
+ nsCOMPtr<nsIURI> originatingURI;
+ GetOriginatingURI(aChannel, getter_AddRefs(originatingURI));
+
+ nsCAutoString result;
+ GetCookieInternal(aHostURI, originatingURI, PR_TRUE, result);
+ *aCookie = result.IsEmpty() ? nsnull : ToNewCString(result);
return NS_OK;
}
NS_IMETHODIMP
nsCookieService::SetCookieString(nsIURI *aHostURI,
nsIPrompt *aPrompt,
const char *aCookieHeader,
nsIChannel *aChannel)
{
- return SetCookieStringInternal(aHostURI, aPrompt, aCookieHeader, nsnull, aChannel, PR_FALSE);
+ NS_ENSURE_ARG(aHostURI);
+ NS_ENSURE_ARG(aCookieHeader);
+
+ nsCOMPtr<nsIURI> originatingURI;
+ GetOriginatingURI(aChannel, getter_AddRefs(originatingURI));
+
+ nsDependentCString cookieString(aCookieHeader);
+ SetCookieStringInternal(aHostURI, originatingURI,
+ cookieString, EmptyCString(), PR_FALSE);
+ return NS_OK;
}
NS_IMETHODIMP
nsCookieService::SetCookieStringFromHttp(nsIURI *aHostURI,
nsIURI *aFirstURI,
nsIPrompt *aPrompt,
const char *aCookieHeader,
const char *aServerTime,
nsIChannel *aChannel)
{
- return SetCookieStringInternal(aHostURI, aPrompt, aCookieHeader, aServerTime, aChannel, PR_TRUE);
+ NS_ENSURE_ARG(aHostURI);
+ NS_ENSURE_ARG(aCookieHeader);
+
+ nsCOMPtr<nsIURI> originatingURI;
+ GetOriginatingURI(aChannel, getter_AddRefs(originatingURI));
+
+ nsDependentCString cookieString(aCookieHeader);
+ nsDependentCString serverTime(aServerTime ? aServerTime : "");
+ SetCookieStringInternal(aHostURI, originatingURI, cookieString,
+ serverTime, PR_TRUE);
+ return NS_OK;
}
-nsresult
-nsCookieService::SetCookieStringInternal(nsIURI *aHostURI,
- nsIPrompt *aPrompt,
- const char *aCookieHeader,
- const char *aServerTime,
- nsIChannel *aChannel,
- PRBool aFromHttp)
+void
+nsCookieService::SetCookieStringInternal(nsIURI *aHostURI,
+ nsIURI *aOriginatingURI,
+ const nsCString &aCookieHeader,
+ const nsCString &aServerTime,
+ PRBool aFromHttp)
{
- if (!aHostURI) {
- COOKIE_LOGFAILURE(SET_COOKIE, nsnull, aCookieHeader, "host URI is null");
- return NS_OK;
- }
-
// get the base domain for the host URI.
// e.g. for "www.bbc.co.uk", this would be "bbc.co.uk".
// file:// URI's (i.e. with an empty host) are allowed, but any other
// scheme must have a non-empty host. A trailing dot in the host
// is acceptable, and will be stripped.
PRBool requireHostMatch;
nsCAutoString baseDomain;
nsresult rv = GetBaseDomain(aHostURI, baseDomain, requireHostMatch);
if (NS_FAILED(rv)) {
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader,
"couldn't get base domain from URI");
- return NS_OK;
+ return;
}
// check default prefs
- PRUint32 cookieStatus = CheckPrefs(aHostURI, aChannel, baseDomain,
- requireHostMatch, aCookieHeader);
+ PRUint32 cookieStatus = CheckPrefs(aHostURI, aOriginatingURI, baseDomain,
+ requireHostMatch, aCookieHeader.get());
// fire a notification if cookie was rejected (but not if there was an error)
switch (cookieStatus) {
case STATUS_REJECTED:
NotifyRejected(aHostURI);
case STATUS_REJECTED_WITH_ERROR:
- return NS_OK;
+ return;
}
// parse server local time. this is not just done here for efficiency
// reasons - if there's an error parsing it, and we need to default it
// to the current time, we must do it here since the current time in
// SetCookieInternal() will change for each cookie processed (e.g. if the
// user is prompted).
PRTime tempServerTime;
PRInt64 serverTime;
- if (aServerTime &&
- PR_ParseTimeString(aServerTime, PR_TRUE, &tempServerTime) == PR_SUCCESS) {
+ PRStatus result = PR_ParseTimeString(aServerTime.get(), PR_TRUE,
+ &tempServerTime);
+ if (result == PR_SUCCESS) {
serverTime = tempServerTime / PR_USEC_PER_SEC;
} else {
serverTime = PR_Now() / PR_USEC_PER_SEC;
}
// We may be adding a bunch of cookies to the DB, so we use async batching
// with storage to make this super fast.
nsCOMPtr<mozIStorageBindingParamsArray> paramsArray;
if (mDBState->dbConn) {
mDBState->stmtInsert->NewBindingParamsArray(getter_AddRefs(paramsArray));
}
- // switch to a nice string type now, and process each cookie in the header
+ // process each cookie in the header
nsDependentCString cookieHeader(aCookieHeader);
- while (SetCookieInternal(aHostURI, aChannel, baseDomain, requireHostMatch,
+ while (SetCookieInternal(aHostURI, baseDomain, requireHostMatch,
cookieHeader, serverTime, aFromHttp, paramsArray));
// If we had a params array, go ahead and write it out to disk now.
if (paramsArray) {
// ...but only if we have sufficient length!
PRUint32 length;
paramsArray->GetLength(&length);
if (length == 0)
- return NS_OK;
+ return;
rv = mDBState->stmtInsert->BindParameters(paramsArray);
NS_ASSERT_SUCCESS(rv);
nsCOMPtr<mozIStoragePendingStatement> handle;
rv = mDBState->stmtInsert->ExecuteAsync(&sInsertCookieDBListener,
getter_AddRefs(handle));
NS_ASSERT_SUCCESS(rv);
}
-
- return NS_OK;
}
// notify observers that a cookie was rejected due to the users' prefs.
void
nsCookieService::NotifyRejected(nsIURI *aHostURI)
{
if (mObserverService)
mObserverService->NotifyObservers(aHostURI, "cookie-rejected", nsnull);
@@ -1483,22 +1531,20 @@ public:
// browser! see bug 236772.
// note: CreationID is unique, so two id's can never be equal.
return aCookie1->CreationID() < aCookie2->CreationID();
}
};
void
nsCookieService::GetCookieInternal(nsIURI *aHostURI,
- nsIChannel *aChannel,
+ nsIURI *aOriginatingURI,
PRBool aHttpBound,
- char **aCookie)
+ nsCString &aCookieString)
{
- *aCookie = nsnull;
-
if (!aHostURI) {
COOKIE_LOGFAILURE(GET_COOKIE, nsnull, nsnull, "host URI is null");
return;
}
// get the base domain, host, and path from the URI.
// e.g. for "www.bbc.co.uk", the base domain would be "bbc.co.uk".
// file:// URI's (i.e. with an empty host) are allowed, but any other
@@ -1515,17 +1561,17 @@ nsCookieService::GetCookieInternal(nsIUR
if (!hostFromURI.IsEmpty() && hostFromURI.Last() == '.')
hostFromURI.Truncate(hostFromURI.Length() - 1);
if (NS_FAILED(rv)) {
COOKIE_LOGFAILURE(GET_COOKIE, aHostURI, nsnull, "invalid host/path from URI");
return;
}
// check default prefs
- PRUint32 cookieStatus = CheckPrefs(aHostURI, aChannel, baseDomain,
+ PRUint32 cookieStatus = CheckPrefs(aHostURI, aOriginatingURI, baseDomain,
requireHostMatch, nsnull);
// for GetCookie(), we don't fire rejection notifications.
switch (cookieStatus) {
case STATUS_REJECTED:
case STATUS_REJECTED_WITH_ERROR:
return;
}
@@ -1638,51 +1684,45 @@ nsCookieService::GetCookieInternal(nsIUR
}
}
// return cookies in order of path length; longest to shortest.
// this is required per RFC2109. if cookies match in length,
// then sort by creation time (see bug 236772).
foundCookieList.Sort(CompareCookiesForSending());
- nsCAutoString cookieData;
for (PRInt32 i = 0; i < count; ++i) {
cookie = foundCookieList.ElementAt(i);
// check if we have anything to write
if (!cookie->Name().IsEmpty() || !cookie->Value().IsEmpty()) {
// if we've already added a cookie to the return list, append a "; " so
// that subsequent cookies are delimited in the final list.
- if (!cookieData.IsEmpty()) {
- cookieData.AppendLiteral("; ");
+ if (!aCookieString.IsEmpty()) {
+ aCookieString.AppendLiteral("; ");
}
if (!cookie->Name().IsEmpty()) {
// we have a name and value - write both
- cookieData += cookie->Name() + NS_LITERAL_CSTRING("=") + cookie->Value();
+ aCookieString += cookie->Name() + NS_LITERAL_CSTRING("=") + cookie->Value();
} else {
// just write value
- cookieData += cookie->Value();
+ aCookieString += cookie->Value();
}
}
}
- // it's wasteful to alloc a new string; but we have no other choice, until we
- // fix the callers to use nsACStrings.
- if (!cookieData.IsEmpty()) {
- COOKIE_LOGSUCCESS(GET_COOKIE, aHostURI, cookieData, nsnull, nsnull);
- *aCookie = ToNewCString(cookieData);
- }
+ if (!aCookieString.IsEmpty())
+ COOKIE_LOGSUCCESS(GET_COOKIE, aHostURI, aCookieString, nsnull, nsnull);
}
// processes a single cookie, and returns PR_TRUE if there are more cookies
// to be processed
PRBool
nsCookieService::SetCookieInternal(nsIURI *aHostURI,
- nsIChannel *aChannel,
const nsCString &aBaseDomain,
PRBool aRequireHostMatch,
nsDependentCString &aCookieHeader,
PRInt64 aServerTime,
PRBool aFromHttp,
mozIStorageBindingParamsArray *aParamsArray)
{
// create a stack-based nsCookieAttributes, to store all the
@@ -1741,20 +1781,20 @@ nsCookieService::SetCookieInternal(nsIUR
cookieAttributes.isHttpOnly);
if (!cookie)
return newCookie;
// check permissions from site permission list, or ask the user,
// to determine if we can set the cookie
if (mPermissionService) {
PRBool permission;
- // we need to think about prompters/parent windows here - TestPermission
- // needs one to prompt, so right now it has to fend for itself to get one
+ // Not passing an nsIChannel here means CanSetCookie will use the currently
+ // active window to display the prompt. This isn't exactly ideal...
mPermissionService->CanSetCookie(aHostURI,
- aChannel,
+ nsnull,
static_cast<nsICookie2*>(static_cast<nsCookie*>(cookie)),
&cookieAttributes.isSession,
&cookieAttributes.expiryTime,
&permission);
if (!permission) {
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader, "cookie rejected by permission manager");
NotifyRejected(aHostURI);
return newCookie;
@@ -2217,19 +2257,36 @@ nsCookieService::IsForeign(const nsCStri
// domain parameter will be equivalent to the host in this case.
if (aRequireHostMatch)
return !firstHost.Equals(aBaseDomain);
// ensure the originating domain is also derived from the host's base domain.
return !IsSubdomainOf(firstHost, aBaseDomain);
}
+void
+nsCookieService::GetOriginatingURI(nsIChannel *aChannel,
+ nsIURI **aURI)
+{
+ // Determine the originating URI. We only need to do this if we're
+ // rejecting third-party cookies.
+ if (mCookiesPermissions != BEHAVIOR_REJECTFOREIGN)
+ return;
+
+ if (!mPermissionService) {
+ NS_WARNING("nsICookiePermission unavailable! Cookie may be rejected");
+ return;
+ }
+
+ mPermissionService->GetOriginatingURI(aChannel, aURI);
+}
+
PRUint32
nsCookieService::CheckPrefs(nsIURI *aHostURI,
- nsIChannel *aChannel,
+ nsIURI *aOriginatingURI,
const nsCString &aBaseDomain,
PRBool aRequireHostMatch,
const char *aCookieHeader)
{
nsresult rv;
// don't let ftp sites get/set cookies (could be a security issue)
PRBool ftp;
@@ -2237,17 +2294,19 @@ nsCookieService::CheckPrefs(nsIURI
COOKIE_LOGFAILURE(aCookieHeader ? SET_COOKIE : GET_COOKIE, aHostURI, aCookieHeader, "ftp sites cannot read cookies");
return STATUS_REJECTED_WITH_ERROR;
}
// check the permission list first; if we find an entry, it overrides
// default prefs. see bug 184059.
if (mPermissionService) {
nsCookieAccess access;
- rv = mPermissionService->CanAccess(aHostURI, aChannel, &access);
+ // Not passing an nsIChannel here is probably OK; our implementation
+ // doesn't do anything with it anyway.
+ rv = mPermissionService->CanAccess(aHostURI, nsnull, &access);
// if we found an entry, use it
if (NS_SUCCEEDED(rv)) {
switch (access) {
case nsICookiePermission::ACCESS_DENY:
COOKIE_LOGFAILURE(aCookieHeader ? SET_COOKIE : GET_COOKIE, aHostURI, aCookieHeader, "cookies are blocked for this site");
return STATUS_REJECTED;
@@ -2259,26 +2318,18 @@ nsCookieService::CheckPrefs(nsIURI
// check default prefs
if (mCookiesPermissions == BEHAVIOR_REJECT) {
COOKIE_LOGFAILURE(aCookieHeader ? SET_COOKIE : GET_COOKIE, aHostURI, aCookieHeader, "cookies are disabled");
return STATUS_REJECTED;
} else if (mCookiesPermissions == BEHAVIOR_REJECTFOREIGN) {
// check if cookie is foreign
- if (!mPermissionService) {
- NS_WARNING("Foreign cookie blocking enabled, but nsICookiePermission unavailable! Rejecting cookie");
- COOKIE_LOGSTRING(PR_LOG_WARNING, ("CheckPrefs(): foreign blocking enabled, but nsICookiePermission unavailable! Rejecting cookie"));
- return STATUS_REJECTED;
- }
-
- nsCOMPtr<nsIURI> firstURI;
- rv = mPermissionService->GetOriginatingURI(aChannel, getter_AddRefs(firstURI));
-
- if (NS_FAILED(rv) || IsForeign(aBaseDomain, aRequireHostMatch, firstURI)) {
+ if (!aOriginatingURI ||
+ IsForeign(aBaseDomain, aRequireHostMatch, aOriginatingURI)) {
COOKIE_LOGFAILURE(aCookieHeader ? SET_COOKIE : GET_COOKIE, aHostURI, aCookieHeader, "originating server test failed");
return STATUS_REJECTED;
}
}
// if nothing has complained, accept cookie
return STATUS_ACCEPTED;
}
@@ -2539,17 +2590,17 @@ purgeCookiesCallback(nsCookieEntry *aEnt
nsCookie *cookie = cookies[i];
// check if the cookie has expired
if (cookie->Expiry() <= data.currentTime) {
data.removedList->AppendElement(cookie, PR_FALSE);
COOKIE_LOGEVICTED(cookie);
// remove from list; do not increment our iterator
- nsCookieService::gCookieService->RemoveCookieFromList(iter, array);
+ gCookieService->RemoveCookieFromList(iter, array);
} else {
// check if the cookie is over the age limit
if (cookie->LastAccessed() <= data.purgeTime) {
data.purgeList.AppendElement(iter);
} else if (cookie->LastAccessed() < data.oldestTime) {
// reset our indicator
--- a/netwerk/cookie/src/nsCookieService.h
+++ b/netwerk/cookie/src/nsCookieService.h
@@ -51,28 +51,36 @@
#include "nsCookie.h"
#include "nsString.h"
#include "nsAutoPtr.h"
#include "nsHashKeys.h"
#include "nsTHashtable.h"
#include "mozIStorageStatement.h"
#include "mozIStorageConnection.h"
-struct nsCookieAttributes;
-struct nsListIter;
-struct nsEnumerationData;
-
class nsICookiePermission;
class nsIEffectiveTLDService;
class nsIIDNService;
class nsIPrefBranch;
class nsIObserverService;
class nsIURI;
class nsIChannel;
+struct nsCookieAttributes;
+struct nsListIter;
+struct nsEnumerationData;
+
+namespace mozilla {
+namespace net {
+#ifdef MOZ_IPC
+class CookieServiceParent;
+#endif
+}
+}
+
// hash entry class
class nsCookieEntry : public PLDHashEntryHdr
{
public:
// Hash methods
typedef const nsCString& KeyType;
typedef const nsCString* KeyTypePointer;
typedef nsTArray< nsRefPtr<nsCookie> > ArrayType;
@@ -154,40 +162,41 @@ class nsCookieService : public nsICookie
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
NS_DECL_NSICOOKIESERVICE
NS_DECL_NSICOOKIEMANAGER
NS_DECL_NSICOOKIEMANAGER2
nsCookieService();
virtual ~nsCookieService();
- static nsCookieService* GetSingleton();
+ static nsICookieService* GetXPCOMSingleton();
nsresult Init();
protected:
void PrefChanged(nsIPrefBranch *aPrefBranch);
nsresult InitDB();
nsresult TryInitDB(PRBool aDeleteExistingDB);
nsresult CreateTable();
void CloseDB();
nsresult Read();
nsresult NormalizeHost(nsCString &aHost);
nsresult GetBaseDomain(nsIURI *aHostURI, nsCString &aBaseDomain, PRBool &aRequireHostMatch);
nsresult GetBaseDomainFromHost(const nsACString &aHost, nsCString &aBaseDomain);
- void GetCookieInternal(nsIURI *aHostURI, nsIChannel *aChannel, PRBool aHttpBound, char **aCookie);
- nsresult SetCookieStringInternal(nsIURI *aHostURI, nsIPrompt *aPrompt, const char *aCookieHeader, const char *aServerTime, nsIChannel *aChannel, PRBool aFromHttp);
- PRBool SetCookieInternal(nsIURI *aHostURI, nsIChannel *aChannel, const nsCString& aBaseDomain, PRBool aRequireHostMatch, nsDependentCString &aCookieHeader, PRInt64 aServerTime, PRBool aFromHttp, mozIStorageBindingParamsArray *aParamsArray = NULL);
+ void GetCookieInternal(nsIURI *aHostURI, nsIURI *aOriginatingURI, PRBool aHttpBound, nsCString &aCookie);
+ void SetCookieStringInternal(nsIURI *aHostURI, nsIURI *aOriginatingURI, const nsCString &aCookieHeader, const nsCString &aServerTime, PRBool aFromHttp);
+ PRBool SetCookieInternal(nsIURI *aHostURI, const nsCString& aBaseDomain, PRBool aRequireHostMatch, nsDependentCString &aCookieHeader, PRInt64 aServerTime, PRBool aFromHttp, mozIStorageBindingParamsArray *aParamsArray = NULL);
void AddInternal(const nsCString& aBaseDomain, nsCookie *aCookie, PRInt64 aCurrentTimeInUsec, nsIURI *aHostURI, const char *aCookieHeader, PRBool aFromHttp, mozIStorageBindingParamsArray *aParamsArray = NULL);
void RemoveCookieFromList(const nsListIter &aIter, mozIStorageBindingParamsArray *aParamsArray = NULL);
PRBool AddCookieToList(const nsCString& aBaseDomain, nsCookie *aCookie, mozIStorageBindingParamsArray *aParamsArray, PRBool aWriteToDB = PR_TRUE);
void UpdateCookieInList(nsCookie *aCookie, PRInt64 aLastAccessed, mozIStorageBindingParamsArray *aParamsArray);
static PRBool GetTokenValue(nsASingleFragmentCString::const_char_iterator &aIter, nsASingleFragmentCString::const_char_iterator &aEndIter, nsDependentCSubstring &aTokenString, nsDependentCSubstring &aTokenValue, PRBool &aEqualsFound);
static PRBool ParseAttributes(nsDependentCString &aCookieHeader, nsCookieAttributes &aCookie);
PRBool IsForeign(const nsCString &aBaseDomain, PRBool aRequireHostMatch, nsIURI *aFirstURI);
- PRUint32 CheckPrefs(nsIURI *aHostURI, nsIChannel *aChannel, const nsCString &aBaseDomain, PRBool aRequireHostMatch, const char *aCookieHeader);
+ void GetOriginatingURI(nsIChannel *aChannel, nsIURI **aURI);
+ PRUint32 CheckPrefs(nsIURI *aHostURI, nsIURI *aOriginatingURI, const nsCString &aBaseDomain, PRBool aRequireHostMatch, const char *aCookieHeader);
PRBool CheckDomain(nsCookieAttributes &aCookie, nsIURI *aHostURI, const nsCString &aBaseDomain, PRBool aRequireHostMatch);
static PRBool CheckPath(nsCookieAttributes &aCookie, nsIURI *aHostURI);
static PRBool GetExpiry(nsCookieAttributes &aCookie, PRInt64 aServerTime, PRInt64 aCurrentTime);
void RemoveAllFromMemory();
void PurgeCookies(PRInt64 aCurrentTimeInUsec);
PRBool FindCookie(const nsCString& aBaseDomain, const nsAFlatCString &aHost, const nsAFlatCString &aName, const nsAFlatCString &aPath, nsListIter &aIter, PRInt64 aCurrentTime);
PRUint32 CountCookiesFromHostInternal(const nsCString &aBaseDomain, nsEnumerationData &aData);
void NotifyRejected(nsIURI *aHostURI);
@@ -210,17 +219,18 @@ class nsCookieService : public nsICookie
DBState mPrivateDBState;
// cached prefs
PRUint8 mCookiesPermissions; // BEHAVIOR_{ACCEPT, REJECTFOREIGN, REJECT}
PRUint16 mMaxNumberOfCookies;
PRUint16 mMaxCookiesPerHost;
PRInt64 mCookiePurgeAge;
- // private static member, used to cache a ptr to nsCookieService,
- // so we can make nsCookieService a singleton xpcom object.
- static nsCookieService *gCookieService;
-
// this callback needs access to member functions
friend PLDHashOperator purgeCookiesCallback(nsCookieEntry *aEntry, void *aArg);
+
+ static nsCookieService* GetSingleton();
+#ifdef MOZ_IPC
+ friend class mozilla::net::CookieServiceParent;
+#endif
};
#endif // nsCookieService_h__
new file mode 100644
--- /dev/null
+++ b/netwerk/cookie/test/unit_ipc/head_ipc_setup.js
@@ -0,0 +1,15 @@
+
+/**
+ * Turn on e10s networking (god help us)
+ */
+Components.classes["@mozilla.org/process/environment;1"]
+ .getService(Components.interfaces.nsIEnvironment)
+ .set("NECKO_E10S_HTTP", "1");
+
+// If using NSPR logging, create child log as "${NSPR_LOG_FILE}.child"
+// - TODO: remove when bug 534764 is fixed
+var env = Components.classes["@mozilla.org/process/environment;1"]
+ .getService(Components.interfaces.nsIEnvironment);
+var log = env.get("NSPR_LOG_FILE");
+if (log)
+ env.set("NSPR_LOG_FILE", log + ".child");
new file mode 100644
--- /dev/null
+++ b/netwerk/cookie/test/unit_ipc/test_ipc_parser_0001.js
@@ -0,0 +1,3 @@
+function run_test() {
+ run_test_in_child("../unit/test_parser_0001.js");
+}
new file mode 100644
--- /dev/null
+++ b/netwerk/cookie/test/unit_ipc/test_ipc_parser_0019.js
@@ -0,0 +1,3 @@
+function run_test() {
+ run_test_in_child("../unit/test_parser_0019.js");
+}
--- a/netwerk/ipc/NeckoChild.cpp
+++ b/netwerk/ipc/NeckoChild.cpp
@@ -37,16 +37,17 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsHttp.h"
#include "mozilla/net/NeckoChild.h"
#include "mozilla/dom/ContentProcessChild.h"
#include "mozilla/net/HttpChannelChild.h"
+#include "mozilla/net/CookieServiceChild.h"
namespace mozilla {
namespace net {
PNeckoChild *gNeckoChild = nsnull;
// C++ file contents
NeckoChild::NeckoChild()
@@ -98,10 +99,28 @@ NeckoChild::DeallocPHttpChannel(PHttpCha
{
NS_ABORT_IF_FALSE(IsNeckoChild(), "DeallocPHttpChannel called by non-child!");
HttpChannelChild *p = static_cast<HttpChannelChild*>(channel);
p->Release();
return true;
}
+PCookieServiceChild*
+NeckoChild::AllocPCookieService()
+{
+ // We don't allocate here: see nsCookieService::GetSingleton()
+ NS_NOTREACHED("AllocPCookieService should not be called");
+ return nsnull;
+}
+
+bool
+NeckoChild::DeallocPCookieService(PCookieServiceChild* cs)
+{
+ NS_ASSERTION(IsNeckoChild(), "DeallocPCookieService called by non-child!");
+
+ CookieServiceChild *p = static_cast<CookieServiceChild*>(cs);
+ p->Release();
+ return true;
+}
+
}} // mozilla::net
--- a/netwerk/ipc/NeckoChild.h
+++ b/netwerk/ipc/NeckoChild.h
@@ -56,16 +56,18 @@ public:
virtual ~NeckoChild();
static void InitNeckoChild();
static void DestroyNeckoChild();
protected:
virtual PHttpChannelChild* AllocPHttpChannel();
virtual bool DeallocPHttpChannel(PHttpChannelChild*);
+ virtual PCookieServiceChild* AllocPCookieService();
+ virtual bool DeallocPCookieService(PCookieServiceChild*);
};
/**
* Reference to the PNecko Child protocol.
* Null if this is not a content process.
*/
extern PNeckoChild *gNeckoChild;
--- a/netwerk/ipc/NeckoParent.cpp
+++ b/netwerk/ipc/NeckoParent.cpp
@@ -36,16 +36,17 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsHttp.h"
#include "mozilla/net/NeckoParent.h"
#include "mozilla/net/HttpChannelParent.h"
+#include "mozilla/net/CookieServiceParent.h"
namespace mozilla {
namespace net {
// C++ file contents
NeckoParent::NeckoParent()
{
}
@@ -65,11 +66,23 @@ NeckoParent::AllocPHttpChannel()
bool
NeckoParent::DeallocPHttpChannel(PHttpChannelParent* channel)
{
HttpChannelParent *p = static_cast<HttpChannelParent *>(channel);
p->Release();
return true;
}
+PCookieServiceParent*
+NeckoParent::AllocPCookieService()
+{
+ return new CookieServiceParent();
+}
+
+bool
+NeckoParent::DeallocPCookieService(PCookieServiceParent* cs)
+{
+ delete cs;
+ return true;
+}
}} // mozilla::net
--- a/netwerk/ipc/NeckoParent.h
+++ b/netwerk/ipc/NeckoParent.h
@@ -53,14 +53,16 @@ class NeckoParent :
{
public:
NeckoParent();
virtual ~NeckoParent();
protected:
virtual PHttpChannelParent* AllocPHttpChannel();
virtual bool DeallocPHttpChannel(PHttpChannelParent*);
+ virtual PCookieServiceParent* AllocPCookieService();
+ virtual bool DeallocPCookieService(PCookieServiceParent*);
};
} // namespace net
} // namespace mozilla
#endif // mozilla_net_NeckoParent_h
--- a/netwerk/ipc/PNecko.ipdl
+++ b/netwerk/ipc/PNecko.ipdl
@@ -35,28 +35,31 @@
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
include protocol "PContentProcess.ipdl";
include protocol "PHttpChannel.ipdl";
+include protocol "PCookieService.ipdl";
namespace mozilla {
namespace net {
//-------------------------------------------------------------------
-protocol PNecko
+sync protocol PNecko
{
manager PContentProcess;
manages PHttpChannel;
+ manages PCookieService;
parent:
__delete__();
PHttpChannel();
+ PCookieService();
};
} // namespace net
} // namespace mozilla