diff options
author | dfalcantara@chromium.org <dfalcantara@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-04 02:38:23 +0000 |
---|---|---|
committer | dfalcantara@chromium.org <dfalcantara@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-04 02:38:23 +0000 |
commit | 7c16976ce7a48a9cd9715c1ed87696386a743ad6 (patch) | |
tree | 0c6c6bd3f90da70c71ba2f9b23a6ff1719f09339 /content | |
parent | 9486104d19c92fd4b91d2cf358800009859f24c6 (diff) | |
download | chromium_src-7c16976ce7a48a9cd9715c1ed87696386a743ad6.zip chromium_src-7c16976ce7a48a9cd9715c1ed87696386a743ad6.tar.gz chromium_src-7c16976ce7a48a9cd9715c1ed87696386a743ad6.tar.bz2 |
[RDS] Reloads a page using the original request URL
When toggling between different versions of a website by changing user agents,
we often need to reload using an earlier URL in a redirect chain to avoid
redirects caused by user-agent detection.
* Adds a new type of reload that hooks into WebFrame::reloadWithOverrideURL,
added in https://bugs.webkit.org/show_bug.cgi?id=89788
* Changes the original request URL we were saving before to be the URL sent
back as part of WebKit's original request. This URL often differs from
the URL stored at the beginning at the redirect chain. It's sent back as
a new field when the renderer navigates.
Part of upstreaming Chrome for Android.
Internal BUG=6272286
BUG=112923
TEST=
Review URL: https://chromiumcodereview.appspot.com/10704048
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@150003 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/renderer_host/test_render_view_host.cc | 13 | ||||
-rw-r--r-- | content/browser/renderer_host/test_render_view_host.h | 14 | ||||
-rw-r--r-- | content/browser/web_contents/navigation_controller_impl.cc | 9 | ||||
-rw-r--r-- | content/browser/web_contents/navigation_controller_impl.h | 5 | ||||
-rw-r--r-- | content/browser/web_contents/navigation_controller_impl_unittest.cc | 78 | ||||
-rw-r--r-- | content/browser/web_contents/web_contents_impl.cc | 14 | ||||
-rw-r--r-- | content/common/view_message_enums.h | 3 | ||||
-rw-r--r-- | content/common/view_messages.h | 3 | ||||
-rw-r--r-- | content/public/browser/navigation_controller.h | 7 | ||||
-rw-r--r-- | content/renderer/render_view_impl.cc | 16 |
10 files changed, 151 insertions, 11 deletions
diff --git a/content/browser/renderer_host/test_render_view_host.cc b/content/browser/renderer_host/test_render_view_host.cc index 12422e9..7545a74 100644 --- a/content/browser/renderer_host/test_render_view_host.cc +++ b/content/browser/renderer_host/test_render_view_host.cc @@ -263,7 +263,19 @@ void TestRenderViewHost::SendNavigate(int page_id, const GURL& url) { void TestRenderViewHost::SendNavigateWithTransition( int page_id, const GURL& url, PageTransition transition) { OnMsgDidStartProvisionalLoadForFrame(0, true, GURL(), url); + SendNavigateWithParameters(page_id, url, transition, url); +} + +void TestRenderViewHost::SendNavigateWithOriginalRequestURL( + int page_id, const GURL& url, const GURL& original_request_url) { + OnMsgDidStartProvisionalLoadForFrame(0, true, GURL(), url); + SendNavigateWithParameters(page_id, url, PAGE_TRANSITION_LINK, + original_request_url); +} +void TestRenderViewHost::SendNavigateWithParameters( + int page_id, const GURL& url, PageTransition transition, + const GURL& original_request_url) { ViewHostMsg_FrameNavigate_Params params; params.page_id = page_id; @@ -286,6 +298,7 @@ void TestRenderViewHost::SendNavigateWithTransition( params.socket_address.set_port(80); params.was_fetched_via_proxy = simulate_fetch_via_proxy_; params.content_state = webkit_glue::CreateHistoryStateForURL(GURL(url)); + params.original_request_url = original_request_url; ViewHostMsg_FrameNavigate msg(1, params); OnMsgNavigate(msg); diff --git a/content/browser/renderer_host/test_render_view_host.h b/content/browser/renderer_host/test_render_view_host.h index d04a2a7..f3b97b6 100644 --- a/content/browser/renderer_host/test_render_view_host.h +++ b/content/browser/renderer_host/test_render_view_host.h @@ -236,6 +236,20 @@ class TestRenderViewHost virtual void SimulateWasHidden() OVERRIDE; virtual void SimulateWasShown() OVERRIDE; + // Calls OnMsgNavigate on the RenderViewHost with the given information, + // including a custom original request URL. Sets the rest of the + // parameters in the message to the "typical" values. This is a helper + // function for simulating the most common types of loads. + void SendNavigateWithOriginalRequestURL( + int page_id, const GURL& url, const GURL& original_request_url); + + // Calls OnMsgNavigate on the RenderViewHost with the given information. + // Sets the rest of the parameters in the message to the "typical" values. + // This is a helper function for simulating the most common types of loads. + void SendNavigateWithParameters( + int page_id, const GURL& url, PageTransition transition, + const GURL& original_request_url); + void TestOnMsgStartDragging(const WebDropData& drop_data); // If set, *delete_counter is incremented when this object destructs. diff --git a/content/browser/web_contents/navigation_controller_impl.cc b/content/browser/web_contents/navigation_controller_impl.cc index 557180f..881169f 100644 --- a/content/browser/web_contents/navigation_controller_impl.cc +++ b/content/browser/web_contents/navigation_controller_impl.cc @@ -243,6 +243,9 @@ void NavigationControllerImpl::Reload(bool check_for_repost) { void NavigationControllerImpl::ReloadIgnoringCache(bool check_for_repost) { ReloadInternal(check_for_repost, RELOAD_IGNORING_CACHE); } +void NavigationControllerImpl::ReloadOriginalRequestURL(bool check_for_repost) { + ReloadInternal(check_for_repost, RELOAD_ORIGINAL_REQUEST_URL); +} void NavigationControllerImpl::ReloadInternal(bool check_for_repost, ReloadType reload_type) { @@ -951,13 +954,9 @@ void NavigationControllerImpl::RendererDidNavigateToNewPage( static_cast<SiteInstanceImpl*>(web_contents_->GetSiteInstance())); new_entry->SetHasPostData(params.is_post); new_entry->SetPostID(params.post_id); + new_entry->SetOriginalRequestURL(params.original_request_url); new_entry->SetIsOverridingUserAgent(params.is_overriding_user_agent); - if (params.redirects.size() > 0) - new_entry->SetOriginalRequestURL(params.redirects[0]); - else - new_entry->SetOriginalRequestURL(params.url); - InsertOrReplaceEntry(new_entry, *did_replace_entry); } diff --git a/content/browser/web_contents/navigation_controller_impl.h b/content/browser/web_contents/navigation_controller_impl.h index a2dddb8..ac3106c 100644 --- a/content/browser/web_contents/navigation_controller_impl.h +++ b/content/browser/web_contents/navigation_controller_impl.h @@ -132,6 +132,11 @@ class CONTENT_EXPORT NavigationControllerImpl content::SiteInstance* instance, int32 page_id) const; + // Reloads the current entry using the original URL used to create it. This + // is used for cases where the user wants to refresh a page using a different + // user agent after following a redirect. + void ReloadOriginalRequestURL(bool check_for_repost); + // Transient entry ----------------------------------------------------------- // Adds an entry that is returned by GetActiveEntry(). The entry is diff --git a/content/browser/web_contents/navigation_controller_impl_unittest.cc b/content/browser/web_contents/navigation_controller_impl_unittest.cc index f2f5017..2c7069b 100644 --- a/content/browser/web_contents/navigation_controller_impl_unittest.cc +++ b/content/browser/web_contents/navigation_controller_impl_unittest.cc @@ -26,6 +26,8 @@ #include "content/public/browser/navigation_details.h" #include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_types.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/render_view_host_observer.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/test/mock_render_process_host.h" #include "content/public/test/test_notification_tracker.h" @@ -664,6 +666,82 @@ TEST_F(NavigationControllerTest, Reload_GeneratesNewPage) { EXPECT_FALSE(controller.CanGoForward()); } +class TestNavigationObserver : public content::RenderViewHostObserver { + public: + TestNavigationObserver(content::RenderViewHost* render_view_host) + : RenderViewHostObserver(render_view_host) { + } + + const GURL& navigated_url() const { + return navigated_url_; + } + + protected: + virtual void Navigate(const GURL& url) OVERRIDE { + navigated_url_ = url; + } + + private: + GURL navigated_url_; +}; + +TEST_F(NavigationControllerTest, ReloadOriginalRequestURL) { + NavigationControllerImpl& controller = controller_impl(); + TestNotificationTracker notifications; + RegisterForAllNavNotifications(¬ifications, &controller); + TestNavigationObserver observer(test_rvh()); + + const GURL original_url("http://foo1"); + const GURL final_url("http://foo2"); + + // Load up the original URL, but get redirected. + controller.LoadURL(original_url, content::Referrer(), + content::PAGE_TRANSITION_TYPED, std::string()); + EXPECT_EQ(0U, notifications.size()); + test_rvh()->SendNavigateWithOriginalRequestURL(0, final_url, original_url); + EXPECT_TRUE(notifications.Check1AndReset( + content::NOTIFICATION_NAV_ENTRY_COMMITTED)); + + // The NavigationEntry should save both the original URL and the final + // redirected URL. + EXPECT_EQ(original_url, controller.GetActiveEntry()->GetOriginalRequestURL()); + EXPECT_EQ(final_url, controller.GetActiveEntry()->GetURL()); + + // Reload using the original URL. + controller.GetActiveEntry()->SetTitle(ASCIIToUTF16("Title")); + controller.ReloadOriginalRequestURL(false); + EXPECT_EQ(0U, notifications.size()); + + // The reload is pending. The request should point to the original URL. + EXPECT_EQ(original_url, observer.navigated_url()); + EXPECT_EQ(controller.GetEntryCount(), 1); + EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0); + EXPECT_EQ(controller.GetPendingEntryIndex(), 0); + EXPECT_TRUE(controller.GetLastCommittedEntry()); + EXPECT_TRUE(controller.GetPendingEntry()); + EXPECT_FALSE(controller.CanGoBack()); + EXPECT_FALSE(controller.CanGoForward()); + + // Make sure the title has been cleared (will be redrawn just after reload). + // Avoids a stale cached title when the new page being reloaded has no title. + // See http://crbug.com/96041. + EXPECT_TRUE(controller.GetActiveEntry()->GetTitle().empty()); + + // Send that the navigation has proceeded; say it got redirected again. + test_rvh()->SendNavigate(0, final_url); + EXPECT_TRUE(notifications.Check1AndReset( + content::NOTIFICATION_NAV_ENTRY_COMMITTED)); + + // Now the reload is committed. + EXPECT_EQ(controller.GetEntryCount(), 1); + EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0); + EXPECT_EQ(controller.GetPendingEntryIndex(), -1); + EXPECT_TRUE(controller.GetLastCommittedEntry()); + EXPECT_FALSE(controller.GetPendingEntry()); + EXPECT_FALSE(controller.CanGoBack()); + EXPECT_FALSE(controller.CanGoForward()); +} + // Tests what happens when we navigate back successfully TEST_F(NavigationControllerTest, Back) { NavigationControllerImpl& controller = controller_impl(); diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 79ea7ab..1d57e35 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -189,6 +189,8 @@ ViewMsg_Navigate_Type::Value GetNavigationType( return ViewMsg_Navigate_Type::RELOAD; case NavigationControllerImpl::RELOAD_IGNORING_CACHE: return ViewMsg_Navigate_Type::RELOAD_IGNORING_CACHE; + case NavigationControllerImpl::RELOAD_ORIGINAL_REQUEST_URL: + return ViewMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL; case NavigationControllerImpl::NO_RELOAD: break; // Fall through to rest of function. } @@ -216,7 +218,6 @@ void MakeNavigateParams(const NavigationEntryImpl& entry, params->pending_history_list_offset = controller.GetIndexOfEntry(&entry); params->current_history_list_offset = controller.GetLastCommittedEntryIndex(); params->current_history_list_length = controller.GetEntryCount(); - params->url = entry.GetURL(); if (!entry.GetBaseURLForDataURL().is_empty()) { params->base_url_for_data_url = entry.GetBaseURLForDataURL(); params->history_url_for_data_url = entry.GetVirtualURL(); @@ -246,6 +247,17 @@ void MakeNavigateParams(const NavigationEntryImpl& entry, } + if (reload_type == NavigationControllerImpl::RELOAD_ORIGINAL_REQUEST_URL && + entry.GetOriginalRequestURL().is_valid() && !entry.GetHasPostData()) { + // We may have been redirected when navigating to the current URL. + // Use the URL the user originally intended to visit, if it's valid and if a + // POST wasn't involved; the latter case avoids issues with sending data to + // the wrong page. + params->url = entry.GetOriginalRequestURL(); + } else { + params->url = entry.GetURL(); + } + if (delegate) delegate->AddNavigationHeaders(params->url, ¶ms->extra_headers); } diff --git a/content/common/view_message_enums.h b/content/common/view_message_enums.h index 772dbca..59a6da11 100644 --- a/content/common/view_message_enums.h +++ b/content/common/view_message_enums.h @@ -35,6 +35,9 @@ struct ViewMsg_Navigate_Type { // Reload the page, ignoring any cache entries. RELOAD_IGNORING_CACHE, + // Reload the page using the original request URL. + RELOAD_ORIGINAL_REQUEST_URL, + // The navigation is the result of session restore and should honor the // page's cache policy while restoring form state. This is set to true if // restoring a tab/session from the previous session and the previous diff --git a/content/common/view_messages.h b/content/common/view_messages.h index a1d3c73..741a3f7 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h @@ -477,6 +477,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) + // Original request's URL. + IPC_STRUCT_MEMBER(GURL, original_request_url) + // User agent override used to navigate. IPC_STRUCT_MEMBER(bool, is_overriding_user_agent) IPC_STRUCT_END() diff --git a/content/public/browser/navigation_controller.h b/content/public/browser/navigation_controller.h index 4932ba0..a1bed25 100644 --- a/content/public/browser/navigation_controller.h +++ b/content/public/browser/navigation_controller.h @@ -31,9 +31,10 @@ struct Referrer; class NavigationController { public: enum ReloadType { - NO_RELOAD, // Normal load. - RELOAD, // Normal (cache-validating) reload. - RELOAD_IGNORING_CACHE // Reload bypassing the cache, aka shift-reload. + NO_RELOAD, // Normal load. + RELOAD, // Normal (cache-validating) reload. + RELOAD_IGNORING_CACHE, // Reload bypassing the cache (shift-reload). + RELOAD_ORIGINAL_REQUEST_URL // Reload using the original request URL. }; // Creates a navigation entry and translates the virtual url to a real one. diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 4d136cc..cfb3ada 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc @@ -361,7 +361,9 @@ static void StopAltErrorPageFetcher(WebDataSource* data_source) { static bool IsReload(const ViewMsg_Navigate_Params& params) { return params.navigation_type == ViewMsg_Navigate_Type::RELOAD || - params.navigation_type == ViewMsg_Navigate_Type::RELOAD_IGNORING_CACHE; + params.navigation_type == ViewMsg_Navigate_Type::RELOAD_IGNORING_CACHE || + params.navigation_type == + ViewMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL; } static WebReferrerPolicy GetReferrerPolicyFromRequest( @@ -1040,9 +1042,16 @@ void RenderViewImpl::OnNavigate(const ViewMsg_Navigate_Params& params) { // have history state, then we need to navigate to it, which corresponds to a // back/forward navigation event. if (is_reload) { + bool reload_original_url = + (params.navigation_type == + ViewMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL); bool ignore_cache = (params.navigation_type == ViewMsg_Navigate_Type::RELOAD_IGNORING_CACHE); - main_frame->reload(ignore_cache); + + if (reload_original_url) + main_frame->reloadWithOverrideURL(params.url, true); + else + main_frame->reload(ignore_cache); } else if (!params.state.empty()) { // We must know the page ID of the page we are navigating back to. DCHECK_NE(params.page_id, -1); @@ -1478,6 +1487,9 @@ void RenderViewImpl::UpdateURL(WebFrame* frame) { params.is_overriding_user_agent = document_state->is_overriding_user_agent(); + // Track the URL of the original request. + params.original_request_url = original_request.url(); + // Save some histogram data so we can compute the average memory used per // page load of the glyphs. UMA_HISTOGRAM_COUNTS_10000("Memory.GlyphPagesPerLoad", |