diff options
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/automation/automation_profile_impl.cc | 42 | ||||
-rw-r--r-- | chrome/browser/automation/url_request_automation_job.cc | 29 | ||||
-rw-r--r-- | chrome/browser/net/chrome_cookie_policy.cc | 162 | ||||
-rw-r--r-- | chrome/browser/net/chrome_cookie_policy.h | 74 | ||||
-rw-r--r-- | chrome/browser/net/chrome_url_request_context.cc | 53 | ||||
-rw-r--r-- | chrome/browser/net/chrome_url_request_context.h | 13 | ||||
-rw-r--r-- | chrome/browser/renderer_host/resource_message_filter.cc | 162 | ||||
-rw-r--r-- | chrome/browser/renderer_host/resource_message_filter.h | 4 | ||||
-rwxr-xr-x | chrome/chrome_browser.gypi | 2 |
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', |