OLD | NEW |
---|---|
(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. | |
Charlie Reis
2011/12/02 22:38:11
Please do not duplicate this code, especially if i
Charlie Reis
2011/12/03 01:39:56
This still concerns me. You can file a bug and ad
Matt Perry
2011/12/03 01:46:31
Doh, sorry, I forgot about this. I'll add a TODO f
| |
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(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 we're redirecting into an extension process, we want to switch | |
100 // processes. We do this by cancelling the redirect and reissuing the request, | |
101 // so that the navigation controller properly assigns the right process to | |
102 // host the new URL. | |
103 const content::ResourceContext& resource_context = *info->context(); | |
104 ProfileIOData* io_data = | |
105 reinterpret_cast<ProfileIOData*>(resource_context.GetUserData(NULL)); | |
106 | |
107 if (CrossesExtensionExtents(io_data->GetExtensionInfoMap()->extensions(), | |
108 request_->url(), new_url)) { | |
109 int render_process_id, render_view_id; | |
110 if (ResourceDispatcherHost::RenderViewForRequest( | |
111 request_, &render_process_id, &render_view_id)) { | |
112 | |
113 GlobalRequestID global_id(info->child_id(), info->request_id()); | |
114 rdh_->MarkAsTransferredNavigation(global_id, request_); | |
115 | |
116 content::BrowserThread::PostTask( | |
117 content::BrowserThread::UI, | |
118 FROM_HERE, | |
119 base::Bind(&RequestTransferURLOnUIThread, | |
120 render_process_id, render_view_id, | |
121 new_url, GURL(request_->referrer()), CURRENT_TAB, | |
122 info->frame_id(), global_id)); | |
123 | |
124 *defer = true; | |
125 return true; | |
126 } | |
127 } | |
128 | |
129 return next_handler_->OnRequestRedirected( | |
130 request_id, new_url, response, defer); | |
131 } | |
132 | |
133 bool TransferNavigationResourceHandler::OnResponseStarted( | |
134 int request_id, content::ResourceResponse* response) { | |
135 return next_handler_->OnResponseStarted(request_id, response); | |
136 } | |
137 | |
138 bool TransferNavigationResourceHandler::OnWillStart(int request_id, | |
139 const GURL& url, | |
140 bool* defer) { | |
141 return next_handler_->OnWillStart(request_id, url, defer); | |
142 } | |
143 | |
144 bool TransferNavigationResourceHandler::OnWillRead(int request_id, | |
145 net::IOBuffer** buf, | |
146 int* buf_size, | |
147 int min_size) { | |
148 return next_handler_->OnWillRead(request_id, buf, buf_size, min_size); | |
149 } | |
150 | |
151 bool TransferNavigationResourceHandler::OnReadCompleted(int request_id, | |
152 int* bytes_read) { | |
153 return next_handler_->OnReadCompleted(request_id, bytes_read); | |
154 } | |
155 | |
156 bool TransferNavigationResourceHandler::OnResponseCompleted( | |
157 int request_id, | |
158 const net::URLRequestStatus& status, | |
159 const std::string& security_info) { | |
160 return next_handler_->OnResponseCompleted(request_id, status, security_info); | |
161 } | |
162 | |
163 void TransferNavigationResourceHandler::OnRequestClosed() { | |
164 next_handler_->OnRequestClosed(); | |
165 } | |
OLD | NEW |