| OLD | NEW |
| 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 23 matching lines...) Expand all Loading... |
| 34 #include "url/gurl.h" | 34 #include "url/gurl.h" |
| 35 | 35 |
| 36 #if !defined(__has_feature) || !__has_feature(objc_arc) | 36 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 37 #error "This file requires ARC support." | 37 #error "This file requires ARC support." |
| 38 #endif | 38 #endif |
| 39 | 39 |
| 40 namespace net { | 40 namespace net { |
| 41 | 41 |
| 42 namespace { | 42 namespace { |
| 43 | 43 |
| 44 #if !defined(NDEBUG) | |
| 45 // The current cookie store. This weak pointer must not be used to do actual | |
| 46 // work. Its only purpose is to check that there is only one synchronized | |
| 47 // cookie store. | |
| 48 CookieStoreIOS* g_current_synchronized_store = nullptr; | |
| 49 #endif | |
| 50 | |
| 51 #pragma mark NotificationTrampoline | 44 #pragma mark NotificationTrampoline |
| 52 | 45 |
| 53 // NotificationTrampoline dispatches cookie notifications to all the existing | 46 // NotificationTrampoline dispatches cookie notifications to all the existing |
| 54 // CookieStoreIOS. | 47 // CookieStoreIOS. |
| 55 class NotificationTrampoline { | 48 class NotificationTrampoline { |
| 56 public: | 49 public: |
| 57 static NotificationTrampoline* GetInstance(); | 50 static NotificationTrampoline* GetInstance(); |
| 58 | 51 |
| 59 void AddObserver(CookieNotificationObserver* obs); | 52 void AddObserver(CookieNotificationObserver* obs); |
| 60 void RemoveObserver(CookieNotificationObserver* obs); | 53 void RemoveObserver(CookieNotificationObserver* obs); |
| (...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 727 void CookieStoreIOS::ClearSystemStore() { | 720 void CookieStoreIOS::ClearSystemStore() { |
| 728 DCHECK(thread_checker_.CalledOnValidThread()); | 721 DCHECK(thread_checker_.CalledOnValidThread()); |
| 729 base::scoped_nsobject<NSArray> copy( | 722 base::scoped_nsobject<NSArray> copy( |
| 730 [[NSArray alloc] initWithArray:[system_store_ cookies]]); | 723 [[NSArray alloc] initWithArray:[system_store_ cookies]]); |
| 731 for (NSHTTPCookie* cookie in copy.get()) | 724 for (NSHTTPCookie* cookie in copy.get()) |
| 732 [system_store_ deleteCookie:cookie]; | 725 [system_store_ deleteCookie:cookie]; |
| 733 DCHECK_EQ(0u, [[system_store_ cookies] count]); | 726 DCHECK_EQ(0u, [[system_store_ cookies] count]); |
| 734 creation_time_manager_->Clear(); | 727 creation_time_manager_->Clear(); |
| 735 } | 728 } |
| 736 | 729 |
| 737 void CookieStoreIOS::SetSynchronizedWithSystemStore(bool synchronized) { | |
| 738 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 739 | |
| 740 if (synchronized == (synchronization_state_ != NOT_SYNCHRONIZED)) | |
| 741 return; // The cookie store is already in the desired state. | |
| 742 | |
| 743 #if !defined(NDEBUG) | |
| 744 if (!synchronized) { | |
| 745 DCHECK_EQ(this, g_current_synchronized_store) | |
| 746 << "This cookie store was not synchronized"; | |
| 747 g_current_synchronized_store = nullptr; | |
| 748 } else { | |
| 749 DCHECK_EQ((CookieStoreIOS*)nullptr, g_current_synchronized_store) | |
| 750 << "Un-synchronize the current cookie store first."; | |
| 751 g_current_synchronized_store = this; | |
| 752 } | |
| 753 #endif | |
| 754 | |
| 755 NSHTTPCookieAcceptPolicy policy = | |
| 756 [system_store_ cookieAcceptPolicy]; | |
| 757 DCHECK(policy == NSHTTPCookieAcceptPolicyAlways || | |
| 758 policy == NSHTTPCookieAcceptPolicyNever); | |
| 759 | |
| 760 // If cookies are disabled, the system cookie store should be empty. | |
| 761 DCHECK(policy == NSHTTPCookieAcceptPolicyAlways || | |
| 762 ![[system_store_ cookies] count]); | |
| 763 | |
| 764 // If cookies are disabled, nothing is done now, the work will be done when | |
| 765 // cookies are re-enabled. | |
| 766 if (policy == NSHTTPCookieAcceptPolicyAlways) { | |
| 767 if (synchronized) { | |
| 768 synchronization_state_ = SYNCHRONIZING; | |
| 769 ClearSystemStore(); | |
| 770 cookie_monster_->GetAllCookiesAsync( | |
| 771 base::Bind(&CookieStoreIOS::AddCookiesToSystemStore, | |
| 772 weak_factory_.GetWeakPtr())); | |
| 773 return; | |
| 774 } else { | |
| 775 // Copy the cookies from the global store to |cookie_monster_|. | |
| 776 FlushStore(base::Closure()); | |
| 777 } | |
| 778 } | |
| 779 synchronization_state_ = synchronized ? SYNCHRONIZED : NOT_SYNCHRONIZED; | |
| 780 | |
| 781 if (synchronization_state_ == NOT_SYNCHRONIZED) { | |
| 782 // If there are pending tasks, then it means that the synchronization is | |
| 783 // being canceled. All pending tasks can be sent to cookie_monster_. | |
| 784 RunAllPendingTasks(); | |
| 785 } | |
| 786 } | |
| 787 | |
| 788 bool CookieStoreIOS::SystemCookiesAllowed() { | 730 bool CookieStoreIOS::SystemCookiesAllowed() { |
| 789 DCHECK(thread_checker_.CalledOnValidThread()); | 731 DCHECK(thread_checker_.CalledOnValidThread()); |
| 790 return [system_store_ cookieAcceptPolicy] == | 732 return [system_store_ cookieAcceptPolicy] == |
| 791 NSHTTPCookieAcceptPolicyAlways; | 733 NSHTTPCookieAcceptPolicyAlways; |
| 792 } | 734 } |
| 793 | 735 |
| 794 void CookieStoreIOS::AddCookiesToSystemStore(const net::CookieList& cookies) { | |
| 795 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 796 if (!SystemCookiesAllowed() || synchronization_state_ != SYNCHRONIZING) { | |
| 797 // If synchronization was aborted, the pending tasks have been processed at | |
| 798 // that time. Now is too late. | |
| 799 DCHECK(tasks_pending_synchronization_.empty()); | |
| 800 return; | |
| 801 } | |
| 802 | |
| 803 // Report metrics. | |
| 804 if (metrics_enabled_) { | |
| 805 size_t cookie_count = cookies.size(); | |
| 806 UMA_HISTOGRAM_COUNTS_10000("CookieIOS.CookieReadCount", cookie_count); | |
| 807 CheckForCookieLoss(cookie_count, COOKIES_READ); | |
| 808 } | |
| 809 | |
| 810 net::CookieList::const_iterator it; | |
| 811 for (it = cookies.begin(); it != cookies.end(); ++it) { | |
| 812 const net::CanonicalCookie& net_cookie = *it; | |
| 813 NSHTTPCookie* system_cookie = SystemCookieFromCanonicalCookie(net_cookie); | |
| 814 // Canonical cookie may not be convertable into system cookie if it contains | |
| 815 // invalid characters. | |
| 816 if (!system_cookie) | |
| 817 continue; | |
| 818 [system_store_ setCookie:system_cookie]; | |
| 819 creation_time_manager_->SetCreationTime(system_cookie, | |
| 820 net_cookie.CreationDate()); | |
| 821 } | |
| 822 | |
| 823 synchronization_state_ = SYNCHRONIZED; | |
| 824 RunAllPendingTasks(); | |
| 825 } | |
| 826 | |
| 827 void CookieStoreIOS::WriteToCookieMonster(NSArray* system_cookies) { | 736 void CookieStoreIOS::WriteToCookieMonster(NSArray* system_cookies) { |
| 828 DCHECK(thread_checker_.CalledOnValidThread()); | 737 DCHECK(thread_checker_.CalledOnValidThread()); |
| 829 if (synchronization_state_ != SYNCHRONIZED) | 738 if (synchronization_state_ != SYNCHRONIZED) |
| 830 return; | 739 return; |
| 831 | 740 |
| 832 // Copy the cookies from the global cookie store to |cookie_monster_|. | 741 // Copy the cookies from the global cookie store to |cookie_monster_|. |
| 833 // Unlike the system store, CookieMonster requires unique creation times. | 742 // Unlike the system store, CookieMonster requires unique creation times. |
| 834 net::CookieList cookie_list; | 743 net::CookieList cookie_list; |
| 835 NSUInteger cookie_count = [system_cookies count]; | 744 NSUInteger cookie_count = [system_cookies count]; |
| 836 cookie_list.reserve(cookie_count); | 745 cookie_list.reserve(cookie_count); |
| 837 for (NSHTTPCookie* cookie in system_cookies) { | 746 for (NSHTTPCookie* cookie in system_cookies) { |
| 838 cookie_list.push_back(CanonicalCookieFromSystemCookie( | 747 cookie_list.push_back(CanonicalCookieFromSystemCookie( |
| 839 cookie, creation_time_manager_->GetCreationTime(cookie))); | 748 cookie, creation_time_manager_->GetCreationTime(cookie))); |
| 840 } | 749 } |
| 841 cookie_monster_->SetAllCookiesAsync(cookie_list, SetCookiesCallback()); | 750 cookie_monster_->SetAllCookiesAsync(cookie_list, SetCookiesCallback()); |
| 842 | 751 |
| 843 // Update metrics. | 752 // Update metrics. |
| 844 if (metrics_enabled_) | 753 if (metrics_enabled_) |
| 845 UMA_HISTOGRAM_COUNTS_10000("CookieIOS.CookieWrittenCount", cookie_count); | 754 UMA_HISTOGRAM_COUNTS_10000("CookieIOS.CookieWrittenCount", cookie_count); |
| 846 } | 755 } |
| 847 | 756 |
| 848 void CookieStoreIOS::RunAllPendingTasks() { | |
| 849 // Executing the tasks while synchronizing would not run the tasks, but merely | |
| 850 // re-enqueue them. This function also does not support mutation of the queue | |
| 851 // during the iteration. | |
| 852 DCHECK(synchronization_state_ != SYNCHRONIZING); | |
| 853 for (const auto& task : tasks_pending_synchronization_) { | |
| 854 task.Run(); | |
| 855 } | |
| 856 tasks_pending_synchronization_.clear(); | |
| 857 } | |
| 858 | |
| 859 void CookieStoreIOS::DeleteCookiesWithFilter(const CookieFilterFunction& filter, | 757 void CookieStoreIOS::DeleteCookiesWithFilter(const CookieFilterFunction& filter, |
| 860 const DeleteCallback& callback) { | 758 const DeleteCallback& callback) { |
| 861 DCHECK(thread_checker_.CalledOnValidThread()); | 759 DCHECK(thread_checker_.CalledOnValidThread()); |
| 862 DCHECK_EQ(SYNCHRONIZED, synchronization_state_); | 760 DCHECK_EQ(SYNCHRONIZED, synchronization_state_); |
| 863 NSArray* cookies = [system_store_ cookies]; | 761 NSArray* cookies = [system_store_ cookies]; |
| 864 | 762 |
| 865 // Collect the cookies to delete. | 763 // Collect the cookies to delete. |
| 866 base::scoped_nsobject<NSMutableArray> to_delete( | 764 base::scoped_nsobject<NSMutableArray> to_delete( |
| 867 [[NSMutableArray alloc] init]); | 765 [[NSMutableArray alloc] init]); |
| 868 for (NSHTTPCookie* cookie in cookies) { | 766 for (NSHTTPCookie* cookie in cookies) { |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1088 weak_factory_.GetWeakPtr(), callback); | 986 weak_factory_.GetWeakPtr(), callback); |
| 1089 } | 987 } |
| 1090 | 988 |
| 1091 base::Closure CookieStoreIOS::WrapClosure(const base::Closure& callback) { | 989 base::Closure CookieStoreIOS::WrapClosure(const base::Closure& callback) { |
| 1092 DCHECK(thread_checker_.CalledOnValidThread()); | 990 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1093 return base::Bind(&CookieStoreIOS::UpdateCachesAfterClosure, | 991 return base::Bind(&CookieStoreIOS::UpdateCachesAfterClosure, |
| 1094 weak_factory_.GetWeakPtr(), callback); | 992 weak_factory_.GetWeakPtr(), callback); |
| 1095 } | 993 } |
| 1096 | 994 |
| 1097 } // namespace net | 995 } // namespace net |
| OLD | NEW |