|
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/. */ |
|
5 |
|
6 #include "mozilla/net/CookieServiceChild.h" |
|
7 #include "mozilla/ipc/URIUtils.h" |
|
8 #include "mozilla/net/NeckoChild.h" |
|
9 #include "nsIURI.h" |
|
10 #include "nsIPrefService.h" |
|
11 #include "nsIPrefBranch.h" |
|
12 #include "nsNetUtil.h" |
|
13 #include "SerializedLoadContext.h" |
|
14 |
|
15 using namespace mozilla::ipc; |
|
16 |
|
17 namespace mozilla { |
|
18 namespace net { |
|
19 |
|
20 // Behavior pref constants |
|
21 static const int32_t BEHAVIOR_ACCEPT = 0; |
|
22 static const int32_t BEHAVIOR_REJECTFOREIGN = 1; |
|
23 // static const int32_t BEHAVIOR_REJECT = 2; |
|
24 static const int32_t BEHAVIOR_LIMITFOREIGN = 3; |
|
25 |
|
26 // Pref string constants |
|
27 static const char kPrefCookieBehavior[] = "network.cookie.cookieBehavior"; |
|
28 static const char kPrefThirdPartySession[] = |
|
29 "network.cookie.thirdparty.sessionOnly"; |
|
30 |
|
31 static CookieServiceChild *gCookieService; |
|
32 |
|
33 CookieServiceChild* |
|
34 CookieServiceChild::GetSingleton() |
|
35 { |
|
36 if (!gCookieService) |
|
37 gCookieService = new CookieServiceChild(); |
|
38 |
|
39 NS_ADDREF(gCookieService); |
|
40 return gCookieService; |
|
41 } |
|
42 |
|
43 NS_IMPL_ISUPPORTS(CookieServiceChild, |
|
44 nsICookieService, |
|
45 nsIObserver, |
|
46 nsISupportsWeakReference) |
|
47 |
|
48 CookieServiceChild::CookieServiceChild() |
|
49 : mCookieBehavior(BEHAVIOR_ACCEPT) |
|
50 , mThirdPartySession(false) |
|
51 { |
|
52 NS_ASSERTION(IsNeckoChild(), "not a child process"); |
|
53 |
|
54 // This corresponds to Release() in DeallocPCookieService. |
|
55 NS_ADDREF_THIS(); |
|
56 |
|
57 // Create a child PCookieService actor. |
|
58 NeckoChild::InitNeckoChild(); |
|
59 gNeckoChild->SendPCookieServiceConstructor(this); |
|
60 |
|
61 // Init our prefs and observer. |
|
62 nsCOMPtr<nsIPrefBranch> prefBranch = |
|
63 do_GetService(NS_PREFSERVICE_CONTRACTID); |
|
64 NS_WARN_IF_FALSE(prefBranch, "no prefservice"); |
|
65 if (prefBranch) { |
|
66 prefBranch->AddObserver(kPrefCookieBehavior, this, true); |
|
67 prefBranch->AddObserver(kPrefThirdPartySession, this, true); |
|
68 PrefChanged(prefBranch); |
|
69 } |
|
70 } |
|
71 |
|
72 CookieServiceChild::~CookieServiceChild() |
|
73 { |
|
74 gCookieService = nullptr; |
|
75 } |
|
76 |
|
77 void |
|
78 CookieServiceChild::PrefChanged(nsIPrefBranch *aPrefBranch) |
|
79 { |
|
80 int32_t val; |
|
81 if (NS_SUCCEEDED(aPrefBranch->GetIntPref(kPrefCookieBehavior, &val))) |
|
82 mCookieBehavior = |
|
83 val >= BEHAVIOR_ACCEPT && val <= BEHAVIOR_LIMITFOREIGN ? val : BEHAVIOR_ACCEPT; |
|
84 |
|
85 bool boolval; |
|
86 if (NS_SUCCEEDED(aPrefBranch->GetBoolPref(kPrefThirdPartySession, &boolval))) |
|
87 mThirdPartySession = !!boolval; |
|
88 |
|
89 if (!mThirdPartyUtil && RequireThirdPartyCheck()) { |
|
90 mThirdPartyUtil = do_GetService(THIRDPARTYUTIL_CONTRACTID); |
|
91 NS_ASSERTION(mThirdPartyUtil, "require ThirdPartyUtil service"); |
|
92 } |
|
93 } |
|
94 |
|
95 bool |
|
96 CookieServiceChild::RequireThirdPartyCheck() |
|
97 { |
|
98 return mCookieBehavior == BEHAVIOR_REJECTFOREIGN || mCookieBehavior == BEHAVIOR_LIMITFOREIGN || mThirdPartySession; |
|
99 } |
|
100 |
|
101 nsresult |
|
102 CookieServiceChild::GetCookieStringInternal(nsIURI *aHostURI, |
|
103 nsIChannel *aChannel, |
|
104 char **aCookieString, |
|
105 bool aFromHttp) |
|
106 { |
|
107 NS_ENSURE_ARG(aHostURI); |
|
108 NS_ENSURE_ARG_POINTER(aCookieString); |
|
109 |
|
110 *aCookieString = nullptr; |
|
111 |
|
112 // Determine whether the request is foreign. Failure is acceptable. |
|
113 bool isForeign = true; |
|
114 if (RequireThirdPartyCheck()) |
|
115 mThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI, &isForeign); |
|
116 |
|
117 URIParams uriParams; |
|
118 SerializeURI(aHostURI, uriParams); |
|
119 |
|
120 // Synchronously call the parent. |
|
121 nsAutoCString result; |
|
122 SendGetCookieString(uriParams, !!isForeign, aFromHttp, |
|
123 IPC::SerializedLoadContext(aChannel), &result); |
|
124 if (!result.IsEmpty()) |
|
125 *aCookieString = ToNewCString(result); |
|
126 |
|
127 return NS_OK; |
|
128 } |
|
129 |
|
130 nsresult |
|
131 CookieServiceChild::SetCookieStringInternal(nsIURI *aHostURI, |
|
132 nsIChannel *aChannel, |
|
133 const char *aCookieString, |
|
134 const char *aServerTime, |
|
135 bool aFromHttp) |
|
136 { |
|
137 NS_ENSURE_ARG(aHostURI); |
|
138 NS_ENSURE_ARG_POINTER(aCookieString); |
|
139 |
|
140 // Determine whether the request is foreign. Failure is acceptable. |
|
141 bool isForeign = true; |
|
142 if (RequireThirdPartyCheck()) |
|
143 mThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI, &isForeign); |
|
144 |
|
145 nsDependentCString cookieString(aCookieString); |
|
146 nsDependentCString serverTime; |
|
147 if (aServerTime) |
|
148 serverTime.Rebind(aServerTime); |
|
149 |
|
150 URIParams uriParams; |
|
151 SerializeURI(aHostURI, uriParams); |
|
152 |
|
153 // Synchronously call the parent. |
|
154 SendSetCookieString(uriParams, !!isForeign, cookieString, serverTime, |
|
155 aFromHttp, IPC::SerializedLoadContext(aChannel)); |
|
156 return NS_OK; |
|
157 } |
|
158 |
|
159 NS_IMETHODIMP |
|
160 CookieServiceChild::Observe(nsISupports *aSubject, |
|
161 const char *aTopic, |
|
162 const char16_t *aData) |
|
163 { |
|
164 NS_ASSERTION(strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0, |
|
165 "not a pref change topic!"); |
|
166 |
|
167 nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(aSubject); |
|
168 if (prefBranch) |
|
169 PrefChanged(prefBranch); |
|
170 return NS_OK; |
|
171 } |
|
172 |
|
173 NS_IMETHODIMP |
|
174 CookieServiceChild::GetCookieString(nsIURI *aHostURI, |
|
175 nsIChannel *aChannel, |
|
176 char **aCookieString) |
|
177 { |
|
178 return GetCookieStringInternal(aHostURI, aChannel, aCookieString, false); |
|
179 } |
|
180 |
|
181 NS_IMETHODIMP |
|
182 CookieServiceChild::GetCookieStringFromHttp(nsIURI *aHostURI, |
|
183 nsIURI *aFirstURI, |
|
184 nsIChannel *aChannel, |
|
185 char **aCookieString) |
|
186 { |
|
187 return GetCookieStringInternal(aHostURI, aChannel, aCookieString, true); |
|
188 } |
|
189 |
|
190 NS_IMETHODIMP |
|
191 CookieServiceChild::SetCookieString(nsIURI *aHostURI, |
|
192 nsIPrompt *aPrompt, |
|
193 const char *aCookieString, |
|
194 nsIChannel *aChannel) |
|
195 { |
|
196 return SetCookieStringInternal(aHostURI, aChannel, aCookieString, |
|
197 nullptr, false); |
|
198 } |
|
199 |
|
200 NS_IMETHODIMP |
|
201 CookieServiceChild::SetCookieStringFromHttp(nsIURI *aHostURI, |
|
202 nsIURI *aFirstURI, |
|
203 nsIPrompt *aPrompt, |
|
204 const char *aCookieString, |
|
205 const char *aServerTime, |
|
206 nsIChannel *aChannel) |
|
207 { |
|
208 return SetCookieStringInternal(aHostURI, aChannel, aCookieString, |
|
209 aServerTime, true); |
|
210 } |
|
211 |
|
212 } |
|
213 } |
|
214 |