summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/automation/automation_profile_impl.cc42
-rw-r--r--chrome/browser/automation/url_request_automation_job.cc29
-rw-r--r--chrome/browser/net/chrome_cookie_policy.cc162
-rw-r--r--chrome/browser/net/chrome_cookie_policy.h74
-rw-r--r--chrome/browser/net/chrome_url_request_context.cc53
-rw-r--r--chrome/browser/net/chrome_url_request_context.h13
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.cc162
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.h4
-rwxr-xr-xchrome/chrome_browser.gypi2
9 files changed, 404 insertions, 137 deletions
diff --git a/chrome/browser/automation/automation_profile_impl.cc b/chrome/browser/automation/automation_profile_impl.cc
index 3a1387d..d09b036 100644
--- a/chrome/browser/automation/automation_profile_impl.cc
+++ b/chrome/browser/automation/automation_profile_impl.cc
@@ -58,8 +58,12 @@ class AutomationCookieStore : public net::CookieStore {
}
// CookieStore implementation.
- virtual bool SetCookie(const GURL& url, const std::string& cookie_line) {
- bool cookie_set = original_cookie_store_->SetCookie(url, cookie_line);
+ virtual bool SetCookieWithOptions(const GURL& url,
+ const std::string& cookie_line,
+ const net::CookieOptions& options) {
+ bool cookie_set =
+ original_cookie_store_->SetCookieWithOptions(url, cookie_line,
+ options);
if (cookie_set) {
// TODO(eroman): Should NOT be accessing the profile from here, as this
// is running on the IO thread.
@@ -68,48 +72,14 @@ class AutomationCookieStore : public net::CookieStore {
}
return cookie_set;
}
- virtual bool SetCookieWithOptions(const GURL& url,
- const std::string& cookie_line,
- const net::CookieOptions& options) {
- return original_cookie_store_->SetCookieWithOptions(url, cookie_line,
- options);
- }
- virtual bool SetCookieWithCreationTime(const GURL& url,
- const std::string& cookie_line,
- const base::Time& creation_time) {
- return original_cookie_store_->SetCookieWithCreationTime(url, cookie_line,
- creation_time);
- }
- virtual bool SetCookieWithCreationTimeWithOptions(
- const GURL& url,
- const std::string& cookie_line,
- const base::Time& creation_time,
- const net::CookieOptions& options) {
- return original_cookie_store_->SetCookieWithCreationTimeWithOptions(url,
- cookie_line, creation_time, options);
- }
- virtual void SetCookies(const GURL& url,
- const std::vector<std::string>& cookies) {
- original_cookie_store_->SetCookies(url, cookies);
- }
- virtual void SetCookiesWithOptions(const GURL& url,
- const std::vector<std::string>& cookies,
- const net::CookieOptions& options) {
- original_cookie_store_->SetCookiesWithOptions(url, cookies, options);
- }
- virtual std::string GetCookies(const GURL& url) {
- return original_cookie_store_->GetCookies(url);
- }
virtual std::string GetCookiesWithOptions(const GURL& url,
const net::CookieOptions& options) {
return original_cookie_store_->GetCookiesWithOptions(url, options);
}
-
virtual void DeleteCookie(const GURL& url,
const std::string& cookie_name) {
return original_cookie_store_->DeleteCookie(url, cookie_name);
}
-
virtual net::CookieMonster* GetCookieMonster() {
return original_cookie_store_->GetCookieMonster();
}
diff --git a/chrome/browser/automation/url_request_automation_job.cc b/chrome/browser/automation/url_request_automation_job.cc
index 319b976..77e927f 100644
--- a/chrome/browser/automation/url_request_automation_job.cc
+++ b/chrome/browser/automation/url_request_automation_job.cc
@@ -13,7 +13,6 @@
#include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h"
#include "chrome/test/automation/automation_messages.h"
#include "net/base/cookie_monster.h"
-#include "net/base/cookie_policy.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/http/http_util.h"
@@ -298,6 +297,9 @@ void URLRequestAutomationJob::OnRequestStarted(int tab, int id,
URLRequestContext* ctx = request_->context();
std::vector<std::string> response_cookies;
+ // NOTE: We ignore Chrome's cookie policy to allow the automation to
+ // decide what cookies should be set.
+
if (!response.headers.empty()) {
headers_ = new net::HttpResponseHeaders(
net::HttpUtil::AssembleRawHeaders(response.headers.data(),
@@ -312,30 +314,23 @@ void URLRequestAutomationJob::OnRequestStarted(int tab, int id,
response_cookies.push_back(value);
}
- if (response_cookies.size()) {
- if (ctx && ctx->cookie_store() && (!ctx->cookie_policy() ||
- ctx->cookie_policy()->CanSetCookie(
- url_for_cookies, request_->first_party_for_cookies()))) {
- net::CookieOptions options;
- options.set_include_httponly();
- ctx->cookie_store()->SetCookiesWithOptions(url_for_cookies,
- response_cookies,
- options);
- }
+ if (response_cookies.size() && ctx && ctx->cookie_store()) {
+ net::CookieOptions options;
+ options.set_include_httponly();
+ ctx->cookie_store()->SetCookiesWithOptions(url_for_cookies,
+ response_cookies,
+ options);
}
}
- if (!response.persistent_cookies.empty() && ctx && ctx->cookie_store() &&
- (!ctx->cookie_policy() || ctx->cookie_policy()->CanSetCookie(
- url_for_cookies, request_->first_party_for_cookies()))) {
+ if (!response.persistent_cookies.empty() && ctx && ctx->cookie_store()) {
StringTokenizer cookie_parser(response.persistent_cookies, ";");
net::CookieMonster::CookieList existing_cookies;
net::CookieMonster* monster = ctx->cookie_store()->GetCookieMonster();
DCHECK(monster);
- if (monster) {
- existing_cookies = monster->GetRawCookies(url_for_cookies);
- }
+ if (monster)
+ existing_cookies = monster->GetAllCookiesForURL(url_for_cookies);
while (cookie_parser.GetNext()) {
std::string cookie_string = cookie_parser.token();
diff --git a/chrome/browser/net/chrome_cookie_policy.cc b/chrome/browser/net/chrome_cookie_policy.cc
new file mode 100644
index 0000000..3e924d1
--- /dev/null
+++ b/chrome/browser/net/chrome_cookie_policy.cc
@@ -0,0 +1,162 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/net/chrome_cookie_policy.h"
+
+#include "base/string_util.h"
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/host_content_settings_map.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/net_errors.h"
+#include "net/base/static_cookie_policy.h"
+
+// If we queue up more than this number of completions, then switch from ASK to
+// BLOCK. More than this number of requests at once seems like it could be a
+// sign of trouble anyways.
+static const size_t kMaxCompletionsPerHost = 10000;
+
+ChromeCookiePolicy::ChromeCookiePolicy(HostContentSettingsMap* map)
+ : host_content_settings_map_(map) {
+}
+
+ChromeCookiePolicy::~ChromeCookiePolicy() {
+ DCHECK(host_completions_map_.empty());
+}
+
+int ChromeCookiePolicy::CanGetCookies(const GURL& url,
+ const GURL& first_party,
+ net::CompletionCallback* callback) {
+ if (host_content_settings_map_->BlockThirdPartyCookies()) {
+ net::StaticCookiePolicy policy(
+ net::StaticCookiePolicy::BLOCK_THIRD_PARTY_COOKIES);
+ int rv = policy.CanGetCookies(url, first_party, NULL);
+ if (rv != net::OK)
+ return rv;
+ }
+
+ const std::string& host = url.host();
+
+ ContentSetting setting = host_content_settings_map_->GetContentSetting(
+ host, CONTENT_SETTINGS_TYPE_COOKIES);
+ if (setting == CONTENT_SETTING_BLOCK)
+ return net::ERR_ACCESS_DENIED;
+ if (setting == CONTENT_SETTING_ALLOW)
+ return net::OK;
+
+ DCHECK(callback);
+
+ // If we are currently prompting the user for a 'set-cookie' matching this
+ // host, then we need to defer reading cookies.
+
+ HostCompletionsMap::iterator it = host_completions_map_.find(host);
+ if (it == host_completions_map_.end())
+ return net::OK;
+
+ if (it->second.size() >= kMaxCompletionsPerHost) {
+ LOG(ERROR) << "Would exceed kMaxCompletionsPerHost";
+ return net::ERR_ACCESS_DENIED;
+ }
+
+ it->second.push_back(Completion::ForGetCookies(callback));
+
+ return net::ERR_IO_PENDING;
+}
+
+int ChromeCookiePolicy::CanSetCookie(const GURL& url,
+ const GURL& first_party,
+ const std::string& cookie_line,
+ net::CompletionCallback* callback) {
+ if (host_content_settings_map_->BlockThirdPartyCookies()) {
+ net::StaticCookiePolicy policy(
+ net::StaticCookiePolicy::BLOCK_THIRD_PARTY_COOKIES);
+ int rv = policy.CanSetCookie(url, first_party, cookie_line, NULL);
+ if (rv != net::OK)
+ return rv;
+ }
+
+ const std::string& host = url.host();
+
+ ContentSetting setting = host_content_settings_map_->GetContentSetting(
+ host, CONTENT_SETTINGS_TYPE_COOKIES);
+ if (setting == CONTENT_SETTING_BLOCK)
+ return net::ERR_ACCESS_DENIED;
+ if (setting == CONTENT_SETTING_ALLOW)
+ return net::OK;
+
+ DCHECK(callback);
+
+ // Else, ask the user...
+
+ Completions& completions = host_completions_map_[host];
+
+ if (completions.size() >= kMaxCompletionsPerHost) {
+ LOG(ERROR) << "Would exceed kMaxCompletionsPerHost";
+ return net::ERR_ACCESS_DENIED;
+ }
+
+ completions.push_back(Completion::ForSetCookie(callback));
+
+ PromptForSetCookie(host, cookie_line);
+ return net::ERR_IO_PENDING;
+}
+
+void ChromeCookiePolicy::PromptForSetCookie(const std::string &host,
+ const std::string& cookie_line) {
+ if (!ChromeThread::CurrentlyOn(ChromeThread::UI)) {
+ ChromeThread::PostTask(
+ ChromeThread::UI, FROM_HERE,
+ NewRunnableMethod(this, &ChromeCookiePolicy::PromptForSetCookie, host,
+ cookie_line));
+ return;
+ }
+
+ // TODO(darin): Prompt user!
+#if 0
+ MessageBox(NULL,
+ UTF8ToWide(cookie_line).c_str(),
+ UTF8ToWide(host).c_str(),
+ MB_OK);
+#endif
+
+ DidPromptForSetCookie(host, net::OK);
+}
+
+void ChromeCookiePolicy::DidPromptForSetCookie(const std::string &host,
+ int result) {
+ if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) {
+ ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE,
+ NewRunnableMethod(this, &ChromeCookiePolicy::DidPromptForSetCookie,
+ host, result));
+ return;
+ }
+
+ // Notify all callbacks, starting with the first until we hit another that
+ // is for a 'set-cookie'.
+ HostCompletionsMap::iterator it = host_completions_map_.find(host);
+ CHECK(it != host_completions_map_.end());
+
+ Completions& completions = it->second;
+ CHECK(!completions.empty() && completions[0].is_set_cookie_request());
+
+ // Gather the list of callbacks to notify, and remove them from the
+ // completions list before handing control to the callbacks (in case
+ // they should call back into us to modify host_completions_map_).
+
+ std::vector<net::CompletionCallback*> callbacks;
+ callbacks.push_back(completions[0].callback());
+ size_t i = 1;
+ for (; i < completions.size(); ++i) {
+ if (completions[i].is_set_cookie_request())
+ break;
+ callbacks.push_back(completions[i].callback());
+ }
+ completions.erase(completions.begin(), completions.begin() + i);
+
+ if (completions.empty())
+ host_completions_map_.erase(it);
+
+ for (size_t j = 0; j < callbacks.size(); ++j)
+ callbacks[j]->Run(result);
+}
diff --git a/chrome/browser/net/chrome_cookie_policy.h b/chrome/browser/net/chrome_cookie_policy.h
new file mode 100644
index 0000000..0d536f8
--- /dev/null
+++ b/chrome/browser/net/chrome_cookie_policy.h
@@ -0,0 +1,74 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_NET_CHROME_COOKIE_POLICY_H_
+#define CHROME_BROWSER_NET_CHROME_COOKIE_POLICY_H_
+
+#include <map>
+#include <vector>
+
+#include "base/ref_counted.h"
+#include "net/base/cookie_policy.h"
+
+class HostContentSettingsMap;
+
+// Implements CookiePolicy that may delay queries to ask the user to decide.
+//
+// We will only prompt the user before setting a cookie. We do not prompt the
+// user before getting a cookie. However, if we are in the process of
+// prompting the user, then any requests to get cookies will be deferred.
+// This is done so that cookie requests remain FIFO.
+//
+class ChromeCookiePolicy
+ : public base::RefCountedThreadSafe<ChromeCookiePolicy>,
+ public net::CookiePolicy {
+ public:
+ explicit ChromeCookiePolicy(HostContentSettingsMap* map);
+ ~ChromeCookiePolicy();
+
+ // CookiePolicy methods:
+ virtual int CanGetCookies(const GURL& url, const GURL& first_party,
+ net::CompletionCallback* callback);
+ virtual int CanSetCookie(const GURL& url, const GURL& first_party,
+ const std::string& cookie_line,
+ net::CompletionCallback* callback);
+
+ private:
+ class Completion {
+ public:
+ static Completion ForSetCookie(net::CompletionCallback* callback) {
+ return Completion(true, callback);
+ }
+
+ static Completion ForGetCookies(net::CompletionCallback* callback) {
+ return Completion(false, callback);
+ }
+
+ bool is_set_cookie_request() const { return is_set_cookie_request_; }
+ net::CompletionCallback* callback() const { return callback_; }
+
+ private:
+ Completion(bool is_set_cookie_request, net::CompletionCallback* callback)
+ : is_set_cookie_request_(is_set_cookie_request),
+ callback_(callback) {
+ }
+
+ bool is_set_cookie_request_;
+ net::CompletionCallback* callback_;
+ };
+
+ typedef std::vector<Completion> Completions;
+ typedef std::map<std::string, Completions> HostCompletionsMap;
+
+ void PromptForSetCookie(const std::string& host,
+ const std::string& cookie_line);
+ void DidPromptForSetCookie(const std::string& host, int result);
+
+ // A map from hostname to callbacks awaiting a cookie policy response.
+ HostCompletionsMap host_completions_map_;
+
+ scoped_refptr<HostContentSettingsMap> host_content_settings_map_;
+};
+
+#endif // CHROME_BROWSER_NET_CHROME_COOKIE_POLICY_H_
diff --git a/chrome/browser/net/chrome_url_request_context.cc b/chrome/browser/net/chrome_url_request_context.cc
index 6b97030..8013800 100644
--- a/chrome/browser/net/chrome_url_request_context.cc
+++ b/chrome/browser/net/chrome_url_request_context.cc
@@ -184,6 +184,9 @@ ChromeURLRequestContext* FactoryForOriginal::Create() {
context->set_cookie_store(new net::CookieMonster(cookie_db.get()));
}
+ context->set_cookie_policy(
+ new ChromeCookiePolicy(host_content_settings_map_));
+
// Create a new AppCacheService (issues fetches through the
// main URLRequestContext that we just created).
context->set_appcache_service(
@@ -262,6 +265,8 @@ ChromeURLRequestContext* FactoryForOffTheRecord::Create() {
new net::HttpCache(context->host_resolver(), context->proxy_service(),
context->ssl_config_service(), 0);
context->set_cookie_store(new net::CookieMonster);
+ context->set_cookie_policy(
+ new ChromeCookiePolicy(host_content_settings_map_));
context->set_http_transaction_factory(cache);
if (CommandLine::ForCurrentProcess()->HasSwitch(
@@ -300,6 +305,7 @@ ChromeURLRequestContext* FactoryForOffTheRecordExtensions::Create() {
const char* schemes[] = {chrome::kExtensionScheme};
cookie_monster->SetCookieableSchemes(schemes, 1);
context->set_cookie_store(cookie_monster);
+ // No dynamic cookie policy for extensions.
return context;
}
@@ -341,6 +347,8 @@ ChromeURLRequestContext* FactoryForMedia::Create() {
context->set_proxy_service(main_context->proxy_service());
// Also share the cookie store of the common profile.
context->set_cookie_store(main_context->cookie_store());
+ context->set_cookie_policy(
+ static_cast<ChromeCookiePolicy*>(main_context->cookie_policy()));
// Create a media cache with default size.
// TODO(hclam): make the maximum size of media cache configurable.
@@ -606,8 +614,6 @@ void ChromeURLRequestContextGetter::GetCookieStoreAsyncHelper(
ChromeURLRequestContext::ChromeURLRequestContext() {
CheckCurrentlyOnIOThread();
- cookie_policy_ = this; // We implement CookiePolicy
-
url_request_tracker()->SetGraveyardFilter(
&ChromeURLRequestContext::ShouldTrackRequest);
}
@@ -640,6 +646,9 @@ ChromeURLRequestContext::~ChromeURLRequestContext() {
delete ftp_transaction_factory_;
delete http_transaction_factory_;
+ // cookie_policy_'s lifetime is auto-managed by chrome_cookie_policy_. We
+ // null this out here to avoid a dangling reference to chrome_cookie_policy_
+ // when ~URLRequestContext runs.
cookie_policy_ = NULL;
}
@@ -756,48 +765,10 @@ bool ChromeURLRequestContext::AreCookiesEnabled() const {
return setting != CONTENT_SETTING_BLOCK;
}
-bool ChromeURLRequestContext::CanGetCookies(const GURL& url,
- const GURL& first_party) {
- if (host_content_settings_map_->BlockThirdPartyCookies()) {
- net::StaticCookiePolicy policy(
- net::StaticCookiePolicy::BLOCK_THIRD_PARTY_COOKIES);
- if (!policy.CanGetCookies(url, first_party))
- return false;
- }
-
- ContentSetting setting = host_content_settings_map_->GetContentSetting(
- url.host(), CONTENT_SETTINGS_TYPE_COOKIES);
- if (setting == CONTENT_SETTING_BLOCK)
- return false;
-
- // TODO(darin): Implement CONTENT_SETTING_ASK
- return true;
-}
-
-bool ChromeURLRequestContext::CanSetCookie(const GURL& url,
- const GURL& first_party) {
- if (host_content_settings_map_->BlockThirdPartyCookies()) {
- net::StaticCookiePolicy policy(
- net::StaticCookiePolicy::BLOCK_THIRD_PARTY_COOKIES);
- if (!policy.CanSetCookie(url, first_party))
- return false;
- }
-
- ContentSetting setting = host_content_settings_map_->GetContentSetting(
- url.host(), CONTENT_SETTINGS_TYPE_COOKIES);
- if (setting == CONTENT_SETTING_BLOCK)
- return false;
-
- // TODO(darin): Implement CONTENT_SETTING_ASK
- return true;
-}
-
ChromeURLRequestContext::ChromeURLRequestContext(
ChromeURLRequestContext* other) {
CheckCurrentlyOnIOThread();
- cookie_policy_ = this; // We implement CookiePolicy
-
// Set URLRequestContext members
host_resolver_ = other->host_resolver_;
proxy_service_ = other->proxy_service_;
@@ -805,6 +776,7 @@ ChromeURLRequestContext::ChromeURLRequestContext(
http_transaction_factory_ = other->http_transaction_factory_;
ftp_transaction_factory_ = other->ftp_transaction_factory_;
cookie_store_ = other->cookie_store_;
+ cookie_policy_ = other->cookie_policy_;
transport_security_state_ = other->transport_security_state_;
accept_language_ = other->accept_language_;
accept_charset_ = other->accept_charset_;
@@ -814,6 +786,7 @@ ChromeURLRequestContext::ChromeURLRequestContext(
extension_info_ = other->extension_info_;
user_script_dir_path_ = other->user_script_dir_path_;
appcache_service_ = other->appcache_service_;
+ chrome_cookie_policy_ = other->chrome_cookie_policy_;
host_content_settings_map_ = other->host_content_settings_map_;
host_zoom_map_ = other->host_zoom_map_;
privacy_blacklist_ = other->privacy_blacklist_;
diff --git a/chrome/browser/net/chrome_url_request_context.h b/chrome/browser/net/chrome_url_request_context.h
index 8d4186d..f52029e 100644
--- a/chrome/browser/net/chrome_url_request_context.h
+++ b/chrome/browser/net/chrome_url_request_context.h
@@ -11,6 +11,7 @@
#include "chrome/browser/host_content_settings_map.h"
#include "chrome/browser/host_zoom_map.h"
#include "chrome/browser/privacy_blacklist/blacklist.h"
+#include "chrome/browser/net/chrome_cookie_policy.h"
#include "chrome/browser/net/url_request_context_getter.h"
#include "chrome/common/appcache/chrome_appcache_service.h"
#include "chrome/common/extensions/extension.h"
@@ -34,8 +35,7 @@ class IOThread;
//
// All methods of this class must be called from the IO thread,
// including the constructor and destructor.
-class ChromeURLRequestContext : public URLRequestContext,
- public net::CookiePolicy {
+class ChromeURLRequestContext : public URLRequestContext {
public:
// Maintains some extension-related state we need on the IO thread.
// TODO(aa): It would be cool if the Extension objects in ExtensionsService
@@ -121,10 +121,6 @@ class ChromeURLRequestContext : public URLRequestContext,
// False only if cookies are globally blocked without exception.
bool AreCookiesEnabled() const;
- // CookiePolicy methods:
- virtual bool CanGetCookies(const GURL& url, const GURL& first_party);
- virtual bool CanSetCookie(const GURL& url, const GURL& first_party);
-
protected:
// Copies the dependencies from |other| into |this|. If you use this
// constructor, then you should hold a reference to |other|, as we
@@ -167,6 +163,10 @@ class ChromeURLRequestContext : public URLRequestContext,
void set_cookie_store(net::CookieStore* cookie_store) {
cookie_store_ = cookie_store;
}
+ void set_cookie_policy(ChromeCookiePolicy* cookie_policy) {
+ chrome_cookie_policy_ = cookie_policy; // Take a strong reference.
+ cookie_policy_ = cookie_policy;
+ }
void set_proxy_service(net::ProxyService* service) {
proxy_service_ = service;
}
@@ -206,6 +206,7 @@ class ChromeURLRequestContext : public URLRequestContext,
FilePath user_script_dir_path_;
scoped_refptr<ChromeAppCacheService> appcache_service_;
+ scoped_refptr<ChromeCookiePolicy> chrome_cookie_policy_;
scoped_refptr<HostContentSettingsMap> host_content_settings_map_;
scoped_refptr<HostZoomMap> host_zoom_map_;
scoped_refptr<Blacklist> privacy_blacklist_;
diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc
index 1bcb7a7..2861718 100644
--- a/chrome/browser/renderer_host/resource_message_filter.cc
+++ b/chrome/browser/renderer_host/resource_message_filter.cc
@@ -152,6 +152,99 @@ Blacklist::Match* GetPrivacyBlacklistMatchForURL(
return blacklist->FindMatch(url);
}
+class SetCookieCompletion : public net::CompletionCallback {
+ public:
+ SetCookieCompletion(const GURL& url, const std::string& cookie_line,
+ URLRequestContext* context)
+ : url_(url),
+ cookie_line_(cookie_line),
+ context_(context) {
+ }
+
+ virtual void RunWithParams(const Tuple1<int>& params) {
+ int result = params.a;
+ if (result == net::OK)
+ context_->cookie_store()->SetCookie(url_, cookie_line_);
+ delete this;
+ }
+
+ private:
+ GURL url_;
+ std::string cookie_line_;
+ scoped_refptr<URLRequestContext> context_;
+};
+
+class GetCookiesCompletion : public net::CompletionCallback {
+ public:
+ GetCookiesCompletion(const GURL& url, IPC::Message* reply_msg,
+ ResourceMessageFilter* filter,
+ URLRequestContext* context)
+ : url_(url),
+ reply_msg_(reply_msg),
+ filter_(filter),
+ context_(context) {
+ }
+
+ virtual void RunWithParams(const Tuple1<int>& params) {
+ int result = params.a;
+ std::string cookies;
+ if (result == net::OK)
+ cookies = context_->cookie_store()->GetCookies(url_);
+ ViewHostMsg_GetCookies::WriteReplyParams(reply_msg_, cookies);
+ filter_->Send(reply_msg_);
+ delete this;
+ }
+
+ private:
+ GURL url_;
+ IPC::Message* reply_msg_;
+ scoped_refptr<ResourceMessageFilter> filter_;
+ scoped_refptr<URLRequestContext> context_;
+};
+
+class GetRawCookiesCompletion : public net::CompletionCallback {
+ public:
+ GetRawCookiesCompletion(const GURL& url, IPC::Message* reply_msg,
+ ResourceMessageFilter* filter,
+ URLRequestContext* context)
+ : url_(url),
+ reply_msg_(reply_msg),
+ filter_(filter),
+ context_(context) {
+ }
+
+ virtual void RunWithParams(const Tuple1<int>& params) {
+ // Ignore the policy result. We only waited on the policy result so that
+ // any pending 'set-cookie' requests could be flushed. The intent of
+ // querying the raw cookies is to reveal the contents of the cookie DB, so
+ // it important that we don't read the cookie db ahead of pending writes.
+
+ net::CookieMonster* cookie_monster =
+ context_->cookie_store()->GetCookieMonster();
+ net::CookieMonster::CookieList cookie_list =
+ cookie_monster->GetAllCookiesForURL(url_);
+
+ std::vector<webkit_glue::WebCookie> cookies;
+ for (size_t i = 0; i < cookie_list.size(); ++i) {
+ // TODO(darin): url.host() is not necessarily the domain of the cookie.
+ // We need a different API on CookieMonster to provide the domain info.
+ // See http://crbug.com/34315.
+ cookies.push_back(
+ webkit_glue::WebCookie(cookie_list[i].first, cookie_list[i].second));
+ }
+
+ ViewHostMsg_GetRawCookies::WriteReplyParams(reply_msg_, cookies);
+ filter_->Send(reply_msg_);
+ delete this;
+ }
+
+ private:
+ GURL url_;
+ IPC::Message* reply_msg_;
+ scoped_refptr<ResourceMessageFilter> filter_;
+ scoped_refptr<URLRequestContext> context_;
+};
+
} // namespace
ResourceMessageFilter::ResourceMessageFilter(
@@ -302,8 +395,8 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWindow, OnMsgCreateWindow)
IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWidget, OnMsgCreateWidget)
IPC_MESSAGE_HANDLER(ViewHostMsg_SetCookie, OnSetCookie)
- IPC_MESSAGE_HANDLER(ViewHostMsg_GetCookies, OnGetCookies)
- IPC_MESSAGE_HANDLER(ViewHostMsg_GetRawCookies, OnGetRawCookies)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetCookies, OnGetCookies)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetRawCookies, OnGetRawCookies)
IPC_MESSAGE_HANDLER(ViewHostMsg_DeleteCookie, OnDeleteCookie)
IPC_MESSAGE_HANDLER(ViewHostMsg_GetCookiesEnabled, OnGetCookiesEnabled)
#if defined(OS_WIN) // This hack is Windows-specific.
@@ -483,58 +576,55 @@ void ResourceMessageFilter::OnSetCookie(const GURL& url,
const std::string& cookie) {
ChromeURLRequestContext* context = GetRequestContextForURL(url);
- DCHECK(context->cookie_policy());
- if (!context->cookie_policy()->CanSetCookie(url, first_party_for_cookies))
- return;
scoped_ptr<Blacklist::Match> match(
GetPrivacyBlacklistMatchForURL(url, context));
if (match.get() && (match->attributes() & Blacklist::kBlockCookies))
return;
- context->cookie_store()->SetCookie(url, cookie);
+
+ SetCookieCompletion* callback = new SetCookieCompletion(url, cookie, context);
+
+ DCHECK(context->cookie_policy());
+ int policy = context->cookie_policy()->CanSetCookie(
+ url, first_party_for_cookies, cookie, callback);
+ if (policy == net::ERR_IO_PENDING)
+ return;
+ callback->Run(policy);
}
void ResourceMessageFilter::OnGetCookies(const GURL& url,
const GURL& first_party_for_cookies,
- std::string* cookies) {
+ IPC::Message* reply_msg) {
URLRequestContext* context = GetRequestContextForURL(url);
+
+ GetCookiesCompletion* callback =
+ new GetCookiesCompletion(url, reply_msg, this, context);
+
DCHECK(context->cookie_policy());
- if (context->cookie_policy()->CanGetCookies(url, first_party_for_cookies))
- *cookies = context->cookie_store()->GetCookies(url);
+ int policy = context->cookie_policy()->CanGetCookies(
+ url, first_party_for_cookies, callback);
+ if (policy == net::ERR_IO_PENDING)
+ return;
+ callback->Run(policy);
}
void ResourceMessageFilter::OnGetRawCookies(
const GURL& url,
const GURL& first_party_for_cookies,
- std::vector<webkit_glue::WebCookie>* raw_cookies) {
- raw_cookies->clear();
-
+ IPC::Message* reply_msg) {
URLRequestContext* context = GetRequestContextForURL(url);
- net::CookieMonster* cookie_monster = context->cookie_store()->
- GetCookieMonster();
- if (!cookie_monster) {
- NOTREACHED();
- return;
- }
- if (!context->cookie_policy()->CanGetCookies(url, first_party_for_cookies))
- return;
+ GetRawCookiesCompletion* callback =
+ new GetRawCookiesCompletion(url, reply_msg, this, context);
- typedef net::CookieMonster::CookieList CookieList;
- CookieList cookieList = cookie_monster->GetRawCookies(url);
- for (CookieList::iterator it = cookieList.begin();
- it != cookieList.end(); ++it) {
- net::CookieMonster::CanonicalCookie& cookie = it->second;
- raw_cookies->push_back(
- webkit_glue::WebCookie(
- cookie.Name(),
- cookie.Value(),
- it->first,
- cookie.Path(),
- cookie.ExpiryDate().ToDoubleT() * 1000,
- cookie.IsHttpOnly(),
- cookie.IsSecure(),
- !cookie.IsPersistent()));
- }
+ // We check policy here to avoid sending back cookies that would not normally
+ // be applied to outbound requests for the given URL. Since this cookie info
+ // is visible in the developer tools, it is helpful to make it match reality.
+ DCHECK(context->cookie_policy());
+ int policy = context->cookie_policy()->CanGetCookies(
+ url, first_party_for_cookies, callback);
+ if (policy == net::ERR_IO_PENDING)
+ return;
+ callback->Run(policy);
}
void ResourceMessageFilter::OnDeleteCookie(const GURL& url,
diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h
index 3931c83..e813ae1 100644
--- a/chrome/browser/renderer_host/resource_message_filter.h
+++ b/chrome/browser/renderer_host/resource_message_filter.h
@@ -133,10 +133,10 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter,
const std::string& cookie);
void OnGetCookies(const GURL& url,
const GURL& first_party_for_cookies,
- std::string* cookies);
+ IPC::Message* reply_msg);
void OnGetRawCookies(const GURL& url,
const GURL& first_party_for_cookies,
- std::vector<webkit_glue::WebCookie>* raw_cookies);
+ IPC::Message* reply_msg);
void OnDeleteCookie(const GURL& url,
const std::string& cookieName);
void OnGetCookiesEnabled(const GURL& url,
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 343db16..8ced6dc 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1253,6 +1253,8 @@
'browser/modal_html_dialog_delegate.h',
'browser/net/browser_url_util.cc',
'browser/net/browser_url_util.h',
+ 'browser/net/chrome_cookie_policy.cc',
+ 'browser/net/chrome_cookie_policy.h',
'browser/net/chrome_url_request_context.cc',
'browser/net/chrome_url_request_context.h',
'browser/net/url_request_context_getter.cc',