Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Side by Side Diff: ios/net/cookies/cookie_store_ios.mm

Issue 2649083002: Divide CookieStoreIOS into two different classes with different backends (Closed)
Patch Set: fix compilation Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 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 #include "ios/net/cookies/cookie_store_ios.h" 5 #include "ios/net/cookies/cookie_store_ios.h"
6 6
7 #import <Foundation/Foundation.h> 7 #import <Foundation/Foundation.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 bool HasExplicitDomain(const std::string& cookie_line) { 267 bool HasExplicitDomain(const std::string& cookie_line) {
268 ParsedCookie cookie(cookie_line); 268 ParsedCookie cookie(cookie_line);
269 return cookie.HasDomain(); 269 return cookie.HasDomain();
270 } 270 }
271 271
272 } // namespace 272 } // namespace
273 273
274 #pragma mark - 274 #pragma mark -
275 #pragma mark CookieStoreIOS 275 #pragma mark CookieStoreIOS
276 276
277 CookieStoreIOS::CookieStoreIOS( 277 CookieStoreIOS::CookieStoreIOS(NSHTTPCookieStorage* cookie_storage)
278 net::CookieMonster::PersistentCookieStore* persistent_store) 278 : CookieStoreIOS(nullptr, cookie_storage) {}
279 : CookieStoreIOS(persistent_store,
280 [NSHTTPCookieStorage sharedHTTPCookieStorage]) {
281 }
282 279
283 CookieStoreIOS::~CookieStoreIOS() { 280 CookieStoreIOS::~CookieStoreIOS() {
284 NotificationTrampoline::GetInstance()->RemoveObserver(this); 281 NotificationTrampoline::GetInstance()->RemoveObserver(this);
285 } 282 }
286 283
287 // static 284 // static
288 std::unique_ptr<CookieStoreIOS> CookieStoreIOS::CreateCookieStore( 285 std::unique_ptr<CookieStoreIOS> CookieStoreIOS::CreateCookieStore(
289 NSHTTPCookieStorage* cookie_storage) { 286 NSHTTPCookieStorage* cookie_storage) {
290 DCHECK(cookie_storage); 287 DCHECK(cookie_storage);
291 // TODO(huey): Update this when CrNet supports multiple cookie jars. 288 // TODO(huey): Update this when CrNet supports multiple cookie jars.
292 [cookie_storage setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways]; 289 [cookie_storage setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
293 290
294 // Create a cookie store with no persistent store backing. Then, populate 291 // Create a cookie store with no persistent store backing. Then, populate
295 // it from the system's cookie jar. 292 // it from the system's cookie jar.
296 std::unique_ptr<CookieStoreIOS> cookie_store( 293 std::unique_ptr<CookieStoreIOS> cookie_store(
297 new CookieStoreIOS(nullptr, cookie_storage)); 294 new CookieStoreIOS(cookie_storage));
298 cookie_store->synchronization_state_ = SYNCHRONIZED;
299 cookie_store->FlushStore(base::Closure()); 295 cookie_store->FlushStore(base::Closure());
300 return cookie_store; 296 return cookie_store;
301 } 297 }
302 298
303 // static 299 // static
304 void CookieStoreIOS::NotifySystemCookiesChanged() { 300 void CookieStoreIOS::NotifySystemCookiesChanged() {
305 NotificationTrampoline::GetInstance()->NotifyCookiesChanged(); 301 NotificationTrampoline::GetInstance()->NotifyCookiesChanged();
306 } 302 }
307 303
308 void CookieStoreIOS::SetMetricsEnabled() { 304 void CookieStoreIOS::SetMetricsEnabled() {
309 static CookieStoreIOS* g_cookie_store_with_metrics = nullptr; 305 static CookieStoreIOS* g_cookie_store_with_metrics = nullptr;
310 DCHECK(!g_cookie_store_with_metrics || g_cookie_store_with_metrics == this) 306 DCHECK(!g_cookie_store_with_metrics || g_cookie_store_with_metrics == this)
311 << "Only one cookie store may use metrics."; 307 << "Only one cookie store may use metrics.";
312 g_cookie_store_with_metrics = this; 308 g_cookie_store_with_metrics = this;
313 metrics_enabled_ = true; 309 metrics_enabled_ = true;
314 } 310 }
315 311
316 #pragma mark - 312 #pragma mark -
317 #pragma mark CookieStore methods 313 #pragma mark CookieStore methods
318 314
319 void CookieStoreIOS::SetCookieWithOptionsAsync( 315 void CookieStoreIOS::SetCookieWithOptionsAsync(
320 const GURL& url, 316 const GURL& url,
321 const std::string& cookie_line, 317 const std::string& cookie_line,
322 const net::CookieOptions& options, 318 const net::CookieOptions& options,
323 const SetCookiesCallback& callback) { 319 const SetCookiesCallback& callback) {
324 DCHECK(thread_checker_.CalledOnValidThread()); 320 DCHECK(thread_checker_.CalledOnValidThread());
325 321
326 switch (synchronization_state_) { 322 // The exclude_httponly() option would only be used by a javascript
327 case NOT_SYNCHRONIZED: 323 // engine.
328 cookie_monster_->SetCookieWithOptionsAsync(url, cookie_line, options, 324 DCHECK(!options.exclude_httponly());
329 WrapSetCallback(callback));
330 break;
331 case SYNCHRONIZED:
332 // The exclude_httponly() option would only be used by a javascript
333 // engine.
334 DCHECK(!options.exclude_httponly());
335 // If cookies are not allowed, they are stashed in the CookieMonster, and
336 // should be written there instead.
337 DCHECK(SystemCookiesAllowed());
338 325
339 base::Time server_time = 326 // If cookies are not allowed, they are stashed in the CookieMonster, and
340 options.has_server_time() ? options.server_time() : base::Time(); 327 // should be written there instead.
341 NSHTTPCookie* cookie = 328 DCHECK(SystemCookiesAllowed());
mef 2017/02/09 18:37:16 This check fails on Cronet tester: https://luci-lo
Eugene But (OOO till 7-30) 2017/02/10 00:10:56 Sorry, I missed this during review. CookieStoreIOS
mef 2017/02/10 16:33:57 sgtm. Looking at CookieStoreIOS::CreateCookieStore
342 GetNSHTTPCookieFromCookieLine(cookie_line, url, server_time);
343 DLOG_IF(WARNING, !cookie)
344 << "Could not create cookie for line: " << cookie_line;
345 329
346 // On iOS, [cookie domain] is not empty when the cookie domain is not 330 base::Time server_time =
347 // specified: it is inferred from the URL instead. The only case when it 331 options.has_server_time() ? options.server_time() : base::Time();
348 // is empty is when the domain attribute is incorrectly formatted. 332 NSHTTPCookie* cookie =
349 std::string domain_string(base::SysNSStringToUTF8([cookie domain])); 333 GetNSHTTPCookieFromCookieLine(cookie_line, url, server_time);
350 std::string dummy; 334 DLOG_IF(WARNING, !cookie) << "Could not create cookie for line: "
351 bool has_explicit_domain = HasExplicitDomain(cookie_line); 335 << cookie_line;
352 bool has_valid_domain =
353 net::cookie_util::GetCookieDomainWithString(
354 url, domain_string, &dummy);
355 // A cookie can be set if all of:
356 // a) The cookie line is well-formed
357 // b) The Domain attribute, if present, was not malformed
358 // c) At least one of:
359 // 1) The cookie had no explicit Domain, so the Domain was inferred
360 // from the URL, or
361 // 2) The cookie had an explicit Domain for which the URL is allowed
362 // to set cookies.
363 bool success = (cookie != nil) && !domain_string.empty() &&
364 (!has_explicit_domain || has_valid_domain);
365 336
366 if (success) { 337 // On iOS, [cookie domain] is not empty when the cookie domain is not
367 [system_store_ setCookie:cookie]; 338 // specified: it is inferred from the URL instead. The only case when it
368 creation_time_manager_->SetCreationTime( 339 // is empty is when the domain attribute is incorrectly formatted.
369 cookie, 340 std::string domain_string(base::SysNSStringToUTF8([cookie domain]));
370 creation_time_manager_->MakeUniqueCreationTime(base::Time::Now())); 341 std::string dummy;
371 } 342 bool has_explicit_domain = HasExplicitDomain(cookie_line);
343 bool has_valid_domain =
344 net::cookie_util::GetCookieDomainWithString(url, domain_string, &dummy);
345 // A cookie can be set if all of:
346 // a) The cookie line is well-formed
347 // b) The Domain attribute, if present, was not malformed
348 // c) At least one of:
349 // 1) The cookie had no explicit Domain, so the Domain was inferred
350 // from the URL, or
351 // 2) The cookie had an explicit Domain for which the URL is allowed
352 // to set cookies.
353 bool success = (cookie != nil) && !domain_string.empty() &&
354 (!has_explicit_domain || has_valid_domain);
372 355
373 if (!callback.is_null()) 356 if (success) {
374 callback.Run(success); 357 [system_store_ setCookie:cookie];
375 break; 358 creation_time_manager_->SetCreationTime(
359 cookie,
360 creation_time_manager_->MakeUniqueCreationTime(base::Time::Now()));
376 } 361 }
362
363 if (!callback.is_null())
364 callback.Run(success);
377 } 365 }
378 366
379 void CookieStoreIOS::SetCookieWithDetailsAsync( 367 void CookieStoreIOS::SetCookieWithDetailsAsync(
380 const GURL& url, 368 const GURL& url,
381 const std::string& name, 369 const std::string& name,
382 const std::string& value, 370 const std::string& value,
383 const std::string& domain, 371 const std::string& domain,
384 const std::string& path, 372 const std::string& path,
385 base::Time creation_time, 373 base::Time creation_time,
386 base::Time expiration_time, 374 base::Time expiration_time,
387 base::Time last_access_time, 375 base::Time last_access_time,
388 bool secure, 376 bool secure,
389 bool http_only, 377 bool http_only,
390 CookieSameSite same_site, 378 CookieSameSite same_site,
391 CookiePriority priority, 379 CookiePriority priority,
392 const SetCookiesCallback& callback) { 380 const SetCookiesCallback& callback) {
393 DCHECK(thread_checker_.CalledOnValidThread()); 381 DCHECK(thread_checker_.CalledOnValidThread());
382 // If cookies are not allowed, they are stashed in the CookieMonster, and
383 // should be written there instead.
384 DCHECK(SystemCookiesAllowed());
394 385
395 switch (synchronization_state_) { 386 bool success = false;
396 case NOT_SYNCHRONIZED: 387
397 cookie_monster_->SetCookieWithDetailsAsync( 388 if (creation_time.is_null())
389 creation_time = base::Time::Now();
390
391 // First create a CanonicalCookie, to normalize the arguments,
392 // particularly domain and path, and perform validation.
393 std::unique_ptr<net::CanonicalCookie> canonical_cookie =
394 net::CanonicalCookie::Create(
398 url, name, value, domain, path, creation_time, expiration_time, 395 url, name, value, domain, path, creation_time, expiration_time,
399 last_access_time, secure, http_only, same_site, priority, 396 secure, http_only, same_site, priority);
400 WrapSetCallback(callback));
401 break;
402 case SYNCHRONIZED:
403 // If cookies are not allowed, they are stashed in the CookieMonster, and
404 // should be written there instead.
405 DCHECK(SystemCookiesAllowed());
406 397
407 bool success = false; 398 if (canonical_cookie) {
399 NSHTTPCookie* cookie = SystemCookieFromCanonicalCookie(*canonical_cookie);
408 400
409 if (creation_time.is_null()) 401 if (cookie != nil) {
410 creation_time = base::Time::Now(); 402 [system_store_ setCookie:cookie];
403 creation_time_manager_->SetCreationTime(
404 cookie, creation_time_manager_->MakeUniqueCreationTime(
405 canonical_cookie->CreationDate()));
406 success = true;
407 }
408 }
411 409
412 // First create a CanonicalCookie, to normalize the arguments, 410 if (!callback.is_null())
413 // particularly domain and path, and perform validation. 411 callback.Run(success);
414 std::unique_ptr<net::CanonicalCookie> canonical_cookie =
415 net::CanonicalCookie::Create(
416 url, name, value, domain, path, creation_time, expiration_time,
417 secure, http_only, same_site, priority);
418
419 if (canonical_cookie) {
420 NSHTTPCookie* cookie =
421 SystemCookieFromCanonicalCookie(*canonical_cookie);
422
423 if (cookie != nil) {
424 [system_store_ setCookie:cookie];
425 creation_time_manager_->SetCreationTime(
426 cookie, creation_time_manager_->MakeUniqueCreationTime(
427 canonical_cookie->CreationDate()));
428 success = true;
429 }
430 }
431
432 if (!callback.is_null())
433 callback.Run(success);
434 break;
435 }
436 } 412 }
437 413
438 void CookieStoreIOS::GetCookiesWithOptionsAsync( 414 void CookieStoreIOS::GetCookiesWithOptionsAsync(
439 const GURL& url, 415 const GURL& url,
440 const net::CookieOptions& options, 416 const net::CookieOptions& options,
441 const GetCookiesCallback& callback) { 417 const GetCookiesCallback& callback) {
442 DCHECK(thread_checker_.CalledOnValidThread()); 418 DCHECK(thread_checker_.CalledOnValidThread());
443 419
444 switch (synchronization_state_) { 420 // If cookies are not allowed, they are stashed in the CookieMonster, and
445 case NOT_SYNCHRONIZED: 421 // should be read from there instead.
446 cookie_monster_->GetCookiesWithOptionsAsync(url, options, callback); 422 DCHECK(SystemCookiesAllowed());
447 break; 423 // The exclude_httponly() option would only be used by a javascript
448 case SYNCHRONIZED: 424 // engine.
449 // If cookies are not allowed, they are stashed in the CookieMonster, and 425 DCHECK(!options.exclude_httponly());
450 // should be read from there instead.
451 DCHECK(SystemCookiesAllowed());
452 // The exclude_httponly() option would only be used by a javascript
453 // engine.
454 DCHECK(!options.exclude_httponly());
455 426
456 // TODO(mkwst): If/when iOS supports Same-Site cookies, we'll need to pass 427 // TODO(mkwst): If/when iOS supports Same-Site cookies, we'll need to pass
457 // options in here as well. https://crbug.com/459154 428 // options in here as well. https://crbug.com/459154
458 NSArray* cookies = GetCookiesForURL(system_store_, 429 NSArray* cookies =
459 url, creation_time_manager_.get()); 430 GetCookiesForURL(system_store_, url, creation_time_manager_.get());
460 if (!callback.is_null()) 431 if (!callback.is_null())
461 callback.Run(BuildCookieLineWithOptions(cookies, options)); 432 callback.Run(BuildCookieLineWithOptions(cookies, options));
462 break;
463 }
464 } 433 }
465 434
466 void CookieStoreIOS::GetCookieListWithOptionsAsync( 435 void CookieStoreIOS::GetCookieListWithOptionsAsync(
467 const GURL& url, 436 const GURL& url,
468 const net::CookieOptions& options, 437 const net::CookieOptions& options,
469 const GetCookieListCallback& callback) { 438 const GetCookieListCallback& callback) {
470 DCHECK(thread_checker_.CalledOnValidThread()); 439 DCHECK(thread_checker_.CalledOnValidThread());
440 if (!SystemCookiesAllowed()) {
441 // If cookies are not allowed, the cookies are stashed in the
442 // CookieMonster, so get them from there.
443 cookie_monster_->GetCookieListWithOptionsAsync(url, options, callback);
444 return;
445 }
471 446
472 switch (synchronization_state_) { 447 // TODO(mkwst): If/when iOS supports Same-Site cookies, we'll need to pass
473 case NOT_SYNCHRONIZED: 448 // options in here as well. https://crbug.com/459154
474 cookie_monster_->GetCookieListWithOptionsAsync(url, options, callback); 449 NSArray* cookies =
475 break; 450 GetCookiesForURL(system_store_, url, creation_time_manager_.get());
476 case SYNCHRONIZED: 451 net::CookieList cookie_list = CanonicalCookieListFromSystemCookies(cookies);
477 if (!SystemCookiesAllowed()) { 452 if (!callback.is_null())
478 // If cookies are not allowed, the cookies are stashed in the 453 callback.Run(cookie_list);
479 // CookieMonster, so get them from there.
480 cookie_monster_->GetCookieListWithOptionsAsync(url, options, callback);
481 return;
482 }
483
484 // TODO(mkwst): If/when iOS supports Same-Site cookies, we'll need to pass
485 // options in here as well. https://crbug.com/459154
486 NSArray* cookies = GetCookiesForURL(system_store_,
487 url, creation_time_manager_.get());
488 net::CookieList cookie_list = CanonicalCookieListFromSystemCookies(
489 cookies);
490 if (!callback.is_null())
491 callback.Run(cookie_list);
492 break;
493 }
494 } 454 }
495 455
496 void CookieStoreIOS::GetAllCookiesAsync(const GetCookieListCallback& callback) { 456 void CookieStoreIOS::GetAllCookiesAsync(const GetCookieListCallback& callback) {
497 DCHECK(thread_checker_.CalledOnValidThread()); 457 DCHECK(thread_checker_.CalledOnValidThread());
498 458
499 switch (synchronization_state_) { 459 if (!SystemCookiesAllowed()) {
500 case NOT_SYNCHRONIZED: 460 // If cookies are not allowed, the cookies are stashed in the
501 cookie_monster_->GetAllCookiesAsync(callback); 461 // CookieMonster, so get them from there.
502 break; 462 cookie_monster_->GetAllCookiesAsync(callback);
503 case SYNCHRONIZED: 463 return;
504 if (!SystemCookiesAllowed()) { 464 }
505 // If cookies are not allowed, the cookies are stashed in the
506 // CookieMonster, so get them from there.
507 cookie_monster_->GetAllCookiesAsync(callback);
508 return;
509 }
510 465
511 NSArray* cookies = GetAllCookies(system_store_, 466 NSArray* cookies = GetAllCookies(system_store_, creation_time_manager_.get());
512 creation_time_manager_.get()); 467 net::CookieList cookie_list = CanonicalCookieListFromSystemCookies(cookies);
513 net::CookieList cookie_list = CanonicalCookieListFromSystemCookies( 468 if (!callback.is_null()) {
514 cookies); 469 callback.Run(cookie_list);
515 if (!callback.is_null()) {
516 callback.Run(cookie_list);
517 }
518 break;
519 } 470 }
520 } 471 }
521 472
522 void CookieStoreIOS::DeleteCookieAsync(const GURL& url, 473 void CookieStoreIOS::DeleteCookieAsync(const GURL& url,
523 const std::string& cookie_name, 474 const std::string& cookie_name,
524 const base::Closure& callback) { 475 const base::Closure& callback) {
525 DCHECK(thread_checker_.CalledOnValidThread()); 476 DCHECK(thread_checker_.CalledOnValidThread());
526 477
527 switch (synchronization_state_) { 478 NSArray* cookies =
528 case NOT_SYNCHRONIZED: 479 GetCookiesForURL(system_store_, url, creation_time_manager_.get());
529 cookie_monster_->DeleteCookieAsync(url, cookie_name, 480 for (NSHTTPCookie* cookie in cookies) {
530 WrapClosure(callback)); 481 if ([[cookie name] isEqualToString:base::SysUTF8ToNSString(cookie_name)]) {
531 break; 482 [system_store_ deleteCookie:cookie];
532 case SYNCHRONIZED: 483 creation_time_manager_->DeleteCreationTime(cookie);
533 NSArray* cookies = GetCookiesForURL(system_store_, 484 }
534 url, creation_time_manager_.get());
535 for (NSHTTPCookie* cookie in cookies) {
536 if ([[cookie name]
537 isEqualToString:base::SysUTF8ToNSString(cookie_name)]) {
538 [system_store_ deleteCookie:cookie];
539 creation_time_manager_->DeleteCreationTime(cookie);
540 }
541 }
542 if (!callback.is_null())
543 callback.Run();
544 break;
545 } 485 }
486
487 if (!callback.is_null())
488 callback.Run();
546 } 489 }
547 490
548 void CookieStoreIOS::DeleteCanonicalCookieAsync( 491 void CookieStoreIOS::DeleteCanonicalCookieAsync(
549 const CanonicalCookie& cookie, 492 const CanonicalCookie& cookie,
550 const DeleteCallback& callback) { 493 const DeleteCallback& callback) {
551 DCHECK(thread_checker_.CalledOnValidThread()); 494 DCHECK(thread_checker_.CalledOnValidThread());
552 495
553 switch (synchronization_state_) { 496 // This relies on the fact cookies are given unique creation dates.
554 case NOT_SYNCHRONIZED: 497 CookieFilterFunction filter = base::Bind(
555 cookie_monster_->DeleteCanonicalCookieAsync(cookie, 498 IsCookieCreatedBetween, cookie.CreationDate(), cookie.CreationDate());
556 WrapDeleteCallback(callback)); 499 DeleteCookiesWithFilter(filter, callback);
557 break;
558 case SYNCHRONIZED:
559 // This relies on the fact cookies are given unique creation dates.
560 CookieFilterFunction filter = base::Bind(
561 IsCookieCreatedBetween, cookie.CreationDate(), cookie.CreationDate());
562 DeleteCookiesWithFilter(filter, callback);
563 }
564 } 500 }
565 501
566 void CookieStoreIOS::DeleteAllCreatedBetweenAsync( 502 void CookieStoreIOS::DeleteAllCreatedBetweenAsync(
567 const base::Time& delete_begin, 503 const base::Time& delete_begin,
568 const base::Time& delete_end, 504 const base::Time& delete_end,
569 const DeleteCallback& callback) { 505 const DeleteCallback& callback) {
570 DCHECK(thread_checker_.CalledOnValidThread()); 506 DCHECK(thread_checker_.CalledOnValidThread());
571 507
572 if (metrics_enabled_) 508 if (metrics_enabled_)
573 ResetCookieCountMetrics(); 509 ResetCookieCountMetrics();
574 510
575 switch (synchronization_state_) { 511 CookieFilterFunction filter = base::Bind(
576 case NOT_SYNCHRONIZED: 512 &IsCookieCreatedBetween, delete_begin, delete_end);
577 cookie_monster_->DeleteAllCreatedBetweenAsync( 513 DeleteCookiesWithFilter(filter, callback);
578 delete_begin, delete_end, WrapDeleteCallback(callback));
579 break;
580 case SYNCHRONIZED:
581 CookieFilterFunction filter =
582 base::Bind(&IsCookieCreatedBetween, delete_begin, delete_end);
583 DeleteCookiesWithFilter(filter, callback);
584 break;
585 }
586 } 514 }
587 515
588 void CookieStoreIOS::DeleteAllCreatedBetweenWithPredicateAsync( 516 void CookieStoreIOS::DeleteAllCreatedBetweenWithPredicateAsync(
589 const base::Time& delete_begin, 517 const base::Time& delete_begin,
590 const base::Time& delete_end, 518 const base::Time& delete_end,
591 const CookiePredicate& predicate, 519 const CookiePredicate& predicate,
592 const DeleteCallback& callback) { 520 const DeleteCallback& callback) {
593 DCHECK(thread_checker_.CalledOnValidThread()); 521 DCHECK(thread_checker_.CalledOnValidThread());
594 522
595 if (metrics_enabled_) 523 if (metrics_enabled_)
596 ResetCookieCountMetrics(); 524 ResetCookieCountMetrics();
597 525
598 switch (synchronization_state_) { 526 CookieFilterFunction filter = base::Bind(
599 case NOT_SYNCHRONIZED: 527 IsCookieCreatedBetweenWithPredicate, delete_begin, delete_end, predicate);
600 cookie_monster_->DeleteAllCreatedBetweenWithPredicateAsync( 528 DeleteCookiesWithFilter(filter, callback);
601 delete_begin, delete_end, predicate, WrapDeleteCallback(callback));
602 break;
603 case SYNCHRONIZED:
604 CookieFilterFunction filter =
605 base::Bind(IsCookieCreatedBetweenWithPredicate, delete_begin,
606 delete_end, predicate);
607 DeleteCookiesWithFilter(filter, callback);
608 break;
609 }
610 } 529 }
611 530
612 void CookieStoreIOS::DeleteSessionCookiesAsync(const DeleteCallback& callback) { 531 void CookieStoreIOS::DeleteSessionCookiesAsync(const DeleteCallback& callback) {
613 DCHECK(thread_checker_.CalledOnValidThread()); 532 DCHECK(thread_checker_.CalledOnValidThread());
614 533
615 if (metrics_enabled_) 534 if (metrics_enabled_)
616 ResetCookieCountMetrics(); 535 ResetCookieCountMetrics();
617 536
618 switch (synchronization_state_) { 537 CookieFilterFunction filter = base::Bind(&IsCookieSessionCookie);
619 case NOT_SYNCHRONIZED: 538 DeleteCookiesWithFilter(filter, callback);
620 cookie_monster_->DeleteSessionCookiesAsync(WrapDeleteCallback(callback));
621 break;
622 case SYNCHRONIZED:
623 CookieFilterFunction filter = base::Bind(&IsCookieSessionCookie);
624 DeleteCookiesWithFilter(filter, callback);
625 break;
626 }
627 } 539 }
628 540
629 void CookieStoreIOS::FlushStore(const base::Closure& closure) { 541 void CookieStoreIOS::FlushStore(const base::Closure& closure) {
630 DCHECK(thread_checker_.CalledOnValidThread()); 542 DCHECK(thread_checker_.CalledOnValidThread());
631 543
632 if (SystemCookiesAllowed()) { 544 if (SystemCookiesAllowed()) {
633 // If cookies are disabled, the system store is empty, and the cookies are 545 // If cookies are disabled, the system store is empty, and the cookies are
634 // stashed on disk. Do not delete the cookies on the disk in this case. 546 // stashed on disk. Do not delete the cookies on the disk in this case.
635 WriteToCookieMonster([system_store_ cookies]); 547 WriteToCookieMonster([system_store_ cookies]);
636 } 548 }
637 cookie_monster_->FlushStore(closure); 549 cookie_monster_->FlushStore(closure);
638 flush_closure_.Cancel(); 550 flush_closure_.Cancel();
639 } 551 }
640 552
641 #pragma mark - 553 #pragma mark -
642 #pragma mark Private methods 554 #pragma mark Protected methods
643 555
644 CookieStoreIOS::CookieStoreIOS( 556 CookieStoreIOS::CookieStoreIOS(
645 net::CookieMonster::PersistentCookieStore* persistent_store, 557 net::CookieMonster::PersistentCookieStore* persistent_store,
646 NSHTTPCookieStorage* system_store) 558 NSHTTPCookieStorage* system_store)
647 : cookie_monster_(new net::CookieMonster(persistent_store, nullptr)), 559 : cookie_monster_(new net::CookieMonster(persistent_store, nullptr)),
648 system_store_(system_store), 560 system_store_(system_store),
649 creation_time_manager_(new CookieCreationTimeManager), 561 creation_time_manager_(new CookieCreationTimeManager),
650 metrics_enabled_(false), 562 metrics_enabled_(false),
651 synchronization_state_(NOT_SYNCHRONIZED),
652 cookie_cache_(new CookieCache()), 563 cookie_cache_(new CookieCache()),
653 weak_factory_(this) { 564 weak_factory_(this) {
654 DCHECK(system_store); 565 DCHECK(system_store);
655 566
656 NotificationTrampoline::GetInstance()->AddObserver(this); 567 NotificationTrampoline::GetInstance()->AddObserver(this);
657 568
658 cookie_monster_->SetPersistSessionCookies(true); 569 cookie_monster_->SetPersistSessionCookies(true);
659 cookie_monster_->SetForceKeepSessionState(); 570 cookie_monster_->SetForceKeepSessionState();
660 } 571 }
661 572
573 CookieStoreIOS::SetCookiesCallback CookieStoreIOS::WrapSetCallback(
574 const SetCookiesCallback& callback) {
575 DCHECK(thread_checker_.CalledOnValidThread());
576 return base::Bind(&CookieStoreIOS::UpdateCachesAfterSet,
577 weak_factory_.GetWeakPtr(), callback);
578 }
579
580 CookieStoreIOS::DeleteCallback CookieStoreIOS::WrapDeleteCallback(
581 const DeleteCallback& callback) {
582 DCHECK(thread_checker_.CalledOnValidThread());
583 return base::Bind(&CookieStoreIOS::UpdateCachesAfterDelete,
584 weak_factory_.GetWeakPtr(), callback);
585 }
586
587 base::Closure CookieStoreIOS::WrapClosure(const base::Closure& callback) {
588 DCHECK(thread_checker_.CalledOnValidThread());
589 return base::Bind(&CookieStoreIOS::UpdateCachesAfterClosure,
590 weak_factory_.GetWeakPtr(), callback);
591 }
592
593 #pragma mark -
594 #pragma mark Private methods
595
662 void CookieStoreIOS::ClearSystemStore() { 596 void CookieStoreIOS::ClearSystemStore() {
663 DCHECK(thread_checker_.CalledOnValidThread()); 597 DCHECK(thread_checker_.CalledOnValidThread());
664 base::scoped_nsobject<NSArray> copy( 598 base::scoped_nsobject<NSArray> copy(
665 [[NSArray alloc] initWithArray:[system_store_ cookies]]); 599 [[NSArray alloc] initWithArray:[system_store_ cookies]]);
666 for (NSHTTPCookie* cookie in copy.get()) 600 for (NSHTTPCookie* cookie in copy.get())
667 [system_store_ deleteCookie:cookie]; 601 [system_store_ deleteCookie:cookie];
668 DCHECK_EQ(0u, [[system_store_ cookies] count]); 602 DCHECK_EQ(0u, [[system_store_ cookies] count]);
669 creation_time_manager_->Clear(); 603 creation_time_manager_->Clear();
670 } 604 }
671 605
672 bool CookieStoreIOS::SystemCookiesAllowed() { 606 bool CookieStoreIOS::SystemCookiesAllowed() {
673 DCHECK(thread_checker_.CalledOnValidThread()); 607 DCHECK(thread_checker_.CalledOnValidThread());
674 return [system_store_ cookieAcceptPolicy] == 608 return [system_store_ cookieAcceptPolicy] ==
675 NSHTTPCookieAcceptPolicyAlways; 609 NSHTTPCookieAcceptPolicyAlways;
676 } 610 }
677 611
678 void CookieStoreIOS::WriteToCookieMonster(NSArray* system_cookies) { 612 void CookieStoreIOS::WriteToCookieMonster(NSArray* system_cookies) {
679 DCHECK(thread_checker_.CalledOnValidThread()); 613 DCHECK(thread_checker_.CalledOnValidThread());
680 if (synchronization_state_ != SYNCHRONIZED)
681 return;
682
683 // Copy the cookies from the global cookie store to |cookie_monster_|. 614 // Copy the cookies from the global cookie store to |cookie_monster_|.
684 // Unlike the system store, CookieMonster requires unique creation times. 615 // Unlike the system store, CookieMonster requires unique creation times.
685 net::CookieList cookie_list; 616 net::CookieList cookie_list;
686 NSUInteger cookie_count = [system_cookies count]; 617 NSUInteger cookie_count = [system_cookies count];
687 cookie_list.reserve(cookie_count); 618 cookie_list.reserve(cookie_count);
688 for (NSHTTPCookie* cookie in system_cookies) { 619 for (NSHTTPCookie* cookie in system_cookies) {
689 cookie_list.push_back(CanonicalCookieFromSystemCookie( 620 cookie_list.push_back(CanonicalCookieFromSystemCookie(
690 cookie, creation_time_manager_->GetCreationTime(cookie))); 621 cookie, creation_time_manager_->GetCreationTime(cookie)));
691 } 622 }
692 cookie_monster_->SetAllCookiesAsync(cookie_list, SetCookiesCallback()); 623 cookie_monster_->SetAllCookiesAsync(cookie_list, SetCookiesCallback());
693 624
694 // Update metrics. 625 // Update metrics.
695 if (metrics_enabled_) 626 if (metrics_enabled_)
696 UMA_HISTOGRAM_COUNTS_10000("CookieIOS.CookieWrittenCount", cookie_count); 627 UMA_HISTOGRAM_COUNTS_10000("CookieIOS.CookieWrittenCount", cookie_count);
697 } 628 }
698 629
699 void CookieStoreIOS::DeleteCookiesWithFilter(const CookieFilterFunction& filter, 630 void CookieStoreIOS::DeleteCookiesWithFilter(const CookieFilterFunction& filter,
700 const DeleteCallback& callback) { 631 const DeleteCallback& callback) {
701 DCHECK(thread_checker_.CalledOnValidThread()); 632 DCHECK(thread_checker_.CalledOnValidThread());
702 DCHECK_EQ(SYNCHRONIZED, synchronization_state_);
703 NSArray* cookies = [system_store_ cookies]; 633 NSArray* cookies = [system_store_ cookies];
704 634
705 // Collect the cookies to delete. 635 // Collect the cookies to delete.
706 base::scoped_nsobject<NSMutableArray> to_delete( 636 base::scoped_nsobject<NSMutableArray> to_delete(
707 [[NSMutableArray alloc] init]); 637 [[NSMutableArray alloc] init]);
708 for (NSHTTPCookie* cookie in cookies) { 638 for (NSHTTPCookie* cookie in cookies) {
709 base::Time creation_time = creation_time_manager_->GetCreationTime(cookie); 639 base::Time creation_time = creation_time_manager_->GetCreationTime(cookie);
710 if (filter.Run(cookie, creation_time)) 640 if (filter.Run(cookie, creation_time))
711 [to_delete addObject:cookie]; 641 [to_delete addObject:cookie];
712 } 642 }
713 643
714 // Delete them. 644 // Delete them.
715 for (NSHTTPCookie* cookie in to_delete.get()) { 645 for (NSHTTPCookie* cookie in to_delete.get()) {
716 [system_store_ deleteCookie:cookie]; 646 [system_store_ deleteCookie:cookie];
717 creation_time_manager_->DeleteCreationTime(cookie); 647 creation_time_manager_->DeleteCreationTime(cookie);
718 } 648 }
719 649
720 if (!callback.is_null()) 650 if (!callback.is_null())
721 callback.Run([to_delete count]); 651 callback.Run([to_delete count]);
722 } 652 }
723 653
724 void CookieStoreIOS::OnSystemCookiesChanged() { 654 void CookieStoreIOS::OnSystemCookiesChanged() {
725 DCHECK(thread_checker_.CalledOnValidThread()); 655 DCHECK(thread_checker_.CalledOnValidThread());
726 656
727 // If the CookieStoreIOS is not synchronized or is not backed by
728 // |NSHTTPCookieStorage sharedHTTPCookieStorage| this callback is irrelevant.
729 if (synchronization_state_ != SYNCHRONIZED ||
730 system_store_ != [NSHTTPCookieStorage sharedHTTPCookieStorage]) {
731 return;
732 }
733
734 for (const auto& hook_map_entry : hook_map_) { 657 for (const auto& hook_map_entry : hook_map_) {
735 std::pair<GURL, std::string> key = hook_map_entry.first; 658 std::pair<GURL, std::string> key = hook_map_entry.first;
736 std::vector<net::CanonicalCookie> removed_cookies; 659 std::vector<net::CanonicalCookie> removed_cookies;
737 std::vector<net::CanonicalCookie> added_cookies; 660 std::vector<net::CanonicalCookie> added_cookies;
738 if (UpdateCacheForCookieFromSystem(key.first, key.second, &removed_cookies, 661 if (UpdateCacheForCookieFromSystem(key.first, key.second, &removed_cookies,
739 &added_cookies)) { 662 &added_cookies)) {
740 RunCallbacksForCookies(key.first, key.second, removed_cookies, 663 RunCallbacksForCookies(key.first, key.second, removed_cookies,
741 net::CookieStore::ChangeCause::UNKNOWN_DELETION); 664 net::CookieStore::ChangeCause::UNKNOWN_DELETION);
742 RunCallbacksForCookies(key.first, key.second, added_cookies, 665 RunCallbacksForCookies(key.first, key.second, added_cookies,
743 net::CookieStore::ChangeCause::INSERTED); 666 net::CookieStore::ChangeCause::INSERTED);
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 CookieStoreIOS::CanonicalCookieListFromSystemCookies(NSArray* cookies) { 830 CookieStoreIOS::CanonicalCookieListFromSystemCookies(NSArray* cookies) {
908 net::CookieList cookie_list; 831 net::CookieList cookie_list;
909 cookie_list.reserve([cookies count]); 832 cookie_list.reserve([cookies count]);
910 for (NSHTTPCookie* cookie in cookies) { 833 for (NSHTTPCookie* cookie in cookies) {
911 base::Time created = creation_time_manager_->GetCreationTime(cookie); 834 base::Time created = creation_time_manager_->GetCreationTime(cookie);
912 cookie_list.push_back(CanonicalCookieFromSystemCookie(cookie, created)); 835 cookie_list.push_back(CanonicalCookieFromSystemCookie(cookie, created));
913 } 836 }
914 return cookie_list; 837 return cookie_list;
915 } 838 }
916 839
917 CookieStoreIOS::SetCookiesCallback CookieStoreIOS::WrapSetCallback(
918 const SetCookiesCallback& callback) {
919 DCHECK(thread_checker_.CalledOnValidThread());
920 return base::Bind(&CookieStoreIOS::UpdateCachesAfterSet,
921 weak_factory_.GetWeakPtr(), callback);
922 }
923
924 CookieStoreIOS::DeleteCallback CookieStoreIOS::WrapDeleteCallback(
925 const DeleteCallback& callback) {
926 DCHECK(thread_checker_.CalledOnValidThread());
927 return base::Bind(&CookieStoreIOS::UpdateCachesAfterDelete,
928 weak_factory_.GetWeakPtr(), callback);
929 }
930
931 base::Closure CookieStoreIOS::WrapClosure(const base::Closure& callback) {
932 DCHECK(thread_checker_.CalledOnValidThread());
933 return base::Bind(&CookieStoreIOS::UpdateCachesAfterClosure,
934 weak_factory_.GetWeakPtr(), callback);
935 }
936
937 } // namespace net 840 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698