diff options
30 files changed, 579 insertions, 89 deletions
diff --git a/chrome/browser/automation/automation_profile_impl.cc b/chrome/browser/automation/automation_profile_impl.cc new file mode 100644 index 0000000..51923ae --- /dev/null +++ b/chrome/browser/automation/automation_profile_impl.cc @@ -0,0 +1,114 @@ +// Copyright (c) 2006-2009 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/automation/automation_profile_impl.h" +#include "chrome/test/automation/automation_messages.h" +#include "net/url_request/url_request_context.h" + +// A special Request context for automation. Substitute a few things +// like cookie store, proxy settings etc to handle them differently +// for automation. +class AutomationURLRequestContext : public URLRequestContext { + public: + AutomationURLRequestContext(URLRequestContext* original_context, + net::CookieStore* automation_cookie_store) { + host_resolver_ = original_context->host_resolver(); + proxy_service_ = original_context->proxy_service(); + http_transaction_factory_ = original_context->http_transaction_factory(); + ftp_transaction_factory_ = original_context->ftp_transaction_factory(); + cookie_store_ = automation_cookie_store; + cookie_policy_.set_type(original_context->cookie_policy()->type()); + force_tls_state_ = original_context->force_tls_state(); + // ftp_auth_cache_ = original_context->ftp_auth_cache(); + blacklist_ = original_context->blacklist(); + accept_language_ = original_context->accept_language(); + accept_charset_ = original_context->accept_charset(); + referrer_charset_ = original_context->referrer_charset(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(AutomationURLRequestContext); +}; + +// CookieStore specialization to have automation specific +// behavior for cookies. +class AutomationCookieStore : public net::CookieStore { + public: + AutomationCookieStore(AutomationProfileImpl* profile, + net::CookieStore* original_cookie_store, + IPC::Message::Sender* automation_client) + : profile_(profile), + original_cookie_store_(original_cookie_store), + automation_client_(automation_client) { + } + + // CookieStore implementation. + virtual bool SetCookie(const GURL& url, const std::string& cookie_line) { + bool cookie_set = original_cookie_store_->SetCookie(url, cookie_line); + if (cookie_set) { + automation_client_->Send(new AutomationMsg_SetCookieAsync(0, + profile_->tab_handle(), url, cookie_line)); + } + 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); + } + + protected: + AutomationProfileImpl* profile_; + net::CookieStore* original_cookie_store_; + IPC::Message::Sender* automation_client_; + + private: + DISALLOW_COPY_AND_ASSIGN(AutomationCookieStore); +}; + +void AutomationProfileImpl::Initialize(Profile* original_profile, + IPC::Message::Sender* automation_client) { + DCHECK(original_profile); + original_profile_ = original_profile; + + URLRequestContext* original_context = original_profile_->GetRequestContext(); + net::CookieStore* original_cookie_store = original_context->cookie_store(); + alternate_cookie_store_.reset(new AutomationCookieStore(this, + original_cookie_store, + automation_client)); + alternate_reqeust_context_ = new AutomationURLRequestContext( + original_context, alternate_cookie_store_.get()); +} + diff --git a/chrome/browser/automation/automation_profile_impl.h b/chrome/browser/automation/automation_profile_impl.h new file mode 100644 index 0000000..2a9b133 --- /dev/null +++ b/chrome/browser/automation/automation_profile_impl.h @@ -0,0 +1,198 @@ +// Copyright (c) 2006-2009 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_AUTOMATION_AUTOMATION_PROFILE_IMPL_H_ +#define CHROME_BROWSER_AUTOMATION_AUTOMATION_PROFILE_IMPL_H_ + +#include "chrome/browser/profile.h" +#include "net/url_request/url_request_context.h" + +namespace net { +class CookieStore; +} + +// Automation overrides for profile settings. +class AutomationProfileImpl : public Profile { + public: + AutomationProfileImpl() : original_profile_(NULL) { + } + + void Initialize(Profile* original_profile, + IPC::Message::Sender* automation_client); + + void set_tab_handle(int tab_handle) { + tab_handle_ = tab_handle; + } + int tab_handle() const { + return tab_handle_; + } + + // Profile implementation. + virtual FilePath GetPath() { + return original_profile_->GetPath(); + } + virtual bool IsOffTheRecord() { + return original_profile_->IsOffTheRecord(); + } + virtual Profile* GetOffTheRecordProfile() { + return original_profile_->GetOffTheRecordProfile(); + } + virtual void DestroyOffTheRecordProfile() { + return original_profile_->DestroyOffTheRecordProfile(); + } + virtual Profile* GetOriginalProfile() { + return original_profile_->GetOriginalProfile(); + } + virtual VisitedLinkMaster* GetVisitedLinkMaster() { + return original_profile_->GetVisitedLinkMaster(); + } + virtual ExtensionsService* GetExtensionsService() { + return original_profile_->GetExtensionsService(); + } + virtual UserScriptMaster* GetUserScriptMaster() { + return original_profile_->GetUserScriptMaster(); + } + virtual ExtensionProcessManager* GetExtensionProcessManager() { + return original_profile_->GetExtensionProcessManager(); + } + virtual ExtensionMessageService* GetExtensionMessageService() { + return original_profile_->GetExtensionMessageService(); + } + virtual SSLHostState* GetSSLHostState() { + return original_profile_->GetSSLHostState(); + } + virtual net::ForceTLSState* GetForceTLSState() { + return original_profile_->GetForceTLSState(); + } + virtual HistoryService* GetHistoryService(ServiceAccessType access) { + return original_profile_->GetHistoryService(access); + } + virtual WebDataService* GetWebDataService(ServiceAccessType access) { + return original_profile_->GetWebDataService(access); + } + virtual PasswordStore* GetPasswordStore(ServiceAccessType access) { + return original_profile_->GetPasswordStore(access); + } + virtual PrefService* GetPrefs() { + return original_profile_->GetPrefs(); + } + virtual TemplateURLModel* GetTemplateURLModel() { + return original_profile_->GetTemplateURLModel(); + } + virtual TemplateURLFetcher* GetTemplateURLFetcher() { + return original_profile_->GetTemplateURLFetcher(); + } + virtual DownloadManager* GetDownloadManager() { + return original_profile_->GetDownloadManager(); + } + virtual bool HasCreatedDownloadManager() const { + return original_profile_->HasCreatedDownloadManager(); + } + virtual void InitThemes() { + return original_profile_->InitThemes(); + } + virtual void SetTheme(Extension* extension) { + return original_profile_->SetTheme(extension); + } + virtual void SetNativeTheme() { + return original_profile_->SetNativeTheme(); + } + virtual void ClearTheme() { + return original_profile_->ClearTheme(); + } + virtual ThemeProvider* GetThemeProvider() { + return original_profile_->GetThemeProvider(); + } + virtual ThumbnailStore* GetThumbnailStore() { + return original_profile_->GetThumbnailStore(); + } + virtual URLRequestContext* GetRequestContext() { + return alternate_reqeust_context_; + } + virtual URLRequestContext* GetRequestContextForMedia() { + return original_profile_->GetRequestContextForMedia(); + } + virtual URLRequestContext* GetRequestContextForExtensions() { + return original_profile_->GetRequestContextForExtensions(); + } + virtual Blacklist* GetBlacklist() { + return original_profile_->GetBlacklist(); + } + virtual SessionService* GetSessionService() { + return original_profile_->GetSessionService(); + } + virtual void ShutdownSessionService() { + return original_profile_->ShutdownSessionService(); + } + virtual bool HasSessionService() const { + return original_profile_->HasSessionService(); + } + virtual std::wstring GetName() { + return original_profile_->GetName(); + } + virtual void SetName(const std::wstring& name) { + return original_profile_->SetName(name); + } + virtual std::wstring GetID() { + return original_profile_->GetID(); + } + virtual void SetID(const std::wstring& id) { + return original_profile_->SetID(id); + } + virtual bool DidLastSessionExitCleanly() { + return original_profile_->DidLastSessionExitCleanly(); + } + virtual BookmarkModel* GetBookmarkModel() { + return original_profile_->GetBookmarkModel(); + } + +#ifdef CHROME_PERSONALIZATION + virtual ProfilePersonalization* GetProfilePersonalization() { + return original_profile_->GetProfilePersonalization(); + } +#endif + + virtual bool IsSameProfile(Profile* profile) { + return original_profile_->IsSameProfile(profile); + } + virtual base::Time GetStartTime() const { + return original_profile_->GetStartTime(); + } + virtual TabRestoreService* GetTabRestoreService() { + return original_profile_->GetTabRestoreService(); + } + virtual void ResetTabRestoreService() { + return original_profile_->ResetTabRestoreService(); + } + virtual void ReinitializeSpellChecker() { + return original_profile_->ReinitializeSpellChecker(); + } + virtual SpellChecker* GetSpellChecker() { + return original_profile_->GetSpellChecker(); + } + virtual WebKitContext* GetWebKitContext() { + return original_profile_->GetWebKitContext(); + } + virtual void MarkAsCleanShutdown() { + return original_profile_->MarkAsCleanShutdown(); + } + virtual void InitExtensions() { + return original_profile_->InitExtensions(); + } + virtual void InitWebResources() { + return original_profile_->InitWebResources(); + } + + protected: + Profile* original_profile_; + scoped_ptr<net::CookieStore> alternate_cookie_store_; + scoped_refptr<URLRequestContext> alternate_reqeust_context_; + int tab_handle_; + + private: + DISALLOW_COPY_AND_ASSIGN(AutomationProfileImpl); +}; + +#endif // CHROME_BROWSER_AUTOMATION_AUTOMATION_PROFILE_IMPL_H_ + diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc index 2f74d23..4bb2d65 100644 --- a/chrome/browser/automation/automation_provider.cc +++ b/chrome/browser/automation/automation_provider.cc @@ -50,7 +50,6 @@ #include "chrome/common/platform_util.h" #include "chrome/common/pref_service.h" #include "chrome/test/automation/automation_messages.h" -#include "net/base/cookie_monster.h" #include "net/proxy/proxy_service.h" #include "net/proxy/proxy_config_service_fixed.h" #include "net/url_request/url_request_context.h" @@ -2396,7 +2395,8 @@ void AutomationProvider::CreateExternalTab( Profile* profile = settings.is_off_the_record ? profile_->GetOffTheRecordProfile() : profile_; external_tab_container->Init(profile, settings.parent, settings.dimensions, - settings.style, settings.load_requests_via_automation); + settings.style, settings.load_requests_via_automation, + settings.handle_top_level_requests); TabContents* tab_contents = external_tab_container->tab_contents(); if (tab_contents) { *tab_handle = tab_tracker_->Add(&tab_contents->controller()); diff --git a/chrome/browser/automation/url_request_automation_job.cc b/chrome/browser/automation/url_request_automation_job.cc index 6ab7f87..5d4cac6 100644 --- a/chrome/browser/automation/url_request_automation_job.cc +++ b/chrome/browser/automation/url_request_automation_job.cc @@ -12,6 +12,7 @@ #include "net/base/io_buffer.h" #include "net/base/net_errors.h" #include "net/url_request/url_request.h" +#include "net/url_request/url_request_context.h" // This class manages the interception of network requests for automation. @@ -191,9 +192,34 @@ void URLRequestAutomationJob::OnRequestStarted( set_expected_content_size(response.content_length); mime_type_ = response.mime_type; - if (!response.headers.empty()) + if (!response.headers.empty()) { headers_ = new net::HttpResponseHeaders(response.headers); + // Parse and set HTTP cookies. + const std::string name = "Set-Cookie"; + std::string value; + std::vector<std::string> response_cookies; + + void* iter = NULL; + while (headers_->EnumerateHeader(&iter, name, &value)) { + if (request_->context()->InterceptCookie(request_, &value)) + response_cookies.push_back(value); + } + + if (response_cookies.size()) { + URLRequestContext* ctx = request_->context(); + if (ctx && ctx->cookie_store() && + ctx->cookie_policy()->CanSetCookie( + request_->url(), request_->first_party_for_cookies())) { + net::CookieOptions options; + options.set_include_httponly(); + ctx->cookie_store()->SetCookiesWithOptions(request_->url(), + response_cookies, + options); + } + } + } + NotifyHeadersComplete(); } diff --git a/chrome/browser/browsing_data_remover.cc b/chrome/browser/browsing_data_remover.cc index abc97ef..96e1543 100644 --- a/chrome/browser/browsing_data_remover.cc +++ b/chrome/browser/browsing_data_remover.cc @@ -110,8 +110,9 @@ void BrowsingDataRemover::Remove(int remove_mask) { if (remove_mask & REMOVE_COOKIES) { UserMetrics::RecordAction(L"ClearBrowsingData_Cookies", profile_); net::CookieMonster* cookie_monster = - profile_->GetRequestContext()->cookie_store(); - cookie_monster->DeleteAllCreatedBetween(delete_begin_, delete_end_, true); + profile_->GetRequestContext()->cookie_store()->GetCookieMonster(); + if (cookie_monster) + cookie_monster->DeleteAllCreatedBetween(delete_begin_, delete_end_, true); } if (remove_mask & REMOVE_PASSWORDS) { diff --git a/chrome/browser/cookies_table_model.cc b/chrome/browser/cookies_table_model.cc index 8aab8e2..3f85819 100644 --- a/chrome/browser/cookies_table_model.cc +++ b/chrome/browser/cookies_table_model.cc @@ -39,7 +39,8 @@ void CookiesTableModel::RemoveCookies(int start_index, int remove_count) { return; } - net::CookieMonster* monster = profile_->GetRequestContext()->cookie_store(); + net::CookieMonster* monster = + profile_->GetRequestContext()->cookie_store()->GetCookieMonster(); // We need to update the searched results list, the full cookie list, // and the view. We walk through the search results list (which is what @@ -158,7 +159,7 @@ static bool ContainsFilterText( void CookiesTableModel::LoadCookies() { // mmargh mmargh mmargh! net::CookieMonster* cookie_monster = - profile_->GetRequestContext()->cookie_store(); + profile_->GetRequestContext()->cookie_store()->GetCookieMonster(); all_cookies_ = cookie_monster->GetAllCookies(); DoFilter(); } diff --git a/chrome/browser/external_tab_container.cc b/chrome/browser/external_tab_container.cc index ab74af1..ee4eb85 100644 --- a/chrome/browser/external_tab_container.cc +++ b/chrome/browser/external_tab_container.cc @@ -46,7 +46,8 @@ bool ExternalTabContainer::Init(Profile* profile, HWND parent, const gfx::Rect& bounds, DWORD style, - bool load_requests_via_automation) { + bool load_requests_via_automation, + bool handle_top_level_requests) { if (IsWindow()) { NOTREACHED(); return false; @@ -66,8 +67,25 @@ bool ExternalTabContainer::Init(Profile* profile, // is the same as the lifetime of the window SetProp(GetNativeView(), kWindowObjectKey, this); + // If we are sending top level requests through the automation then + // we should be using automation to load url requests as well. + DCHECK(handle_top_level_requests ? load_requests_via_automation : 1); + + if (load_requests_via_automation) { + // Customize our profile. + // TODO(joshia): If we are loading requests via automation + // and handling cookies in automation then it's probably better to + // use OTR profile so that cookies are not persisted in chrome. + automation_profile_.reset(new AutomationProfileImpl); + automation_profile_->Initialize(profile, + automation_resource_message_filter_); + profile = automation_profile_.get(); + } + tab_contents_ = new TabContents(profile, NULL, MSG_ROUTING_NONE, NULL); tab_contents_->set_delegate(this); + tab_contents_->GetMutableRendererPrefs()->browser_handles_top_level_requests = + handle_top_level_requests; tab_contents_->render_view_host()->AllowBindings( BindingsPolicy::EXTERNAL_HOST); @@ -163,13 +181,16 @@ void ExternalTabContainer::OpenURLFromTab(TabContents* source, case SINGLETON_TAB: case NEW_FOREGROUND_TAB: case NEW_BACKGROUND_TAB: + case NEW_POPUP: case NEW_WINDOW: + case SAVE_TO_DISK: if (automation_) { automation_->Send(new AutomationMsg_OpenURL(0, tab_handle_, url, disposition)); } break; default: + NOTREACHED(); break; } } diff --git a/chrome/browser/external_tab_container.h b/chrome/browser/external_tab_container.h index f698c9e..0c19ebf 100644 --- a/chrome/browser/external_tab_container.h +++ b/chrome/browser/external_tab_container.h @@ -8,6 +8,7 @@ #include <vector> #include "chrome/browser/automation/automation_resource_message_filter.h" +#include "chrome/browser/automation/automation_profile_impl.h" #include "chrome/browser/browser.h" #include "chrome/browser/tab_contents/tab_contents_delegate.h" #include "chrome/common/notification_observer.h" @@ -41,7 +42,8 @@ class ExternalTabContainer : public TabContentsDelegate, HWND parent, const gfx::Rect& bounds, DWORD style, - bool load_requests_via_automation); + bool load_requests_via_automation, + bool handle_top_level_requests); // This is invoked when the external host reflects back to us a keyboard // message it did not process @@ -157,6 +159,9 @@ class ExternalTabContainer : public TabContentsDelegate, // Scoped browser object for this ExternalTabContainer instance. scoped_ptr<Browser> browser_; + // A customized profile for automation specific needs. + scoped_ptr<AutomationProfileImpl> automation_profile_; + DISALLOW_COPY_AND_ASSIGN(ExternalTabContainer); }; diff --git a/chrome/browser/importer/toolbar_importer.cc b/chrome/browser/importer/toolbar_importer.cc index 83fb29f..20e10da 100644 --- a/chrome/browser/importer/toolbar_importer.cc +++ b/chrome/browser/importer/toolbar_importer.cc @@ -25,9 +25,9 @@ static const char* kGoogleDomainSecureCookieId = "SID="; bool toolbar_importer_utils::IsGoogleGAIACookieInstalled() { URLRequestContext* context = Profile::GetDefaultRequestContext(); - net::CookieMonster* store = context->cookie_store(); + net::CookieStore* store = context->cookie_store(); GURL url(kGoogleDomainUrl); - net::CookieMonster::CookieOptions options; + net::CookieOptions options; options.set_include_httponly(); // The SID cookie might be httponly. std::string cookies = store->GetCookiesWithOptions(url, options); std::vector<std::string> cookie_list; diff --git a/chrome/browser/net/chrome_url_request_context.cc b/chrome/browser/net/chrome_url_request_context.cc index 8e407f7..7130b45 100644 --- a/chrome/browser/net/chrome_url_request_context.cc +++ b/chrome/browser/net/chrome_url_request_context.cc @@ -178,11 +178,13 @@ ChromeURLRequestContext* ChromeURLRequestContext::CreateOriginalForExtensions( context->cookie_db_.reset(new SQLitePersistentCookieStore( cookie_store_path.ToWStringHack(), g_browser_process->db_thread()->message_loop())); - context->cookie_store_ = new net::CookieMonster(context->cookie_db_.get()); + net::CookieMonster* cookie_monster = new net::CookieMonster( + context->cookie_db_.get()); // Enable cookies for extension URLs only. const char* schemes[] = {chrome::kExtensionScheme}; - context->cookie_store_->SetCookieableSchemes(schemes, 1); + cookie_monster->SetCookieableSchemes(schemes, 1); + context->cookie_store_ = cookie_monster; return context; } @@ -213,11 +215,12 @@ ChromeURLRequestContext* ChromeURLRequestContext::CreateOffTheRecordForExtensions(Profile* profile) { DCHECK(profile->IsOffTheRecord()); ChromeURLRequestContext* context = new ChromeURLRequestContext(profile); - context->cookie_store_ = new net::CookieMonster; + net::CookieMonster* cookie_monster = new net::CookieMonster; // Enable cookies for extension URLs only. const char* schemes[] = {chrome::kExtensionScheme}; - context->cookie_store_->SetCookieableSchemes(schemes, 1); + cookie_monster->SetCookieableSchemes(schemes, 1); + context->cookie_store_ = cookie_monster; return context; } @@ -290,7 +293,7 @@ ChromeURLRequestContext::ChromeURLRequestContext(Profile* profile) // net_util::GetSuggestedFilename is unlikely to be taken. referrer_charset_ = default_charset; - cookie_policy_.SetType(net::CookiePolicy::FromInt( + cookie_policy_.set_type(net::CookiePolicy::FromInt( prefs_->GetInteger(prefs::kCookieBehavior))); blacklist_ = profile->GetBlacklist(); @@ -397,7 +400,7 @@ const std::string& ChromeURLRequestContext::GetUserAgent( return webkit_glue::GetUserAgent(url); } -bool ChromeURLRequestContext::interceptCookie(const URLRequest* request, +bool ChromeURLRequestContext::InterceptCookie(const URLRequest* request, std::string* cookie) { const URLRequest::UserData* d = request->GetUserData(&Blacklist::kRequestDataKey); @@ -414,7 +417,7 @@ bool ChromeURLRequestContext::interceptCookie(const URLRequest* request, return true; } -bool ChromeURLRequestContext::allowSendingCookies(const URLRequest* request) +bool ChromeURLRequestContext::AllowSendingCookies(const URLRequest* request) const { const URLRequest::UserData* d = request->GetUserData(&Blacklist::kRequestDataKey); @@ -438,7 +441,7 @@ void ChromeURLRequestContext::OnCookiePolicyChange( net::CookiePolicy::Type type) { DCHECK(MessageLoop::current() == ChromeThread::GetMessageLoop(ChromeThread::IO)); - cookie_policy_.SetType(type); + cookie_policy_.set_type(type); } void ChromeURLRequestContext::OnDefaultCharsetChange( diff --git a/chrome/browser/net/chrome_url_request_context.h b/chrome/browser/net/chrome_url_request_context.h index fba8395..9dc0393 100644 --- a/chrome/browser/net/chrome_url_request_context.h +++ b/chrome/browser/net/chrome_url_request_context.h @@ -65,9 +65,9 @@ class ChromeURLRequestContext : public URLRequestContext, virtual const std::string& GetUserAgent(const GURL& url) const; - virtual bool interceptCookie(const URLRequest* request, std::string* cookie); + virtual bool InterceptCookie(const URLRequest* request, std::string* cookie); - virtual bool allowSendingCookies(const URLRequest* request) const; + virtual bool AllowSendingCookies(const URLRequest* request) const; private: // Private constructor, use the static factory methods instead. This is diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc index ca2f502..d57daae 100644 --- a/chrome/browser/plugin_process_host.cc +++ b/chrome/browser/plugin_process_host.cc @@ -44,7 +44,6 @@ #include "ipc/ipc_channel_handle.h" #include "ipc/ipc_descriptors.h" #include "ipc/ipc_switches.h" -#include "net/base/cookie_monster.h" #include "net/base/file_stream.h" #include "net/base/io_buffer.h" #include "net/url_request/url_request.h" diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc index e1a37a1..5cb59a1 100644 --- a/chrome/browser/renderer_host/resource_message_filter.cc +++ b/chrome/browser/renderer_host/resource_message_filter.cc @@ -36,7 +36,6 @@ #include "chrome/common/pref_service.h" #include "chrome/common/render_messages.h" #include "chrome/common/url_constants.h" -#include "net/base/cookie_monster.h" #include "net/base/mime_util.h" #include "net/base/load_flags.h" #include "net/http/http_cache.h" diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 1b86683..4ff0e8b 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -620,6 +620,8 @@ 'browser/automation/extension_automation_constants.cc', 'browser/automation/automation_extension_function.h', 'browser/automation/automation_extension_function.cc', + 'browser/automation/automation_profile_impl.cc', + 'browser/automation/automation_profile_impl.h', 'browser/automation/automation_provider.cc', 'browser/automation/automation_provider.h', 'browser/automation/automation_provider_list.cc', diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index 2ca15fd..c6c457c 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -1602,6 +1602,7 @@ struct ParamTraits<RendererPreferences> { WriteParam(m, p.should_antialias_text); WriteParam(m, static_cast<int>(p.hinting)); WriteParam(m, static_cast<int>(p.subpixel_rendering)); + WriteParam(m, p.browser_handles_top_level_requests); } static bool Read(const Message* m, void** iter, param_type* p) { if (!ReadParam(m, iter, &p->can_accept_load_drops)) @@ -1621,6 +1622,9 @@ struct ParamTraits<RendererPreferences> { static_cast<RendererPreferencesSubpixelRenderingEnum>( subpixel_rendering); + if (!ReadParam(m, iter, &p->browser_handles_top_level_requests)) + return false; + return true; } static void Log(const param_type& p, std::wstring* l) { diff --git a/chrome/common/renderer_preferences.h b/chrome/common/renderer_preferences.h index 95e8ddf..8f94c0d 100644 --- a/chrome/common/renderer_preferences.h +++ b/chrome/common/renderer_preferences.h @@ -46,12 +46,16 @@ struct RendererPreferences { // Currently only used by Linux. RendererPreferencesSubpixelRenderingEnum subpixel_rendering; + // Browser wants a look at all top level requests + bool browser_handles_top_level_requests; + RendererPreferences() : can_accept_load_drops(true), should_antialias_text(true), hinting(RENDERER_PREFERENCES_HINTING_SYSTEM_DEFAULT), subpixel_rendering( - RENDERER_PREFERENCES_SUBPIXEL_RENDERING_SYSTEM_DEFAULT) { + RENDERER_PREFERENCES_SUBPIXEL_RENDERING_SYSTEM_DEFAULT), + browser_handles_top_level_requests(false) { } }; diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index f41e007..40e1344 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -198,7 +198,8 @@ RenderView::RenderView(RenderThreadBase* render_thread) delay_seconds_for_form_state_sync_(kDefaultDelaySecondsForFormStateSync), preferred_width_(0), send_preferred_width_changes_(false), - determine_page_text_after_loading_stops_(false) { + determine_page_text_after_loading_stops_(false), + last_top_level_navigation_page_id_(-1) { } RenderView::~RenderView() { @@ -1495,17 +1496,35 @@ WebNavigationPolicy RenderView::PolicyForNavigationAction( WebNavigationType type, WebNavigationPolicy default_policy, bool is_redirect) { + // Webkit is asking whether to navigate to a new URL. + // This is fine normally, except if we're showing UI from one security + // context and they're trying to navigate to a different context. + const GURL& url = request.url(); + + // If the browser is interested, then give it a chance to look at top level + // navigations + if (renderer_preferences_.browser_handles_top_level_requests && + // Only send once. + last_top_level_navigation_page_id_ != page_id_ && + // Not interested in reloads. + type != WebKit::WebNavigationTypeReload && + // Must be a top level frame. + frame->GetParent() == NULL) { + // Skip if navigation is on the same page (using '#'). + GURL frame_origin = frame->GetURL().GetOrigin(); + if (url.GetOrigin() != frame_origin || url.ref().empty()) { + last_top_level_navigation_page_id_ = page_id_; + OpenURL(webview, url, GURL(), default_policy); + return WebKit::WebNavigationPolicyIgnore; // Suppress the load here. + } + } + // A content initiated navigation may have originated from a link-click, // script, drag-n-drop operation, etc. bool is_content_initiated = NavigationState::FromDataSource(frame->GetProvisionalDataSource())-> is_content_initiated(); - // Webkit is asking whether to navigate to a new URL. - // This is fine normally, except if we're showing UI from one security - // context and they're trying to navigate to a different context. - const GURL& url = request.url(); - // We only care about navigations that are within the current tab (as opposed // to, for example, opening a new window). // But we sometimes navigate to about:blank to clear a tab, and we want to diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index 7aa408029b..7f2749e 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -815,6 +815,9 @@ class RenderView : public RenderWidget, RendererPreferences renderer_preferences_; + // page id for the last navigation sent to the browser. + int32 last_top_level_navigation_page_id_; + DISALLOW_COPY_AND_ASSIGN(RenderView); }; diff --git a/chrome/test/automation/automation_messages.h b/chrome/test/automation/automation_messages.h index 710b170..7fa2aa7 100644 --- a/chrome/test/automation/automation_messages.h +++ b/chrome/test/automation/automation_messages.h @@ -303,6 +303,7 @@ struct ExternalTabSettings { unsigned int style; bool is_off_the_record; bool load_requests_via_automation; + bool handle_top_level_requests; }; // Traits for ExternalTabSettings structure to pack/unpack. @@ -315,13 +316,15 @@ struct ParamTraits<ExternalTabSettings> { WriteParam(m, p.style); WriteParam(m, p.is_off_the_record); WriteParam(m, p.load_requests_via_automation); + WriteParam(m, p.handle_top_level_requests); } static bool Read(const Message* m, void** iter, param_type* p) { return ReadParam(m, iter, &p->parent) && ReadParam(m, iter, &p->dimensions) && ReadParam(m, iter, &p->style) && ReadParam(m, iter, &p->is_off_the_record) && - ReadParam(m, iter, &p->load_requests_via_automation); + ReadParam(m, iter, &p->load_requests_via_automation) && + ReadParam(m, iter, &p->handle_top_level_requests); } static void Log(const param_type& p, std::wstring* l) { l->append(L"("); @@ -334,6 +337,8 @@ struct ParamTraits<ExternalTabSettings> { LogParam(p.is_off_the_record, l); l->append(L", "); LogParam(p.load_requests_via_automation, l); + l->append(L", "); + LogParam(p.handle_top_level_requests, l); l->append(L")"); } }; diff --git a/chrome/test/automation/automation_messages_internal.h b/chrome/test/automation/automation_messages_internal.h index b899139..39ce010 100644 --- a/chrome/test/automation/automation_messages_internal.h +++ b/chrome/test/automation/automation_messages_internal.h @@ -960,4 +960,9 @@ IPC_BEGIN_MESSAGES(Automation) IPC_MESSAGE_ROUTED1(AutomationMsg_PrintAsync, int /* tab_handle */) + IPC_MESSAGE_ROUTED3(AutomationMsg_SetCookieAsync, + int /* tab_handle */, + GURL /* url */, + std::string /* cookie */) + IPC_END_MESSAGES(Automation) diff --git a/net/base/cookie_monster.h b/net/base/cookie_monster.h index 24db893..638a8ed 100644 --- a/net/base/cookie_monster.h +++ b/net/base/cookie_monster.h @@ -15,6 +15,7 @@ #include "base/basictypes.h" #include "base/lock.h" #include "base/time.h" +#include "net/base/cookie_store.h" class GURL; @@ -30,7 +31,7 @@ namespace net { // // TODO(deanm) Implement CookieMonster, the cookie database. // - Verify that our domain enforcement and non-dotted handling is correct -class CookieMonster { +class CookieMonster : public CookieStore { public: class ParsedCookie; class CanonicalCookie; @@ -49,18 +50,6 @@ class CookieMonster { typedef std::pair<std::string, CanonicalCookie> CookieListPair; typedef std::vector<CookieListPair> CookieList; - class CookieOptions { - public: - // Default is to exclude httponly, which means: - // - reading operations will not return httponly cookies. - // - writing operations will not write httponly cookies. - CookieOptions() : exclude_httponly_(true) {} - void set_exclude_httponly() { exclude_httponly_ = true; } - void set_include_httponly() { exclude_httponly_ = false; } - bool exclude_httponly() const { return exclude_httponly_; } - private: - bool exclude_httponly_; - }; CookieMonster(); @@ -85,35 +74,32 @@ class CookieMonster { // Parse the string with the cookie time (very forgivingly). static base::Time ParseCookieTime(const std::string& time_string); - // Set a single cookie. Expects a cookie line, like "a=1; domain=b.com". - bool SetCookie(const GURL& url, const std::string& cookie_line); - bool SetCookieWithOptions(const GURL& url, - const std::string& cookie_line, - const CookieOptions& options); - // Sets a single cookie with a specific creation date. To set a cookie with - // a creation date of Now() use SetCookie() instead (it calls this function - // internally). - bool SetCookieWithCreationTime(const GURL& url, - const std::string& cookie_line, - const base::Time& creation_time); - bool SetCookieWithCreationTimeWithOptions( - const GURL& url, - const std::string& cookie_line, - const base::Time& creation_time, - const CookieOptions& options); - // Set a vector of response cookie values for the same URL. - void SetCookies(const GURL& url, const std::vector<std::string>& cookies); - void SetCookiesWithOptions(const GURL& url, - const std::vector<std::string>& cookies, - const CookieOptions& options); - - // TODO what if the total size of all the cookies >4k, can we have a header - // that big or do we need multiple Cookie: headers? - // Simple interface, get a cookie string "a=b; c=d" for the given URL. - // It will _not_ return httponly cookies, see CookieOptions. - std::string GetCookies(const GURL& url); - std::string GetCookiesWithOptions(const GURL& url, + // CookieStore implementation. + virtual bool SetCookie(const GURL& url, const std::string& cookie_line); + virtual bool SetCookieWithOptions(const GURL& url, + const std::string& cookie_line, const CookieOptions& options); + virtual bool SetCookieWithCreationTime(const GURL& url, + const std::string& cookie_line, + const base::Time& creation_time); + virtual bool SetCookieWithCreationTimeWithOptions( + const GURL& url, + const std::string& cookie_line, + const base::Time& creation_time, + const CookieOptions& options); + virtual void SetCookies(const GURL& url, + const std::vector<std::string>& cookies); + virtual void SetCookiesWithOptions(const GURL& url, + const std::vector<std::string>& cookies, + const CookieOptions& options); + virtual std::string GetCookies(const GURL& url); + virtual std::string GetCookiesWithOptions(const GURL& url, + const CookieOptions& options); + + virtual CookieMonster* GetCookieMonster() { + return this; + } + // Returns all the cookies, for use in management UI, etc. This does not mark // the cookies as having been accessed. CookieList GetAllCookies(); diff --git a/net/base/cookie_monster_unittest.cc b/net/base/cookie_monster_unittest.cc index d650d0f..bb36585 100644 --- a/net/base/cookie_monster_unittest.cc +++ b/net/base/cookie_monster_unittest.cc @@ -528,7 +528,7 @@ TEST(CookieMonsterTest, PathTest) { TEST(CookieMonsterTest, HttpOnlyTest) { GURL url_google(kUrlGoogle); net::CookieMonster cm; - net::CookieMonster::CookieOptions options; + net::CookieOptions options; options.set_include_httponly(); // Create a httponly cookie. @@ -693,7 +693,7 @@ TEST(CookieMonsterTest, TestCookieDeletion) { TEST(CookieMonsterTest, TestCookieDeleteAll) { GURL url_google(kUrlGoogle); net::CookieMonster cm; - net::CookieMonster::CookieOptions options; + net::CookieOptions options; options.set_include_httponly(); EXPECT_TRUE(cm.SetCookie(url_google, kValidCookieLine)); diff --git a/net/base/cookie_options.h b/net/base/cookie_options.h new file mode 100644 index 0000000..e9301fe --- /dev/null +++ b/net/base/cookie_options.h @@ -0,0 +1,27 @@ +// Copyright (c) 2006-2009 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. + +// Brought to you by number 42. + +#ifndef NET_BASE_COOKIE_OPTIONS_H_ +#define NET_BASE_COOKIE_OPTIONS_H_ + +namespace net { + +class CookieOptions { + public: + // Default is to exclude httponly, which means: + // - reading operations will not return httponly cookies. + // - writing operations will not write httponly cookies. + CookieOptions() : exclude_httponly_(true) {} + void set_exclude_httponly() { exclude_httponly_ = true; } + void set_include_httponly() { exclude_httponly_ = false; } + bool exclude_httponly() const { return exclude_httponly_; } + private: + bool exclude_httponly_; +}; +} // namespace net + +#endif // NET_BASE_COOKIE_OPTIONS_H_ + diff --git a/net/base/cookie_policy.h b/net/base/cookie_policy.h index 4c01705..8efe998 100644 --- a/net/base/cookie_policy.h +++ b/net/base/cookie_policy.h @@ -38,7 +38,11 @@ class CookiePolicy { // Sets the current policy to enforce. This should be called when the user's // preferences change. - void SetType(Type type) { type_ = type; } + void set_type(Type type) { type_ = type; } + + Type type() const { + return type_; + } CookiePolicy(); diff --git a/net/base/cookie_policy_unittest.cc b/net/base/cookie_policy_unittest.cc index 982b250..22cf59e 100644 --- a/net/base/cookie_policy_unittest.cc +++ b/net/base/cookie_policy_unittest.cc @@ -37,7 +37,7 @@ TEST_F(CookiePolicyTest, DefaultPolicyTest) { TEST_F(CookiePolicyTest, AllowAllCookiesTest) { net::CookiePolicy cp; - cp.SetType(net::CookiePolicy::ALLOW_ALL_COOKIES); + cp.set_type(net::CookiePolicy::ALLOW_ALL_COOKIES); EXPECT_TRUE(cp.CanGetCookies(url_google_, url_google_)); EXPECT_TRUE(cp.CanGetCookies(url_google_, url_google_secure_)); @@ -54,7 +54,7 @@ TEST_F(CookiePolicyTest, AllowAllCookiesTest) { TEST_F(CookiePolicyTest, BlockThirdPartyCookiesTest) { net::CookiePolicy cp; - cp.SetType(net::CookiePolicy::BLOCK_THIRD_PARTY_COOKIES); + cp.set_type(net::CookiePolicy::BLOCK_THIRD_PARTY_COOKIES); EXPECT_TRUE(cp.CanGetCookies(url_google_, url_google_)); EXPECT_TRUE(cp.CanGetCookies(url_google_, url_google_secure_)); @@ -71,7 +71,7 @@ TEST_F(CookiePolicyTest, BlockThirdPartyCookiesTest) { TEST_F(CookiePolicyTest, BlockAllCookiesTest) { net::CookiePolicy cp; - cp.SetType(net::CookiePolicy::BLOCK_ALL_COOKIES); + cp.set_type(net::CookiePolicy::BLOCK_ALL_COOKIES); EXPECT_FALSE(cp.CanGetCookies(url_google_, url_google_)); EXPECT_FALSE(cp.CanGetCookies(url_google_, url_google_secure_)); diff --git a/net/base/cookie_store.h b/net/base/cookie_store.h new file mode 100644 index 0000000..3fa33b9 --- /dev/null +++ b/net/base/cookie_store.h @@ -0,0 +1,64 @@ +// Copyright (c) 2006-2009 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. + +// Brought to you by number 42. + +#ifndef NET_BASE_COOKIE_STORE_H_ +#define NET_BASE_COOKIE_STORE_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/time.h" +#include "net/base/cookie_options.h" + +class GURL; + +namespace net { + +class CookieMonster; + +// An interface for storing and retrieving cookies. Implementations need to +// be therad safe as its methods can be accessed from IO as well as UI threads. +class CookieStore { + public: + // Set a single cookie. Expects a cookie line, like "a=1; domain=b.com". + virtual bool SetCookie(const GURL& url, const std::string& cookie_line) = 0; + virtual bool SetCookieWithOptions(const GURL& url, + const std::string& cookie_line, + const CookieOptions& options) = 0; + // Sets a single cookie with a specific creation date. To set a cookie with + // a creation date of Now() use SetCookie() instead (it calls this function + // internally). + virtual bool SetCookieWithCreationTime(const GURL& url, + const std::string& cookie_line, + const base::Time& creation_time) = 0; + virtual bool SetCookieWithCreationTimeWithOptions( + const GURL& url, + const std::string& cookie_line, + const base::Time& creation_time, + const CookieOptions& options) = 0; + // Set a vector of response cookie values for the same URL. + virtual void SetCookies(const GURL& url, + const std::vector<std::string>& cookies) = 0; + virtual void SetCookiesWithOptions(const GURL& url, + const std::vector<std::string>& cookies, + const CookieOptions& options) = 0; + + // TODO what if the total size of all the cookies >4k, can we have a header + // that big or do we need multiple Cookie: headers? + // Simple interface, get a cookie string "a=b; c=d" for the given URL. + // It will _not_ return httponly cookies, see CookieOptions. + virtual std::string GetCookies(const GURL& url) = 0; + virtual std::string GetCookiesWithOptions(const GURL& url, + const CookieOptions& options) = 0; + + virtual CookieMonster* GetCookieMonster() { + return NULL; + }; +}; + +} // namespace net + +#endif // NET_BASE_COOKIE_STORE_H_ diff --git a/net/net.gyp b/net/net.gyp index 1b8fc96..f52caaf 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -48,8 +48,10 @@ 'base/connection_type_histograms.h', 'base/cookie_monster.cc', 'base/cookie_monster.h', + 'base/cookie_options.h', 'base/cookie_policy.cc', 'base/cookie_policy.h', + 'base/cookie_store.h', 'base/data_url.cc', 'base/data_url.h', 'base/directory_lister.cc', diff --git a/net/url_request/url_request_context.h b/net/url_request/url_request_context.h index 486ade0..3682112 100644 --- a/net/url_request/url_request_context.h +++ b/net/url_request/url_request_context.h @@ -13,11 +13,11 @@ #include "base/ref_counted.h" #include "base/string_util.h" #include "net/base/cookie_policy.h" +#include "net/base/cookie_store.h" #include "net/base/host_resolver.h" #include "net/ftp/ftp_auth_cache.h" namespace net { -class CookieMonster; class ForceTLSState; class FtpTransactionFactory; class HttpTransactionFactory; @@ -60,7 +60,7 @@ class URLRequestContext : } // Gets the cookie store for this context. - net::CookieMonster* cookie_store() { return cookie_store_; } + net::CookieStore* cookie_store() { return cookie_store_; } // Gets the cookie policy for this context. net::CookiePolicy* cookie_policy() { return &cookie_policy_; } @@ -96,13 +96,13 @@ class URLRequestContext : // Called for each cookie returning for the given request. A pointer to // the cookie is passed so that it can be modified. Returns true if the // cookie was not dropped (it could still be modified though). - virtual bool interceptCookie(const URLRequest* request, std::string* cookie) { + virtual bool InterceptCookie(const URLRequest* request, std::string* cookie) { return true; } // Called before adding cookies to sent requests. Allows overriding // requests to block sending of cookies. - virtual bool allowSendingCookies(const URLRequest* request) const { + virtual bool AllowSendingCookies(const URLRequest* request) const { return true; } @@ -117,7 +117,7 @@ class URLRequestContext : net::ProxyService* proxy_service_; net::HttpTransactionFactory* http_transaction_factory_; net::FtpTransactionFactory* ftp_transaction_factory_; - net::CookieMonster* cookie_store_; + net::CookieStore* cookie_store_; net::CookiePolicy cookie_policy_; net::ForceTLSState* force_tls_state_;; net::FtpAuthCache ftp_auth_cache_; diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index 20c7d88..cf2b63c 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc @@ -13,7 +13,6 @@ #include "base/rand_util.h" #include "base/string_util.h" #include "net/base/cert_status_flags.h" -#include "net/base/cookie_monster.h" #include "net/base/filter.h" #include "net/base/force_tls_state.h" #include "net/base/load_flags.h" @@ -529,7 +528,7 @@ void URLRequestHttpJob::NotifyHeadersComplete() { ctx->cookie_policy()->CanSetCookie( request_->url(), request_->first_party_for_cookies())) { FetchResponseCookies(); - net::CookieMonster::CookieOptions options; + net::CookieOptions options; options.set_include_httponly(); ctx->cookie_store()->SetCookiesWithOptions(request_->url(), response_cookies_, @@ -663,7 +662,7 @@ void URLRequestHttpJob::AddExtraHeaders() { URLRequestContext* context = request_->context(); if (context) { - if (context->allowSendingCookies(request_)) + if (context->AllowSendingCookies(request_)) request_info_.extra_headers += AssembleRequestCookies(); if (!context->accept_language().empty()) request_info_.extra_headers += "Accept-Language: " + @@ -681,7 +680,7 @@ std::string URLRequestHttpJob::AssembleRequestCookies() { if (context->cookie_store() && context->cookie_policy()->CanGetCookies( request_->url(), request_->first_party_for_cookies())) { - net::CookieMonster::CookieOptions options; + net::CookieOptions options; options.set_include_httponly(); std::string cookies = request_->context()->cookie_store()-> GetCookiesWithOptions(request_->url(), options); @@ -701,7 +700,7 @@ void URLRequestHttpJob::FetchResponseCookies() { void* iter = NULL; while (response_info_->headers->EnumerateHeader(&iter, name, &value)) - if (request_->context()->interceptCookie(request_, &value)) + if (request_->context()->InterceptCookie(request_, &value)) response_cookies_.push_back(value); } diff --git a/webkit/tools/test_shell/simple_resource_loader_bridge.cc b/webkit/tools/test_shell/simple_resource_loader_bridge.cc index a47abc30..c11bcec 100644 --- a/webkit/tools/test_shell/simple_resource_loader_bridge.cc +++ b/webkit/tools/test_shell/simple_resource_loader_bridge.cc @@ -38,7 +38,6 @@ #include "base/timer.h" #include "base/thread.h" #include "base/waitable_event.h" -#include "net/base/cookie_monster.h" #include "net/base/io_buffer.h" #include "net/base/load_flags.h" #include "net/base/net_errors.h" |