Chromium Code Reviews| 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 |