diff options
author | mpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-03 02:00:48 +0000 |
---|---|---|
committer | mpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-03 02:00:48 +0000 |
commit | 4ad5d77d96dfc6f08a845b6871ecbffa64d6f6e2 (patch) | |
tree | 269f9c3132012cea865b9630082ba9009d08f8df /content/browser/tab_contents | |
parent | 143ee25a94004844d0edc8ab5c57913af5d2056f (diff) | |
download | chromium_src-4ad5d77d96dfc6f08a845b6871ecbffa64d6f6e2.zip chromium_src-4ad5d77d96dfc6f08a845b6871ecbffa64d6f6e2.tar.gz chromium_src-4ad5d77d96dfc6f08a845b6871ecbffa64d6f6e2.tar.bz2 |
Fix a bug where redirect chain gets lost on process swap.
BUG=79520
TEST=
Review URL: http://codereview.chromium.org/8669014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112847 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/tab_contents')
-rw-r--r-- | content/browser/tab_contents/navigation_controller.cc | 19 | ||||
-rw-r--r-- | content/browser/tab_contents/navigation_controller.h | 15 | ||||
-rw-r--r-- | content/browser/tab_contents/navigation_entry.h | 19 | ||||
-rw-r--r-- | content/browser/tab_contents/page_navigator.h | 6 | ||||
-rw-r--r-- | content/browser/tab_contents/tab_contents.cc | 29 | ||||
-rw-r--r-- | content/browser/tab_contents/tab_contents.h | 6 |
6 files changed, 88 insertions, 6 deletions
diff --git a/content/browser/tab_contents/navigation_controller.cc b/content/browser/tab_contents/navigation_controller.cc index 383a1ec..21582ab 100644 --- a/content/browser/tab_contents/navigation_controller.cc +++ b/content/browser/tab_contents/navigation_controller.cc @@ -497,6 +497,25 @@ void NavigationController::AddTransientEntry(NavigationEntry* entry) { tab_contents_->NotifyNavigationStateChanged(kInvalidateAll); } +void NavigationController::TransferURL( + const GURL& url, + const GURL& referrer, + content::PageTransition transition, + const std::string& extra_headers, + const GlobalRequestID& transferred_global_request_id, + bool is_renderer_initiated) { + // The user initiated a load, we don't need to reload anymore. + needs_reload_ = false; + + NavigationEntry* entry = CreateNavigationEntry(url, referrer, transition, + is_renderer_initiated, + extra_headers, + browser_context_); + entry->set_transferred_global_request_id(transferred_global_request_id); + + LoadEntry(entry); +} + void NavigationController::LoadURL( const GURL& url, const GURL& referrer, diff --git a/content/browser/tab_contents/navigation_controller.h b/content/browser/tab_contents/navigation_controller.h index 5d99842..1e8096d 100644 --- a/content/browser/tab_contents/navigation_controller.h +++ b/content/browser/tab_contents/navigation_controller.h @@ -14,6 +14,7 @@ #include "base/memory/linked_ptr.h" #include "base/time.h" #include "googleurl/src/gurl.h" +#include "content/browser/renderer_host/global_request_id.h" #include "content/browser/ssl/ssl_manager.h" #include "content/common/content_export.h" #include "content/public/browser/navigation_type.h" @@ -187,6 +188,20 @@ class CONTENT_EXPORT NavigationController { content::PageTransition type, const std::string& extra_headers); + // 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 + // navigate. + // |transferred_global_request_id| identifies the request ID of the old + // request. + void TransferURL( + const GURL& url, + const GURL& referrer, + content::PageTransition transition, + const std::string& extra_headers, + const GlobalRequestID& transferred_global_request_id, + bool is_renderer_initiated); + // Loads the current page if this NavigationController was restored from // history and the current page has not loaded yet. void LoadIfNecessary(); diff --git a/content/browser/tab_contents/navigation_entry.h b/content/browser/tab_contents/navigation_entry.h index eea3f35..8648ebb 100644 --- a/content/browser/tab_contents/navigation_entry.h +++ b/content/browser/tab_contents/navigation_entry.h @@ -10,6 +10,7 @@ #include "base/basictypes.h" #include "base/memory/ref_counted.h" +#include "content/browser/renderer_host/global_request_id.h" #include "content/common/content_export.h" #include "content/public/common/page_transition_types.h" #include "content/public/common/page_type.h" @@ -412,6 +413,15 @@ class CONTENT_EXPORT NavigationEntry { return restore_type_; } + void set_transferred_global_request_id( + const GlobalRequestID& transferred_global_request_id) { + transferred_global_request_id_ = transferred_global_request_id; + } + + GlobalRequestID transferred_global_request_id() const { + return transferred_global_request_id_; + } + private: // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING // Session/Tab restore save portions of this class so that it can be recreated @@ -451,6 +461,15 @@ class CONTENT_EXPORT NavigationEntry { // cleared to force a refresh. mutable string16 cached_display_title_; + // In case a navigation is transferred to a new RVH but the request has + // been generated in the renderer already, this identifies the old request so + // that it can be resumed. The old request is stored until the + // ResourceDispatcher receives the navigation from the renderer which + // carries this |transferred_global_request_id_| annotation. Once the request + // is transferred to the new process, this is cleared and the request + // continues as normal. + GlobalRequestID transferred_global_request_id_; + // Copy and assignment is explicitly allowed for this class. }; diff --git a/content/browser/tab_contents/page_navigator.h b/content/browser/tab_contents/page_navigator.h index 9369a7a..98bafd3 100644 --- a/content/browser/tab_contents/page_navigator.h +++ b/content/browser/tab_contents/page_navigator.h @@ -12,6 +12,7 @@ #include <string> +#include "content/browser/renderer_host/global_request_id.h" #include "content/common/content_export.h" #include "content/public/common/page_transition_types.h" #include "googleurl/src/gurl.h" @@ -26,7 +27,6 @@ struct CONTENT_EXPORT OpenURLParams { content::PageTransition transition, bool is_renderer_initiated); ~OpenURLParams(); -class TabContents; // The URL/referrer to be opened. GURL url; @@ -44,6 +44,10 @@ class TabContents; // The override encoding of the URL contents to be opened. std::string override_encoding; + // Reference to the old request id in case this is a navigation that is being + // transferred to a new renderer. + GlobalRequestID transferred_global_request_id; + private: OpenURLParams(); }; diff --git a/content/browser/tab_contents/tab_contents.cc b/content/browser/tab_contents/tab_contents.cc index 284ea26..bfdbd979 100644 --- a/content/browser/tab_contents/tab_contents.cc +++ b/content/browser/tab_contents/tab_contents.cc @@ -167,6 +167,10 @@ void MakeNavigateParams(const NavigationEntry& entry, GetNavigationType(controller.browser_context(), entry, reload_type); params->request_time = base::Time::Now(); params->extra_headers = entry.extra_headers(); + params->transferred_request_child_id = + entry.transferred_global_request_id().child_id; + params->transferred_request_request_id = + entry.transferred_global_request_id().request_id; if (delegate) delegate->AddNavigationHeaders(params->url, ¶ms->extra_headers); @@ -1750,6 +1754,17 @@ void TabContents::RequestOpenURL(const GURL& url, const GURL& referrer, WindowOpenDisposition disposition, int64 source_frame_id) { + // Delegate to RequestTransferURL because this is just the generic + // case where |old_request_id| is empty. + RequestTransferURL(url, referrer, disposition, source_frame_id, + GlobalRequestID()); +} + +void TabContents::RequestTransferURL(const GURL& url, + const GURL& referrer, + WindowOpenDisposition disposition, + int64 source_frame_id, + const GlobalRequestID& old_request_id) { TabContents* new_contents = NULL; content::PageTransition transition_type = content::PAGE_TRANSITION_LINK; if (render_manager_.web_ui()) { @@ -1761,13 +1776,17 @@ void TabContents::RequestOpenURL(const GURL& url, // want web sites to see a referrer of "chrome://blah" (and some // chrome: URLs might have search terms or other stuff we don't want to // send to the site), so we send no referrer. - new_contents = OpenURL(url, GURL(), disposition, - render_manager_.web_ui()->link_transition_type()); + OpenURLParams params(url, GURL(), disposition, + render_manager_.web_ui()->link_transition_type(), + false /* is_renderer_initiated */); + params.transferred_global_request_id = old_request_id; + new_contents = OpenURL(params); transition_type = render_manager_.web_ui()->link_transition_type(); } else { - new_contents = OpenURL(OpenURLParams( - url, referrer, disposition, content::PAGE_TRANSITION_LINK, - true /* is_renderer_initiated */)); + OpenURLParams params(url, referrer, disposition, + content::PAGE_TRANSITION_LINK, true /* is_renderer_initiated */); + params.transferred_global_request_id = old_request_id; + new_contents = OpenURL(params); } if (new_contents) { // Notify observers. diff --git a/content/browser/tab_contents/tab_contents.h b/content/browser/tab_contents/tab_contents.h index 0473b7d..46120ed 100644 --- a/content/browser/tab_contents/tab_contents.h +++ b/content/browser/tab_contents/tab_contents.h @@ -513,6 +513,12 @@ class CONTENT_EXPORT TabContents : public PageNavigator, const GURL& referrer, WindowOpenDisposition disposition, int64 source_frame_id) OVERRIDE; + virtual void RequestTransferURL( + const GURL& url, + const GURL& referrer, + WindowOpenDisposition disposition, + int64 source_frame_id, + const GlobalRequestID& transferred_global_request_id) OVERRIDE; virtual void RunJavaScriptMessage(const RenderViewHost* rvh, const string16& message, const string16& default_prompt, |