1 // Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4
5 #include <algorithm>
6 #include <vector>
7
8 #include "include/base/cef_callback.h"
9 #include "include/base/cef_logging.h"
10 #include "include/base/cef_ref_counted.h"
11 #include "include/cef_cookie.h"
12 #include "include/cef_request_context_handler.h"
13 #include "include/cef_scheme.h"
14 #include "include/cef_server.h"
15 #include "include/cef_waitable_event.h"
16 #include "include/wrapper/cef_closure_task.h"
17 #include "tests/ceftests/routing_test_handler.h"
18 #include "tests/ceftests/test_handler.h"
19 #include "tests/ceftests/test_server.h"
20 #include "tests/ceftests/test_suite.h"
21 #include "tests/ceftests/test_util.h"
22 #include "tests/gtest/include/gtest/gtest.h"
23
24 namespace {
25
26 const char* kTestUrl = "http://www.test.com/path/to/cookietest/foo.html";
27 const char* kTestDomain = "www.test.com";
28 const char* kTestPath = "/path/to/cookietest";
29
30 const int kIgnoreNumDeleted = -2;
31
32 typedef std::vector<CefCookie> CookieVector;
33
34 class TestCompletionCallback : public CefCompletionCallback {
35 public:
TestCompletionCallback(CefRefPtr<CefWaitableEvent> event)36 explicit TestCompletionCallback(CefRefPtr<CefWaitableEvent> event)
37 : event_(event) {}
38
OnComplete()39 void OnComplete() override {
40 EXPECT_TRUE(CefCurrentlyOn(TID_UI));
41 event_->Signal();
42 }
43
44 private:
45 CefRefPtr<CefWaitableEvent> event_;
46
47 IMPLEMENT_REFCOUNTING(TestCompletionCallback);
48 DISALLOW_COPY_AND_ASSIGN(TestCompletionCallback);
49 };
50
51 class TestSetCookieCallback : public CefSetCookieCallback {
52 public:
TestSetCookieCallback(bool expected_success,CefRefPtr<CefWaitableEvent> event)53 TestSetCookieCallback(bool expected_success,
54 CefRefPtr<CefWaitableEvent> event)
55 : expected_success_(expected_success), event_(event) {}
56
OnComplete(bool success)57 void OnComplete(bool success) override {
58 EXPECT_TRUE(CefCurrentlyOn(TID_UI));
59 EXPECT_EQ(expected_success_, success);
60 event_->Signal();
61 }
62
63 private:
64 bool expected_success_;
65 CefRefPtr<CefWaitableEvent> event_;
66
67 IMPLEMENT_REFCOUNTING(TestSetCookieCallback);
68 DISALLOW_COPY_AND_ASSIGN(TestSetCookieCallback);
69 };
70
71 class TestDeleteCookiesCallback : public CefDeleteCookiesCallback {
72 public:
TestDeleteCookiesCallback(int expected_num_deleted,CefRefPtr<CefWaitableEvent> event)73 TestDeleteCookiesCallback(int expected_num_deleted,
74 CefRefPtr<CefWaitableEvent> event)
75 : expected_num_deleted_(expected_num_deleted), event_(event) {}
76
OnComplete(int num_deleted)77 void OnComplete(int num_deleted) override {
78 EXPECT_TRUE(CefCurrentlyOn(TID_UI));
79 if (expected_num_deleted_ != kIgnoreNumDeleted) {
80 EXPECT_EQ(expected_num_deleted_, num_deleted);
81 }
82 event_->Signal();
83 }
84
85 private:
86 int expected_num_deleted_;
87 CefRefPtr<CefWaitableEvent> event_;
88
89 IMPLEMENT_REFCOUNTING(TestDeleteCookiesCallback);
90 DISALLOW_COPY_AND_ASSIGN(TestDeleteCookiesCallback);
91 };
92
93 class TestVisitor : public CefCookieVisitor {
94 public:
TestVisitor(CookieVector * cookies,bool deleteCookies,base::OnceClosure callback)95 TestVisitor(CookieVector* cookies,
96 bool deleteCookies,
97 base::OnceClosure callback)
98 : cookies_(cookies),
99 delete_cookies_(deleteCookies),
100 callback_(std::move(callback)) {
101 EXPECT_TRUE(cookies_);
102 EXPECT_FALSE(callback_.is_null());
103 }
~TestVisitor()104 ~TestVisitor() override { std::move(callback_).Run(); }
105
Visit(const CefCookie & cookie,int count,int total,bool & deleteCookie)106 bool Visit(const CefCookie& cookie,
107 int count,
108 int total,
109 bool& deleteCookie) override {
110 EXPECT_TRUE(CefCurrentlyOn(TID_UI));
111 cookies_->push_back(cookie);
112 if (delete_cookies_)
113 deleteCookie = true;
114 return true;
115 }
116
117 private:
118 CookieVector* cookies_;
119 bool delete_cookies_;
120 base::OnceClosure callback_;
121
122 IMPLEMENT_REFCOUNTING(TestVisitor);
123 };
124
125 // Set the cookies.
SetCookies(CefRefPtr<CefCookieManager> manager,const CefString & url,const CookieVector & cookies,bool expected_success,CefRefPtr<CefWaitableEvent> event)126 void SetCookies(CefRefPtr<CefCookieManager> manager,
127 const CefString& url,
128 const CookieVector& cookies,
129 bool expected_success,
130 CefRefPtr<CefWaitableEvent> event) {
131 CookieVector::const_iterator it = cookies.begin();
132 for (; it != cookies.end(); ++it) {
133 EXPECT_TRUE(manager->SetCookie(
134 url, *it, new TestSetCookieCallback(expected_success, event)));
135 event->Wait();
136 }
137 }
138
139 // Delete the cookie.
DeleteCookies(CefRefPtr<CefCookieManager> manager,const CefString & url,const CefString & cookie_name,int expected_num_deleted,CefRefPtr<CefWaitableEvent> event)140 void DeleteCookies(CefRefPtr<CefCookieManager> manager,
141 const CefString& url,
142 const CefString& cookie_name,
143 int expected_num_deleted,
144 CefRefPtr<CefWaitableEvent> event) {
145 EXPECT_TRUE(manager->DeleteCookies(
146 url, cookie_name,
147 new TestDeleteCookiesCallback(expected_num_deleted, event)));
148 event->Wait();
149 }
150
151 // Create a test cookie. If |withDomain| is true a domain cookie will be
152 // created, otherwise a host cookie will be created.
CreateCookie(CefRefPtr<CefCookieManager> manager,CefCookie & cookie,bool withDomain,bool sessionCookie,CefRefPtr<CefWaitableEvent> event)153 void CreateCookie(CefRefPtr<CefCookieManager> manager,
154 CefCookie& cookie,
155 bool withDomain,
156 bool sessionCookie,
157 CefRefPtr<CefWaitableEvent> event) {
158 CefString(&cookie.name).FromASCII("my_cookie");
159 CefString(&cookie.value).FromASCII("My Value");
160 if (withDomain)
161 CefString(&cookie.domain).FromASCII(kTestDomain);
162 CefString(&cookie.path).FromASCII(kTestPath);
163 if (!sessionCookie) {
164 cookie.has_expires = true;
165 cookie.expires.year = 2200;
166 cookie.expires.month = 4;
167 cookie.expires.day_of_week = 5;
168 cookie.expires.day_of_month = 11;
169 }
170
171 CookieVector cookies;
172 cookies.push_back(cookie);
173
174 SetCookies(manager, kTestUrl, cookies, true, event);
175 }
176
177 // Visit URL cookies. Execute |callback| on completion.
VisitUrlCookies(CefRefPtr<CefCookieManager> manager,const CefString & url,bool includeHttpOnly,CookieVector & cookies,bool deleteCookies,base::OnceClosure callback)178 void VisitUrlCookies(CefRefPtr<CefCookieManager> manager,
179 const CefString& url,
180 bool includeHttpOnly,
181 CookieVector& cookies,
182 bool deleteCookies,
183 base::OnceClosure callback) {
184 EXPECT_TRUE(manager->VisitUrlCookies(
185 url, includeHttpOnly,
186 new TestVisitor(&cookies, deleteCookies, std::move(callback))));
187 }
188
189 // Visit URL cookies. Block on |event|.
VisitUrlCookies(CefRefPtr<CefCookieManager> manager,const CefString & url,bool includeHttpOnly,CookieVector & cookies,bool deleteCookies,CefRefPtr<CefWaitableEvent> event)190 void VisitUrlCookies(CefRefPtr<CefCookieManager> manager,
191 const CefString& url,
192 bool includeHttpOnly,
193 CookieVector& cookies,
194 bool deleteCookies,
195 CefRefPtr<CefWaitableEvent> event) {
196 VisitUrlCookies(manager, url, includeHttpOnly, cookies, deleteCookies,
197 base::BindOnce(&CefWaitableEvent::Signal, event));
198 event->Wait();
199 }
200
201 // Visit all cookies. Execute |callback| on completion.
VisitAllCookies(CefRefPtr<CefCookieManager> manager,CookieVector & cookies,bool deleteCookies,base::OnceClosure callback)202 void VisitAllCookies(CefRefPtr<CefCookieManager> manager,
203 CookieVector& cookies,
204 bool deleteCookies,
205 base::OnceClosure callback) {
206 EXPECT_TRUE(manager->VisitAllCookies(
207 new TestVisitor(&cookies, deleteCookies, std::move(callback))));
208 }
209
210 // Visit all cookies. Block on |event|.
VisitAllCookies(CefRefPtr<CefCookieManager> manager,CookieVector & cookies,bool deleteCookies,CefRefPtr<CefWaitableEvent> event)211 void VisitAllCookies(CefRefPtr<CefCookieManager> manager,
212 CookieVector& cookies,
213 bool deleteCookies,
214 CefRefPtr<CefWaitableEvent> event) {
215 VisitAllCookies(manager, cookies, deleteCookies,
216 base::BindOnce(&CefWaitableEvent::Signal, event));
217 event->Wait();
218 }
219
220 // Retrieve the test cookie. If |withDomain| is true check that the cookie
221 // is a domain cookie, otherwise a host cookie. if |deleteCookies| is true
222 // the cookie will be deleted when it's retrieved.
GetCookie(CefRefPtr<CefCookieManager> manager,const CefCookie & cookie,bool withDomain,CefRefPtr<CefWaitableEvent> event,bool deleteCookies)223 void GetCookie(CefRefPtr<CefCookieManager> manager,
224 const CefCookie& cookie,
225 bool withDomain,
226 CefRefPtr<CefWaitableEvent> event,
227 bool deleteCookies) {
228 CookieVector cookies;
229
230 // Get the cookie and delete it.
231 VisitUrlCookies(manager, kTestUrl, false, cookies, deleteCookies, event);
232
233 EXPECT_EQ(1U, cookies.size());
234 if (cookies.size() != 1U)
235 return;
236
237 const CefCookie& cookie_read = cookies[0];
238 EXPECT_EQ(CefString(&cookie_read.name), "my_cookie");
239 EXPECT_EQ(CefString(&cookie_read.value), "My Value");
240 if (withDomain)
241 EXPECT_EQ(CefString(&cookie_read.domain), ".www.test.com");
242 else
243 EXPECT_EQ(CefString(&cookie_read.domain), kTestDomain);
244 EXPECT_EQ(CefString(&cookie_read.path), kTestPath);
245 EXPECT_EQ(cookie.has_expires, cookie_read.has_expires);
246 EXPECT_EQ(cookie.expires.year, cookie_read.expires.year);
247 EXPECT_EQ(cookie.expires.month, cookie_read.expires.month);
248 EXPECT_EQ(cookie.expires.day_of_week, cookie_read.expires.day_of_week);
249 EXPECT_EQ(cookie.expires.day_of_month, cookie_read.expires.day_of_month);
250 EXPECT_EQ(cookie.expires.hour, cookie_read.expires.hour);
251 EXPECT_EQ(cookie.expires.minute, cookie_read.expires.minute);
252 EXPECT_EQ(cookie.expires.second, cookie_read.expires.second);
253 EXPECT_EQ(cookie.expires.millisecond, cookie_read.expires.millisecond);
254 EXPECT_EQ(cookie.same_site, cookie_read.same_site);
255 EXPECT_EQ(cookie.priority, cookie_read.priority);
256 }
257
258 // Verify that no cookies exist. If |withUrl| is true it will only check for
259 // cookies matching the URL.
VerifyNoCookies(CefRefPtr<CefCookieManager> manager,CefRefPtr<CefWaitableEvent> event,bool withUrl)260 void VerifyNoCookies(CefRefPtr<CefCookieManager> manager,
261 CefRefPtr<CefWaitableEvent> event,
262 bool withUrl) {
263 CookieVector cookies;
264
265 // Verify that the cookie has been deleted.
266 if (withUrl) {
267 VisitUrlCookies(manager, kTestUrl, false, cookies, false, event);
268 } else {
269 VisitAllCookies(manager, cookies, false, event);
270 }
271
272 EXPECT_EQ(0U, cookies.size());
273 }
274
275 // Delete all system cookies.
DeleteAllCookies(CefRefPtr<CefCookieManager> manager,CefRefPtr<CefWaitableEvent> event)276 void DeleteAllCookies(CefRefPtr<CefCookieManager> manager,
277 CefRefPtr<CefWaitableEvent> event) {
278 DeleteCookies(manager, CefString(), CefString(), kIgnoreNumDeleted, event);
279 }
280
TestDomainCookie(CefRefPtr<CefCookieManager> manager,CefRefPtr<CefWaitableEvent> event)281 void TestDomainCookie(CefRefPtr<CefCookieManager> manager,
282 CefRefPtr<CefWaitableEvent> event) {
283 CefCookie cookie;
284
285 // Create a domain cookie.
286 CreateCookie(manager, cookie, true, false, event);
287
288 // Retrieve, verify and delete the domain cookie.
289 GetCookie(manager, cookie, true, event, true);
290
291 // Verify that the cookie was deleted.
292 VerifyNoCookies(manager, event, true);
293 }
294
TestHostCookie(CefRefPtr<CefCookieManager> manager,CefRefPtr<CefWaitableEvent> event)295 void TestHostCookie(CefRefPtr<CefCookieManager> manager,
296 CefRefPtr<CefWaitableEvent> event) {
297 CefCookie cookie;
298
299 // Create a host cookie.
300 CreateCookie(manager, cookie, false, false, event);
301
302 // Retrieve, verify and delete the host cookie.
303 GetCookie(manager, cookie, false, event, true);
304
305 // Verify that the cookie was deleted.
306 VerifyNoCookies(manager, event, true);
307 }
308
TestInvalidCookie(CefRefPtr<CefCookieManager> manager,CefRefPtr<CefWaitableEvent> event)309 void TestInvalidCookie(CefRefPtr<CefCookieManager> manager,
310 CefRefPtr<CefWaitableEvent> event) {
311 CookieVector cookies;
312
313 CefCookie cookie;
314 const char* kUrl = "http://www.xyz.com";
315 CefString(&cookie.name).FromASCII("invalid1");
316 CefString(&cookie.value).FromASCII("invalid1");
317 CefString(&cookie.domain).FromASCII(".zyx.com"); // domain mismatch
318
319 cookies.push_back(cookie);
320
321 // No cookies will be set due to non canonical cookie
322 SetCookies(manager, kUrl, cookies, false, event);
323 }
324
TestMultipleCookies(CefRefPtr<CefCookieManager> manager,CefRefPtr<CefWaitableEvent> event)325 void TestMultipleCookies(CefRefPtr<CefCookieManager> manager,
326 CefRefPtr<CefWaitableEvent> event) {
327 std::stringstream ss;
328 int i;
329
330 CookieVector cookies;
331
332 const int kNumCookies = 4;
333
334 // Create the cookies.
335 for (i = 0; i < kNumCookies; i++) {
336 CefCookie cookie;
337
338 ss << "my_cookie" << i;
339 CefString(&cookie.name).FromASCII(ss.str().c_str());
340 ss.str("");
341 ss << "My Value " << i;
342 CefString(&cookie.value).FromASCII(ss.str().c_str());
343 ss.str("");
344
345 cookies.push_back(cookie);
346 }
347
348 // Set the cookies.
349 SetCookies(manager, kTestUrl, cookies, true, event);
350 cookies.clear();
351
352 // Get the cookies without deleting them.
353 VisitUrlCookies(manager, kTestUrl, false, cookies, false, event);
354
355 EXPECT_EQ((CookieVector::size_type)kNumCookies, cookies.size());
356
357 CookieVector::const_iterator it = cookies.begin();
358 for (i = 0; it != cookies.end(); ++it, ++i) {
359 const CefCookie& cookie = *it;
360
361 ss << "my_cookie" << i;
362 EXPECT_EQ(CefString(&cookie.name), ss.str());
363 ss.str("");
364 ss << "My Value " << i;
365 EXPECT_EQ(CefString(&cookie.value), ss.str());
366 ss.str("");
367 }
368
369 cookies.clear();
370
371 // Delete the 2nd cookie.
372 DeleteCookies(manager, kTestUrl, CefString("my_cookie1"), 1, event);
373
374 // Verify that the cookie has been deleted.
375 VisitUrlCookies(manager, kTestUrl, false, cookies, false, event);
376
377 EXPECT_EQ(3U, cookies.size());
378 if (cookies.size() != 3U)
379 return;
380
381 EXPECT_EQ(CefString(&cookies[0].name), "my_cookie0");
382 EXPECT_EQ(CefString(&cookies[1].name), "my_cookie2");
383 EXPECT_EQ(CefString(&cookies[2].name), "my_cookie3");
384
385 cookies.clear();
386
387 // Delete the rest of the cookies.
388 DeleteCookies(manager, kTestUrl, CefString(), 3, event);
389
390 // Verify that the cookies have been deleted.
391 VisitUrlCookies(manager, kTestUrl, false, cookies, false, event);
392
393 EXPECT_EQ(0U, cookies.size());
394
395 // Create the cookies.
396 for (i = 0; i < kNumCookies; i++) {
397 CefCookie cookie;
398
399 ss << "my_cookie" << i;
400 CefString(&cookie.name).FromASCII(ss.str().c_str());
401 ss.str("");
402 ss << "My Value " << i;
403 CefString(&cookie.value).FromASCII(ss.str().c_str());
404 ss.str("");
405
406 cookies.push_back(cookie);
407 }
408
409 // Delete all of the cookies using the visitor.
410 VisitUrlCookies(manager, kTestUrl, false, cookies, true, event);
411
412 cookies.clear();
413
414 // Verify that the cookies have been deleted.
415 VisitUrlCookies(manager, kTestUrl, false, cookies, false, event);
416
417 EXPECT_EQ(0U, cookies.size());
418 }
419
TestAllCookies(CefRefPtr<CefCookieManager> manager,CefRefPtr<CefWaitableEvent> event)420 void TestAllCookies(CefRefPtr<CefCookieManager> manager,
421 CefRefPtr<CefWaitableEvent> event) {
422 CookieVector cookies;
423
424 // Delete all system cookies just in case something is left over from a
425 // different test.
426 DeleteAllCookies(manager, event);
427
428 // Verify that all system cookies have been deleted.
429 VisitAllCookies(manager, cookies, false, event);
430
431 EXPECT_EQ(0U, cookies.size());
432
433 // Create cookies with 2 separate hosts.
434 CefCookie cookie1;
435 const char* kUrl1 = "http://www.foo.com";
436 CefString(&cookie1.name).FromASCII("my_cookie1");
437 CefString(&cookie1.value).FromASCII("My Value 1");
438
439 cookies.push_back(cookie1);
440 SetCookies(manager, kUrl1, cookies, true, event);
441 cookies.clear();
442
443 CefCookie cookie2;
444 const char* kUrl2 = "http://www.bar.com";
445 CefString(&cookie2.name).FromASCII("my_cookie2");
446 CefString(&cookie2.value).FromASCII("My Value 2");
447
448 cookies.push_back(cookie2);
449 SetCookies(manager, kUrl2, cookies, true, event);
450 cookies.clear();
451
452 // Verify that all system cookies can be retrieved.
453 VisitAllCookies(manager, cookies, false, event);
454
455 EXPECT_EQ(2U, cookies.size());
456 if (cookies.size() != 2U)
457 return;
458
459 EXPECT_EQ(CefString(&cookies[0].name), "my_cookie1");
460 EXPECT_EQ(CefString(&cookies[0].value), "My Value 1");
461 EXPECT_EQ(CefString(&cookies[0].domain), "www.foo.com");
462 EXPECT_EQ(CefString(&cookies[1].name), "my_cookie2");
463 EXPECT_EQ(CefString(&cookies[1].value), "My Value 2");
464 EXPECT_EQ(CefString(&cookies[1].domain), "www.bar.com");
465 cookies.clear();
466
467 // Verify that the cookies can be retrieved separately.
468 VisitUrlCookies(manager, kUrl1, false, cookies, false, event);
469
470 EXPECT_EQ(1U, cookies.size());
471 if (cookies.size() != 1U)
472 return;
473
474 EXPECT_EQ(CefString(&cookies[0].name), "my_cookie1");
475 EXPECT_EQ(CefString(&cookies[0].value), "My Value 1");
476 EXPECT_EQ(CefString(&cookies[0].domain), "www.foo.com");
477 cookies.clear();
478
479 VisitUrlCookies(manager, kUrl2, false, cookies, false, event);
480
481 EXPECT_EQ(1U, cookies.size());
482 if (cookies.size() != 1U)
483 return;
484
485 EXPECT_EQ(CefString(&cookies[0].name), "my_cookie2");
486 EXPECT_EQ(CefString(&cookies[0].value), "My Value 2");
487 EXPECT_EQ(CefString(&cookies[0].domain), "www.bar.com");
488 cookies.clear();
489
490 // Delete all of the system cookies.
491 DeleteAllCookies(manager, event);
492
493 // Verify that all system cookies have been deleted.
494 VerifyNoCookies(manager, event, false);
495 }
496
497 } // namespace
498
499 // Test creation of a invalid cookie.
TEST(CookieTest,BasicInvalidCookie)500 TEST(CookieTest, BasicInvalidCookie) {
501 CefRefPtr<CefWaitableEvent> event =
502 CefWaitableEvent::CreateWaitableEvent(true, false);
503
504 CefRefPtr<CefCookieManager> manager =
505 CefCookieManager::GetGlobalManager(new TestCompletionCallback(event));
506 event->Wait();
507 EXPECT_TRUE(manager.get());
508
509 TestInvalidCookie(manager, event);
510 }
511
512 // Test creation of a domain cookie.
TEST(CookieTest,BasicDomainCookie)513 TEST(CookieTest, BasicDomainCookie) {
514 CefRefPtr<CefWaitableEvent> event =
515 CefWaitableEvent::CreateWaitableEvent(true, false);
516
517 CefRefPtr<CefCookieManager> manager =
518 CefCookieManager::GetGlobalManager(new TestCompletionCallback(event));
519 event->Wait();
520 EXPECT_TRUE(manager.get());
521
522 TestDomainCookie(manager, event);
523 }
524
525 // Test creation of a host cookie.
TEST(CookieTest,BasicHostCookie)526 TEST(CookieTest, BasicHostCookie) {
527 CefRefPtr<CefWaitableEvent> event =
528 CefWaitableEvent::CreateWaitableEvent(true, false);
529
530 CefRefPtr<CefCookieManager> manager =
531 CefCookieManager::GetGlobalManager(new TestCompletionCallback(event));
532 event->Wait();
533 EXPECT_TRUE(manager.get());
534
535 TestHostCookie(manager, event);
536 }
537
538 // Test creation of multiple cookies.
TEST(CookieTest,BasicMultipleCookies)539 TEST(CookieTest, BasicMultipleCookies) {
540 CefRefPtr<CefWaitableEvent> event =
541 CefWaitableEvent::CreateWaitableEvent(true, false);
542
543 CefRefPtr<CefCookieManager> manager =
544 CefCookieManager::GetGlobalManager(new TestCompletionCallback(event));
545 event->Wait();
546 EXPECT_TRUE(manager.get());
547
548 TestMultipleCookies(manager, event);
549 }
550
TEST(CookieTest,BasicAllCookies)551 TEST(CookieTest, BasicAllCookies) {
552 CefRefPtr<CefWaitableEvent> event =
553 CefWaitableEvent::CreateWaitableEvent(true, false);
554
555 CefRefPtr<CefCookieManager> manager =
556 CefCookieManager::GetGlobalManager(new TestCompletionCallback(event));
557 event->Wait();
558 EXPECT_TRUE(manager.get());
559
560 TestAllCookies(manager, event);
561 }
562
563 namespace {
564
565 const char* kCookieJSUrl1 = "http://tests/cookie1.html";
566 const char* kCookieJSUrl2 = "http://tests/cookie2.html";
567
568 class CookieTestJSHandler : public TestHandler {
569 public:
CookieTestJSHandler()570 CookieTestJSHandler() {}
571
RunTest()572 void RunTest() override {
573 std::string page =
574 "<html><head>"
575 "<script>"
576 "document.cookie='name1=value1;"
577 // Invalid date should not cause a crash (see issue #2927).
578 " expires=Tue, 07 Nov 94276 07:58:05 GMT'"
579 "</script>"
580 "</head><body>COOKIE TEST1</body></html>";
581 AddResource(kCookieJSUrl1, page, "text/html");
582
583 page =
584 "<html><head>"
585 "<script>"
586 "document.cookie='name2=value2';"
587 "</script>"
588 "</head><body>COOKIE TEST2</body></html>";
589 AddResource(kCookieJSUrl2, page, "text/html");
590
591 // Create the request context that will use an in-memory cache.
592 CefRequestContextSettings settings;
593 CefRefPtr<CefRequestContext> request_context =
594 CefRequestContext::CreateContext(settings, nullptr);
595 manager_ = request_context->GetCookieManager(nullptr);
596
597 // Create the browser.
598 CreateBrowser(kCookieJSUrl1, request_context);
599
600 // Time out the test after a reasonable period of time.
601 SetTestTimeout();
602 }
603
604 // Go to the next URL.
LoadNextURL(CefRefPtr<CefFrame> frame)605 void LoadNextURL(CefRefPtr<CefFrame> frame) {
606 if (!CefCurrentlyOn(TID_UI)) {
607 CefPostTask(TID_UI, base::BindOnce(&CookieTestJSHandler::LoadNextURL,
608 this, frame));
609 return;
610 }
611
612 frame->LoadURL(kCookieJSUrl2);
613 }
614
CompleteTest()615 void CompleteTest() {
616 if (!CefCurrentlyOn(TID_UI)) {
617 CefPostTask(TID_UI,
618 base::BindOnce(&CookieTestJSHandler::CompleteTest, this));
619 return;
620 }
621
622 DestroyTest();
623 }
624
OnLoadEnd(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,int httpStatusCode)625 void OnLoadEnd(CefRefPtr<CefBrowser> browser,
626 CefRefPtr<CefFrame> frame,
627 int httpStatusCode) override {
628 std::string url = frame->GetURL();
629 if (url == kCookieJSUrl1) {
630 got_load_end1_.yes();
631 VerifyCookie(
632 manager_, url, "name1", "value1", true, &got_cookie1_,
633 base::BindOnce(&CookieTestJSHandler::LoadNextURL, this, frame));
634 } else {
635 got_load_end2_.yes();
636 VerifyCookie(manager_, url, "name2", "value2", true, &got_cookie2_,
637 base::BindOnce(&CookieTestJSHandler::CompleteTest, this));
638 }
639 }
640
641 // Verify that the cookie was set successfully.
VerifyCookie(CefRefPtr<CefCookieManager> manager,const std::string & url,const std::string & name,const std::string & value,bool deleteCookie,TrackCallback * callback,base::OnceClosure continue_callback)642 void VerifyCookie(CefRefPtr<CefCookieManager> manager,
643 const std::string& url,
644 const std::string& name,
645 const std::string& value,
646 bool deleteCookie,
647 TrackCallback* callback,
648 base::OnceClosure continue_callback) {
649 // Get the cookie.
650 EXPECT_TRUE(cookies_.empty());
651 VisitUrlCookies(
652 manager, url, false, cookies_, deleteCookie,
653 base::BindOnce(&CookieTestJSHandler::VerifyCookieComplete, this, name,
654 value, callback, std::move(continue_callback)));
655 }
656
VerifyCookieComplete(const std::string & name,const std::string & value,TrackCallback * callback,base::OnceClosure continue_callback)657 void VerifyCookieComplete(const std::string& name,
658 const std::string& value,
659 TrackCallback* callback,
660 base::OnceClosure continue_callback) {
661 if (cookies_.size() == 1U && CefString(&cookies_[0].name) == name &&
662 CefString(&cookies_[0].value) == value) {
663 callback->yes();
664 }
665
666 cookies_.clear();
667 std::move(continue_callback).Run();
668 }
669
670 CefRefPtr<CefCookieManager> manager_;
671
672 CookieVector cookies_;
673
674 TrackCallback got_load_end1_;
675 TrackCallback got_load_end2_;
676 TrackCallback got_cookie1_;
677 TrackCallback got_cookie2_;
678
679 IMPLEMENT_REFCOUNTING(CookieTestJSHandler);
680 };
681
682 } // namespace
683
684 // Verify use of multiple cookie managers vis JS.
TEST(CookieTest,GetCookieManagerJS)685 TEST(CookieTest, GetCookieManagerJS) {
686 CefRefPtr<CookieTestJSHandler> handler = new CookieTestJSHandler();
687 handler->ExecuteTest();
688
689 EXPECT_TRUE(handler->got_load_end1_);
690 EXPECT_TRUE(handler->got_load_end2_);
691 EXPECT_TRUE(handler->got_cookie1_);
692 EXPECT_TRUE(handler->got_cookie2_);
693
694 ReleaseAndWaitForDestructor(handler);
695 }
696
697 namespace {
698
699 const char kCustomCookieScheme[] = "ccustom";
700
701 class CompletionCallback : public CefCompletionCallback {
702 public:
CompletionCallback(base::OnceClosure callback)703 explicit CompletionCallback(base::OnceClosure callback)
704 : callback_(std::move(callback)) {}
705
OnComplete()706 void OnComplete() override { std::move(callback_).Run(); }
707
708 private:
709 base::OnceClosure callback_;
710 IMPLEMENT_REFCOUNTING(CompletionCallback);
711 };
712
713 class CookieTestSchemeHandler : public TestHandler {
714 public:
715 class SchemeHandler : public CefResourceHandler {
716 public:
SchemeHandler(CookieTestSchemeHandler * handler)717 explicit SchemeHandler(CookieTestSchemeHandler* handler)
718 : handler_(handler), offset_(0) {}
719
Open(CefRefPtr<CefRequest> request,bool & handle_request,CefRefPtr<CefCallback> callback)720 bool Open(CefRefPtr<CefRequest> request,
721 bool& handle_request,
722 CefRefPtr<CefCallback> callback) override {
723 EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
724
725 std::string url = request->GetURL();
726 if (url == handler_->url1_) {
727 content_ = "<html><body>COOKIE TEST1</body></html>";
728 cookie_ = "name1=value1";
729 handler_->got_process_request1_.yes();
730 } else if (url == handler_->url2_) {
731 content_ = "<html><body>COOKIE TEST2</body></html>";
732 cookie_ = "name2=value2";
733 handler_->got_process_request2_.yes();
734 } else if (url == handler_->url3_) {
735 content_ = "<html><body>COOKIE TEST3</body></html>";
736 handler_->got_process_request3_.yes();
737
738 // Verify that the cookie was passed in.
739 CefRequest::HeaderMap headerMap;
740 request->GetHeaderMap(headerMap);
741 CefRequest::HeaderMap::iterator it = headerMap.find("Cookie");
742 if (it != headerMap.end() && it->second == "name2=value2")
743 handler_->got_process_request_cookie_.yes();
744 }
745
746 // Continue immediately.
747 handle_request = true;
748 return true;
749 }
750
GetResponseHeaders(CefRefPtr<CefResponse> response,int64 & response_length,CefString & redirectUrl)751 void GetResponseHeaders(CefRefPtr<CefResponse> response,
752 int64& response_length,
753 CefString& redirectUrl) override {
754 response_length = content_.size();
755
756 response->SetStatus(200);
757 response->SetMimeType("text/html");
758
759 if (!cookie_.empty()) {
760 CefResponse::HeaderMap headerMap;
761 response->GetHeaderMap(headerMap);
762 headerMap.insert(std::make_pair("Set-Cookie", cookie_));
763 response->SetHeaderMap(headerMap);
764 }
765 }
766
Read(void * data_out,int bytes_to_read,int & bytes_read,CefRefPtr<CefResourceReadCallback> callback)767 bool Read(void* data_out,
768 int bytes_to_read,
769 int& bytes_read,
770 CefRefPtr<CefResourceReadCallback> callback) override {
771 EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
772
773 bool has_data = false;
774 bytes_read = 0;
775
776 size_t size = content_.size();
777 if (offset_ < size) {
778 int transfer_size =
779 std::min(bytes_to_read, static_cast<int>(size - offset_));
780 memcpy(data_out, content_.c_str() + offset_, transfer_size);
781 offset_ += transfer_size;
782
783 bytes_read = transfer_size;
784 has_data = true;
785 }
786
787 return has_data;
788 }
789
Cancel()790 void Cancel() override {}
791
792 private:
793 CookieTestSchemeHandler* handler_;
794 std::string content_;
795 size_t offset_;
796 std::string cookie_;
797
798 IMPLEMENT_REFCOUNTING(SchemeHandler);
799 DISALLOW_COPY_AND_ASSIGN(SchemeHandler);
800 };
801
802 class SchemeHandlerFactory : public CefSchemeHandlerFactory {
803 public:
SchemeHandlerFactory(CookieTestSchemeHandler * handler)804 explicit SchemeHandlerFactory(CookieTestSchemeHandler* handler)
805 : handler_(handler) {}
806
Create(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,const CefString & scheme_name,CefRefPtr<CefRequest> request)807 CefRefPtr<CefResourceHandler> Create(
808 CefRefPtr<CefBrowser> browser,
809 CefRefPtr<CefFrame> frame,
810 const CefString& scheme_name,
811 CefRefPtr<CefRequest> request) override {
812 std::string url = request->GetURL();
813 if (url == handler_->url3_) {
814 // Verify that the cookie was not passed in.
815 CefRequest::HeaderMap headerMap;
816 request->GetHeaderMap(headerMap);
817 CefRequest::HeaderMap::iterator it = headerMap.find("Cookie");
818 if (it != headerMap.end() && it->second == "name2=value2")
819 handler_->got_create_cookie_.yes();
820 }
821
822 return new SchemeHandler(handler_);
823 }
824
825 private:
826 CookieTestSchemeHandler* handler_;
827
828 IMPLEMENT_REFCOUNTING(SchemeHandlerFactory);
829 DISALLOW_COPY_AND_ASSIGN(SchemeHandlerFactory);
830 };
831
CookieTestSchemeHandler(const std::string & scheme,bool use_global,bool block_cookies=false)832 CookieTestSchemeHandler(const std::string& scheme,
833 bool use_global,
834 bool block_cookies = false)
835 : scheme_(scheme),
836 use_global_(use_global),
837 block_cookies_(block_cookies) {
838 url1_ = scheme + "://cookie-tests/cookie1.html";
839 url2_ = scheme + "://cookie-tests/cookie2.html";
840 url3_ = scheme + "://cookie-tests/cookie3.html";
841 }
842
RunTest()843 void RunTest() override {
844 if (use_global_) {
845 request_context_ = CefRequestContext::GetGlobalContext();
846 } else {
847 // Create the request context that will use an in-memory cache.
848 CefRequestContextSettings settings;
849
850 if (scheme_ == kCustomCookieScheme || block_cookies_) {
851 if (!block_cookies_) {
852 CefString(&settings.cookieable_schemes_list) = kCustomCookieScheme;
853 } else {
854 settings.cookieable_schemes_exclude_defaults = true;
855 }
856 }
857
858 request_context_ = CefRequestContext::CreateContext(settings, nullptr);
859 }
860
861 // Register the scheme handler.
862 request_context_->RegisterSchemeHandlerFactory(
863 scheme_, "cookie-tests", new SchemeHandlerFactory(this));
864
865 manager_ = request_context_->GetCookieManager(nullptr);
866
867 // Create the browser.
868 CreateBrowser(url1_, request_context_);
869
870 // Time out the test after a reasonable period of time.
871 SetTestTimeout();
872 }
873
874 // Go to the next URL.
LoadNextURL(CefRefPtr<CefFrame> frame,const std::string & url)875 void LoadNextURL(CefRefPtr<CefFrame> frame, const std::string& url) {
876 if (!CefCurrentlyOn(TID_UI)) {
877 CefPostTask(TID_UI, base::BindOnce(&CookieTestSchemeHandler::LoadNextURL,
878 this, frame, url));
879 return;
880 }
881
882 frame->LoadURL(url);
883 }
884
CompleteTest(CefRefPtr<CefBrowser> browser)885 void CompleteTest(CefRefPtr<CefBrowser> browser) {
886 if (!CefCurrentlyOn(TID_UI)) {
887 CefPostTask(TID_UI, base::BindOnce(&CookieTestSchemeHandler::CompleteTest,
888 this, browser));
889 return;
890 }
891
892 // Unregister the scheme handler.
893 browser->GetHost()->GetRequestContext()->RegisterSchemeHandlerFactory(
894 scheme_, "cookie-tests", nullptr);
895
896 DestroyTest();
897 }
898
OnLoadEnd(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,int httpStatusCode)899 void OnLoadEnd(CefRefPtr<CefBrowser> browser,
900 CefRefPtr<CefFrame> frame,
901 int httpStatusCode) override {
902 std::string url = frame->GetURL();
903 if (url == url1_) {
904 got_load_end1_.yes();
905 VerifyCookie(manager_, url, "name1", "value1", true, &got_cookie1_,
906 base::BindOnce(&CookieTestSchemeHandler::LoadNextURL, this,
907 frame, url2_));
908 } else if (url == url2_) {
909 got_load_end2_.yes();
910 VerifyCookie(manager_, url, "name2", "value2", false, &got_cookie2_,
911 base::BindOnce(&CookieTestSchemeHandler::LoadNextURL, this,
912 frame, url3_));
913 } else {
914 got_load_end3_.yes();
915 VerifyCookie(manager_, url, "name2", "value2", true, &got_cookie3_,
916 base::BindOnce(&CookieTestSchemeHandler::CompleteTest, this,
917 browser));
918 }
919 }
920
DestroyTest()921 void DestroyTest() override {
922 EXPECT_TRUE(got_process_request1_);
923 EXPECT_TRUE(got_process_request2_);
924 EXPECT_TRUE(got_process_request3_);
925 EXPECT_TRUE(got_load_end1_);
926 EXPECT_TRUE(got_load_end2_);
927 EXPECT_TRUE(got_load_end3_);
928
929 if (block_cookies_) {
930 EXPECT_FALSE(got_create_cookie_);
931 EXPECT_FALSE(got_process_request_cookie_);
932 EXPECT_FALSE(got_cookie1_);
933 EXPECT_FALSE(got_cookie2_);
934 EXPECT_FALSE(got_cookie3_);
935 } else {
936 EXPECT_TRUE(got_create_cookie_);
937 EXPECT_TRUE(got_process_request_cookie_);
938 EXPECT_TRUE(got_cookie1_);
939 EXPECT_TRUE(got_cookie2_);
940 EXPECT_TRUE(got_cookie3_);
941 }
942
943 // Unregister the scheme handler.
944 request_context_->RegisterSchemeHandlerFactory(scheme_, "cookie-tests",
945 nullptr);
946 request_context_ = nullptr;
947
948 TestHandler::DestroyTest();
949 }
950
951 // Verify that the cookie was set successfully.
VerifyCookie(CefRefPtr<CefCookieManager> manager,const std::string & url,const std::string & name,const std::string & value,bool deleteCookie,TrackCallback * callback,base::OnceClosure continue_callback)952 void VerifyCookie(CefRefPtr<CefCookieManager> manager,
953 const std::string& url,
954 const std::string& name,
955 const std::string& value,
956 bool deleteCookie,
957 TrackCallback* callback,
958 base::OnceClosure continue_callback) {
959 // Get the cookie.
960 EXPECT_TRUE(cookies_.empty());
961 VisitUrlCookies(
962 manager, url, false, cookies_, deleteCookie,
963 base::BindOnce(&CookieTestSchemeHandler::VerifyCookieComplete, this,
964 name, value, callback, std::move(continue_callback)));
965 }
966
VerifyCookieComplete(const std::string & name,const std::string & value,TrackCallback * callback,base::OnceClosure continue_callback)967 void VerifyCookieComplete(const std::string& name,
968 const std::string& value,
969 TrackCallback* callback,
970 base::OnceClosure continue_callback) {
971 if (cookies_.size() == 1U && CefString(&cookies_[0].name) == name &&
972 CefString(&cookies_[0].value) == value) {
973 callback->yes();
974 }
975
976 cookies_.clear();
977 std::move(continue_callback).Run();
978 }
979
980 const std::string scheme_;
981 const bool use_global_;
982 const bool block_cookies_;
983 std::string url1_;
984 std::string url2_;
985 std::string url3_;
986
987 CefRefPtr<CefRequestContext> request_context_;
988 CefRefPtr<CefCookieManager> manager_;
989
990 CookieVector cookies_;
991
992 TrackCallback got_process_request1_;
993 TrackCallback got_process_request2_;
994 TrackCallback got_process_request3_;
995 TrackCallback got_create_cookie_;
996 TrackCallback got_process_request_cookie_;
997 TrackCallback got_load_end1_;
998 TrackCallback got_load_end2_;
999 TrackCallback got_load_end3_;
1000 TrackCallback got_cookie1_;
1001 TrackCallback got_cookie2_;
1002 TrackCallback got_cookie3_;
1003
1004 IMPLEMENT_REFCOUNTING(CookieTestSchemeHandler);
1005 };
1006
1007 } // namespace
1008
1009 // Verify use of the global cookie manager with HTTP.
TEST(CookieTest,GetCookieManagerHttpGlobal)1010 TEST(CookieTest, GetCookieManagerHttpGlobal) {
1011 CefRefPtr<CookieTestSchemeHandler> handler =
1012 new CookieTestSchemeHandler("http", true);
1013 handler->ExecuteTest();
1014 ReleaseAndWaitForDestructor(handler);
1015 }
1016
1017 // Verify use of an in-memory cookie manager with HTTP.
TEST(CookieTest,GetCookieManagerHttpInMemory)1018 TEST(CookieTest, GetCookieManagerHttpInMemory) {
1019 CefRefPtr<CookieTestSchemeHandler> handler =
1020 new CookieTestSchemeHandler("http", false);
1021 handler->ExecuteTest();
1022 ReleaseAndWaitForDestructor(handler);
1023 }
1024
1025 // Verify use of an in-memory cookie manager with HTTP to block all cookies.
TEST(CookieTest,GetCookieManagerHttpInMemoryBlocked)1026 TEST(CookieTest, GetCookieManagerHttpInMemoryBlocked) {
1027 CefRefPtr<CookieTestSchemeHandler> handler =
1028 new CookieTestSchemeHandler("http", false, true);
1029 handler->ExecuteTest();
1030 ReleaseAndWaitForDestructor(handler);
1031 }
1032
1033 // Verify use of the global cookie manager with a custom scheme.
TEST(CookieTest,GetCookieManagerCustomGlobal)1034 TEST(CookieTest, GetCookieManagerCustomGlobal) {
1035 CefRefPtr<CookieTestSchemeHandler> handler =
1036 new CookieTestSchemeHandler(kCustomCookieScheme, true);
1037 handler->ExecuteTest();
1038 ReleaseAndWaitForDestructor(handler);
1039 }
1040
1041 // Verify use of an in-memory cookie manager with a custom scheme.
TEST(CookieTest,GetCookieManagerCustomInMemory)1042 TEST(CookieTest, GetCookieManagerCustomInMemory) {
1043 CefRefPtr<CookieTestSchemeHandler> handler =
1044 new CookieTestSchemeHandler(kCustomCookieScheme, false);
1045 handler->ExecuteTest();
1046 ReleaseAndWaitForDestructor(handler);
1047 }
1048
1049 namespace {
1050
1051 const char kCookieAccessScheme[] = "http";
1052 const char kCookieAccessDomain[] = "test-cookies.com";
1053 const char* kCookieAccessServerAddress = test_server::kServerAddress;
1054 const uint16 kCookieAccessServerPort = test_server::kServerPort;
1055
GetCookieAccessOrigin(const std::string & scheme,bool server_backend)1056 std::string GetCookieAccessOrigin(const std::string& scheme,
1057 bool server_backend) {
1058 std::stringstream ss;
1059 if (server_backend) {
1060 ss << scheme << "://" << kCookieAccessServerAddress << ":"
1061 << kCookieAccessServerPort;
1062 } else {
1063 ss << scheme << "://" << kCookieAccessDomain;
1064 }
1065 return ss.str();
1066 }
1067
GetCookieAccessUrl1(const std::string & scheme,bool server_backend)1068 std::string GetCookieAccessUrl1(const std::string& scheme,
1069 bool server_backend) {
1070 return GetCookieAccessOrigin(scheme, server_backend) + "/cookie1.html";
1071 }
1072
GetCookieAccessUrl2(const std::string & scheme,bool server_backend)1073 std::string GetCookieAccessUrl2(const std::string& scheme,
1074 bool server_backend) {
1075 return GetCookieAccessOrigin(scheme, server_backend) + "/cookie2.html";
1076 }
1077
TestCookieString(const std::string & cookie_str,int & cookie_js_ct,int & cookie_net_ct)1078 void TestCookieString(const std::string& cookie_str,
1079 int& cookie_js_ct,
1080 int& cookie_net_ct) {
1081 if (cookie_str.find("name_js=value_js") != std::string::npos) {
1082 cookie_js_ct++;
1083 }
1084 if (cookie_str.find("name_net=value_net") != std::string::npos) {
1085 cookie_net_ct++;
1086 }
1087 }
1088
1089 struct CookieAccessData {
1090 CefRefPtr<CefResponse> response;
1091 std::string response_data;
1092
1093 int request_ct_ = 0;
1094 int cookie_js_ct_ = 0;
1095 int cookie_net_ct_ = 0;
1096 };
1097
1098 class CookieAccessResponseHandler {
1099 public:
CookieAccessResponseHandler()1100 CookieAccessResponseHandler() {}
1101 virtual void AddResponse(const std::string& url, CookieAccessData* data) = 0;
1102
1103 protected:
~CookieAccessResponseHandler()1104 virtual ~CookieAccessResponseHandler() {}
1105 };
1106
GetHeaderValue(const CefServer::HeaderMap & header_map,const std::string & header_name)1107 std::string GetHeaderValue(const CefServer::HeaderMap& header_map,
1108 const std::string& header_name) {
1109 CefServer::HeaderMap::const_iterator it = header_map.find(header_name);
1110 if (it != header_map.end())
1111 return it->second;
1112 return std::string();
1113 }
1114
1115 // Serves request responses.
1116 class CookieAccessSchemeHandler : public CefResourceHandler {
1117 public:
CookieAccessSchemeHandler(CookieAccessData * data)1118 explicit CookieAccessSchemeHandler(CookieAccessData* data)
1119 : data_(data), offset_(0) {}
1120
Open(CefRefPtr<CefRequest> request,bool & handle_request,CefRefPtr<CefCallback> callback)1121 bool Open(CefRefPtr<CefRequest> request,
1122 bool& handle_request,
1123 CefRefPtr<CefCallback> callback) override {
1124 EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
1125
1126 CefRequest::HeaderMap headerMap;
1127 request->GetHeaderMap(headerMap);
1128 const std::string& cookie_str = GetHeaderValue(headerMap, "Cookie");
1129 TestCookieString(cookie_str, data_->cookie_js_ct_, data_->cookie_net_ct_);
1130
1131 // Continue immediately.
1132 handle_request = true;
1133 return true;
1134 }
1135
GetResponseHeaders(CefRefPtr<CefResponse> response,int64 & response_length,CefString & redirectUrl)1136 void GetResponseHeaders(CefRefPtr<CefResponse> response,
1137 int64& response_length,
1138 CefString& redirectUrl) override {
1139 EXPECT_IO_THREAD();
1140
1141 response->SetStatus(data_->response->GetStatus());
1142 response->SetStatusText(data_->response->GetStatusText());
1143 response->SetMimeType(data_->response->GetMimeType());
1144
1145 CefResponse::HeaderMap headerMap;
1146 data_->response->GetHeaderMap(headerMap);
1147 response->SetHeaderMap(headerMap);
1148
1149 response_length = data_->response_data.length();
1150 }
1151
Read(void * data_out,int bytes_to_read,int & bytes_read,CefRefPtr<CefResourceReadCallback> callback)1152 bool Read(void* data_out,
1153 int bytes_to_read,
1154 int& bytes_read,
1155 CefRefPtr<CefResourceReadCallback> callback) override {
1156 EXPECT_FALSE(CefCurrentlyOn(TID_UI) || CefCurrentlyOn(TID_IO));
1157
1158 bool has_data = false;
1159 bytes_read = 0;
1160
1161 size_t size = data_->response_data.length();
1162 if (offset_ < size) {
1163 int transfer_size =
1164 std::min(bytes_to_read, static_cast<int>(size - offset_));
1165 memcpy(data_out, data_->response_data.c_str() + offset_, transfer_size);
1166 offset_ += transfer_size;
1167
1168 bytes_read = transfer_size;
1169 has_data = true;
1170 }
1171
1172 return has_data;
1173 }
1174
Cancel()1175 void Cancel() override { EXPECT_IO_THREAD(); }
1176
1177 private:
TestCookie(const CefCookie & cookie,TrackCallback & got_cookie_js,TrackCallback & got_cookie_net)1178 static void TestCookie(const CefCookie& cookie,
1179 TrackCallback& got_cookie_js,
1180 TrackCallback& got_cookie_net) {
1181 const std::string& cookie_name = CefString(&cookie.name);
1182 const std::string& cookie_val = CefString(&cookie.value);
1183 if (cookie_name == "name_js") {
1184 EXPECT_STREQ("value_js", cookie_val.c_str());
1185 got_cookie_js.yes();
1186 } else if (cookie_name == "name_net") {
1187 EXPECT_STREQ("value_net", cookie_val.c_str());
1188 got_cookie_net.yes();
1189 } else {
1190 ADD_FAILURE() << "Unexpected cookie: " << cookie_name;
1191 }
1192 }
1193
1194 // |data_| is not owned by this object.
1195 CookieAccessData* data_;
1196
1197 size_t offset_;
1198
1199 IMPLEMENT_REFCOUNTING(CookieAccessSchemeHandler);
1200 DISALLOW_COPY_AND_ASSIGN(CookieAccessSchemeHandler);
1201 };
1202
1203 class CookieAccessSchemeHandlerFactory : public CefSchemeHandlerFactory,
1204 public CookieAccessResponseHandler {
1205 public:
CookieAccessSchemeHandlerFactory()1206 CookieAccessSchemeHandlerFactory() {}
1207
Create(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,const CefString & scheme_name,CefRefPtr<CefRequest> request)1208 CefRefPtr<CefResourceHandler> Create(CefRefPtr<CefBrowser> browser,
1209 CefRefPtr<CefFrame> frame,
1210 const CefString& scheme_name,
1211 CefRefPtr<CefRequest> request) override {
1212 EXPECT_IO_THREAD();
1213 const std::string& url = request->GetURL();
1214 ResponseDataMap::const_iterator it = data_map_.find(url);
1215 if (it != data_map_.end()) {
1216 it->second->request_ct_++;
1217
1218 return new CookieAccessSchemeHandler(it->second);
1219 }
1220
1221 // Unknown test.
1222 if (!IgnoreURL(url)) {
1223 ADD_FAILURE() << "Unexpected url: " << url;
1224 }
1225 return nullptr;
1226 }
1227
AddResponse(const std::string & url,CookieAccessData * data)1228 void AddResponse(const std::string& url, CookieAccessData* data) override {
1229 data_map_.insert(std::make_pair(url, data));
1230 }
1231
Shutdown(base::OnceClosure complete_callback)1232 void Shutdown(base::OnceClosure complete_callback) {
1233 if (!CefCurrentlyOn(TID_IO)) {
1234 CefPostTask(TID_IO, base::BindOnce(std::move(complete_callback)));
1235 return;
1236 }
1237
1238 std::move(complete_callback).Run();
1239 }
1240
1241 private:
1242 // Map of URL to Data.
1243 typedef std::map<std::string, CookieAccessData*> ResponseDataMap;
1244 ResponseDataMap data_map_;
1245
1246 IMPLEMENT_REFCOUNTING(CookieAccessSchemeHandlerFactory);
1247 };
1248
1249 // HTTP server handler.
1250 class CookieAccessServerHandler : public test_server::ObserverHelper,
1251 public CookieAccessResponseHandler {
1252 public:
CookieAccessServerHandler()1253 CookieAccessServerHandler()
1254 : initialized_(false),
1255 expected_http_request_ct_(-1),
1256 actual_http_request_ct_(0) {}
1257
~CookieAccessServerHandler()1258 virtual ~CookieAccessServerHandler() { RunCompleteCallback(); }
1259
1260 // Must be called before CreateServer().
AddResponse(const std::string & url,CookieAccessData * data)1261 void AddResponse(const std::string& url, CookieAccessData* data) override {
1262 EXPECT_FALSE(initialized_);
1263 data_map_.insert(std::make_pair(url, data));
1264 }
1265
1266 // Must be called before CreateServer().
SetExpectedRequestCount(int count)1267 void SetExpectedRequestCount(int count) {
1268 EXPECT_FALSE(initialized_);
1269 expected_http_request_ct_ = count;
1270 }
1271
1272 // |complete_callback| will be executed on the UI thread after the server is
1273 // started.
CreateServer(base::OnceClosure complete_callback)1274 void CreateServer(base::OnceClosure complete_callback) {
1275 EXPECT_UI_THREAD();
1276
1277 if (expected_http_request_ct_ < 0) {
1278 // Default to the assumption of one request per registered URL.
1279 SetExpectedRequestCount(static_cast<int>(data_map_.size()));
1280 }
1281
1282 EXPECT_FALSE(initialized_);
1283 initialized_ = true;
1284
1285 EXPECT_TRUE(complete_callback_.is_null());
1286 complete_callback_ = std::move(complete_callback);
1287
1288 Initialize();
1289 }
1290
1291 // Results in a call to VerifyResults() and eventual execution of the
1292 // |complete_callback| on the UI thread via CookieAccessServerHandler
1293 // destruction.
ShutdownServer(base::OnceClosure complete_callback)1294 void ShutdownServer(base::OnceClosure complete_callback) {
1295 EXPECT_UI_THREAD();
1296
1297 EXPECT_TRUE(complete_callback_.is_null());
1298 complete_callback_ = std::move(complete_callback);
1299
1300 Shutdown();
1301 }
1302
OnInitialized(const std::string & server_origin)1303 void OnInitialized(const std::string& server_origin) override {
1304 EXPECT_UI_THREAD();
1305 EXPECT_STREQ(server_origin.c_str(),
1306 GetCookieAccessOrigin(kCookieAccessScheme, true).c_str());
1307
1308 EXPECT_FALSE(got_server_created_);
1309 got_server_created_.yes();
1310
1311 RunCompleteCallback();
1312 }
1313
OnShutdown()1314 void OnShutdown() override {
1315 EXPECT_UI_THREAD();
1316
1317 EXPECT_FALSE(got_server_destroyed_);
1318 got_server_destroyed_.yes();
1319
1320 VerifyResults();
1321
1322 delete this;
1323 }
1324
OnHttpRequest(CefRefPtr<CefServer> server,int connection_id,const CefString & client_address,CefRefPtr<CefRequest> request)1325 bool OnHttpRequest(CefRefPtr<CefServer> server,
1326 int connection_id,
1327 const CefString& client_address,
1328 CefRefPtr<CefRequest> request) override {
1329 EXPECT_UI_THREAD();
1330 EXPECT_FALSE(client_address.empty());
1331
1332 // Log the requests for better error reporting.
1333 request_log_ += request->GetMethod().ToString() + " " +
1334 request->GetURL().ToString() + "\n";
1335
1336 HandleRequest(server, connection_id, request);
1337
1338 actual_http_request_ct_++;
1339
1340 return true;
1341 }
1342
1343 private:
VerifyResults()1344 void VerifyResults() {
1345 EXPECT_TRUE(got_server_created_);
1346 EXPECT_TRUE(got_server_destroyed_);
1347 EXPECT_EQ(expected_http_request_ct_, actual_http_request_ct_)
1348 << request_log_;
1349 }
1350
HandleRequest(CefRefPtr<CefServer> server,int connection_id,CefRefPtr<CefRequest> request)1351 void HandleRequest(CefRefPtr<CefServer> server,
1352 int connection_id,
1353 CefRefPtr<CefRequest> request) {
1354 const std::string& url = request->GetURL();
1355 ResponseDataMap::const_iterator it = data_map_.find(url);
1356 if (it != data_map_.end()) {
1357 it->second->request_ct_++;
1358
1359 CefRequest::HeaderMap headerMap;
1360 request->GetHeaderMap(headerMap);
1361 const std::string& cookie_str = GetHeaderValue(headerMap, "cookie");
1362 TestCookieString(cookie_str, it->second->cookie_js_ct_,
1363 it->second->cookie_net_ct_);
1364
1365 SendResponse(server, connection_id, it->second->response,
1366 it->second->response_data);
1367 } else {
1368 // Unknown test.
1369 if (!IgnoreURL(url)) {
1370 ADD_FAILURE() << "Unexpected url: " << url;
1371 }
1372 server->SendHttp500Response(connection_id, "Unknown test");
1373 }
1374 }
1375
SendResponse(CefRefPtr<CefServer> server,int connection_id,CefRefPtr<CefResponse> response,const std::string & response_data)1376 static void SendResponse(CefRefPtr<CefServer> server,
1377 int connection_id,
1378 CefRefPtr<CefResponse> response,
1379 const std::string& response_data) {
1380 // Execute on the server thread because some methods require it.
1381 CefRefPtr<CefTaskRunner> task_runner = server->GetTaskRunner();
1382 if (!task_runner->BelongsToCurrentThread()) {
1383 task_runner->PostTask(CefCreateClosureTask(
1384 base::BindOnce(CookieAccessServerHandler::SendResponse, server,
1385 connection_id, response, response_data)));
1386 return;
1387 }
1388
1389 int response_code = response->GetStatus();
1390 const CefString& content_type = response->GetMimeType();
1391 int64 content_length = static_cast<int64>(response_data.size());
1392
1393 CefResponse::HeaderMap extra_headers;
1394 response->GetHeaderMap(extra_headers);
1395
1396 server->SendHttpResponse(connection_id, response_code, content_type,
1397 content_length, extra_headers);
1398
1399 if (content_length != 0) {
1400 server->SendRawData(connection_id, response_data.data(),
1401 response_data.size());
1402 server->CloseConnection(connection_id);
1403 }
1404
1405 // The connection should be closed.
1406 EXPECT_FALSE(server->IsValidConnection(connection_id));
1407 }
1408
RunCompleteCallback()1409 void RunCompleteCallback() {
1410 EXPECT_UI_THREAD();
1411
1412 EXPECT_FALSE(complete_callback_.is_null());
1413 std::move(complete_callback_).Run();
1414 }
1415
1416 // Map of URL to Data.
1417 typedef std::map<std::string, CookieAccessData*> ResponseDataMap;
1418 ResponseDataMap data_map_;
1419
1420 bool initialized_;
1421
1422 // Only accessed on the UI thread.
1423 base::OnceClosure complete_callback_;
1424
1425 // After initialization the below members are only accessed on the server
1426 // thread.
1427
1428 TrackCallback got_server_created_;
1429 TrackCallback got_server_destroyed_;
1430
1431 int expected_http_request_ct_;
1432 int actual_http_request_ct_;
1433
1434 std::string request_log_;
1435
1436 DISALLOW_COPY_AND_ASSIGN(CookieAccessServerHandler);
1437 };
1438
1439 class CookieAccessTestHandler : public RoutingTestHandler,
1440 public CefCookieAccessFilter {
1441 public:
1442 enum TestMode {
1443 ALLOW = 0,
1444 BLOCK_READ = 1 << 0,
1445 BLOCK_WRITE = 1 << 1,
1446 BLOCK_READ_WRITE = BLOCK_READ | BLOCK_WRITE,
1447 ALLOW_NO_FILTER = 1 << 2,
1448
1449 // Block all cookies using CefRequestContextSettings. Can only be used with
1450 // a non-global request context because it's too late (during test
1451 // execution) to call this method on the global context.
1452 BLOCK_ALL_COOKIES = 1 << 3,
1453
1454 // Return nullptr from GetResourceRequestHandler. Can only be used in
1455 // combination with the SERVER or SCHEME_HANDLER backend (the
1456 // RESOURCE_HANDLER backend would not be called).
1457 ALLOW_NO_HANDLER = 1 << 4,
1458 };
1459
1460 enum TestBackend {
1461 // Test an HTTP server backend.
1462 SERVER,
1463
1464 // Test a custom scheme handler backend.
1465 SCHEME_HANDLER,
1466
1467 // Test that GetResourceHandler behaves the same as a custom scheme handler.
1468 RESOURCE_HANDLER,
1469 };
1470
CookieAccessTestHandler(TestMode test_mode,TestBackend test_backend,bool custom_scheme,bool use_global)1471 CookieAccessTestHandler(TestMode test_mode,
1472 TestBackend test_backend,
1473 bool custom_scheme,
1474 bool use_global)
1475 : test_mode_(test_mode),
1476 test_backend_(test_backend),
1477 scheme_(custom_scheme ? kCustomCookieScheme : kCookieAccessScheme),
1478 use_global_(use_global) {
1479 if (test_mode_ == BLOCK_ALL_COOKIES)
1480 CHECK(!use_global_);
1481 else if (test_mode_ == ALLOW_NO_HANDLER)
1482 CHECK_NE(RESOURCE_HANDLER, test_backend_);
1483 if (test_backend_ == SERVER)
1484 CHECK(!custom_scheme);
1485 }
1486
RunTest()1487 void RunTest() override {
1488 if (use_global_) {
1489 context_ = CefRequestContext::GetGlobalContext();
1490 } else {
1491 // Create the request context that will use an in-memory cache.
1492 CefRequestContextSettings settings;
1493
1494 const bool block_cookies = (test_mode_ == BLOCK_ALL_COOKIES);
1495 if (scheme_ == kCustomCookieScheme || block_cookies) {
1496 if (!block_cookies) {
1497 CefString(&settings.cookieable_schemes_list) = kCustomCookieScheme;
1498 } else {
1499 settings.cookieable_schemes_exclude_defaults = true;
1500 }
1501 }
1502
1503 context_ = CefRequestContext::CreateContext(settings, nullptr);
1504 }
1505
1506 SetTestTimeout();
1507
1508 cookie_manager_ = context_->GetCookieManager(nullptr);
1509 RunTestSetupContinue();
1510 }
1511
DestroyTest()1512 void DestroyTest() override {
1513 if (!CefCurrentlyOn(TID_UI)) {
1514 CefPostTask(TID_UI,
1515 base::BindOnce(&CookieAccessTestHandler::DestroyTest, this));
1516 return;
1517 }
1518
1519 cookie_manager_ = nullptr;
1520 context_ = nullptr;
1521
1522 // Got both network requests.
1523 EXPECT_EQ(1, data1_.request_ct_);
1524 EXPECT_EQ(1, data2_.request_ct_);
1525
1526 if (test_mode_ == ALLOW_NO_FILTER || test_mode_ == ALLOW_NO_HANDLER) {
1527 EXPECT_EQ(0, can_save_cookie1_ct_);
1528 EXPECT_EQ(0, can_send_cookie2_ct_);
1529 } else {
1530 if (test_mode_ == BLOCK_ALL_COOKIES) {
1531 // Never send any cookies.
1532 EXPECT_EQ(0, can_send_cookie2_ct_);
1533 EXPECT_EQ(0, can_save_cookie1_ct_);
1534 } else if (test_mode_ & BLOCK_WRITE) {
1535 // Get 1 calls to CanSendCookie for the 2nd network request due to the
1536 // JS cookie (network cookie is blocked).
1537 EXPECT_EQ(1, can_send_cookie2_ct_);
1538 // Get 1 call to CanSaveCookie for the 1st network request due to the
1539 // network cookie.
1540 EXPECT_EQ(1, can_save_cookie1_ct_);
1541 } else {
1542 // Get 2 calls to CanSendCookie for the 2nd network request due to the
1543 // network cookie + JS cookie.
1544 EXPECT_EQ(2, can_send_cookie2_ct_);
1545 // Get 1 call to CanSaveCookie for the 1st network request due to the
1546 // network cookie.
1547 EXPECT_EQ(1, can_save_cookie1_ct_);
1548 }
1549 }
1550
1551 if (test_mode_ == BLOCK_ALL_COOKIES) {
1552 // Never get the JS cookie via JS.
1553 EXPECT_EQ(0, cookie_js1_ct_);
1554 EXPECT_EQ(0, cookie_js2_ct_);
1555 EXPECT_EQ(0, cookie_js3_ct_);
1556 } else {
1557 // Always get the JS cookie via JS.
1558 EXPECT_EQ(1, cookie_js1_ct_);
1559 EXPECT_EQ(1, cookie_js2_ct_);
1560 EXPECT_EQ(1, cookie_js3_ct_);
1561 }
1562
1563 // Only get the net cookie via JS if cookie write was allowed.
1564 if ((test_mode_ & BLOCK_WRITE) || test_mode_ == BLOCK_ALL_COOKIES) {
1565 EXPECT_EQ(0, cookie_net1_ct_);
1566 EXPECT_EQ(0, cookie_net2_ct_);
1567 EXPECT_EQ(0, cookie_net3_ct_);
1568 } else {
1569 EXPECT_EQ(1, cookie_net1_ct_);
1570 EXPECT_EQ(1, cookie_net2_ct_);
1571 EXPECT_EQ(1, cookie_net3_ct_);
1572 }
1573
1574 // No cookies sent for the 1st network request.
1575 EXPECT_EQ(0, data1_.cookie_js_ct_);
1576 EXPECT_EQ(0, data1_.cookie_net_ct_);
1577
1578 // 2nd network request...
1579 if ((test_mode_ & BLOCK_READ) || test_mode_ == BLOCK_ALL_COOKIES) {
1580 // No cookies sent if reading was blocked.
1581 EXPECT_EQ(0, data2_.cookie_js_ct_);
1582 EXPECT_EQ(0, data2_.cookie_net_ct_);
1583 } else if (test_mode_ & BLOCK_WRITE) {
1584 // Only JS cookie sent if writing was blocked.
1585 EXPECT_EQ(1, data2_.cookie_js_ct_);
1586 EXPECT_EQ(0, data2_.cookie_net_ct_);
1587 } else {
1588 // All cookies sent.
1589 EXPECT_EQ(1, data2_.cookie_js_ct_);
1590 EXPECT_EQ(1, data2_.cookie_net_ct_);
1591 }
1592
1593 TestHandler::DestroyTest();
1594 }
1595
GetCookieAccessFilter(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefRefPtr<CefRequest> request)1596 CefRefPtr<CefCookieAccessFilter> GetCookieAccessFilter(
1597 CefRefPtr<CefBrowser> browser,
1598 CefRefPtr<CefFrame> frame,
1599 CefRefPtr<CefRequest> request) override {
1600 EXPECT_IO_THREAD();
1601
1602 if (test_mode_ == ALLOW_NO_FILTER)
1603 return nullptr;
1604
1605 return this;
1606 }
1607
GetResourceRequestHandler(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefRefPtr<CefRequest> request,bool is_navigation,bool is_download,const CefString & request_initiator,bool & disable_default_handling)1608 CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(
1609 CefRefPtr<CefBrowser> browser,
1610 CefRefPtr<CefFrame> frame,
1611 CefRefPtr<CefRequest> request,
1612 bool is_navigation,
1613 bool is_download,
1614 const CefString& request_initiator,
1615 bool& disable_default_handling) override {
1616 if (test_mode_ == ALLOW_NO_HANDLER)
1617 return nullptr;
1618
1619 return this;
1620 }
1621
GetResourceHandler(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefRefPtr<CefRequest> request)1622 CefRefPtr<CefResourceHandler> GetResourceHandler(
1623 CefRefPtr<CefBrowser> browser,
1624 CefRefPtr<CefFrame> frame,
1625 CefRefPtr<CefRequest> request) override {
1626 if (test_backend_ == RESOURCE_HANDLER && scheme_factory_) {
1627 return scheme_factory_->Create(browser, frame, scheme_, request);
1628 }
1629
1630 return nullptr;
1631 }
1632
CanSendCookie(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefRefPtr<CefRequest> request,const CefCookie & cookie)1633 bool CanSendCookie(CefRefPtr<CefBrowser> browser,
1634 CefRefPtr<CefFrame> frame,
1635 CefRefPtr<CefRequest> request,
1636 const CefCookie& cookie) override {
1637 EXPECT_IO_THREAD();
1638
1639 const std::string& url = request->GetURL();
1640 if (url == GetCookieAccessUrl2(scheme_, test_backend_ == SERVER)) {
1641 can_send_cookie2_ct_++;
1642 } else if (!IgnoreURL(url)) {
1643 ADD_FAILURE() << "Unexpected url: " << url;
1644 }
1645
1646 return !(test_mode_ & BLOCK_READ);
1647 }
1648
CanSaveCookie(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefRefPtr<CefRequest> request,CefRefPtr<CefResponse> response,const CefCookie & cookie)1649 bool CanSaveCookie(CefRefPtr<CefBrowser> browser,
1650 CefRefPtr<CefFrame> frame,
1651 CefRefPtr<CefRequest> request,
1652 CefRefPtr<CefResponse> response,
1653 const CefCookie& cookie) override {
1654 EXPECT_IO_THREAD();
1655
1656 // Expecting the network cookie only.
1657 EXPECT_STREQ("name_net", CefString(&cookie.name).ToString().c_str());
1658 EXPECT_STREQ("value_net", CefString(&cookie.value).ToString().c_str());
1659
1660 const std::string& url = request->GetURL();
1661 if (url == GetCookieAccessUrl1(scheme_, test_backend_ == SERVER)) {
1662 can_save_cookie1_ct_++;
1663 } else if (!IgnoreURL(url)) {
1664 ADD_FAILURE() << "Unexpected url: " << url;
1665 }
1666
1667 return !(test_mode_ & BLOCK_WRITE);
1668 }
1669
OnQuery(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,int64 query_id,const CefString & request,bool persistent,CefRefPtr<Callback> callback)1670 bool OnQuery(CefRefPtr<CefBrowser> browser,
1671 CefRefPtr<CefFrame> frame,
1672 int64 query_id,
1673 const CefString& request,
1674 bool persistent,
1675 CefRefPtr<Callback> callback) override {
1676 const std::string& url = frame->GetURL();
1677 const std::string& cookie_str = request.ToString();
1678 if (url == GetCookieAccessUrl1(scheme_, test_backend_ == SERVER)) {
1679 TestCookieString(cookie_str, cookie_js1_ct_, cookie_net1_ct_);
1680 browser->GetMainFrame()->LoadURL(
1681 GetCookieAccessUrl2(scheme_, test_backend_ == SERVER));
1682 } else if (url == GetCookieAccessUrl2(scheme_, test_backend_ == SERVER)) {
1683 TestCookieString(cookie_str, cookie_js2_ct_, cookie_net2_ct_);
1684 FinishTest();
1685 } else {
1686 ADD_FAILURE() << "Unexpected url: " << url;
1687 }
1688 return true;
1689 }
1690
1691 private:
AddResponses(CookieAccessResponseHandler * handler)1692 void AddResponses(CookieAccessResponseHandler* handler) {
1693 // 1st request sets a cookie via net response headers and JS, then retrieves
1694 // the cookies via JS.
1695 {
1696 data1_.response = CefResponse::Create();
1697 data1_.response->SetMimeType("text/html");
1698 data1_.response->SetStatus(200);
1699 data1_.response->SetStatusText("OK");
1700
1701 CefResponse::HeaderMap headerMap;
1702 data1_.response->GetHeaderMap(headerMap);
1703 headerMap.insert(std::make_pair("Set-Cookie", "name_net=value_net"));
1704 data1_.response->SetHeaderMap(headerMap);
1705
1706 data1_.response_data =
1707 "<html><head>"
1708 "<script>"
1709 "document.cookie='name_js=value_js';"
1710 "window.testQuery({request:document.cookie});"
1711 "</script>"
1712 "</head><body>COOKIE ACCESS TEST 1</body></html>";
1713
1714 handler->AddResponse(
1715 GetCookieAccessUrl1(scheme_, test_backend_ == SERVER), &data1_);
1716 }
1717
1718 // 2nd request retrieves the cookies via JS.
1719 {
1720 data2_.response = CefResponse::Create();
1721 data2_.response->SetMimeType("text/html");
1722 data2_.response->SetStatus(200);
1723 data2_.response->SetStatusText("OK");
1724
1725 data2_.response_data =
1726 "<html><head>"
1727 "<script>"
1728 "window.testQuery({request:document.cookie});"
1729 "</script>"
1730 "</head><body>COOKIE ACCESS TEST 2</body></html>";
1731
1732 handler->AddResponse(
1733 GetCookieAccessUrl2(scheme_, test_backend_ == SERVER), &data2_);
1734 }
1735 }
1736
RunTestSetupContinue()1737 void RunTestSetupContinue() {
1738 CefPostTask(
1739 TID_UI,
1740 base::BindOnce(
1741 &CookieAccessTestHandler::StartBackend, this,
1742 base::BindOnce(&CookieAccessTestHandler::RunTestContinue, this)));
1743 }
1744
StartBackend(base::OnceClosure complete_callback)1745 void StartBackend(base::OnceClosure complete_callback) {
1746 if (test_backend_ == SERVER) {
1747 StartServer(std::move(complete_callback));
1748 } else {
1749 StartSchemeHandler(std::move(complete_callback));
1750 }
1751 }
1752
StartServer(base::OnceClosure complete_callback)1753 void StartServer(base::OnceClosure complete_callback) {
1754 EXPECT_FALSE(server_handler_);
1755
1756 server_handler_ = new CookieAccessServerHandler();
1757 AddResponses(server_handler_);
1758 server_handler_->CreateServer(std::move(complete_callback));
1759 }
1760
StartSchemeHandler(base::OnceClosure complete_callback)1761 void StartSchemeHandler(base::OnceClosure complete_callback) {
1762 // Add the factory registration.
1763 scheme_factory_ = new CookieAccessSchemeHandlerFactory();
1764 AddResponses(scheme_factory_.get());
1765 if (test_backend_ == SCHEME_HANDLER) {
1766 context_->RegisterSchemeHandlerFactory(scheme_, kCookieAccessDomain,
1767 scheme_factory_.get());
1768 }
1769
1770 std::move(complete_callback).Run();
1771 }
1772
RunTestContinue()1773 void RunTestContinue() {
1774 if (!CefCurrentlyOn(TID_UI)) {
1775 CefPostTask(TID_UI, base::BindOnce(
1776 &CookieAccessTestHandler::RunTestContinue, this));
1777 return;
1778 }
1779
1780 CreateBrowser(GetCookieAccessUrl1(scheme_, test_backend_ == SERVER),
1781 context_);
1782 }
1783
FinishTest()1784 void FinishTest() {
1785 // Verify that cookies were set correctly.
1786 class TestVisitor : public CefCookieVisitor {
1787 public:
1788 explicit TestVisitor(CookieAccessTestHandler* handler)
1789 : handler_(handler) {}
1790 ~TestVisitor() override {
1791 // Destroy the test.
1792 CefPostTask(
1793 TID_UI,
1794 base::BindOnce(&CookieAccessTestHandler::ShutdownBackend, handler_,
1795 base::BindOnce(&CookieAccessTestHandler::DestroyTest,
1796 handler_)));
1797 }
1798
1799 bool Visit(const CefCookie& cookie,
1800 int count,
1801 int total,
1802 bool& deleteCookie) override {
1803 const std::string& name = CefString(&cookie.name);
1804 const std::string& value = CefString(&cookie.value);
1805 if (name == "name_js" && value == "value_js")
1806 handler_->cookie_js3_ct_++;
1807 else if (name == "name_net" && value == "value_net")
1808 handler_->cookie_net3_ct_++;
1809
1810 // Clean up the cookies.
1811 deleteCookie = true;
1812
1813 return true;
1814 }
1815
1816 private:
1817 CookieAccessTestHandler* handler_;
1818 IMPLEMENT_REFCOUNTING(TestVisitor);
1819 };
1820
1821 cookie_manager_->VisitAllCookies(new TestVisitor(this));
1822 }
1823
ShutdownBackend(base::OnceClosure complete_callback)1824 void ShutdownBackend(base::OnceClosure complete_callback) {
1825 if (test_backend_ == SERVER) {
1826 ShutdownServer(std::move(complete_callback));
1827 } else {
1828 ShutdownSchemeHandler(std::move(complete_callback));
1829 }
1830 }
1831
ShutdownServer(base::OnceClosure complete_callback)1832 void ShutdownServer(base::OnceClosure complete_callback) {
1833 EXPECT_TRUE(server_handler_);
1834
1835 // |server_handler_| will delete itself after shutdown.
1836 server_handler_->ShutdownServer(std::move(complete_callback));
1837 server_handler_ = nullptr;
1838 }
1839
ShutdownSchemeHandler(base::OnceClosure complete_callback)1840 void ShutdownSchemeHandler(base::OnceClosure complete_callback) {
1841 EXPECT_TRUE(scheme_factory_);
1842
1843 if (test_backend_ == SCHEME_HANDLER) {
1844 context_->RegisterSchemeHandlerFactory(scheme_, kCookieAccessDomain,
1845 nullptr);
1846 }
1847 scheme_factory_->Shutdown(std::move(complete_callback));
1848 scheme_factory_ = nullptr;
1849 }
1850
1851 const TestMode test_mode_;
1852 const TestBackend test_backend_;
1853 const std::string scheme_;
1854 const bool use_global_;
1855 CefRefPtr<CefRequestContext> context_;
1856 CefRefPtr<CefCookieManager> cookie_manager_;
1857
1858 CookieAccessServerHandler* server_handler_ = nullptr;
1859 CefRefPtr<CookieAccessSchemeHandlerFactory> scheme_factory_;
1860
1861 CookieAccessData data1_;
1862 CookieAccessData data2_;
1863
1864 // 1st request.
1865 int can_save_cookie1_ct_ = 0;
1866 int cookie_js1_ct_ = 0;
1867 int cookie_net1_ct_ = 0;
1868
1869 // 2nd request.
1870 int can_send_cookie2_ct_ = 0;
1871 int cookie_js2_ct_ = 0;
1872 int cookie_net2_ct_ = 0;
1873
1874 // From cookie manager.
1875 int cookie_js3_ct_ = 0;
1876 int cookie_net3_ct_ = 0;
1877
1878 DISALLOW_COPY_AND_ASSIGN(CookieAccessTestHandler);
1879 IMPLEMENT_REFCOUNTING(CookieAccessTestHandler);
1880 };
1881
1882 } // namespace
1883
1884 #define ACCESS_TEST(name, test_mode, backend_mode, custom_scheme, use_global) \
1885 TEST(CookieTest, Access##name) { \
1886 CefRefPtr<CookieAccessTestHandler> handler = new CookieAccessTestHandler( \
1887 CookieAccessTestHandler::test_mode, \
1888 CookieAccessTestHandler::backend_mode, custom_scheme, use_global); \
1889 handler->ExecuteTest(); \
1890 ReleaseAndWaitForDestructor(handler); \
1891 }
1892
1893 #define ACCESS_TEST_ALL_MODES(name, backend_mode, custom_scheme, use_global) \
1894 ACCESS_TEST(name##Allow, ALLOW, backend_mode, custom_scheme, use_global) \
1895 ACCESS_TEST(name##AllowNoFilter, ALLOW_NO_FILTER, backend_mode, \
1896 custom_scheme, use_global) \
1897 ACCESS_TEST(name##BlockRead, BLOCK_READ, backend_mode, custom_scheme, \
1898 use_global) \
1899 ACCESS_TEST(name##BlockWrite, BLOCK_WRITE, backend_mode, custom_scheme, \
1900 use_global) \
1901 ACCESS_TEST(name##BlockReadWrite, BLOCK_READ_WRITE, backend_mode, \
1902 custom_scheme, use_global)
1903
1904 // These tests only work with a non-global context.
1905 #define ACCESS_TEST_BLOCKALLCOOKIES_MODES(name, backend_mode, custom_scheme) \
1906 ACCESS_TEST(name##BlockAllCookies, BLOCK_ALL_COOKIES, backend_mode, \
1907 custom_scheme, false)
1908
1909 // These tests only work with SERVER and SCHEME_HANDLER backends.
1910 #define ACCESS_TEST_ALLOWNOHANDLER_MODES(name, backend_mode, custom_scheme) \
1911 ACCESS_TEST(name##GlobalAllowNoHandler, ALLOW_NO_HANDLER, backend_mode, \
1912 custom_scheme, false) \
1913 ACCESS_TEST(name##InMemoryAllowNoHandler, ALLOW_NO_HANDLER, backend_mode, \
1914 custom_scheme, true)
1915
1916 #define ACCESS_TEST_CUSTOM(name, backend_mode) \
1917 ACCESS_TEST_ALL_MODES(name##CustomGlobal, backend_mode, true, true) \
1918 ACCESS_TEST_ALL_MODES(name##CustomInMemory, backend_mode, true, false) \
1919 ACCESS_TEST_BLOCKALLCOOKIES_MODES(name##CustomInMemory, backend_mode, true)
1920
1921 #define ACCESS_TEST_STANDARD(name, backend_mode) \
1922 ACCESS_TEST_ALL_MODES(name##StandardGlobal, backend_mode, false, true) \
1923 ACCESS_TEST_ALL_MODES(name##StandardInMemory, backend_mode, false, false) \
1924 ACCESS_TEST_BLOCKALLCOOKIES_MODES(name##StandardInMemory, backend_mode, false)
1925
1926 // Server backend only works with standard schemes.
1927 ACCESS_TEST_STANDARD(Server, SERVER)
1928 ACCESS_TEST_ALLOWNOHANDLER_MODES(ServerStandard, SERVER, false)
1929
1930 // Other backends work with all schemes.
1931 ACCESS_TEST_CUSTOM(Scheme, SCHEME_HANDLER)
1932 ACCESS_TEST_ALLOWNOHANDLER_MODES(SchemeCustom, SCHEME_HANDLER, true)
1933 ACCESS_TEST_STANDARD(Scheme, SCHEME_HANDLER)
1934 ACCESS_TEST_ALLOWNOHANDLER_MODES(SchemeStandard, SCHEME_HANDLER, false)
1935
1936 ACCESS_TEST_CUSTOM(Resource, RESOURCE_HANDLER)
1937 ACCESS_TEST_STANDARD(Resource, RESOURCE_HANDLER)
1938
1939 namespace {
1940
1941 // Tests the behavior of restarting of a network request that sets cookies and
1942 // a network request that includes cookies.
1943 // 1. Begin loading URL1, then restart the request in OnResourceResponse.
1944 // No cookies are saved.
1945 // 2. Load URL1 successfully. Network and JS cookies are saved.
1946 // 3. Begin loading URL2, then restart the request in OnResourceResponse.
1947 // Cookies are sent with the request/response.
1948 // 4. Load URL2 successfully. Cookies are sent with the request/response.
1949 class CookieRestartTestHandler : public RoutingTestHandler,
1950 public CefCookieAccessFilter {
1951 public:
CookieRestartTestHandler(bool use_global)1952 explicit CookieRestartTestHandler(bool use_global)
1953 : scheme_(kCookieAccessScheme), use_global_(use_global) {}
1954
RunTest()1955 void RunTest() override {
1956 if (use_global_) {
1957 context_ = CefRequestContext::GetGlobalContext();
1958 } else {
1959 // Create the request context that will use an in-memory cache.
1960 CefRequestContextSettings settings;
1961 context_ = CefRequestContext::CreateContext(settings, nullptr);
1962 }
1963
1964 cookie_manager_ = context_->GetCookieManager(nullptr);
1965
1966 SetTestTimeout();
1967 RunTestSetupContinue();
1968 }
1969
DestroyTest()1970 void DestroyTest() override {
1971 if (!CefCurrentlyOn(TID_UI)) {
1972 CefPostTask(TID_UI,
1973 base::BindOnce(&CookieRestartTestHandler::DestroyTest, this));
1974 return;
1975 }
1976
1977 cookie_manager_ = nullptr;
1978 context_ = nullptr;
1979
1980 // Get 2 network requests for each URL.
1981 EXPECT_EQ(2, data1_.request_ct_);
1982 EXPECT_EQ(2, data2_.request_ct_);
1983
1984 // Get resource request callbacks for all requests (2 for each URL).
1985 EXPECT_EQ(4, before_resource_load_ct_);
1986 EXPECT_EQ(4, resource_response_ct_);
1987
1988 // Get JS query callbacks for the successful requests (1 for each URL).
1989 EXPECT_EQ(2, query_ct_);
1990
1991 // No cookies sent for the URL1 network requests because (a) we don't have
1992 // any cookies set initially and (b) we don't save cookies from the 1st URL1
1993 // request which is restarted.
1994 EXPECT_EQ(0, data1_.cookie_js_ct_);
1995 EXPECT_EQ(0, data1_.cookie_net_ct_);
1996
1997 // Net and JS cookies sent for both URL2 network requests.
1998 EXPECT_EQ(2, data2_.cookie_js_ct_);
1999 EXPECT_EQ(2, data2_.cookie_net_ct_);
2000
2001 // 1 call to CanSaveCookie for the net cookie returned by the successful
2002 // URL1 request.
2003 EXPECT_EQ(1, can_save_cookie_ct_);
2004 // 4 calls to CanSendCookie because both net and JS cookies are sent for
2005 // each URL2 request.
2006 EXPECT_EQ(4, can_send_cookie_ct_);
2007
2008 // Get the net and JS cookies from the JS query for the successful requests
2009 // (1 for each URL).
2010 EXPECT_EQ(1, cookie_js1_ct_);
2011 EXPECT_EQ(1, cookie_net1_ct_);
2012 EXPECT_EQ(1, cookie_js2_ct_);
2013 EXPECT_EQ(1, cookie_net2_ct_);
2014
2015 // Get the net and JS cookies from the cookie manager at the end.
2016 EXPECT_EQ(1, cookie_manager_js_ct_);
2017 EXPECT_EQ(1, cookie_manager_net_ct_);
2018
2019 TestHandler::DestroyTest();
2020 }
2021
GetCookieAccessFilter(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefRefPtr<CefRequest> request)2022 CefRefPtr<CefCookieAccessFilter> GetCookieAccessFilter(
2023 CefRefPtr<CefBrowser> browser,
2024 CefRefPtr<CefFrame> frame,
2025 CefRefPtr<CefRequest> request) override {
2026 EXPECT_IO_THREAD();
2027 return this;
2028 }
2029
GetResourceRequestHandler(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefRefPtr<CefRequest> request,bool is_navigation,bool is_download,const CefString & request_initiator,bool & disable_default_handling)2030 CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(
2031 CefRefPtr<CefBrowser> browser,
2032 CefRefPtr<CefFrame> frame,
2033 CefRefPtr<CefRequest> request,
2034 bool is_navigation,
2035 bool is_download,
2036 const CefString& request_initiator,
2037 bool& disable_default_handling) override {
2038 return this;
2039 }
2040
GetResourceHandler(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefRefPtr<CefRequest> request)2041 CefRefPtr<CefResourceHandler> GetResourceHandler(
2042 CefRefPtr<CefBrowser> browser,
2043 CefRefPtr<CefFrame> frame,
2044 CefRefPtr<CefRequest> request) override {
2045 return nullptr;
2046 }
2047
CanSendCookie(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefRefPtr<CefRequest> request,const CefCookie & cookie)2048 bool CanSendCookie(CefRefPtr<CefBrowser> browser,
2049 CefRefPtr<CefFrame> frame,
2050 CefRefPtr<CefRequest> request,
2051 const CefCookie& cookie) override {
2052 EXPECT_IO_THREAD();
2053 can_send_cookie_ct_++;
2054
2055 // Called before the URL2 network requests.
2056 EXPECT_LE(2, before_resource_load_ct_);
2057
2058 return true;
2059 }
2060
CanSaveCookie(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefRefPtr<CefRequest> request,CefRefPtr<CefResponse> response,const CefCookie & cookie)2061 bool CanSaveCookie(CefRefPtr<CefBrowser> browser,
2062 CefRefPtr<CefFrame> frame,
2063 CefRefPtr<CefRequest> request,
2064 CefRefPtr<CefResponse> response,
2065 const CefCookie& cookie) override {
2066 EXPECT_IO_THREAD();
2067 can_save_cookie_ct_++;
2068
2069 // Called after the successful URL1 network request.
2070 EXPECT_EQ(2, before_resource_load_ct_);
2071
2072 // Expecting the network cookie only.
2073 EXPECT_STREQ("name_net", CefString(&cookie.name).ToString().c_str());
2074 EXPECT_STREQ("value_net", CefString(&cookie.value).ToString().c_str());
2075
2076 return true;
2077 }
2078
OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefRefPtr<CefRequest> request,CefRefPtr<CefCallback> callback)2079 cef_return_value_t OnBeforeResourceLoad(
2080 CefRefPtr<CefBrowser> browser,
2081 CefRefPtr<CefFrame> frame,
2082 CefRefPtr<CefRequest> request,
2083 CefRefPtr<CefCallback> callback) override {
2084 EXPECT_IO_THREAD();
2085 before_resource_load_ct_++;
2086
2087 const std::string& url = request->GetURL();
2088
2089 if (before_resource_load_ct_ <= 2) {
2090 EXPECT_STREQ(GetCookieAccessUrl1(scheme_, true).c_str(), url.c_str());
2091 } else {
2092 EXPECT_STREQ(GetCookieAccessUrl2(scheme_, true).c_str(), url.c_str());
2093 }
2094
2095 const std::string& cookie_str = request->GetHeaderByName("Cookie");
2096 int cookie_js_ct = 0;
2097 int cookie_net_ct = 0;
2098 TestCookieString(cookie_str, cookie_js_ct, cookie_net_ct);
2099
2100 // Expect both cookies with the URL2 requests only.
2101 if (before_resource_load_ct_ >= 3) {
2102 EXPECT_EQ(1, cookie_js_ct);
2103 EXPECT_EQ(1, cookie_net_ct);
2104 } else {
2105 EXPECT_EQ(0, cookie_js_ct);
2106 EXPECT_EQ(0, cookie_net_ct);
2107 }
2108
2109 return RV_CONTINUE;
2110 }
2111
OnResourceResponse(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefRefPtr<CefRequest> request,CefRefPtr<CefResponse> response)2112 bool OnResourceResponse(CefRefPtr<CefBrowser> browser,
2113 CefRefPtr<CefFrame> frame,
2114 CefRefPtr<CefRequest> request,
2115 CefRefPtr<CefResponse> response) override {
2116 EXPECT_IO_THREAD();
2117 resource_response_ct_++;
2118
2119 const std::string& url = request->GetURL();
2120 const std::string& set_cookie_str = response->GetHeaderByName("Set-Cookie");
2121
2122 // Expect the network cookie with URL1 requests only.
2123 if (resource_response_ct_ <= 2) {
2124 EXPECT_STREQ(GetCookieAccessUrl1(scheme_, true).c_str(), url.c_str());
2125 EXPECT_STREQ("name_net=value_net", set_cookie_str.c_str());
2126 } else {
2127 EXPECT_STREQ(GetCookieAccessUrl2(scheme_, true).c_str(), url.c_str());
2128 EXPECT_TRUE(set_cookie_str.empty());
2129 }
2130
2131 if (resource_response_ct_ == 1 || resource_response_ct_ == 3) {
2132 // Restart the request loading this data.
2133 request->SetHeaderByName("X-Custom-Header", "value", false);
2134 return true;
2135 }
2136 return false;
2137 }
2138
OnQuery(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,int64 query_id,const CefString & request,bool persistent,CefRefPtr<Callback> callback)2139 bool OnQuery(CefRefPtr<CefBrowser> browser,
2140 CefRefPtr<CefFrame> frame,
2141 int64 query_id,
2142 const CefString& request,
2143 bool persistent,
2144 CefRefPtr<Callback> callback) override {
2145 query_ct_++;
2146
2147 const std::string& url = frame->GetURL();
2148 const std::string& cookie_str = request.ToString();
2149 if (url == GetCookieAccessUrl1(scheme_, true)) {
2150 TestCookieString(cookie_str, cookie_js1_ct_, cookie_net1_ct_);
2151 browser->GetMainFrame()->LoadURL(GetCookieAccessUrl2(scheme_, true));
2152 } else if (url == GetCookieAccessUrl2(scheme_, true)) {
2153 TestCookieString(cookie_str, cookie_js2_ct_, cookie_net2_ct_);
2154 FinishTest();
2155 } else {
2156 ADD_FAILURE() << "Unexpected url: " << url;
2157 }
2158 return true;
2159 }
2160
2161 private:
AddResponses(CookieAccessResponseHandler * handler)2162 void AddResponses(CookieAccessResponseHandler* handler) {
2163 // Sets a cookie via net response headers and JS, then retrieves the cookies
2164 // via JS.
2165 {
2166 data1_.response = CefResponse::Create();
2167 data1_.response->SetMimeType("text/html");
2168 data1_.response->SetStatus(200);
2169 data1_.response->SetStatusText("OK");
2170
2171 CefResponse::HeaderMap headerMap;
2172 data1_.response->GetHeaderMap(headerMap);
2173 headerMap.insert(std::make_pair("Set-Cookie", "name_net=value_net"));
2174 data1_.response->SetHeaderMap(headerMap);
2175
2176 data1_.response_data =
2177 "<html><head>"
2178 "<script>"
2179 "document.cookie='name_js=value_js';"
2180 "window.testQuery({request:document.cookie});"
2181 "</script>"
2182 "</head><body>COOKIE RESTART TEST1</body></html>";
2183
2184 handler->AddResponse(GetCookieAccessUrl1(scheme_, true), &data1_);
2185 }
2186
2187 // Retrieves the cookies via JS.
2188 {
2189 data2_.response = CefResponse::Create();
2190 data2_.response->SetMimeType("text/html");
2191 data2_.response->SetStatus(200);
2192 data2_.response->SetStatusText("OK");
2193
2194 data2_.response_data =
2195 "<html><head>"
2196 "<script>"
2197 "window.testQuery({request:document.cookie});"
2198 "</script>"
2199 "</head><body>COOKIE RESTART TEST2</body></html>";
2200
2201 handler->AddResponse(GetCookieAccessUrl2(scheme_, true), &data2_);
2202 }
2203 }
2204
RunTestSetupContinue()2205 void RunTestSetupContinue() {
2206 CefPostTask(
2207 TID_UI,
2208 base::BindOnce(
2209 &CookieRestartTestHandler::StartServer, this,
2210 base::BindOnce(&CookieRestartTestHandler::RunTestContinue, this)));
2211 }
2212
StartServer(base::OnceClosure complete_callback)2213 void StartServer(base::OnceClosure complete_callback) {
2214 EXPECT_FALSE(server_handler_);
2215
2216 server_handler_ = new CookieAccessServerHandler();
2217 AddResponses(server_handler_);
2218 // 2 requests for each URL.
2219 server_handler_->SetExpectedRequestCount(4);
2220 server_handler_->CreateServer(std::move(complete_callback));
2221 }
2222
RunTestContinue()2223 void RunTestContinue() {
2224 if (!CefCurrentlyOn(TID_UI)) {
2225 CefPostTask(
2226 TID_UI,
2227 base::BindOnce(&CookieRestartTestHandler::RunTestContinue, this));
2228 return;
2229 }
2230
2231 CreateBrowser(GetCookieAccessUrl1(scheme_, true), context_);
2232 }
2233
FinishTest()2234 void FinishTest() {
2235 // Verify that cookies were set correctly.
2236 class TestVisitor : public CefCookieVisitor {
2237 public:
2238 explicit TestVisitor(CookieRestartTestHandler* handler)
2239 : handler_(handler) {}
2240 ~TestVisitor() override {
2241 // Destroy the test.
2242 CefPostTask(TID_UI,
2243 base::BindOnce(
2244 &CookieRestartTestHandler::ShutdownServer, handler_,
2245 base::BindOnce(&CookieRestartTestHandler::DestroyTest,
2246 handler_)));
2247 }
2248
2249 bool Visit(const CefCookie& cookie,
2250 int count,
2251 int total,
2252 bool& deleteCookie) override {
2253 const std::string& name = CefString(&cookie.name);
2254 const std::string& value = CefString(&cookie.value);
2255 if (name == "name_js" && value == "value_js")
2256 handler_->cookie_manager_js_ct_++;
2257 else if (name == "name_net" && value == "value_net")
2258 handler_->cookie_manager_net_ct_++;
2259
2260 // Clean up the cookies.
2261 deleteCookie = true;
2262
2263 return true;
2264 }
2265
2266 private:
2267 CookieRestartTestHandler* handler_;
2268 IMPLEMENT_REFCOUNTING(TestVisitor);
2269 };
2270
2271 cookie_manager_->VisitAllCookies(new TestVisitor(this));
2272 }
2273
ShutdownServer(base::OnceClosure complete_callback)2274 void ShutdownServer(base::OnceClosure complete_callback) {
2275 EXPECT_TRUE(server_handler_);
2276
2277 // |server_handler_| will delete itself after shutdown.
2278 server_handler_->ShutdownServer(std::move(complete_callback));
2279 server_handler_ = nullptr;
2280 }
2281
2282 const std::string scheme_;
2283 const bool use_global_;
2284 CefRefPtr<CefRequestContext> context_;
2285 CefRefPtr<CefCookieManager> cookie_manager_;
2286
2287 CookieAccessServerHandler* server_handler_ = nullptr;
2288
2289 CookieAccessData data1_;
2290 CookieAccessData data2_;
2291
2292 int before_resource_load_ct_ = 0;
2293 int resource_response_ct_ = 0;
2294 int query_ct_ = 0;
2295
2296 // From network requests.
2297 int can_save_cookie_ct_ = 0;
2298 int can_send_cookie_ct_ = 0;
2299 int cookie_js1_ct_ = 0;
2300 int cookie_net1_ct_ = 0;
2301 int cookie_js2_ct_ = 0;
2302 int cookie_net2_ct_ = 0;
2303
2304 // From cookie manager.
2305 int cookie_manager_js_ct_ = 0;
2306 int cookie_manager_net_ct_ = 0;
2307
2308 DISALLOW_COPY_AND_ASSIGN(CookieRestartTestHandler);
2309 IMPLEMENT_REFCOUNTING(CookieRestartTestHandler);
2310 };
2311
2312 } // namespace
2313
TEST(CookieTest,RestartGlobal)2314 TEST(CookieTest, RestartGlobal) {
2315 CefRefPtr<CookieRestartTestHandler> handler =
2316 new CookieRestartTestHandler(true);
2317 handler->ExecuteTest();
2318 ReleaseAndWaitForDestructor(handler);
2319 }
2320
TEST(CookieTest,RestartInMemory)2321 TEST(CookieTest, RestartInMemory) {
2322 CefRefPtr<CookieRestartTestHandler> handler =
2323 new CookieRestartTestHandler(false);
2324 handler->ExecuteTest();
2325 ReleaseAndWaitForDestructor(handler);
2326 }
2327
2328 // Entry point for registering custom schemes.
2329 // Called from client_app_delegates.cc.
RegisterCookieCustomSchemes(CefRawPtr<CefSchemeRegistrar> registrar)2330 void RegisterCookieCustomSchemes(CefRawPtr<CefSchemeRegistrar> registrar) {
2331 // Used by GetCookieManagerCustom* tests.
2332 registrar->AddCustomScheme(
2333 kCustomCookieScheme,
2334 CEF_SCHEME_OPTION_STANDARD | CEF_SCHEME_OPTION_CORS_ENABLED);
2335 }
2336
2337 // Entry point for registering cookieable schemes.
2338 // Called from client_app_delegates.cc.
RegisterCookieCookieableSchemes(std::vector<std::string> & cookieable_schemes)2339 void RegisterCookieCookieableSchemes(
2340 std::vector<std::string>& cookieable_schemes) {
2341 // Used by GetCookieManagerCustom* tests.
2342 cookieable_schemes.push_back(kCustomCookieScheme);
2343 }
2344