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

Unified Diff: content/browser/loader/cross_site_resource_handler.cc

Issue 15476003: Move TransferNavigationResourceThrottle into CrossSiteResourceHandler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove null check on cross_site_handler(). Created 7 years, 3 months 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
Index: content/browser/loader/cross_site_resource_handler.cc
diff --git a/content/browser/loader/cross_site_resource_handler.cc b/content/browser/loader/cross_site_resource_handler.cc
index 90fe84a6b50515deaf3ed80b25fceffccb3ffe9c..6bac75adde6b8246e7748a8876d22973ab1c9988 100644
--- a/content/browser/loader/cross_site_resource_handler.cc
+++ b/content/browser/loader/cross_site_resource_handler.cc
@@ -9,14 +9,17 @@
#include "base/bind.h"
#include "base/logging.h"
#include "content/browser/cross_site_request_manager.h"
+#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/browser/resource_controller.h"
#include "content/public/common/resource_response.h"
#include "net/http/http_response_headers.h"
+#include "net/url_request/url_request.h"
namespace content {
@@ -24,13 +27,21 @@ namespace {
void OnCrossSiteResponseHelper(int render_process_id,
int render_view_id,
- int request_id) {
+ const GlobalRequestID& global_request_id,
+ bool is_transfer,
+ const GURL& transfer_url,
+ const Referrer& referrer,
+ int64 frame_id) {
RenderViewHostImpl* rvh = RenderViewHostImpl::FromID(render_process_id,
render_view_id);
- if (rvh && rvh->GetDelegate()->GetRendererManagementDelegate()) {
- rvh->GetDelegate()->GetRendererManagementDelegate()->OnCrossSiteResponse(
- rvh, GlobalRequestID(render_process_id, request_id));
- }
+ if (!rvh)
+ return;
+ RenderViewHostDelegate* delegate = rvh->GetDelegate();
+ if (!delegate || !delegate->GetRendererManagementDelegate())
+ return;
+
+ delegate->GetRendererManagementDelegate()->OnCrossSiteResponse(
+ rvh, global_request_id, is_transfer, transfer_url, referrer, frame_id);
}
} // namespace
@@ -77,10 +88,16 @@ bool CrossSiteResourceHandler::OnResponseStarted(
ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request_);
- // A swap may no longer be needed if we transferred back into the original
- // process due to a redirect.
- bool swap_needed = CrossSiteRequestManager::GetInstance()->
- HasPendingCrossSiteRequest(info->GetChildID(), info->GetRouteID());
+ // We will need to swap processes if either (1) a redirect that requires a
+ // transfer occurred before we got here, or (2) a pending cross-site request
+ // was already in progress. Note that a swap may no longer be needed if we
+ // transferred back into the original process due to a redirect.
+ bool should_transfer =
+ GetContentClient()->browser()->ShouldSwapProcessesForRedirect(
+ info->GetContext(), request_->original_url(), request_->url());
+ bool swap_needed = should_transfer ||
+ CrossSiteRequestManager::GetInstance()->
+ HasPendingCrossSiteRequest(info->GetChildID(), info->GetRouteID());
// If this is a download, just pass the response through without doing a
// cross-site check. The renderer will see it is a download and abort the
@@ -90,8 +107,9 @@ bool CrossSiteResourceHandler::OnResponseStarted(
// page. We should allow the navigation to finish without running the unload
// handler or swapping in the pending RenderViewHost.
//
- // In both cases, the pending RenderViewHost will stick around until the next
- // cross-site navigation, since we are unable to tell when to destroy it.
+ // In both cases, any pending RenderViewHost (if one was created for this
+ // navigation) will stick around until the next cross-site navigation, since
+ // we are unable to tell when to destroy it.
// See RenderViewHostManager::RendererAbortedProvisionalLoad.
if (!swap_needed || info->is_download() ||
(response->head.headers.get() &&
@@ -99,8 +117,10 @@ bool CrossSiteResourceHandler::OnResponseStarted(
return next_handler_->OnResponseStarted(request_id, response, defer);
}
- // Tell the renderer to run the onunload event handler.
- StartCrossSiteTransition(request_id, response);
+ // Now that we know a swap is needed and we have something to commit, we
+ // pause to let the UI thread run the unload handler of the previous page
+ // and set up a transfer if needed.
+ StartCrossSiteTransition(request_id, response, should_transfer);
// Defer loading until after the onunload event handler has run.
did_defer_ = *defer = true;
@@ -119,19 +139,24 @@ bool CrossSiteResourceHandler::OnResponseCompleted(
const net::URLRequestStatus& status,
const std::string& security_info) {
if (!in_cross_site_transition_) {
+ ResourceRequestInfoImpl* info =
+ ResourceRequestInfoImpl::ForRequest(request_);
+ // If we've already completed the transition, or we're canceling the
+ // request, or an error occurred with no cross-process navigation in
+ // progress, then we should just pass this through.
if (has_started_response_ ||
- status.status() != net::URLRequestStatus::FAILED) {
- // We've already completed the transition or we're canceling the request,
- // so just pass it through.
+ status.status() != net::URLRequestStatus::FAILED ||
+ !CrossSiteRequestManager::GetInstance()->HasPendingCrossSiteRequest(
+ info->GetChildID(), info->GetRouteID())) {
return next_handler_->OnResponseCompleted(request_id, status,
security_info);
}
- // An error occured, we should wait now for the cross-site transition,
+ // An error occurred. We should wait now for the cross-process transition,
// so that the error message (e.g., 404) can be displayed to the user.
// Also continue with the logic below to remember that we completed
// during the cross-site transition.
- StartCrossSiteTransition(request_id, NULL);
+ StartCrossSiteTransition(request_id, NULL, false);
}
// We have to buffer the call until after the transition completes.
@@ -186,19 +211,35 @@ void CrossSiteResourceHandler::ResumeResponse() {
// telling the old RenderViewHost to run its onunload handler.
void CrossSiteResourceHandler::StartCrossSiteTransition(
int request_id,
- ResourceResponse* response) {
+ ResourceResponse* response,
+ bool should_transfer) {
in_cross_site_transition_ = true;
response_ = response;
// Store this handler on the ExtraRequestInfo, so that RDH can call our
- // ResumeResponse method when the close ACK is received.
+ // ResumeResponse method when we are ready to resume.
ResourceRequestInfoImpl* info =
ResourceRequestInfoImpl::ForRequest(request_);
info->set_cross_site_handler(this);
+ DCHECK_EQ(request_id, info->GetRequestID());
+ GlobalRequestID global_id(info->GetChildID(), info->GetRequestID());
+
// Tell the contents responsible for this request that a cross-site response
// is starting, so that it can tell its old renderer to run its onunload
- // handler now. We will wait to hear the corresponding ClosePage_ACK.
+ // handler now. We will wait until the unload is finished and (if a transfer
+ // is needed) for the new renderer's request to arrive.
+ GURL transfer_url;
+ Referrer referrer;
+ int frame_id = -1;
+ if (should_transfer) {
+ transfer_url = request_->url();
+ referrer = Referrer(GURL(request_->referrer()), info->GetReferrerPolicy());
+ frame_id = info->GetFrameID();
+
+ ResourceDispatcherHostImpl::Get()->MarkAsTransferredNavigation(
+ global_id, transfer_url);
+ }
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
@@ -206,10 +247,11 @@ void CrossSiteResourceHandler::StartCrossSiteTransition(
&OnCrossSiteResponseHelper,
info->GetChildID(),
info->GetRouteID(),
- request_id));
-
- // TODO(creis): If the above call should fail, then we need to notify the IO
- // thread to proceed anyway, using ResourceDispatcherHost::OnClosePageACK.
+ global_id,
+ should_transfer,
+ transfer_url,
+ referrer,
+ frame_id));
}
void CrossSiteResourceHandler::ResumeIfDeferred() {
« no previous file with comments | « content/browser/loader/cross_site_resource_handler.h ('k') | content/browser/loader/resource_dispatcher_host_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698