Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2185)

Unified Diff: chrome/browser/renderer_host/transfer_navigation_resource_handler.cc

Issue 8669014: Fix a bug where redirect chain gets lost on process swap. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: conditional disabling Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/renderer_host/transfer_navigation_resource_handler.h ('k') | chrome/browser/ui/browser.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/renderer_host/transfer_navigation_resource_handler.cc
diff --git a/chrome/browser/renderer_host/transfer_navigation_resource_handler.cc b/chrome/browser/renderer_host/transfer_navigation_resource_handler.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f678ad2e2d434dc7d6c91fcee2df206575fab771
--- /dev/null
+++ b/chrome/browser/renderer_host/transfer_navigation_resource_handler.cc
@@ -0,0 +1,167 @@
+// Copyright (c) 2011 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/renderer_host/transfer_navigation_resource_handler.h"
+
+#include "base/bind.h"
+#include "chrome/browser/profiles/profile_io_data.h"
+#include "chrome/browser/extensions/extension_info_map.h"
+#include "content/browser/renderer_host/render_view_host.h"
+#include "content/browser/renderer_host/render_view_host_delegate.h"
+#include "content/browser/renderer_host/resource_dispatcher_host.h"
+#include "content/browser/renderer_host/resource_dispatcher_host_request_info.h"
+
+namespace {
+
+// This code is borrowed from ChromeContentRendererClient. We want to mimic
+// the logic used by the renderer.
+const Extension* GetNonBookmarkAppExtension(
+ const ExtensionSet& extensions, const GURL& url) {
+ // Exclude bookmark apps, which do not use the app process model.
+ const Extension* extension = extensions.GetByURL(ExtensionURLInfo(url));
+ if (extension && extension->from_bookmark())
+ extension = NULL;
+ return extension;
+}
+
+bool CrossesExtensionExtents(
+ const ExtensionSet& extensions,
+ const GURL& old_url,
+ const GURL& new_url) {
+ const Extension* new_url_extension = GetNonBookmarkAppExtension(extensions,
+ new_url);
+ const Extension* old_url_extension = GetNonBookmarkAppExtension(extensions,
+ old_url);
+
+ // TODO(creis): Temporary workaround for crbug.com/59285: Only return true if
+ // we would enter an extension app's extent from a non-app, or if we leave an
+ // extension with no web extent. We avoid swapping processes to exit a hosted
+ // app for now, since we do not yet support postMessage calls from outside the
+ // app back into it (e.g., as in Facebook OAuth 2.0).
+ bool old_url_is_hosted_app = old_url_extension &&
+ !old_url_extension->web_extent().is_empty();
+ if (old_url_is_hosted_app)
+ return false;
+
+ return old_url_extension != new_url_extension;
+}
+
+void RequestTransferURLOnUIThread(int render_process_id,
+ int render_view_id,
+ GURL new_url,
+ GURL referrer,
+ WindowOpenDisposition window_open_disposition,
+ int64 frame_id,
+ const GlobalRequestID& request_id) {
+ RenderViewHost* rvh = RenderViewHost::FromID(render_process_id,
+ render_view_id);
+ if (!rvh)
+ return;
+
+ RenderViewHostDelegate* delegate = rvh->delegate();
+ if (!delegate)
+ return;
+
+ delegate->RequestTransferURL(new_url, referrer, window_open_disposition,
+ frame_id, request_id);
+}
+
+} // namespace
+
+TransferNavigationResourceHandler::TransferNavigationResourceHandler(
+ ResourceHandler* handler,
+ ResourceDispatcherHost* resource_dispatcher_host,
+ net::URLRequest* request)
+ : next_handler_(handler),
+ rdh_(resource_dispatcher_host),
+ request_(request) {
+}
+
+TransferNavigationResourceHandler::~TransferNavigationResourceHandler() {
+}
+
+bool TransferNavigationResourceHandler::OnUploadProgress(int request_id,
+ uint64 position,
+ uint64 size) {
+ return next_handler_->OnUploadProgress(request_id, position, size);
+}
+
+bool TransferNavigationResourceHandler::OnRequestRedirected(
+ int request_id,
+ const GURL& new_url,
+ content::ResourceResponse* response,
+ bool* defer) {
+
+ ResourceDispatcherHostRequestInfo* info =
+ ResourceDispatcherHost::InfoForRequest(request_);
+
+ // If a toplevel request is redirecting across extension extents, we want to
+ // switch processes. We do this by deferring the redirect and resuming the
+ // request once the navigation controller properly assigns the right process
+ // to host the new URL.
+ // TODO(mpcomplete): handle for cases other than extensions (e.g. WebUI).
+ const content::ResourceContext& resource_context = *info->context();
+ ProfileIOData* io_data =
+ reinterpret_cast<ProfileIOData*>(resource_context.GetUserData(NULL));
+
+ if (info->resource_type() == ResourceType::MAIN_FRAME &&
+ CrossesExtensionExtents(io_data->GetExtensionInfoMap()->extensions(),
+ request_->url(), new_url)) {
+ int render_process_id, render_view_id;
+ if (ResourceDispatcherHost::RenderViewForRequest(
+ request_, &render_process_id, &render_view_id)) {
+
+ GlobalRequestID global_id(info->child_id(), info->request_id());
+ rdh_->MarkAsTransferredNavigation(global_id, request_);
+
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&RequestTransferURLOnUIThread,
+ render_process_id, render_view_id,
+ new_url, GURL(request_->referrer()), CURRENT_TAB,
+ info->frame_id(), global_id));
+
+ *defer = true;
+ return true;
+ }
+ }
+
+ return next_handler_->OnRequestRedirected(
+ request_id, new_url, response, defer);
+}
+
+bool TransferNavigationResourceHandler::OnResponseStarted(
+ int request_id, content::ResourceResponse* response) {
+ return next_handler_->OnResponseStarted(request_id, response);
+}
+
+bool TransferNavigationResourceHandler::OnWillStart(int request_id,
+ const GURL& url,
+ bool* defer) {
+ return next_handler_->OnWillStart(request_id, url, defer);
+}
+
+bool TransferNavigationResourceHandler::OnWillRead(int request_id,
+ net::IOBuffer** buf,
+ int* buf_size,
+ int min_size) {
+ return next_handler_->OnWillRead(request_id, buf, buf_size, min_size);
+}
+
+bool TransferNavigationResourceHandler::OnReadCompleted(int request_id,
+ int* bytes_read) {
+ return next_handler_->OnReadCompleted(request_id, bytes_read);
+}
+
+bool TransferNavigationResourceHandler::OnResponseCompleted(
+ int request_id,
+ const net::URLRequestStatus& status,
+ const std::string& security_info) {
+ return next_handler_->OnResponseCompleted(request_id, status, security_info);
+}
+
+void TransferNavigationResourceHandler::OnRequestClosed() {
+ next_handler_->OnRequestClosed();
+}
« no previous file with comments | « chrome/browser/renderer_host/transfer_navigation_resource_handler.h ('k') | chrome/browser/ui/browser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698