1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "mozilla/net/CookieServiceChild.h"
7 #include "mozilla/dom/TabChild.h"
8 #include "mozilla/ipc/URIUtils.h"
9 #include "mozilla/net/NeckoChild.h"
11 #include "nsIPrefService.h"
12 #include "nsIPrefBranch.h"
13 #include "nsITabChild.h"
14 #include "nsNetUtil.h"
16 using namespace mozilla::ipc
;
21 // Behavior pref constants
22 static const int32_t BEHAVIOR_ACCEPT
= 0;
23 static const int32_t BEHAVIOR_REJECTFOREIGN
= 1;
24 static const int32_t BEHAVIOR_REJECT
= 2;
25 static const int32_t BEHAVIOR_LIMITFOREIGN
= 3;
27 // Pref string constants
28 static const char kPrefCookieBehavior
[] = "network.cookie.cookieBehavior";
29 static const char kPrefThirdPartySession
[] =
30 "network.cookie.thirdparty.sessionOnly";
32 static CookieServiceChild
*gCookieService
;
35 CookieServiceChild::GetSingleton()
38 gCookieService
= new CookieServiceChild();
40 NS_ADDREF(gCookieService
);
41 return gCookieService
;
44 NS_IMPL_ISUPPORTS3(CookieServiceChild
,
47 nsISupportsWeakReference
)
49 CookieServiceChild::CookieServiceChild()
50 : mCookieBehavior(BEHAVIOR_ACCEPT
)
51 , mThirdPartySession(false)
53 NS_ASSERTION(IsNeckoChild(), "not a child process");
55 // This corresponds to Release() in DeallocPCookieService.
58 // Create a child PCookieService actor.
59 NeckoChild::InitNeckoChild();
60 gNeckoChild
->SendPCookieServiceConstructor(this);
62 // Init our prefs and observer.
63 nsCOMPtr
<nsIPrefBranch
> prefBranch
=
64 do_GetService(NS_PREFSERVICE_CONTRACTID
);
65 NS_WARN_IF_FALSE(prefBranch
, "no prefservice");
67 prefBranch
->AddObserver(kPrefCookieBehavior
, this, true);
68 prefBranch
->AddObserver(kPrefThirdPartySession
, this, true);
69 PrefChanged(prefBranch
);
73 CookieServiceChild::~CookieServiceChild()
75 gCookieService
= nullptr;
79 CookieServiceChild::PrefChanged(nsIPrefBranch
*aPrefBranch
)
82 if (NS_SUCCEEDED(aPrefBranch
->GetIntPref(kPrefCookieBehavior
, &val
)))
84 val
>= BEHAVIOR_ACCEPT
&& val
<= BEHAVIOR_LIMITFOREIGN
? val
: BEHAVIOR_ACCEPT
;
87 if (NS_SUCCEEDED(aPrefBranch
->GetBoolPref(kPrefThirdPartySession
, &boolval
)))
88 mThirdPartySession
= !!boolval
;
90 if (!mThirdPartyUtil
&& RequireThirdPartyCheck()) {
91 mThirdPartyUtil
= do_GetService(THIRDPARTYUTIL_CONTRACTID
);
92 NS_ASSERTION(mThirdPartyUtil
, "require ThirdPartyUtil service");
97 CookieServiceChild::RequireThirdPartyCheck()
99 return mCookieBehavior
== BEHAVIOR_REJECTFOREIGN
|| mCookieBehavior
== BEHAVIOR_LIMITFOREIGN
|| mThirdPartySession
;
103 CookieServiceChild::GetCookieStringInternal(nsIURI
*aHostURI
,
104 nsIChannel
*aChannel
,
105 char **aCookieString
,
108 NS_ENSURE_ARG(aHostURI
);
109 NS_ENSURE_ARG_POINTER(aCookieString
);
111 *aCookieString
= NULL
;
113 // Determine whether the request is foreign. Failure is acceptable.
114 bool isForeign
= true;
115 if (RequireThirdPartyCheck())
116 mThirdPartyUtil
->IsThirdPartyChannel(aChannel
, aHostURI
, &isForeign
);
119 SerializeURI(aHostURI
, uriParams
);
121 nsCOMPtr
<nsITabChild
> iTabChild
;
122 mozilla::dom::TabChild
* tabChild
= nullptr;
124 NS_QueryNotificationCallbacks(aChannel
, iTabChild
);
126 tabChild
= static_cast<mozilla::dom::TabChild
*>(iTabChild
.get());
128 if (MissingRequiredTabChild(tabChild
, "cookie")) {
129 return NS_ERROR_ILLEGAL_VALUE
;
133 // Synchronously call the parent.
134 nsAutoCString result
;
135 SendGetCookieString(uriParams
, !!isForeign
, aFromHttp
,
136 IPC::SerializedLoadContext(aChannel
), tabChild
, &result
);
137 if (!result
.IsEmpty())
138 *aCookieString
= ToNewCString(result
);
144 CookieServiceChild::SetCookieStringInternal(nsIURI
*aHostURI
,
145 nsIChannel
*aChannel
,
146 const char *aCookieString
,
147 const char *aServerTime
,
150 NS_ENSURE_ARG(aHostURI
);
151 NS_ENSURE_ARG_POINTER(aCookieString
);
153 // Determine whether the request is foreign. Failure is acceptable.
154 bool isForeign
= true;
155 if (RequireThirdPartyCheck())
156 mThirdPartyUtil
->IsThirdPartyChannel(aChannel
, aHostURI
, &isForeign
);
158 nsDependentCString
cookieString(aCookieString
);
159 nsDependentCString serverTime
;
161 serverTime
.Rebind(aServerTime
);
164 SerializeURI(aHostURI
, uriParams
);
166 nsCOMPtr
<nsITabChild
> iTabChild
;
167 mozilla::dom::TabChild
* tabChild
= nullptr;
169 NS_QueryNotificationCallbacks(aChannel
, iTabChild
);
171 tabChild
= static_cast<mozilla::dom::TabChild
*>(iTabChild
.get());
173 if (MissingRequiredTabChild(tabChild
, "cookie")) {
174 return NS_ERROR_ILLEGAL_VALUE
;
178 // Synchronously call the parent.
179 SendSetCookieString(uriParams
, !!isForeign
, cookieString
, serverTime
,
180 aFromHttp
, IPC::SerializedLoadContext(aChannel
), tabChild
);
185 CookieServiceChild::Observe(nsISupports
*aSubject
,
187 const PRUnichar
*aData
)
189 NS_ASSERTION(strcmp(aTopic
, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID
) == 0,
190 "not a pref change topic!");
192 nsCOMPtr
<nsIPrefBranch
> prefBranch
= do_QueryInterface(aSubject
);
194 PrefChanged(prefBranch
);
199 CookieServiceChild::GetCookieString(nsIURI
*aHostURI
,
200 nsIChannel
*aChannel
,
201 char **aCookieString
)
203 return GetCookieStringInternal(aHostURI
, aChannel
, aCookieString
, false);
207 CookieServiceChild::GetCookieStringFromHttp(nsIURI
*aHostURI
,
209 nsIChannel
*aChannel
,
210 char **aCookieString
)
212 return GetCookieStringInternal(aHostURI
, aChannel
, aCookieString
, true);
216 CookieServiceChild::SetCookieString(nsIURI
*aHostURI
,
218 const char *aCookieString
,
219 nsIChannel
*aChannel
)
221 return SetCookieStringInternal(aHostURI
, aChannel
, aCookieString
,
226 CookieServiceChild::SetCookieStringFromHttp(nsIURI
*aHostURI
,
229 const char *aCookieString
,
230 const char *aServerTime
,
231 nsIChannel
*aChannel
)
233 return SetCookieStringInternal(aHostURI
, aChannel
, aCookieString
,