OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 // Provides a temporary redirection while clients are updated to use the new |
| 6 // path. |
| 7 |
5 #ifndef NET_BASE_COOKIE_STORE_UNITTEST_H_ | 8 #ifndef NET_BASE_COOKIE_STORE_UNITTEST_H_ |
6 #define NET_BASE_COOKIE_STORE_UNITTEST_H_ | 9 #define NET_BASE_COOKIE_STORE_UNITTEST_H_ |
7 #pragma once | 10 #pragma once |
8 | 11 |
9 #include "base/bind.h" | 12 #include "net/cookies/cookie_store_unittest.h" |
10 #include "base/message_loop.h" | |
11 #include "base/string_tokenizer.h" | |
12 #include "base/threading/thread.h" | |
13 #include "googleurl/src/gurl.h" | |
14 #include "net/base/cookie_monster.h" | |
15 #include "net/base/cookie_store.h" | |
16 #include "net/base/cookie_store_test_callbacks.h" | |
17 #include "testing/gtest/include/gtest/gtest.h" | |
18 | |
19 // This file declares unittest templates that can be used to test common | |
20 // behavior of any CookieStore implementation. | |
21 // See cookie_monster_unittest.cc for an example of an implementation. | |
22 | |
23 namespace net { | |
24 | |
25 using base::Thread; | |
26 | |
27 const int kTimeout = 1000; | |
28 | |
29 const char kUrlFtp[] = "ftp://ftp.google.izzle/"; | |
30 const char kUrlGoogle[] = "http://www.google.izzle"; | |
31 const char kUrlGoogleFoo[] = "http://www.google.izzle/foo"; | |
32 const char kUrlGoogleBar[] = "http://www.google.izzle/bar"; | |
33 const char kUrlGoogleSecure[] = "https://www.google.izzle"; | |
34 const char kValidCookieLine[] = "A=B; path=/"; | |
35 const char kValidDomainCookieLine[] = "A=B; path=/; domain=google.izzle"; | |
36 | |
37 // The CookieStoreTestTraits must have the following members: | |
38 // struct CookieStoreTestTraits { | |
39 // // Factory function. | |
40 // static scoped_refptr<CookieStore> Create(); | |
41 // | |
42 // // The cookie store is a CookieMonster. Only used to test | |
43 // // GetCookieMonster(). | |
44 // static const bool is_cookie_monster; | |
45 // | |
46 // // The cookie store supports cookies with the exclude_httponly() option. | |
47 // static const bool supports_http_only; | |
48 // | |
49 // // The cookie store supports the GetCookiesWithInfoAsync() method. | |
50 // static const bool supports_cookies_with_info; | |
51 // | |
52 // // The cookie store is able to make the difference between the ".com" | |
53 // // and the "com" domains. | |
54 // static const bool supports_non_dotted_domains; | |
55 // | |
56 // // The cookie store handles the domains with trailing dots (such as "com.") | |
57 // // correctly. | |
58 // static const bool supports_trailing_dots; | |
59 // | |
60 // // The cookie store rejects cookies for invalid schemes such as ftp. | |
61 // static const bool filters_schemes; | |
62 // | |
63 // // The cookie store has a bug happening when a path is a substring of | |
64 // // another. | |
65 // static const bool has_path_prefix_bug; | |
66 // | |
67 // // Time to wait between two cookie insertions to ensure that cookies have | |
68 // // different creation times. | |
69 // static const int creation_time_granularity_in_ms; | |
70 // }; | |
71 | |
72 template <class CookieStoreTestTraits> | |
73 class CookieStoreTest : public testing::Test { | |
74 protected: | |
75 CookieStoreTest() | |
76 : url_google_(kUrlGoogle), | |
77 url_google_secure_(kUrlGoogleSecure), | |
78 url_google_foo_(kUrlGoogleFoo), | |
79 url_google_bar_(kUrlGoogleBar) { | |
80 // This test may be used outside of the net test suite, and thus may not | |
81 // have a message loop. | |
82 if (!MessageLoop::current()) | |
83 message_loop_.reset(new MessageLoop); | |
84 weak_factory_.reset( | |
85 new base::WeakPtrFactory<MessageLoop>(MessageLoop::current())); | |
86 } | |
87 | |
88 // Helper methods for the asynchronous Cookie Store API that call the | |
89 // asynchronous method and then pump the loop until the callback is invoked, | |
90 // finally returning the value. | |
91 | |
92 std::string GetCookies(CookieStore* cs, const GURL& url) { | |
93 DCHECK(cs); | |
94 CookieOptions options; | |
95 if (!CookieStoreTestTraits::supports_http_only) | |
96 options.set_include_httponly(); | |
97 GetCookieStringCallback callback; | |
98 cs->GetCookiesWithOptionsAsync( | |
99 url, options, | |
100 base::Bind(&GetCookieStringCallback::Run, base::Unretained(&callback))); | |
101 RunFor(kTimeout); | |
102 EXPECT_TRUE(callback.did_run()); | |
103 return callback.cookie(); | |
104 } | |
105 | |
106 std::string GetCookiesWithOptions(CookieStore* cs, | |
107 const GURL& url, | |
108 const CookieOptions& options) { | |
109 DCHECK(cs); | |
110 GetCookieStringCallback callback; | |
111 cs->GetCookiesWithOptionsAsync( | |
112 url, options, base::Bind(&GetCookieStringCallback::Run, | |
113 base::Unretained(&callback))); | |
114 RunFor(kTimeout); | |
115 EXPECT_TRUE(callback.did_run()); | |
116 return callback.cookie(); | |
117 } | |
118 | |
119 void GetCookiesWithInfo(CookieStore* cs, | |
120 const GURL& url, | |
121 const CookieOptions& options, | |
122 std::string* cookie_line, | |
123 std::vector<CookieStore::CookieInfo>* cookie_info) { | |
124 DCHECK(cs); | |
125 DCHECK(cookie_line); | |
126 DCHECK(cookie_info); | |
127 GetCookiesWithInfoCallback callback; | |
128 cs->GetCookiesWithInfoAsync( | |
129 url, options, base::Bind(&GetCookiesWithInfoCallback::Run, | |
130 base::Unretained(&callback))); | |
131 RunFor(kTimeout); | |
132 EXPECT_TRUE(callback.did_run()); | |
133 *cookie_line = callback.cookie_line(); | |
134 *cookie_info = callback.cookie_info(); | |
135 } | |
136 | |
137 bool SetCookieWithOptions(CookieStore* cs, | |
138 const GURL& url, | |
139 const std::string& cookie_line, | |
140 const CookieOptions& options) { | |
141 DCHECK(cs); | |
142 SetCookieCallback callback; | |
143 cs->SetCookieWithOptionsAsync( | |
144 url, cookie_line, options, | |
145 base::Bind(&SetCookieCallback::Run, base::Unretained(&callback))); | |
146 RunFor(kTimeout); | |
147 EXPECT_TRUE(callback.did_run()); | |
148 return callback.result(); | |
149 } | |
150 | |
151 bool SetCookie(CookieStore* cs, | |
152 const GURL& url, | |
153 const std::string& cookie_line) { | |
154 CookieOptions options; | |
155 if (!CookieStoreTestTraits::supports_http_only) | |
156 options.set_include_httponly(); | |
157 return SetCookieWithOptions(cs, url, cookie_line, options); | |
158 } | |
159 | |
160 void DeleteCookie(CookieStore* cs, | |
161 const GURL& url, | |
162 const std::string& cookie_name) { | |
163 DCHECK(cs); | |
164 DeleteCookieCallback callback; | |
165 cs->DeleteCookieAsync( | |
166 url, cookie_name, | |
167 base::Bind(&DeleteCookieCallback::Run, base::Unretained(&callback))); | |
168 RunFor(kTimeout); | |
169 EXPECT_TRUE(callback.did_run()); | |
170 } | |
171 | |
172 int DeleteCreatedBetween(CookieStore* cs, | |
173 const base::Time& delete_begin, | |
174 const base::Time& delete_end) { | |
175 DCHECK(cs); | |
176 DeleteCallback callback; | |
177 cs->DeleteAllCreatedBetweenAsync( | |
178 delete_begin, delete_end, | |
179 base::Bind(&DeleteCallback::Run, base::Unretained(&callback))); | |
180 RunFor(kTimeout); | |
181 EXPECT_TRUE(callback.did_run()); | |
182 return callback.num_deleted(); | |
183 } | |
184 | |
185 void RunFor(int ms) { | |
186 // Runs the test thread message loop for up to |ms| milliseconds. | |
187 MessageLoop::current()->PostDelayedTask( | |
188 FROM_HERE, base::Bind(&MessageLoop::Quit, weak_factory_->GetWeakPtr()), | |
189 base::TimeDelta::FromMilliseconds(ms)); | |
190 MessageLoop::current()->Run(); | |
191 weak_factory_->InvalidateWeakPtrs(); | |
192 } | |
193 | |
194 scoped_refptr<CookieStore> GetCookieStore() { | |
195 return CookieStoreTestTraits::Create(); | |
196 } | |
197 | |
198 // Compares two cookie lines. | |
199 void MatchCookieLines(const std::string& line1, const std::string& line2) { | |
200 EXPECT_EQ(TokenizeCookieLine(line1), TokenizeCookieLine(line2)); | |
201 } | |
202 | |
203 // Check the cookie line by polling until equality or a timeout is reached. | |
204 void MatchCookieLineWithTimeout(CookieStore* cs, | |
205 const GURL& url, | |
206 const std::string& line) { | |
207 std::string cookies = GetCookies(cs, url); | |
208 bool matched = (TokenizeCookieLine(line) == TokenizeCookieLine(cookies)); | |
209 base::Time polling_end_date = base::Time::Now() + | |
210 base::TimeDelta::FromMilliseconds( | |
211 CookieStoreTestTraits::creation_time_granularity_in_ms); | |
212 | |
213 while (!matched && base::Time::Now() <= polling_end_date) { | |
214 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10)); | |
215 cookies = GetCookies(cs, url); | |
216 matched = (TokenizeCookieLine(line) == TokenizeCookieLine(cookies)); | |
217 } | |
218 | |
219 EXPECT_TRUE(matched) << "\"" << cookies | |
220 << "\" does not match \"" << line << "\""; | |
221 } | |
222 | |
223 GURL url_google_; | |
224 GURL url_google_secure_; | |
225 GURL url_google_foo_; | |
226 GURL url_google_bar_; | |
227 | |
228 scoped_ptr<base::WeakPtrFactory<MessageLoop> > weak_factory_; | |
229 scoped_ptr<MessageLoop> message_loop_; | |
230 | |
231 private: | |
232 // Returns a set of strings of type "name=value". Fails in case of duplicate. | |
233 std::set<std::string> TokenizeCookieLine(const std::string& line) { | |
234 std::set<std::string> tokens; | |
235 StringTokenizer tokenizer(line, " ;"); | |
236 while (tokenizer.GetNext()) | |
237 EXPECT_TRUE(tokens.insert(tokenizer.token()).second); | |
238 return tokens; | |
239 } | |
240 }; | |
241 | |
242 TYPED_TEST_CASE_P(CookieStoreTest); | |
243 | |
244 TYPED_TEST_P(CookieStoreTest, TypeTest) { | |
245 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
246 EXPECT_EQ(cs->GetCookieMonster(), | |
247 (TypeParam::is_cookie_monster) ? | |
248 static_cast<CookieMonster*>(cs.get()) : NULL); | |
249 } | |
250 | |
251 TYPED_TEST_P(CookieStoreTest, DomainTest) { | |
252 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
253 EXPECT_TRUE(this->SetCookie(cs, this->url_google_, "A=B")); | |
254 this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_)); | |
255 EXPECT_TRUE(this->SetCookie(cs, this->url_google_, | |
256 "C=D; domain=.google.izzle")); | |
257 this->MatchCookieLines("A=B; C=D", this->GetCookies(cs, this->url_google_)); | |
258 | |
259 // Verify that A=B was set as a host cookie rather than a domain | |
260 // cookie -- should not be accessible from a sub sub-domain. | |
261 this->MatchCookieLines("C=D", | |
262 this->GetCookies(cs, GURL("http://foo.www.google.izzle"))); | |
263 | |
264 // Test and make sure we find domain cookies on the same domain. | |
265 EXPECT_TRUE(this->SetCookie(cs, this->url_google_, | |
266 "E=F; domain=.www.google.izzle")); | |
267 this->MatchCookieLines("A=B; C=D; E=F", | |
268 this->GetCookies(cs, this->url_google_)); | |
269 | |
270 // Test setting a domain= that doesn't start w/ a dot, should | |
271 // treat it as a domain cookie, as if there was a pre-pended dot. | |
272 EXPECT_TRUE(this->SetCookie(cs, this->url_google_, | |
273 "G=H; domain=www.google.izzle")); | |
274 this->MatchCookieLines("A=B; C=D; E=F; G=H", | |
275 this->GetCookies(cs, this->url_google_)); | |
276 | |
277 // Test domain enforcement, should fail on a sub-domain or something too deep. | |
278 EXPECT_FALSE(this->SetCookie(cs, this->url_google_, "I=J; domain=.izzle")); | |
279 this->MatchCookieLines("", this->GetCookies(cs, GURL("http://a.izzle"))); | |
280 EXPECT_FALSE(this->SetCookie(cs, this->url_google_, | |
281 "K=L; domain=.bla.www.google.izzle")); | |
282 this->MatchCookieLines("C=D; E=F; G=H", | |
283 this->GetCookies(cs, GURL("http://bla.www.google.izzle"))); | |
284 this->MatchCookieLines("A=B; C=D; E=F; G=H", | |
285 this->GetCookies(cs, this->url_google_)); | |
286 } | |
287 | |
288 // FireFox recognizes domains containing trailing periods as valid. | |
289 // IE and Safari do not. Assert the expected policy here. | |
290 TYPED_TEST_P(CookieStoreTest, DomainWithTrailingDotTest) { | |
291 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
292 EXPECT_FALSE(this->SetCookie(cs, this->url_google_, | |
293 "a=1; domain=.www.google.com.")); | |
294 EXPECT_FALSE(this->SetCookie(cs, this->url_google_, | |
295 "b=2; domain=.www.google.com..")); | |
296 this->MatchCookieLines("", this->GetCookies(cs, this->url_google_)); | |
297 } | |
298 | |
299 // Test that cookies can bet set on higher level domains. | |
300 // http://b/issue?id=896491 | |
301 TYPED_TEST_P(CookieStoreTest, ValidSubdomainTest) { | |
302 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
303 GURL url_abcd("http://a.b.c.d.com"); | |
304 GURL url_bcd("http://b.c.d.com"); | |
305 GURL url_cd("http://c.d.com"); | |
306 GURL url_d("http://d.com"); | |
307 | |
308 EXPECT_TRUE(this->SetCookie(cs, url_abcd, "a=1; domain=.a.b.c.d.com")); | |
309 EXPECT_TRUE(this->SetCookie(cs, url_abcd, "b=2; domain=.b.c.d.com")); | |
310 EXPECT_TRUE(this->SetCookie(cs, url_abcd, "c=3; domain=.c.d.com")); | |
311 EXPECT_TRUE(this->SetCookie(cs, url_abcd, "d=4; domain=.d.com")); | |
312 | |
313 this->MatchCookieLines("a=1; b=2; c=3; d=4", this->GetCookies(cs, url_abcd)); | |
314 this->MatchCookieLines("b=2; c=3; d=4", this->GetCookies(cs, url_bcd)); | |
315 this->MatchCookieLines("c=3; d=4", this->GetCookies(cs, url_cd)); | |
316 this->MatchCookieLines("d=4", this->GetCookies(cs, url_d)); | |
317 | |
318 // Check that the same cookie can exist on different sub-domains. | |
319 EXPECT_TRUE(this->SetCookie(cs, url_bcd, "X=bcd; domain=.b.c.d.com")); | |
320 EXPECT_TRUE(this->SetCookie(cs, url_bcd, "X=cd; domain=.c.d.com")); | |
321 this->MatchCookieLines("b=2; c=3; d=4; X=bcd; X=cd", | |
322 this->GetCookies(cs, url_bcd)); | |
323 this->MatchCookieLines("c=3; d=4; X=cd", this->GetCookies(cs, url_cd)); | |
324 } | |
325 | |
326 // Test that setting a cookie which specifies an invalid domain has | |
327 // no side-effect. An invalid domain in this context is one which does | |
328 // not match the originating domain. | |
329 // http://b/issue?id=896472 | |
330 TYPED_TEST_P(CookieStoreTest, InvalidDomainTest) { | |
331 { | |
332 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
333 GURL url_foobar("http://foo.bar.com"); | |
334 | |
335 // More specific sub-domain than allowed. | |
336 EXPECT_FALSE(this->SetCookie(cs, url_foobar, | |
337 "a=1; domain=.yo.foo.bar.com")); | |
338 | |
339 EXPECT_FALSE(this->SetCookie(cs, url_foobar, "b=2; domain=.foo.com")); | |
340 EXPECT_FALSE(this->SetCookie(cs, url_foobar, "c=3; domain=.bar.foo.com")); | |
341 | |
342 // Different TLD, but the rest is a substring. | |
343 EXPECT_FALSE(this->SetCookie(cs, url_foobar, | |
344 "d=4; domain=.foo.bar.com.net")); | |
345 | |
346 // A substring that isn't really a parent domain. | |
347 EXPECT_FALSE(this->SetCookie(cs, url_foobar, "e=5; domain=ar.com")); | |
348 | |
349 // Completely invalid domains: | |
350 EXPECT_FALSE(this->SetCookie(cs, url_foobar, "f=6; domain=.")); | |
351 EXPECT_FALSE(this->SetCookie(cs, url_foobar, "g=7; domain=/")); | |
352 EXPECT_FALSE(this->SetCookie(cs, url_foobar, | |
353 "h=8; domain=http://foo.bar.com")); | |
354 EXPECT_FALSE(this->SetCookie(cs, url_foobar, "i=9; domain=..foo.bar.com")); | |
355 EXPECT_FALSE(this->SetCookie(cs, url_foobar, "j=10; domain=..bar.com")); | |
356 | |
357 // Make sure there isn't something quirky in the domain canonicalization | |
358 // that supports full URL semantics. | |
359 EXPECT_FALSE(this->SetCookie(cs, url_foobar, | |
360 "k=11; domain=.foo.bar.com?blah")); | |
361 EXPECT_FALSE(this->SetCookie(cs, url_foobar, | |
362 "l=12; domain=.foo.bar.com/blah")); | |
363 EXPECT_FALSE(this->SetCookie(cs, url_foobar, | |
364 "m=13; domain=.foo.bar.com:80")); | |
365 EXPECT_FALSE(this->SetCookie(cs, url_foobar, | |
366 "n=14; domain=.foo.bar.com:")); | |
367 EXPECT_FALSE(this->SetCookie(cs, url_foobar, | |
368 "o=15; domain=.foo.bar.com#sup")); | |
369 | |
370 this->MatchCookieLines("", this->GetCookies(cs, url_foobar)); | |
371 } | |
372 | |
373 { | |
374 // Make sure the cookie code hasn't gotten its subdomain string handling | |
375 // reversed, missed a suffix check, etc. It's important here that the two | |
376 // hosts below have the same domain + registry. | |
377 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
378 GURL url_foocom("http://foo.com.com"); | |
379 EXPECT_FALSE(this->SetCookie(cs, url_foocom, | |
380 "a=1; domain=.foo.com.com.com")); | |
381 this->MatchCookieLines("", this->GetCookies(cs, url_foocom)); | |
382 } | |
383 } | |
384 | |
385 // Test the behavior of omitting dot prefix from domain, should | |
386 // function the same as FireFox. | |
387 // http://b/issue?id=889898 | |
388 TYPED_TEST_P(CookieStoreTest, DomainWithoutLeadingDotTest) { | |
389 { // The omission of dot results in setting a domain cookie. | |
390 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
391 GURL url_hosted("http://manage.hosted.filefront.com"); | |
392 GURL url_filefront("http://www.filefront.com"); | |
393 EXPECT_TRUE(this->SetCookie(cs, url_hosted, | |
394 "sawAd=1; domain=filefront.com")); | |
395 this->MatchCookieLines("sawAd=1", this->GetCookies(cs, url_hosted)); | |
396 this->MatchCookieLines("sawAd=1", this->GetCookies(cs, url_filefront)); | |
397 } | |
398 | |
399 { // Even when the domains match exactly, don't consider it host cookie. | |
400 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
401 GURL url("http://www.google.com"); | |
402 EXPECT_TRUE(this->SetCookie(cs, url, "a=1; domain=www.google.com")); | |
403 this->MatchCookieLines("a=1", this->GetCookies(cs, url)); | |
404 this->MatchCookieLines("a=1", | |
405 this->GetCookies(cs, GURL("http://sub.www.google.com"))); | |
406 this->MatchCookieLines("", | |
407 this->GetCookies(cs, GURL("http://something-else.com"))); | |
408 } | |
409 } | |
410 | |
411 // Test that the domain specified in cookie string is treated case-insensitive | |
412 // http://b/issue?id=896475. | |
413 TYPED_TEST_P(CookieStoreTest, CaseInsensitiveDomainTest) { | |
414 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
415 GURL url("http://www.google.com"); | |
416 EXPECT_TRUE(this->SetCookie(cs, url, "a=1; domain=.GOOGLE.COM")); | |
417 EXPECT_TRUE(this->SetCookie(cs, url, "b=2; domain=.wWw.gOOgLE.coM")); | |
418 this->MatchCookieLines("a=1; b=2", this->GetCookies(cs, url)); | |
419 } | |
420 | |
421 TYPED_TEST_P(CookieStoreTest, TestIpAddress) { | |
422 GURL url_ip("http://1.2.3.4/weee"); | |
423 { | |
424 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
425 EXPECT_TRUE(this->SetCookie(cs, url_ip, kValidCookieLine)); | |
426 this->MatchCookieLines("A=B", this->GetCookies(cs, url_ip)); | |
427 } | |
428 | |
429 { // IP addresses should not be able to set domain cookies. | |
430 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
431 EXPECT_FALSE(this->SetCookie(cs, url_ip, "b=2; domain=.1.2.3.4")); | |
432 EXPECT_FALSE(this->SetCookie(cs, url_ip, "c=3; domain=.3.4")); | |
433 this->MatchCookieLines("", this->GetCookies(cs, url_ip)); | |
434 // It should be allowed to set a cookie if domain= matches the IP address | |
435 // exactly. This matches IE/Firefox, even though it seems a bit wrong. | |
436 EXPECT_FALSE(this->SetCookie(cs, url_ip, "b=2; domain=1.2.3.3")); | |
437 this->MatchCookieLines("", this->GetCookies(cs, url_ip)); | |
438 EXPECT_TRUE(this->SetCookie(cs, url_ip, "b=2; domain=1.2.3.4")); | |
439 this->MatchCookieLines("b=2", this->GetCookies(cs, url_ip)); | |
440 } | |
441 } | |
442 | |
443 // Test host cookies, and setting of cookies on TLD. | |
444 TYPED_TEST_P(CookieStoreTest, TestNonDottedAndTLD) { | |
445 { | |
446 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
447 GURL url("http://com/"); | |
448 // Allow setting on "com", (but only as a host cookie). | |
449 EXPECT_TRUE(this->SetCookie(cs, url, "a=1")); | |
450 EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=.com")); | |
451 EXPECT_FALSE(this->SetCookie(cs, url, "c=3; domain=com")); | |
452 this->MatchCookieLines("a=1", this->GetCookies(cs, url)); | |
453 // Make sure it doesn't show up for a normal .com, it should be a host | |
454 // not a domain cookie. | |
455 this->MatchCookieLines("", | |
456 this->GetCookies(cs, GURL("http://hopefully-no-cookies.com/"))); | |
457 if (TypeParam::supports_non_dotted_domains) { | |
458 this->MatchCookieLines("", this->GetCookies(cs, GURL("http://.com/"))); | |
459 } | |
460 } | |
461 | |
462 { | |
463 // http://com. should be treated the same as http://com. | |
464 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
465 GURL url("http://com./index.html"); | |
466 if (TypeParam::supports_trailing_dots) { | |
467 EXPECT_TRUE(this->SetCookie(cs, url, "a=1")); | |
468 this->MatchCookieLines("a=1", this->GetCookies(cs, url)); | |
469 this->MatchCookieLines("", | |
470 this->GetCookies(cs, GURL("http://hopefully-no-cookies.com./"))); | |
471 } else { | |
472 EXPECT_FALSE(this->SetCookie(cs, url, "a=1")); | |
473 } | |
474 } | |
475 | |
476 { // Should not be able to set host cookie from a subdomain. | |
477 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
478 GURL url("http://a.b"); | |
479 EXPECT_FALSE(this->SetCookie(cs, url, "a=1; domain=.b")); | |
480 EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=b")); | |
481 this->MatchCookieLines("", this->GetCookies(cs, url)); | |
482 } | |
483 | |
484 { // Same test as above, but explicitly on a known TLD (com). | |
485 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
486 GURL url("http://google.com"); | |
487 EXPECT_FALSE(this->SetCookie(cs, url, "a=1; domain=.com")); | |
488 EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=com")); | |
489 this->MatchCookieLines("", this->GetCookies(cs, url)); | |
490 } | |
491 | |
492 { // Make sure can't set cookie on TLD which is dotted. | |
493 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
494 GURL url("http://google.co.uk"); | |
495 EXPECT_FALSE(this->SetCookie(cs, url, "a=1; domain=.co.uk")); | |
496 EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=.uk")); | |
497 this->MatchCookieLines("", this->GetCookies(cs, url)); | |
498 this->MatchCookieLines("", | |
499 this->GetCookies(cs, GURL("http://something-else.co.uk"))); | |
500 this->MatchCookieLines("", | |
501 this->GetCookies(cs, GURL("http://something-else.uk"))); | |
502 } | |
503 | |
504 { // Intranet URLs should only be able to set host cookies. | |
505 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
506 GURL url("http://b"); | |
507 EXPECT_TRUE(this->SetCookie(cs, url, "a=1")); | |
508 EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=.b")); | |
509 EXPECT_FALSE(this->SetCookie(cs, url, "c=3; domain=b")); | |
510 this->MatchCookieLines("a=1", this->GetCookies(cs, url)); | |
511 } | |
512 } | |
513 | |
514 // Test reading/writing cookies when the domain ends with a period, | |
515 // as in "www.google.com." | |
516 TYPED_TEST_P(CookieStoreTest, TestHostEndsWithDot) { | |
517 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
518 GURL url("http://www.google.com"); | |
519 GURL url_with_dot("http://www.google.com."); | |
520 EXPECT_TRUE(this->SetCookie(cs, url, "a=1")); | |
521 this->MatchCookieLines("a=1", this->GetCookies(cs, url)); | |
522 | |
523 if (TypeParam::supports_trailing_dots) { | |
524 // Do not share cookie space with the dot version of domain. | |
525 // Note: this is not what FireFox does, but it _is_ what IE+Safari do. | |
526 EXPECT_FALSE(this->SetCookie(cs, url, "b=2; domain=.www.google.com.")); | |
527 this->MatchCookieLines("a=1", this->GetCookies(cs, url)); | |
528 | |
529 EXPECT_TRUE(this->SetCookie(cs, url_with_dot, "b=2; domain=.google.com.")); | |
530 this->MatchCookieLines("b=2", this->GetCookies(cs, url_with_dot)); | |
531 } else { | |
532 EXPECT_TRUE(this->SetCookie(cs, url, "b=2; domain=.www.google.com.")); | |
533 EXPECT_FALSE(this->SetCookie(cs, url_with_dot, "b=2; domain=.google.com.")); | |
534 } | |
535 | |
536 // Make sure there weren't any side effects. | |
537 this->MatchCookieLines("", | |
538 this->GetCookies(cs, GURL("http://hopefully-no-cookies.com/"))); | |
539 this->MatchCookieLines("", this->GetCookies(cs, GURL("http://.com/"))); | |
540 } | |
541 | |
542 TYPED_TEST_P(CookieStoreTest, InvalidScheme) { | |
543 if (!TypeParam::filters_schemes) | |
544 return; | |
545 | |
546 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
547 EXPECT_FALSE(this->SetCookie(cs, GURL(kUrlFtp), kValidCookieLine)); | |
548 } | |
549 | |
550 TYPED_TEST_P(CookieStoreTest, InvalidScheme_Read) { | |
551 if (!TypeParam::filters_schemes) | |
552 return; | |
553 | |
554 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
555 EXPECT_TRUE(this->SetCookie(cs, GURL(kUrlGoogle), kValidDomainCookieLine)); | |
556 this->MatchCookieLines("", this->GetCookies(cs, GURL(kUrlFtp))); | |
557 } | |
558 | |
559 TYPED_TEST_P(CookieStoreTest, PathTest) { | |
560 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
561 std::string url("http://www.google.izzle"); | |
562 EXPECT_TRUE(this->SetCookie(cs, GURL(url), "A=B; path=/wee")); | |
563 this->MatchCookieLines("A=B", this->GetCookies(cs, GURL(url + "/wee"))); | |
564 this->MatchCookieLines("A=B", this->GetCookies(cs, GURL(url + "/wee/"))); | |
565 this->MatchCookieLines("A=B", this->GetCookies(cs, GURL(url + "/wee/war"))); | |
566 this->MatchCookieLines("A=B", | |
567 this->GetCookies(cs, GURL(url + "/wee/war/more/more"))); | |
568 if (!TypeParam::has_path_prefix_bug) | |
569 this->MatchCookieLines("", this->GetCookies(cs, GURL(url + "/weehee"))); | |
570 this->MatchCookieLines("", this->GetCookies(cs, GURL(url + "/"))); | |
571 | |
572 // If we add a 0 length path, it should default to / | |
573 EXPECT_TRUE(this->SetCookie(cs, GURL(url), "A=C; path=")); | |
574 this->MatchCookieLines("A=B; A=C", this->GetCookies(cs, GURL(url + "/wee"))); | |
575 this->MatchCookieLines("A=C", this->GetCookies(cs, GURL(url + "/"))); | |
576 } | |
577 | |
578 TYPED_TEST_P(CookieStoreTest, HttpOnlyTest) { | |
579 if (!TypeParam::supports_http_only) | |
580 return; | |
581 | |
582 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
583 CookieOptions options; | |
584 options.set_include_httponly(); | |
585 | |
586 // Create a httponly cookie. | |
587 EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_, "A=B; httponly", | |
588 options)); | |
589 | |
590 // Check httponly read protection. | |
591 this->MatchCookieLines("", this->GetCookies(cs, this->url_google_)); | |
592 this->MatchCookieLines("A=B", | |
593 this->GetCookiesWithOptions(cs, this->url_google_, options)); | |
594 | |
595 // Check httponly overwrite protection. | |
596 EXPECT_FALSE(this->SetCookie(cs, this->url_google_, "A=C")); | |
597 this->MatchCookieLines("", this->GetCookies(cs, this->url_google_)); | |
598 this->MatchCookieLines("A=B", | |
599 this->GetCookiesWithOptions(cs, this->url_google_, options)); | |
600 EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_, "A=C", | |
601 options)); | |
602 this->MatchCookieLines("A=C", this->GetCookies(cs, this->url_google_)); | |
603 | |
604 // Check httponly create protection. | |
605 EXPECT_FALSE(this->SetCookie(cs, this->url_google_, "B=A; httponly")); | |
606 this->MatchCookieLines("A=C", | |
607 this->GetCookiesWithOptions(cs, this->url_google_, options)); | |
608 EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_, "B=A; httponly", | |
609 options)); | |
610 this->MatchCookieLines("A=C; B=A", | |
611 this->GetCookiesWithOptions(cs, this->url_google_, options)); | |
612 this->MatchCookieLines("A=C", this->GetCookies(cs, this->url_google_)); | |
613 } | |
614 | |
615 TYPED_TEST_P(CookieStoreTest, TestGetCookiesWithInfo) { | |
616 if (!TypeParam::supports_cookies_with_info) | |
617 return; | |
618 | |
619 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
620 CookieOptions options; | |
621 | |
622 EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_, "A=B", | |
623 options)); | |
624 EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_, | |
625 "C=D; Mac-Key=390jfn0awf3; Mac-Algorithm=hmac-sha-1", options)); | |
626 | |
627 this->MatchCookieLines("A=B; C=D", | |
628 this->GetCookiesWithOptions(cs, this->url_google_, options)); | |
629 | |
630 std::string cookie_line; | |
631 std::vector<CookieStore::CookieInfo> cookie_infos; | |
632 | |
633 this->GetCookiesWithInfo(cs, this->url_google_, options, &cookie_line, | |
634 &cookie_infos); | |
635 | |
636 EXPECT_EQ("A=B; C=D", cookie_line); | |
637 | |
638 EXPECT_EQ(2U, cookie_infos.size()); | |
639 | |
640 EXPECT_EQ("A", cookie_infos[0].name); | |
641 EXPECT_EQ("", cookie_infos[0].mac_key); | |
642 EXPECT_EQ("", cookie_infos[0].mac_algorithm); | |
643 | |
644 EXPECT_EQ("C", cookie_infos[1].name); | |
645 EXPECT_EQ("390jfn0awf3", cookie_infos[1].mac_key); | |
646 EXPECT_EQ("hmac-sha-1", cookie_infos[1].mac_algorithm); | |
647 } | |
648 | |
649 TYPED_TEST_P(CookieStoreTest, TestCookieDeletion) { | |
650 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
651 | |
652 // Create a session cookie. | |
653 EXPECT_TRUE(this->SetCookie(cs, this->url_google_, kValidCookieLine)); | |
654 this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_)); | |
655 // Delete it via Max-Age. | |
656 EXPECT_TRUE(this->SetCookie(cs, this->url_google_, | |
657 std::string(kValidCookieLine) + "; max-age=0")); | |
658 this->MatchCookieLineWithTimeout(cs, this->url_google_, ""); | |
659 | |
660 // Create a session cookie. | |
661 EXPECT_TRUE(this->SetCookie(cs, this->url_google_, kValidCookieLine)); | |
662 this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_)); | |
663 // Delete it via Expires. | |
664 EXPECT_TRUE(this->SetCookie(cs, this->url_google_, | |
665 std::string(kValidCookieLine) + | |
666 "; expires=Mon, 18-Apr-1977 22:50:13 GMT")); | |
667 this->MatchCookieLines("", this->GetCookies(cs, this->url_google_)); | |
668 | |
669 // Create a persistent cookie. | |
670 EXPECT_TRUE(this->SetCookie(cs, this->url_google_, | |
671 std::string(kValidCookieLine) + | |
672 "; expires=Mon, 18-Apr-22 22:50:13 GMT")); | |
673 | |
674 this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_)); | |
675 // Delete it via Max-Age. | |
676 EXPECT_TRUE(this->SetCookie(cs, this->url_google_, | |
677 std::string(kValidCookieLine) + "; max-age=0")); | |
678 this->MatchCookieLineWithTimeout(cs, this->url_google_, ""); | |
679 | |
680 // Create a persistent cookie. | |
681 EXPECT_TRUE(this->SetCookie(cs, this->url_google_, | |
682 std::string(kValidCookieLine) + | |
683 "; expires=Mon, 18-Apr-22 22:50:13 GMT")); | |
684 this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_)); | |
685 // Delete it via Expires. | |
686 EXPECT_TRUE(this->SetCookie(cs, this->url_google_, | |
687 std::string(kValidCookieLine) + | |
688 "; expires=Mon, 18-Apr-1977 22:50:13 GMT")); | |
689 this->MatchCookieLines("", this->GetCookies(cs, this->url_google_)); | |
690 | |
691 // Create a persistent cookie. | |
692 EXPECT_TRUE(this->SetCookie(cs, this->url_google_, | |
693 std::string(kValidCookieLine) + | |
694 "; expires=Mon, 18-Apr-22 22:50:13 GMT")); | |
695 this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_)); | |
696 // Delete it via Expires, with a unix epoch of 0. | |
697 EXPECT_TRUE(this->SetCookie(cs, this->url_google_, | |
698 std::string(kValidCookieLine) + | |
699 "; expires=Thu, 1-Jan-1970 00:00:00 GMT")); | |
700 this->MatchCookieLines("", this->GetCookies(cs, this->url_google_)); | |
701 } | |
702 | |
703 TYPED_TEST_P(CookieStoreTest, TestDeleteAllCreatedBetween) { | |
704 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
705 const base::Time last_month = base::Time::Now() - | |
706 base::TimeDelta::FromDays(30); | |
707 const base::Time last_minute = base::Time::Now() - | |
708 base::TimeDelta::FromMinutes(1); | |
709 const base::Time next_minute = base::Time::Now() + | |
710 base::TimeDelta::FromMinutes(1); | |
711 const base::Time next_month = base::Time::Now() + | |
712 base::TimeDelta::FromDays(30); | |
713 | |
714 // Add a cookie. | |
715 EXPECT_TRUE(this->SetCookie(cs, this->url_google_, "A=B")); | |
716 // Check that the cookie is in the store. | |
717 this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_)); | |
718 | |
719 // Remove cookies in empty intervals. | |
720 EXPECT_EQ(0, this->DeleteCreatedBetween(cs, last_month, last_minute)); | |
721 EXPECT_EQ(0, this->DeleteCreatedBetween(cs, next_minute, next_month)); | |
722 // Check that the cookie is still there. | |
723 this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_)); | |
724 | |
725 // Remove the cookie with an interval defined by two dates. | |
726 EXPECT_EQ(1, this->DeleteCreatedBetween(cs, last_minute, next_minute)); | |
727 // Check that the cookie disappeared. | |
728 this->MatchCookieLines("", this->GetCookies(cs, this->url_google_)); | |
729 | |
730 // Add another cookie. | |
731 EXPECT_TRUE(this->SetCookie(cs, this->url_google_, "C=D")); | |
732 // Check that the cookie is in the store. | |
733 this->MatchCookieLines("C=D", this->GetCookies(cs, this->url_google_)); | |
734 | |
735 // Remove the cookie with a null ending time. | |
736 EXPECT_EQ(1, this->DeleteCreatedBetween(cs, last_minute, base::Time())); | |
737 // Check that the cookie disappeared. | |
738 this->MatchCookieLines("", this->GetCookies(cs, this->url_google_)); | |
739 } | |
740 | |
741 TYPED_TEST_P(CookieStoreTest, TestSecure) { | |
742 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
743 | |
744 EXPECT_TRUE(this->SetCookie(cs, this->url_google_, "A=B")); | |
745 this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_)); | |
746 this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_secure_)); | |
747 | |
748 EXPECT_TRUE(this->SetCookie(cs, this->url_google_secure_, "A=B; secure")); | |
749 // The secure should overwrite the non-secure. | |
750 this->MatchCookieLines("", this->GetCookies(cs, this->url_google_)); | |
751 this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_secure_)); | |
752 | |
753 EXPECT_TRUE(this->SetCookie(cs, this->url_google_secure_, "D=E; secure")); | |
754 this->MatchCookieLines("", this->GetCookies(cs, this->url_google_)); | |
755 this->MatchCookieLines("A=B; D=E", | |
756 this->GetCookies(cs, this->url_google_secure_)); | |
757 | |
758 EXPECT_TRUE(this->SetCookie(cs, this->url_google_secure_, "A=B")); | |
759 // The non-secure should overwrite the secure. | |
760 this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_)); | |
761 this->MatchCookieLines("D=E; A=B", | |
762 this->GetCookies(cs, this->url_google_secure_)); | |
763 } | |
764 | |
765 static const int kLastAccessThresholdMilliseconds = 200; | |
766 | |
767 // Formerly NetUtilTest.CookieTest back when we used wininet's cookie handling. | |
768 TYPED_TEST_P(CookieStoreTest, NetUtilCookieTest) { | |
769 const GURL test_url("http://mojo.jojo.google.izzle/"); | |
770 | |
771 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
772 | |
773 EXPECT_TRUE(this->SetCookie(cs, test_url, "foo=bar")); | |
774 std::string value = this->GetCookies(cs, test_url); | |
775 this->MatchCookieLines("foo=bar", value); | |
776 | |
777 // test that we can retrieve all cookies: | |
778 EXPECT_TRUE(this->SetCookie(cs, test_url, "x=1")); | |
779 EXPECT_TRUE(this->SetCookie(cs, test_url, "y=2")); | |
780 | |
781 std::string result = this->GetCookies(cs, test_url); | |
782 EXPECT_FALSE(result.empty()); | |
783 EXPECT_NE(result.find("x=1"), std::string::npos) << result; | |
784 EXPECT_NE(result.find("y=2"), std::string::npos) << result; | |
785 } | |
786 | |
787 TYPED_TEST_P(CookieStoreTest, OverwritePersistentCookie) { | |
788 GURL url_google("http://www.google.com/"); | |
789 GURL url_chromium("http://chromium.org"); | |
790 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
791 | |
792 // Insert a cookie "a" for path "/path1" | |
793 EXPECT_TRUE( | |
794 this->SetCookie(cs, url_google, "a=val1; path=/path1; " | |
795 "expires=Mon, 18-Apr-22 22:50:13 GMT")); | |
796 | |
797 // Insert a cookie "b" for path "/path1" | |
798 EXPECT_TRUE( | |
799 this->SetCookie(cs, url_google, "b=val1; path=/path1; " | |
800 "expires=Mon, 18-Apr-22 22:50:14 GMT")); | |
801 | |
802 // Insert a cookie "b" for path "/path1", that is httponly. This should | |
803 // overwrite the non-http-only version. | |
804 CookieOptions allow_httponly; | |
805 allow_httponly.set_include_httponly(); | |
806 EXPECT_TRUE( | |
807 this->SetCookieWithOptions(cs, url_google, | |
808 "b=val2; path=/path1; httponly; " | |
809 "expires=Mon, 18-Apr-22 22:50:14 GMT", | |
810 allow_httponly)); | |
811 | |
812 // Insert a cookie "a" for path "/path1". This should overwrite. | |
813 EXPECT_TRUE(this->SetCookie(cs, url_google, | |
814 "a=val33; path=/path1; " | |
815 "expires=Mon, 18-Apr-22 22:50:14 GMT")); | |
816 | |
817 // Insert a cookie "a" for path "/path2". This should NOT overwrite | |
818 // cookie "a", since the path is different. | |
819 EXPECT_TRUE(this->SetCookie(cs, url_google, | |
820 "a=val9; path=/path2; " | |
821 "expires=Mon, 18-Apr-22 22:50:14 GMT")); | |
822 | |
823 // Insert a cookie "a" for path "/path1", but this time for "chromium.org". | |
824 // Although the name and path match, the hostnames do not, so shouldn't | |
825 // overwrite. | |
826 EXPECT_TRUE(this->SetCookie(cs, url_chromium, | |
827 "a=val99; path=/path1; " | |
828 "expires=Mon, 18-Apr-22 22:50:14 GMT")); | |
829 | |
830 if (TypeParam::supports_http_only) { | |
831 this->MatchCookieLines("a=val33", | |
832 this->GetCookies(cs, GURL("http://www.google.com/path1"))); | |
833 } else { | |
834 this->MatchCookieLines("a=val33; b=val2", | |
835 this->GetCookies(cs, GURL("http://www.google.com/path1"))); | |
836 } | |
837 this->MatchCookieLines("a=val9", | |
838 this->GetCookies(cs, GURL("http://www.google.com/path2"))); | |
839 this->MatchCookieLines("a=val99", | |
840 this->GetCookies(cs, GURL("http://chromium.org/path1"))); | |
841 } | |
842 | |
843 TYPED_TEST_P(CookieStoreTest, CookieOrdering) { | |
844 // Put a random set of cookies into a store and make sure they're returned in | |
845 // the right order. | |
846 // Cookies should be sorted by path length and creation time, as per RFC6265. | |
847 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
848 EXPECT_TRUE(this->SetCookie(cs, GURL("http://d.c.b.a.google.com/aa/x.html"), | |
849 "c=1")); | |
850 EXPECT_TRUE(this->SetCookie(cs, GURL("http://b.a.google.com/aa/bb/cc/x.html"), | |
851 "d=1; domain=b.a.google.com")); | |
852 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds( | |
853 TypeParam::creation_time_granularity_in_ms)); | |
854 EXPECT_TRUE(this->SetCookie(cs, GURL("http://b.a.google.com/aa/bb/cc/x.html"), | |
855 "a=4; domain=b.a.google.com")); | |
856 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds( | |
857 TypeParam::creation_time_granularity_in_ms)); | |
858 EXPECT_TRUE(this->SetCookie(cs, | |
859 GURL("http://c.b.a.google.com/aa/bb/cc/x.html"), | |
860 "e=1; domain=c.b.a.google.com")); | |
861 EXPECT_TRUE(this->SetCookie(cs, | |
862 GURL("http://d.c.b.a.google.com/aa/bb/x.html"), | |
863 "b=1")); | |
864 EXPECT_TRUE(this->SetCookie(cs, GURL("http://news.bbc.co.uk/midpath/x.html"), | |
865 "g=10")); | |
866 EXPECT_EQ("d=1; a=4; e=1; b=1; c=1", | |
867 this->GetCookies(cs, GURL("http://d.c.b.a.google.com/aa/bb/cc/dd"))); | |
868 } | |
869 | |
870 REGISTER_TYPED_TEST_CASE_P(CookieStoreTest, | |
871 TypeTest, DomainTest, DomainWithTrailingDotTest, ValidSubdomainTest, | |
872 InvalidDomainTest, DomainWithoutLeadingDotTest, CaseInsensitiveDomainTest, | |
873 TestIpAddress, TestNonDottedAndTLD, TestHostEndsWithDot, InvalidScheme, | |
874 InvalidScheme_Read, PathTest, HttpOnlyTest, TestGetCookiesWithInfo, | |
875 TestCookieDeletion, TestDeleteAllCreatedBetween, TestSecure, | |
876 NetUtilCookieTest, OverwritePersistentCookie, CookieOrdering); | |
877 | |
878 template<class CookieStoreTestTraits> | |
879 class MultiThreadedCookieStoreTest : | |
880 public CookieStoreTest<CookieStoreTestTraits> { | |
881 public: | |
882 MultiThreadedCookieStoreTest() : other_thread_("CMTthread") {} | |
883 | |
884 // Helper methods for calling the asynchronous CookieStore methods | |
885 // from a different thread. | |
886 | |
887 void GetCookiesTask(CookieStore* cs, | |
888 const GURL& url, | |
889 GetCookieStringCallback* callback) { | |
890 CookieOptions options; | |
891 if (!CookieStoreTestTraits::supports_http_only) | |
892 options.set_include_httponly(); | |
893 cs->GetCookiesWithOptionsAsync( | |
894 url, options, | |
895 base::Bind(&GetCookieStringCallback::Run, base::Unretained(callback))); | |
896 } | |
897 | |
898 void GetCookiesWithOptionsTask(CookieStore* cs, | |
899 const GURL& url, | |
900 const CookieOptions& options, | |
901 GetCookieStringCallback* callback) { | |
902 cs->GetCookiesWithOptionsAsync( | |
903 url, options, | |
904 base::Bind(&GetCookieStringCallback::Run, base::Unretained(callback))); | |
905 } | |
906 | |
907 void GetCookiesWithInfoTask(CookieStore* cs, | |
908 const GURL& url, | |
909 const CookieOptions& options, | |
910 GetCookiesWithInfoCallback* callback) { | |
911 cs->GetCookiesWithInfoAsync( | |
912 url, options, | |
913 base::Bind(&GetCookiesWithInfoCallback::Run, | |
914 base::Unretained(callback))); | |
915 } | |
916 | |
917 void SetCookieWithOptionsTask(CookieStore* cs, | |
918 const GURL& url, | |
919 const std::string& cookie_line, | |
920 const CookieOptions& options, | |
921 SetCookieCallback* callback) { | |
922 cs->SetCookieWithOptionsAsync( | |
923 url, cookie_line, options, | |
924 base::Bind(&SetCookieCallback::Run, base::Unretained(callback))); | |
925 } | |
926 | |
927 void DeleteCookieTask(CookieStore* cs, | |
928 const GURL& url, | |
929 const std::string& cookie_name, | |
930 DeleteCookieCallback* callback) { | |
931 cs->DeleteCookieAsync( | |
932 url, cookie_name, | |
933 base::Bind(&DeleteCookieCallback::Run, base::Unretained(callback))); | |
934 } | |
935 | |
936 protected: | |
937 void RunOnOtherThread(const base::Closure& task) { | |
938 other_thread_.Start(); | |
939 other_thread_.message_loop()->PostTask(FROM_HERE, task); | |
940 CookieStoreTest<CookieStoreTestTraits>::RunFor(kTimeout); | |
941 other_thread_.Stop(); | |
942 } | |
943 | |
944 Thread other_thread_; | |
945 }; | |
946 | |
947 TYPED_TEST_CASE_P(MultiThreadedCookieStoreTest); | |
948 | |
949 // TODO(ycxiao): Eventually, we will need to create a separate thread, create | |
950 // the cookie store on that thread (or at least its store, i.e., the DB | |
951 // thread). | |
952 TYPED_TEST_P(MultiThreadedCookieStoreTest, ThreadCheckGetCookies) { | |
953 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
954 EXPECT_TRUE(this->SetCookie(cs, this->url_google_, "A=B")); | |
955 this->MatchCookieLines("A=B", this->GetCookies(cs, this->url_google_)); | |
956 GetCookieStringCallback callback(&this->other_thread_); | |
957 base::Closure task = base::Bind( | |
958 &net::MultiThreadedCookieStoreTest<TypeParam>::GetCookiesTask, | |
959 base::Unretained(this), | |
960 cs, this->url_google_, &callback); | |
961 this->RunOnOtherThread(task); | |
962 EXPECT_TRUE(callback.did_run()); | |
963 EXPECT_EQ("A=B", callback.cookie()); | |
964 } | |
965 | |
966 TYPED_TEST_P(MultiThreadedCookieStoreTest, ThreadCheckGetCookiesWithOptions) { | |
967 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
968 CookieOptions options; | |
969 if (!TypeParam::supports_http_only) | |
970 options.set_include_httponly(); | |
971 EXPECT_TRUE(this->SetCookie(cs, this->url_google_, "A=B")); | |
972 this->MatchCookieLines("A=B", | |
973 this->GetCookiesWithOptions(cs, this->url_google_, options)); | |
974 GetCookieStringCallback callback(&this->other_thread_); | |
975 base::Closure task = base::Bind( | |
976 &net::MultiThreadedCookieStoreTest<TypeParam>::GetCookiesWithOptionsTask, | |
977 base::Unretained(this), | |
978 cs, this->url_google_, options, &callback); | |
979 this->RunOnOtherThread(task); | |
980 EXPECT_TRUE(callback.did_run()); | |
981 EXPECT_EQ("A=B", callback.cookie()); | |
982 } | |
983 | |
984 TYPED_TEST_P(MultiThreadedCookieStoreTest, ThreadCheckGetCookiesWithInfo) { | |
985 if (!TypeParam::supports_cookies_with_info) | |
986 return; | |
987 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
988 CookieOptions options; | |
989 std::string cookie_line; | |
990 std::vector<CookieStore::CookieInfo> cookie_infos; | |
991 EXPECT_TRUE(this->SetCookie(cs, this->url_google_, "A=B")); | |
992 this->GetCookiesWithInfo(cs, this->url_google_, options, &cookie_line, | |
993 &cookie_infos); | |
994 this->MatchCookieLines("A=B", cookie_line); | |
995 EXPECT_EQ(1U, cookie_infos.size()); | |
996 EXPECT_EQ("A", cookie_infos[0].name); | |
997 EXPECT_EQ("", cookie_infos[0].mac_key); | |
998 EXPECT_EQ("", cookie_infos[0].mac_algorithm); | |
999 GetCookiesWithInfoCallback callback(&this->other_thread_); | |
1000 base::Closure task = base::Bind( | |
1001 &net::MultiThreadedCookieStoreTest<TypeParam>::GetCookiesWithInfoTask, | |
1002 base::Unretained(this), cs, this->url_google_, options, &callback); | |
1003 this->RunOnOtherThread(task); | |
1004 EXPECT_TRUE(callback.did_run()); | |
1005 this->MatchCookieLines("A=B", callback.cookie_line()); | |
1006 EXPECT_EQ(1U, callback.cookie_info().size()); | |
1007 EXPECT_EQ("A", callback.cookie_info()[0].name); | |
1008 EXPECT_EQ("", callback.cookie_info()[0].mac_key); | |
1009 EXPECT_EQ("", callback.cookie_info()[0].mac_algorithm); | |
1010 } | |
1011 | |
1012 TYPED_TEST_P(MultiThreadedCookieStoreTest, ThreadCheckSetCookieWithOptions) { | |
1013 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
1014 CookieOptions options; | |
1015 if (!TypeParam::supports_http_only) | |
1016 options.set_include_httponly(); | |
1017 EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_, "A=B", | |
1018 options)); | |
1019 SetCookieCallback callback(&this->other_thread_); | |
1020 base::Closure task = base::Bind( | |
1021 &net::MultiThreadedCookieStoreTest<TypeParam>::SetCookieWithOptionsTask, | |
1022 base::Unretained(this), | |
1023 cs, this->url_google_, "A=B", options, &callback); | |
1024 this->RunOnOtherThread(task); | |
1025 EXPECT_TRUE(callback.did_run()); | |
1026 EXPECT_TRUE(callback.result()); | |
1027 } | |
1028 | |
1029 TYPED_TEST_P(MultiThreadedCookieStoreTest, ThreadCheckDeleteCookie) { | |
1030 scoped_refptr<CookieStore> cs(this->GetCookieStore()); | |
1031 CookieOptions options; | |
1032 if (!TypeParam::supports_http_only) | |
1033 options.set_include_httponly(); | |
1034 EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_, "A=B", | |
1035 options)); | |
1036 this->DeleteCookie(cs, this->url_google_, "A"); | |
1037 EXPECT_TRUE(this->SetCookieWithOptions(cs, this->url_google_, "A=B", | |
1038 options)); | |
1039 DeleteCookieCallback callback(&this->other_thread_); | |
1040 base::Closure task = base::Bind( | |
1041 &net::MultiThreadedCookieStoreTest<TypeParam>::DeleteCookieTask, | |
1042 base::Unretained(this), | |
1043 cs, this->url_google_, "A", &callback); | |
1044 this->RunOnOtherThread(task); | |
1045 EXPECT_TRUE(callback.did_run()); | |
1046 } | |
1047 | |
1048 REGISTER_TYPED_TEST_CASE_P(MultiThreadedCookieStoreTest, | |
1049 ThreadCheckGetCookies, ThreadCheckGetCookiesWithOptions, | |
1050 ThreadCheckGetCookiesWithInfo, ThreadCheckSetCookieWithOptions, | |
1051 ThreadCheckDeleteCookie); | |
1052 | |
1053 } // namespace net | |
1054 | 13 |
1055 #endif // NET_BASE_COOKIE_STORE_UNITTEST_H_ | 14 #endif // NET_BASE_COOKIE_STORE_UNITTEST_H_ |
OLD | NEW |