summaryrefslogtreecommitdiffstats
path: root/content/browser/tab_contents
diff options
context:
space:
mode:
authormpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-03 02:00:48 +0000
committermpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-03 02:00:48 +0000
commit4ad5d77d96dfc6f08a845b6871ecbffa64d6f6e2 (patch)
tree269f9c3132012cea865b9630082ba9009d08f8df /content/browser/tab_contents
parent143ee25a94004844d0edc8ab5c57913af5d2056f (diff)
downloadchromium_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.cc19
-rw-r--r--content/browser/tab_contents/navigation_controller.h15
-rw-r--r--content/browser/tab_contents/navigation_entry.h19
-rw-r--r--content/browser/tab_contents/page_navigator.h6
-rw-r--r--content/browser/tab_contents/tab_contents.cc29
-rw-r--r--content/browser/tab_contents/tab_contents.h6
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, &params->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,