diff options
-rw-r--r-- | chrome/browser/instant/instant_loader.cc | 36 | ||||
-rw-r--r-- | chrome/browser/instant/instant_loader.h | 3 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_config.cc | 3 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_config.h | 6 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_contents.cc | 10 | ||||
-rw-r--r-- | content/browser/web_contents/navigation_controller_impl.cc | 34 | ||||
-rw-r--r-- | content/browser/web_contents/navigation_controller_impl.h | 7 | ||||
-rw-r--r-- | content/browser/web_contents/web_contents_impl.cc | 19 | ||||
-rw-r--r-- | content/browser/web_contents/web_contents_impl.h | 4 | ||||
-rw-r--r-- | content/common/view_messages.h | 7 | ||||
-rw-r--r-- | content/public/browser/navigation_controller.h | 10 | ||||
-rw-r--r-- | content/public/common/renderer_preferences.h | 6 | ||||
-rw-r--r-- | content/public/renderer/document_state.cc | 1 | ||||
-rw-r--r-- | content/public/renderer/document_state.h | 8 | ||||
-rw-r--r-- | content/renderer/render_view_impl.cc | 41 | ||||
-rw-r--r-- | content/renderer/render_view_impl.h | 3 |
16 files changed, 172 insertions, 26 deletions
diff --git a/chrome/browser/instant/instant_loader.cc b/chrome/browser/instant/instant_loader.cc index a3667bb..460f343 100644 --- a/chrome/browser/instant/instant_loader.cc +++ b/chrome/browser/instant/instant_loader.cc @@ -702,6 +702,11 @@ bool InstantLoader::Update(TabContents* tab_contents, if (created_preview_contents) CreatePreviewContents(tab_contents); + // Carry over the user agent override setting to the new entry. + content::NavigationEntry* entry = + tab_contents->web_contents()->GetController().GetActiveEntry(); + bool override_user_agent = entry && entry->GetIsOverridingUserAgent(); + if (template_url) { DCHECK(template_url_id_ == template_url->id()); if (!created_preview_contents) { @@ -733,14 +738,17 @@ bool InstantLoader::Update(TabContents* tab_contents, complete_suggested_text_.substr(user_text_.size()); } } else { - LoadInstantURL(template_url, transition_type, user_text_, verbatim); + LoadInstantURL(template_url, transition_type, user_text_, verbatim, + override_user_agent); } } else { DCHECK(template_url_id_ == 0); preview_tab_contents_delegate_->PrepareForNewLoad(); frame_load_observer_.reset(NULL); - preview_contents_->web_contents()->GetController().LoadURL( - url_, content::Referrer(), transition_type, std::string()); + + preview_contents_->web_contents()->GetController(). + LoadURLWithUserAgentOverride(url_, content::Referrer(), transition_type, + false, std::string(), override_user_agent); } return true; } @@ -864,9 +872,14 @@ void InstantLoader::MaybeLoadInstantURL(TabContents* tab_contents, if (preview_contents_.get()) return; + // Carry over the user agent override setting to the new entry. + content::NavigationEntry* entry = + tab_contents->web_contents()->GetController().GetActiveEntry(); + bool override_user_agent = entry && entry->GetIsOverridingUserAgent(); + CreatePreviewContents(tab_contents); LoadInstantURL(template_url, content::PAGE_TRANSITION_GENERATED, string16(), - true); + true, override_user_agent); } bool InstantLoader::IsNavigationPending() const { @@ -1111,6 +1124,11 @@ void InstantLoader::SetupPreviewContents(TabContents* tab_contents) { gfx::Rect tab_bounds; tab_contents->web_contents()->GetView()->GetContainerBounds(&tab_bounds); preview_contents_->web_contents()->GetView()->SizeContents(tab_bounds.size()); + + // Carry over the user agent override string. + const std::string& override = + tab_contents->web_contents()->GetUserAgentOverride(); + preview_contents_->web_contents()->SetUserAgentOverride(override); } void InstantLoader::CreatePreviewContents(TabContents* tab_contents) { @@ -1128,7 +1146,8 @@ void InstantLoader::CreatePreviewContents(TabContents* tab_contents) { void InstantLoader::LoadInstantURL(const TemplateURL* template_url, content::PageTransition transition_type, const string16& user_text, - bool verbatim) { + bool verbatim, + bool override_user_agent) { preview_tab_contents_delegate_->PrepareForNewLoad(); // Load the instant URL. We don't reflect the url we load in url() as @@ -1144,8 +1163,11 @@ void InstantLoader::LoadInstantURL(const TemplateURL* template_url, CommandLine* cl = CommandLine::ForCurrentProcess(); if (cl->HasSwitch(switches::kInstantURL)) instant_url = GURL(cl->GetSwitchValueASCII(switches::kInstantURL)); - preview_contents_->web_contents()->GetController().LoadURL( - instant_url, content::Referrer(), transition_type, std::string()); + + preview_contents_->web_contents()->GetController(). + LoadURLWithUserAgentOverride(instant_url, content::Referrer(), + transition_type, false, std::string(), override_user_agent); + RenderViewHost* host = preview_contents_->web_contents()->GetRenderViewHost(); preview_contents_->web_contents()->HideContents(); diff --git a/chrome/browser/instant/instant_loader.h b/chrome/browser/instant/instant_loader.h index bec2d1a..12b3c85 100644 --- a/chrome/browser/instant/instant_loader.h +++ b/chrome/browser/instant/instant_loader.h @@ -196,7 +196,8 @@ class InstantLoader : public content::NotificationObserver { void LoadInstantURL(const TemplateURL* template_url, content::PageTransition transition_type, const string16& user_text, - bool verbatim); + bool verbatim, + bool override_user_agent); InstantLoaderDelegate* delegate_; diff --git a/chrome/browser/prerender/prerender_config.cc b/chrome/browser/prerender/prerender_config.cc index 936c105..f409918 100644 --- a/chrome/browser/prerender/prerender_config.cc +++ b/chrome/browser/prerender/prerender_config.cc @@ -11,7 +11,8 @@ Config::Config() : max_bytes(100 * 1024 * 1024), rate_limit_enabled(true), max_age(base::TimeDelta::FromSeconds(30)), https_allowed(true), - default_tab_bounds(640, 480) { + default_tab_bounds(640, 480), + is_overriding_user_agent(false) { } } // namespace prerender diff --git a/chrome/browser/prerender/prerender_config.h b/chrome/browser/prerender/prerender_config.h index 46b83a5..97abcbd 100644 --- a/chrome/browser/prerender/prerender_config.h +++ b/chrome/browser/prerender/prerender_config.h @@ -32,6 +32,12 @@ struct Config { // The default tab bounds used as the prerenderer tab size when the active tab // cannot be accessed. gfx::Rect default_tab_bounds; + + // User agent being used as an override for the WebContents. + std::string user_agent_override; + + // Is the user agent being overridden for this NavigationEntry? + bool is_overriding_user_agent; }; } // namespace prerender diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc index ce7e59a..fa9e06d 100644 --- a/chrome/browser/prerender/prerender_contents.cc +++ b/chrome/browser/prerender/prerender_contents.cc @@ -369,12 +369,18 @@ void PrerenderContents::StartPrerendering( DCHECK(load_start_time_.is_null()); load_start_time_ = base::TimeTicks::Now(); - new_contents->GetController().LoadURL( + // Transfer over the user agent override. + new_contents->SetUserAgentOverride( + prerender_manager_->config().user_agent_override); + + new_contents->GetController().LoadURLWithUserAgentOverride( prerender_url_, referrer_, (origin_ == ORIGIN_OMNIBOX ? content::PAGE_TRANSITION_TYPED : content::PAGE_TRANSITION_LINK), - std::string()); + false, + std::string(), + prerender_manager_->config().is_overriding_user_agent); } bool PrerenderContents::GetChildId(int* child_id) const { diff --git a/content/browser/web_contents/navigation_controller_impl.cc b/content/browser/web_contents/navigation_controller_impl.cc index b24eb5b..5dad661 100644 --- a/content/browser/web_contents/navigation_controller_impl.cc +++ b/content/browser/web_contents/navigation_controller_impl.cc @@ -114,6 +114,12 @@ bool AreURLsInPageNavigation(const GURL& existing_url, const GURL& new_url) { new_url.ReplaceComponents(replacements); } +// Determines whether or not we should be carrying over a user agent override +// between two NavigationEntries. +bool ShouldKeepOverride(const content::NavigationEntry* last_entry) { + return last_entry && last_entry->GetIsOverridingUserAgent(); +} + } // namespace // NavigationControllerImpl ---------------------------------------------------- @@ -577,14 +583,9 @@ void NavigationControllerImpl::LoadURL( if (content::HandleDebugURL(url, transition)) return; - // The user initiated a load, we don't need to reload anymore. - needs_reload_ = false; - - NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry( - CreateNavigationEntry( - url, referrer, transition, false, extra_headers, browser_context_)); - - LoadEntry(entry); + bool override = ShouldKeepOverride(GetLastCommittedEntry()); + LoadURLWithUserAgentOverride(url, referrer, transition, false, extra_headers, + override); } void NavigationControllerImpl::LoadURLFromRenderer( @@ -592,12 +593,26 @@ void NavigationControllerImpl::LoadURLFromRenderer( const content::Referrer& referrer, content::PageTransition transition, const std::string& extra_headers) { + bool override = ShouldKeepOverride(GetLastCommittedEntry()); + LoadURLWithUserAgentOverride(url, referrer, transition, true, extra_headers, + override); +} + +void NavigationControllerImpl::LoadURLWithUserAgentOverride( + const GURL& url, + const content::Referrer& referrer, + content::PageTransition transition, + bool is_renderer_initiated, + const std::string& extra_headers, + bool is_overriding_user_agent) { // The user initiated a load, we don't need to reload anymore. needs_reload_ = false; NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry( CreateNavigationEntry( - url, referrer, transition, true, extra_headers, browser_context_)); + url, referrer, transition, is_renderer_initiated, extra_headers, + browser_context_)); + entry->SetIsOverridingUserAgent(is_overriding_user_agent); LoadEntry(entry); } @@ -868,6 +883,7 @@ void NavigationControllerImpl::RendererDidNavigateToNewPage( static_cast<SiteInstanceImpl*>(web_contents_->GetSiteInstance())); new_entry->SetHasPostData(params.is_post); new_entry->SetPostID(params.post_id); + new_entry->SetIsOverridingUserAgent(params.is_overriding_user_agent); if (params.redirects.size() > 0) new_entry->SetOriginalRequestURL(params.redirects[0]); diff --git a/content/browser/web_contents/navigation_controller_impl.h b/content/browser/web_contents/navigation_controller_impl.h index dfe4dd6..5053475 100644 --- a/content/browser/web_contents/navigation_controller_impl.h +++ b/content/browser/web_contents/navigation_controller_impl.h @@ -63,6 +63,13 @@ class CONTENT_EXPORT NavigationControllerImpl const content::Referrer& referrer, content::PageTransition type, const std::string& extra_headers) OVERRIDE; + virtual void LoadURLWithUserAgentOverride( + const GURL& url, + const content::Referrer& referrer, + content::PageTransition type, + bool is_renderer_initiated, + const std::string& extra_headers, + bool is_overriding_user_agent) OVERRIDE; virtual void TransferURL( const GURL& url, const content::Referrer& referrer, diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 8d21408..7cdfb2b 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -227,6 +227,7 @@ void MakeNavigateParams(const NavigationEntryImpl& entry, entry.transferred_global_request_id().child_id; params->transferred_request_request_id = entry.transferred_global_request_id().request_id; + params->is_overriding_user_agent = entry.GetIsOverridingUserAgent(); // Avoid downloading when in view-source mode. params->allow_download = !entry.IsViewSourceMode(); params->embedder_channel_name = embedder_channel_name; @@ -749,11 +750,25 @@ content::WebUI* WebContentsImpl::GetCommittedWebUI() const { } void WebContentsImpl::SetUserAgentOverride(const std::string& override) { - user_agent_override_ = override; + if (GetUserAgentOverride() == override) + return; + + renderer_preferences_.user_agent_override = override; + + // Send the new override string to the renderer. + RenderViewHost* host = GetRenderViewHost(); + if (host) + host->SyncRendererPrefs(); + + // Reload the page if a load is currently in progress to avoid having + // different parts of the page loaded using different user agents. + NavigationEntry* entry = controller_.GetActiveEntry(); + if (is_loading_ && entry != NULL && entry->GetIsOverridingUserAgent()) + controller_.ReloadIgnoringCache(true); } const std::string& WebContentsImpl::GetUserAgentOverride() const { - return user_agent_override_; + return renderer_preferences_.user_agent_override; } const string16& WebContentsImpl::GetTitle() const { diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index cc18b58..4426f1a 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h @@ -665,10 +665,6 @@ class CONTENT_EXPORT WebContentsImpl // is closed. WebContentsImpl* opener_; - // User agent to use if a NavigationEntry requires that the default user agent - // is overridden. - std::string user_agent_override_; - // Helper classes ------------------------------------------------------------ // Manages creation and swapping of render views. diff --git a/content/common/view_messages.h b/content/common/view_messages.h index 5d4d202..8ffd5ba 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h @@ -313,6 +313,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::RendererPreferences) IPC_STRUCT_TRAITS_MEMBER(caret_blink_interval) IPC_STRUCT_TRAITS_MEMBER(enable_referrers) IPC_STRUCT_TRAITS_MEMBER(default_zoom_level) + IPC_STRUCT_TRAITS_MEMBER(user_agent_override) IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_BEGIN(content::SSLStatus) @@ -452,6 +453,9 @@ IPC_STRUCT_BEGIN_WITH_PARENT(ViewHostMsg_FrameNavigate_Params, // Serialized history item state to store in the navigation entry. IPC_STRUCT_MEMBER(std::string, content_state) + + // User agent override used to navigate. + IPC_STRUCT_MEMBER(bool, is_overriding_user_agent) IPC_STRUCT_END() // This message is used for supporting popup menus on Mac OS X using native @@ -656,6 +660,9 @@ IPC_STRUCT_BEGIN(ViewMsg_Navigate_Params) // guest RenderView. The embedder_channel_name and embedder_container_id // together uniquely identify a browser plugin instance. IPC_STRUCT_MEMBER(int, embedder_container_id) + + // Whether or not the user agent override string should be used. + IPC_STRUCT_MEMBER(bool, is_overriding_user_agent) IPC_STRUCT_END() IPC_STRUCT_BEGIN(ViewMsg_New_Params) diff --git a/content/public/browser/navigation_controller.h b/content/public/browser/navigation_controller.h index c9c1a01..06e7806 100644 --- a/content/public/browser/navigation_controller.h +++ b/content/public/browser/navigation_controller.h @@ -167,6 +167,16 @@ class NavigationController { PageTransition type, const std::string& extra_headers) = 0; + // Same as LoadURL, but allows overriding the user agent of the + // NavigationEntry before it loads. + // TODO(dfalcantara): Consolidate the LoadURL* interfaces. + virtual void LoadURLWithUserAgentOverride(const GURL& url, + const Referrer& referrer, + PageTransition type, + bool is_renderer_initiated, + const std::string& extra_headers, + bool is_overriding_user_agent) = 0; + // Behaves like LoadURL() and LoadURLFromRenderer() but marks the new // navigation as being transferred from one RVH to another. In this case the // browser can recycle the old request once the new renderer wants to diff --git a/content/public/common/renderer_preferences.h b/content/public/common/renderer_preferences.h index ac7e58c..abb3328 100644 --- a/content/public/common/renderer_preferences.h +++ b/content/public/common/renderer_preferences.h @@ -13,6 +13,8 @@ #define CONTENT_PUBLIC_COMMON_RENDERER_PREFERENCES_H_ #pragma once +#include <string> + #include "content/common/content_export.h" #include "third_party/skia/include/core/SkColor.h" @@ -89,6 +91,10 @@ struct CONTENT_EXPORT RendererPreferences { // Default page zoom level. double default_zoom_level; + + // The user agent given to WebKit when it requests one and the user agent is + // being overridden for the current navigation. + std::string user_agent_override; }; } // namespace content diff --git a/content/public/renderer/document_state.cc b/content/public/renderer/document_state.cc index 1fcb604..9e71d7b 100644 --- a/content/public/renderer/document_state.cc +++ b/content/public/renderer/document_state.cc @@ -19,6 +19,7 @@ DocumentState::DocumentState() was_alternate_protocol_available_(false), was_fetched_via_proxy_(false), use_error_page_(false), + is_overriding_user_agent_(false), was_prefetcher_(false), was_referred_by_prefetcher_(false), load_type_(UNDEFINED_LOAD), diff --git a/content/public/renderer/document_state.h b/content/public/renderer/document_state.h index d39a893..94d10b4 100644 --- a/content/public/renderer/document_state.h +++ b/content/public/renderer/document_state.h @@ -192,6 +192,12 @@ class DocumentState : public WebKit::WebDataSource::ExtraData { use_error_page_ = use_error_page; } + // True if the user agent was overridden for this page. + bool is_overriding_user_agent() const { return is_overriding_user_agent_; } + void set_is_overriding_user_agent(bool state) { + is_overriding_user_agent_ = state; + } + void set_was_prefetcher(bool value) { was_prefetcher_ = value; } bool was_prefetcher() const { return was_prefetcher_; } @@ -273,6 +279,8 @@ class DocumentState : public WebKit::WebDataSource::ExtraData { bool use_error_page_; + bool is_overriding_user_agent_; + // A prefetcher is a page that contains link rel=prefetch elements. bool was_prefetcher_; bool was_referred_by_prefetcher_; diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 16837b9..8236194 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc @@ -1451,6 +1451,10 @@ void RenderViewImpl::UpdateURL(WebFrame* frame) { params.post_id = ExtractPostId(item); } + // Send the user agent override back. + params.is_overriding_user_agent = + document_state->is_overriding_user_agent(); + // Save some histogram data so we can compute the average memory used per // page load of the glyphs. UMA_HISTOGRAM_COUNTS_10000("Memory.GlyphPagesPerLoad", @@ -2736,6 +2740,17 @@ void RenderViewImpl::didCreateDataSource(WebFrame* frame, WebDataSource* ds) { PopulateDocumentStateFromPending(document_state); } + // Carry over the user agent override flag, if it exists. + if (content_initiated && webview() && webview()->mainFrame() && + webview()->mainFrame()->dataSource()) { + DocumentState* old_document_state = + DocumentState::FromDataSource(webview()->mainFrame()->dataSource()); + if (old_document_state) { + document_state->set_is_overriding_user_agent( + old_document_state->is_overriding_user_agent()); + } + } + // The rest of RenderView assumes that a WebDataSource will always have a // non-null NavigationState. if (content_initiated) @@ -2819,6 +2834,7 @@ void RenderViewImpl::PopulateDocumentStateFromPending( document_state->set_load_type(DocumentState::NORMAL_LOAD); document_state->set_referrer_policy(params.referrer.policy); + document_state->set_is_overriding_user_agent(params.is_overriding_user_agent); } NavigationState* RenderViewImpl::CreateNavigationStateFromPending() { @@ -3714,6 +3730,31 @@ void RenderViewImpl::willOpenSocketStream( SocketStreamHandleData::AddToHandle(handle, routing_id_); } +WebKit::WebString RenderViewImpl::userAgentOverride( + WebKit::WebFrame* frame, + const WebKit::WebURL& url) { + if (!webview() || !webview()->mainFrame() || + renderer_preferences_.user_agent_override.empty()) { + return WebKit::WebString(); + } + + // If we're in the middle of committing a load, the data source we need + // will still be provisional. + WebFrame* main_frame = webview()->mainFrame(); + WebDataSource* data_source = NULL; + if (main_frame->provisionalDataSource()) + data_source = main_frame->provisionalDataSource(); + else + data_source = main_frame->dataSource(); + + DocumentState* document_state = + data_source ? DocumentState::FromDataSource(data_source) : NULL; + if (document_state && document_state->is_overriding_user_agent()) + return WebString::fromUTF8(renderer_preferences_.user_agent_override); + else + return WebKit::WebString(); +} + // WebKit::WebPageSerializerClient implementation ------------------------------ void RenderViewImpl::didSerializeDataForFrame( diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h index 8468942..f8daf58 100644 --- a/content/renderer/render_view_impl.h +++ b/content/renderer/render_view_impl.h @@ -651,6 +651,9 @@ class RenderViewImpl : public RenderWidget, WebKit::WebFrame* source, WebKit::WebSecurityOrigin targetOrigin, WebKit::WebDOMMessageEvent event) OVERRIDE; + virtual WebKit::WebString userAgentOverride( + WebKit::WebFrame* frame, + const WebKit::WebURL& url) OVERRIDE; // WebKit::WebPageSerializerClient implementation ---------------------------- |