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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/renderer_host/transfer_navigation_resource_handler.h"
6
7 #include "base/bind.h"
8 #include "chrome/browser/profiles/profile_io_data.h"
9 #include "chrome/browser/extensions/extension_info_map.h"
10 #include "content/browser/renderer_host/render_view_host.h"
11 #include "content/browser/renderer_host/render_view_host_delegate.h"
12 #include "content/browser/renderer_host/resource_dispatcher_host.h"
13 #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h"
14
15 namespace {
16
17 // This code is borrowed from ChromeContentRendererClient. We want to mimic
18 // the logic used by the renderer.
19 const Extension* GetNonBookmarkAppExtension(
20 const ExtensionSet& extensions, const GURL& url) {
21 // Exclude bookmark apps, which do not use the app process model.
22 const Extension* extension = extensions.GetByURL(ExtensionURLInfo(url));
23 if (extension && extension->from_bookmark())
24 extension = NULL;
25 return extension;
26 }
27
28 bool CrossesExtensionExtents(
29 const ExtensionSet& extensions,
30 const GURL& old_url,
31 const GURL& new_url) {
32 const Extension* new_url_extension = GetNonBookmarkAppExtension(extensions,
33 new_url);
34 const Extension* old_url_extension = GetNonBookmarkAppExtension(extensions,
35 old_url);
36
37 // TODO(creis): Temporary workaround for crbug.com/59285: Only return true if
38 // we would enter an extension app's extent from a non-app, or if we leave an
39 // extension with no web extent. We avoid swapping processes to exit a hosted
40 // app for now, since we do not yet support postMessage calls from outside the
41 // app back into it (e.g., as in Facebook OAuth 2.0).
42 bool old_url_is_hosted_app = old_url_extension &&
43 !old_url_extension->web_extent().is_empty();
44 if (old_url_is_hosted_app)
45 return false;
46
47 return old_url_extension != new_url_extension;
48 }
49
50 void RequestTransferURLOnUIThread(int render_process_id,
51 int render_view_id,
52 GURL new_url,
53 GURL referrer,
54 WindowOpenDisposition window_open_disposition,
55 int64 frame_id,
56 const GlobalRequestID& request_id) {
57 RenderViewHost* rvh = RenderViewHost::FromID(render_process_id,
58 render_view_id);
59 if (!rvh)
60 return;
61
62 RenderViewHostDelegate* delegate = rvh->delegate();
63 if (!delegate)
64 return;
65
66 delegate->RequestTransferURL(new_url, referrer, window_open_disposition,
67 frame_id, request_id);
68 }
69
70 } // namespace
71
72 TransferNavigationResourceHandler::TransferNavigationResourceHandler(
73 ResourceHandler* handler,
74 ResourceDispatcherHost* resource_dispatcher_host,
75 net::URLRequest* request)
76 : next_handler_(handler),
77 rdh_(resource_dispatcher_host),
78 request_(request) {
79 }
80
81 TransferNavigationResourceHandler::~TransferNavigationResourceHandler() {
82 }
83
84 bool TransferNavigationResourceHandler::OnUploadProgress(int request_id,
85 uint64 position,
86 uint64 size) {
87 return next_handler_->OnUploadProgress(request_id, position, size);
88 }
89
90 bool TransferNavigationResourceHandler::OnRequestRedirected(
91 int request_id,
92 const GURL& new_url,
93 content::ResourceResponse* response,
94 bool* defer) {
95
96 ResourceDispatcherHostRequestInfo* info =
97 ResourceDispatcherHost::InfoForRequest(request_);
98
99 // If a toplevel request is redirecting across extension extents, we want to
100 // switch processes. We do this by deferring the redirect and resuming the
101 // request once the navigation controller properly assigns the right process
102 // to host the new URL.
103 // TODO(mpcomplete): handle for cases other than extensions (e.g. WebUI).
104 const content::ResourceContext& resource_context = *info->context();
105 ProfileIOData* io_data =
106 reinterpret_cast<ProfileIOData*>(resource_context.GetUserData(NULL));
107
108 if (info->resource_type() == ResourceType::MAIN_FRAME &&
109 CrossesExtensionExtents(io_data->GetExtensionInfoMap()->extensions(),
110 request_->url(), new_url)) {
111 int render_process_id, render_view_id;
112 if (ResourceDispatcherHost::RenderViewForRequest(
113 request_, &render_process_id, &render_view_id)) {
114
115 GlobalRequestID global_id(info->child_id(), info->request_id());
116 rdh_->MarkAsTransferredNavigation(global_id, request_);
117
118 content::BrowserThread::PostTask(
119 content::BrowserThread::UI,
120 FROM_HERE,
121 base::Bind(&RequestTransferURLOnUIThread,
122 render_process_id, render_view_id,
123 new_url, GURL(request_->referrer()), CURRENT_TAB,
124 info->frame_id(), global_id));
125
126 *defer = true;
127 return true;
128 }
129 }
130
131 return next_handler_->OnRequestRedirected(
132 request_id, new_url, response, defer);
133 }
134
135 bool TransferNavigationResourceHandler::OnResponseStarted(
136 int request_id, content::ResourceResponse* response) {
137 return next_handler_->OnResponseStarted(request_id, response);
138 }
139
140 bool TransferNavigationResourceHandler::OnWillStart(int request_id,
141 const GURL& url,
142 bool* defer) {
143 return next_handler_->OnWillStart(request_id, url, defer);
144 }
145
146 bool TransferNavigationResourceHandler::OnWillRead(int request_id,
147 net::IOBuffer** buf,
148 int* buf_size,
149 int min_size) {
150 return next_handler_->OnWillRead(request_id, buf, buf_size, min_size);
151 }
152
153 bool TransferNavigationResourceHandler::OnReadCompleted(int request_id,
154 int* bytes_read) {
155 return next_handler_->OnReadCompleted(request_id, bytes_read);
156 }
157
158 bool TransferNavigationResourceHandler::OnResponseCompleted(
159 int request_id,
160 const net::URLRequestStatus& status,
161 const std::string& security_info) {
162 return next_handler_->OnResponseCompleted(request_id, status, security_info);
163 }
164
165 void TransferNavigationResourceHandler::OnRequestClosed() {
166 next_handler_->OnRequestClosed();
167 }
OLDNEW
« 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