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
3 // found in the LICENSE file.
5 #include "ios/chrome/browser/net/cookie_util.h"
7 #import <Foundation/Foundation.h>
8 #include <sys/sysctl.h>
10 #include "base/logging.h"
11 #import "base/mac/bind_objc_block.h"
12 #include "base/memory/ref_counted.h"
13 #include "ios/net/cookies/cookie_store_ios.h"
14 #include "ios/public/provider/chrome/browser/browser_state/chrome_browser_state.h"
15 #include "ios/web/public/web_thread.h"
16 #include "net/cookies/cookie_monster.h"
17 #include "net/cookies/cookie_store.h"
18 #include "net/extras/sqlite/sqlite_persistent_cookie_store.h"
19 #include "net/url_request/url_request_context.h"
20 #include "net/url_request/url_request_context_getter.h"
22 namespace cookie_util {
26 // Date of the last cookie deletion.
27 NSString* const kLastCookieDeletionDate = @"LastCookieDeletionDate";
30 void DoNothing(int n) {}
32 // Creates a SQLitePersistentCookieStore running on a background thread.
33 scoped_refptr<net::SQLitePersistentCookieStore> CreatePersistentCookieStore(
34 const base::FilePath& path,
35 bool restore_old_session_cookies,
36 net::CookieCryptoDelegate* crypto_delegate) {
37 return scoped_refptr<net::SQLitePersistentCookieStore>(
38 new net::SQLitePersistentCookieStore(
39 path, web::WebThread::GetTaskRunnerForThread(web::WebThread::IO),
40 web::WebThread::GetBlockingPool()->GetSequencedTaskRunner(
41 web::WebThread::GetBlockingPool()->GetSequenceToken()),
42 restore_old_session_cookies, crypto_delegate));
45 // Creates a CookieMonster configured by |config|.
46 net::CookieMonster* CreateCookieMonster(const CookieStoreConfig& config) {
47 if (config.path.empty()) {
48 // Empty path means in-memory store.
49 return new net::CookieMonster(nullptr, nullptr);
52 const bool restore_old_session_cookies =
53 config.session_cookie_mode == CookieStoreConfig::RESTORED_SESSION_COOKIES;
54 scoped_refptr<net::SQLitePersistentCookieStore> persistent_store =
55 CreatePersistentCookieStore(config.path, restore_old_session_cookies,
56 config.crypto_delegate);
57 net::CookieMonster* cookie_monster =
58 new net::CookieMonster(persistent_store.get(), nullptr);
59 if (restore_old_session_cookies)
60 cookie_monster->SetPersistSessionCookies(true);
61 return cookie_monster;
66 CookieStoreConfig::CookieStoreConfig(const base::FilePath& path,
67 SessionCookieMode session_cookie_mode,
68 CookieStoreType cookie_store_type,
69 net::CookieCryptoDelegate* crypto_delegate)
71 session_cookie_mode(session_cookie_mode),
72 cookie_store_type(cookie_store_type),
73 crypto_delegate(crypto_delegate) {
74 CHECK(!path.empty() || session_cookie_mode == EPHEMERAL_SESSION_COOKIES);
77 CookieStoreConfig::~CookieStoreConfig() {}
79 net::CookieStore* CreateCookieStore(const CookieStoreConfig& config) {
80 if (config.cookie_store_type == CookieStoreConfig::COOKIE_MONSTER)
81 return CreateCookieMonster(config);
83 scoped_refptr<net::SQLitePersistentCookieStore> persistent_store = nullptr;
84 if (config.session_cookie_mode ==
85 CookieStoreConfig::RESTORED_SESSION_COOKIES) {
86 DCHECK(!config.path.empty());
87 persistent_store = CreatePersistentCookieStore(
88 config.path, true /* restore_old_session_cookies */,
89 config.crypto_delegate);
91 return new net::CookieStoreIOS(persistent_store.get());
94 bool ShouldClearSessionCookies() {
95 NSUserDefaults* standardDefaults = [NSUserDefaults standardUserDefaults];
96 struct timeval boottime;
97 int mib[2] = {CTL_KERN, KERN_BOOTTIME};
98 size_t size = sizeof(boottime);
99 time_t lastCookieDeletionDate =
100 [standardDefaults integerForKey:kLastCookieDeletionDate];
103 bool clear_cookies = true;
104 if (lastCookieDeletionDate != 0 &&
105 sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 && boottime.tv_sec != 0) {
106 clear_cookies = boottime.tv_sec > lastCookieDeletionDate;
109 [standardDefaults setInteger:now forKey:kLastCookieDeletionDate];
110 return clear_cookies;
113 // Clears the session cookies for |profile|.
114 void ClearSessionCookies(ios::ChromeBrowserState* browser_state) {
115 scoped_refptr<net::URLRequestContextGetter> getter =
116 browser_state->GetRequestContext();
117 web::WebThread::PostTask(
118 web::WebThread::IO, FROM_HERE, base::BindBlock(^{
119 getter->GetURLRequestContext()
121 ->DeleteSessionCookiesAsync(base::Bind(&DoNothing));
125 } // namespace cookie_util