Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "chrome/browser/net/chrome_cookie_policy.h" | 5 #include "chrome/browser/net/chrome_cookie_policy.h" |
| 6 | 6 |
| 7 #include "base/string_util.h" | 7 #include "base/string_util.h" |
| 8 #include "chrome/browser/browser_list.h" | 8 #include "chrome/browser/browser_list.h" |
| 9 #include "chrome/browser/chrome_thread.h" | 9 #include "chrome/browser/chrome_thread.h" |
| 10 #include "chrome/browser/cookie_prompt_modal_dialog_delegate.h" | |
| 11 #include "chrome/browser/host_content_settings_map.h" | 10 #include "chrome/browser/host_content_settings_map.h" |
| 12 #include "chrome/browser/message_box_handler.h" | |
| 13 #include "net/base/net_errors.h" | 11 #include "net/base/net_errors.h" |
| 14 #include "net/base/static_cookie_policy.h" | 12 #include "net/base/static_cookie_policy.h" |
| 15 | 13 |
| 16 // If we queue up more than this number of completions, then switch from ASK to | 14 // If we queue up more than this number of completions, then switch from ASK to |
| 17 // BLOCK. More than this number of requests at once seems like it could be a | 15 // BLOCK. More than this number of requests at once seems like it could be a |
| 18 // sign of trouble anyways. | 16 // sign of trouble anyways. |
| 19 static const size_t kMaxCompletionsPerHost = 10000; | 17 static const size_t kMaxCompletionsPerHost = 10000; |
| 20 | 18 |
| 21 // ---------------------------------------------------------------------------- | 19 // ---------------------------------------------------------------------------- |
| 22 | 20 |
| 23 // ChromeCookiePolicy cannot just subclass the delegate interface because we | |
| 24 // may have several prompts pending. | |
| 25 class ChromeCookiePolicy::PromptDelegate | |
| 26 : public CookiePromptModalDialogDelegate { | |
| 27 public: | |
| 28 PromptDelegate(ChromeCookiePolicy* cookie_policy, const std::string& host) | |
| 29 : cookie_policy_(cookie_policy), | |
| 30 host_(host) { | |
| 31 } | |
| 32 | |
| 33 // CookiesPromptViewDelegate methods: | |
| 34 virtual void AllowSiteData(bool session_expire); | |
| 35 virtual void BlockSiteData(); | |
| 36 | |
| 37 private: | |
| 38 void NotifyDone(int policy); | |
| 39 | |
| 40 scoped_refptr<ChromeCookiePolicy> cookie_policy_; | |
| 41 std::string host_; | |
| 42 }; | |
| 43 | |
| 44 void ChromeCookiePolicy::PromptDelegate::AllowSiteData(bool session_expire) { | |
| 45 int policy = net::OK; | |
| 46 if (session_expire) | |
| 47 policy = net::OK_FOR_SESSION_ONLY; | |
| 48 NotifyDone(policy); | |
| 49 } | |
| 50 | |
| 51 void ChromeCookiePolicy::PromptDelegate::BlockSiteData() { | |
| 52 NotifyDone(net::ERR_ACCESS_DENIED); | |
| 53 } | |
| 54 | |
| 55 void ChromeCookiePolicy::PromptDelegate::NotifyDone(int policy) { | |
| 56 cookie_policy_->DidPromptForSetCookie(host_, policy); | |
| 57 delete this; | |
| 58 } | |
| 59 | |
| 60 // ---------------------------------------------------------------------------- | |
| 61 | |
| 62 ChromeCookiePolicy::ChromeCookiePolicy(HostContentSettingsMap* map) | 21 ChromeCookiePolicy::ChromeCookiePolicy(HostContentSettingsMap* map) |
| 63 : host_content_settings_map_(map) { | 22 : host_content_settings_map_(map) { |
| 64 } | 23 } |
| 65 | 24 |
| 66 ChromeCookiePolicy::~ChromeCookiePolicy() { | 25 ChromeCookiePolicy::~ChromeCookiePolicy() { |
| 67 DCHECK(host_completions_map_.empty()); | 26 DCHECK(host_completions_map_.empty()); |
| 68 } | 27 } |
| 69 | 28 |
| 70 int ChromeCookiePolicy::CanGetCookies(const GURL& url, | 29 int ChromeCookiePolicy::CanGetCookies(const GURL& url, |
| 71 const GURL& first_party, | 30 const GURL& first_party, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 113 int rv = policy.CanSetCookie(url, first_party, cookie_line, NULL); | 72 int rv = policy.CanSetCookie(url, first_party, cookie_line, NULL); |
| 114 if (rv != net::OK) | 73 if (rv != net::OK) |
| 115 return rv; | 74 return rv; |
| 116 } | 75 } |
| 117 | 76 |
| 118 int policy = CheckPolicy(url); | 77 int policy = CheckPolicy(url); |
| 119 if (policy != net::ERR_IO_PENDING) | 78 if (policy != net::ERR_IO_PENDING) |
| 120 return policy; | 79 return policy; |
| 121 | 80 |
| 122 DCHECK(callback); | 81 DCHECK(callback); |
| 123 | 82 |
|
willchan no longer on Chromium
2011/03/23 15:44:53
Is the following code ever supposed to be hit? Or
| |
| 124 // Else, ask the user... | |
| 125 | |
| 126 Completions& completions = host_completions_map_[url.host()]; | 83 Completions& completions = host_completions_map_[url.host()]; |
| 127 | |
| 128 if (completions.size() >= kMaxCompletionsPerHost) { | 84 if (completions.size() >= kMaxCompletionsPerHost) { |
| 129 LOG(ERROR) << "Would exceed kMaxCompletionsPerHost"; | 85 LOG(ERROR) << "Would exceed kMaxCompletionsPerHost"; |
| 130 policy = net::ERR_ACCESS_DENIED; | 86 policy = net::ERR_ACCESS_DENIED; |
| 131 } else { | 87 } else { |
| 132 completions.push_back(Completion::ForSetCookie(callback)); | 88 completions.push_back(Completion::ForSetCookie(callback)); |
|
willchan no longer on Chromium
2011/03/23 22:33:24
If that's the case, then when do these completions
| |
| 133 policy = net::ERR_IO_PENDING; | 89 policy = net::ERR_IO_PENDING; |
| 134 } | 90 } |
| 135 | 91 |
| 136 PromptForSetCookie(url, cookie_line); | |
| 137 return policy; | 92 return policy; |
| 138 } | 93 } |
| 139 | 94 |
| 140 int ChromeCookiePolicy::CheckPolicy(const GURL& url) const { | 95 int ChromeCookiePolicy::CheckPolicy(const GURL& url) const { |
| 141 ContentSetting setting = host_content_settings_map_->GetContentSetting( | 96 ContentSetting setting = host_content_settings_map_->GetContentSetting( |
| 142 url, CONTENT_SETTINGS_TYPE_COOKIES, ""); | 97 url, CONTENT_SETTINGS_TYPE_COOKIES, ""); |
| 143 if (setting == CONTENT_SETTING_BLOCK) | 98 if (setting == CONTENT_SETTING_BLOCK) |
| 144 return net::ERR_ACCESS_DENIED; | 99 return net::ERR_ACCESS_DENIED; |
| 145 if (setting == CONTENT_SETTING_ALLOW) | 100 if (setting == CONTENT_SETTING_ALLOW) |
| 146 return net::OK; | 101 return net::OK; |
| 147 if (setting == CONTENT_SETTING_SESSION_ONLY) | 102 if (setting == CONTENT_SETTING_SESSION_ONLY) |
| 148 return net::OK_FOR_SESSION_ONLY; | 103 return net::OK_FOR_SESSION_ONLY; |
| 149 return net::ERR_IO_PENDING; // Need to prompt. | 104 return net::ERR_IO_PENDING; // Need to prompt. |
|
willchan no longer on Chromium
2011/03/23 15:44:53
What's supposed to happen in this case? Is this ca
| |
| 150 } | 105 } |
| 151 | 106 |
| 152 void ChromeCookiePolicy::PromptForSetCookie(const GURL& url, | |
| 153 const std::string& cookie_line) { | |
| 154 if (!ChromeThread::CurrentlyOn(ChromeThread::UI)) { | |
| 155 ChromeThread::PostTask( | |
| 156 ChromeThread::UI, FROM_HERE, | |
| 157 NewRunnableMethod(this, &ChromeCookiePolicy::PromptForSetCookie, url, | |
| 158 cookie_line)); | |
| 159 return; | |
| 160 } | |
| 161 | |
| 162 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | |
| 163 const std::string& host = url.host(); | |
| 164 | |
| 165 // The policy may have changed (due to the "remember" option) | |
| 166 int policy = CheckPolicy(url); | |
| 167 if (policy != net::ERR_IO_PENDING) { | |
| 168 DidPromptForSetCookie(host, policy); | |
| 169 return; | |
| 170 } | |
| 171 | |
| 172 // Show the prompt on top of the current tab. | |
| 173 Browser* browser = BrowserList::GetLastActive(); | |
| 174 if (!browser || !browser->GetSelectedTabContents()) { | |
| 175 DidPromptForSetCookie(host, net::ERR_ACCESS_DENIED); | |
| 176 return; | |
| 177 } | |
| 178 | |
| 179 RunCookiePrompt(browser->GetSelectedTabContents(), | |
| 180 host_content_settings_map_, url, cookie_line, | |
| 181 new PromptDelegate(this, host)); | |
| 182 } | |
| 183 | |
| 184 void ChromeCookiePolicy::DidPromptForSetCookie(const std::string& host, | |
| 185 int policy) { | |
| 186 if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) { | |
| 187 ChromeThread::PostTask( | |
| 188 ChromeThread::IO, FROM_HERE, | |
| 189 NewRunnableMethod(this, &ChromeCookiePolicy::DidPromptForSetCookie, | |
| 190 host, policy)); | |
| 191 return; | |
| 192 } | |
| 193 | |
| 194 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); | |
| 195 | |
| 196 // Notify all callbacks, starting with the first until we hit another that | |
| 197 // is for a 'set-cookie'. | |
| 198 HostCompletionsMap::iterator it = host_completions_map_.find(host); | |
| 199 CHECK(it != host_completions_map_.end()); | |
| 200 | |
| 201 Completions& completions = it->second; | |
| 202 CHECK(!completions.empty() && completions[0].is_set_cookie_request()); | |
| 203 | |
| 204 // Gather the list of callbacks to notify, and remove them from the | |
| 205 // completions list before handing control to the callbacks (in case | |
| 206 // they should call back into us to modify host_completions_map_). | |
| 207 | |
| 208 std::vector<net::CompletionCallback*> callbacks; | |
| 209 callbacks.push_back(completions[0].callback()); | |
| 210 size_t i = 1; | |
| 211 for (; i < completions.size(); ++i) { | |
| 212 if (completions[i].is_set_cookie_request()) | |
| 213 break; | |
| 214 callbacks.push_back(completions[i].callback()); | |
| 215 } | |
| 216 completions.erase(completions.begin(), completions.begin() + i); | |
| 217 | |
| 218 if (completions.empty()) | |
| 219 host_completions_map_.erase(it); | |
| 220 | |
| 221 for (size_t j = 0; j < callbacks.size(); ++j) | |
| 222 callbacks[j]->Run(policy); | |
| 223 } | |
| OLD | NEW |