| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <string> | 5 #include <string> |
| 6 | 6 |
| 7 #include "content/browser/renderer_host/cross_site_resource_handler.h" | 7 #include "content/browser/renderer_host/cross_site_resource_handler.h" |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "content/browser/renderer_host/global_request_id.h" | 10 #include "content/browser/renderer_host/global_request_id.h" |
| 11 #include "content/browser/renderer_host/render_view_host.h" | 11 #include "content/browser/renderer_host/render_view_host.h" |
| 12 #include "content/browser/renderer_host/render_view_host_delegate.h" | 12 #include "content/browser/renderer_host/render_view_host_delegate.h" |
| 13 #include "content/browser/renderer_host/render_view_host_notification_task.h" | 13 #include "content/browser/renderer_host/render_view_host_notification_task.h" |
| 14 #include "content/browser/renderer_host/resource_dispatcher_host.h" | 14 #include "content/browser/renderer_host/resource_dispatcher_host.h" |
| 15 #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h" | 15 #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h" |
| 16 #include "content/common/resource_response.h" | 16 #include "content/public/common/resource_response.h" |
| 17 #include "net/base/io_buffer.h" | 17 #include "net/base/io_buffer.h" |
| 18 #include "net/http/http_response_headers.h" | 18 #include "net/http/http_response_headers.h" |
| 19 | 19 |
| 20 CrossSiteResourceHandler::CrossSiteResourceHandler( | 20 CrossSiteResourceHandler::CrossSiteResourceHandler( |
| 21 ResourceHandler* handler, | 21 ResourceHandler* handler, |
| 22 int render_process_host_id, | 22 int render_process_host_id, |
| 23 int render_view_id, | 23 int render_view_id, |
| 24 ResourceDispatcherHost* resource_dispatcher_host) | 24 ResourceDispatcherHost* resource_dispatcher_host) |
| 25 : next_handler_(handler), | 25 : next_handler_(handler), |
| 26 render_process_host_id_(render_process_host_id), | 26 render_process_host_id_(render_process_host_id), |
| 27 render_view_id_(render_view_id), | 27 render_view_id_(render_view_id), |
| 28 has_started_response_(false), | 28 has_started_response_(false), |
| 29 in_cross_site_transition_(false), | 29 in_cross_site_transition_(false), |
| 30 request_id_(-1), | 30 request_id_(-1), |
| 31 completed_during_transition_(false), | 31 completed_during_transition_(false), |
| 32 completed_status_(), | 32 completed_status_(), |
| 33 response_(NULL), | 33 response_(NULL), |
| 34 rdh_(resource_dispatcher_host) {} | 34 rdh_(resource_dispatcher_host) {} |
| 35 | 35 |
| 36 bool CrossSiteResourceHandler::OnUploadProgress(int request_id, | 36 bool CrossSiteResourceHandler::OnUploadProgress(int request_id, |
| 37 uint64 position, | 37 uint64 position, |
| 38 uint64 size) { | 38 uint64 size) { |
| 39 return next_handler_->OnUploadProgress(request_id, position, size); | 39 return next_handler_->OnUploadProgress(request_id, position, size); |
| 40 } | 40 } |
| 41 | 41 |
| 42 bool CrossSiteResourceHandler::OnRequestRedirected(int request_id, | 42 bool CrossSiteResourceHandler::OnRequestRedirected( |
| 43 const GURL& new_url, | 43 int request_id, |
| 44 ResourceResponse* response, | 44 const GURL& new_url, |
| 45 bool* defer) { | 45 content::ResourceResponse* response, |
| 46 bool* defer) { |
| 46 // We should not have started the transition before being redirected. | 47 // We should not have started the transition before being redirected. |
| 47 DCHECK(!in_cross_site_transition_); | 48 DCHECK(!in_cross_site_transition_); |
| 48 return next_handler_->OnRequestRedirected( | 49 return next_handler_->OnRequestRedirected( |
| 49 request_id, new_url, response, defer); | 50 request_id, new_url, response, defer); |
| 50 } | 51 } |
| 51 | 52 |
| 52 bool CrossSiteResourceHandler::OnResponseStarted(int request_id, | 53 bool CrossSiteResourceHandler::OnResponseStarted( |
| 53 ResourceResponse* response) { | 54 int request_id, |
| 55 content::ResourceResponse* response) { |
| 54 // At this point, we know that the response is safe to send back to the | 56 // At this point, we know that the response is safe to send back to the |
| 55 // renderer: it is not a download, and it has passed the SSL and safe | 57 // renderer: it is not a download, and it has passed the SSL and safe |
| 56 // browsing checks. | 58 // browsing checks. |
| 57 // We should not have already started the transition before now. | 59 // We should not have already started the transition before now. |
| 58 DCHECK(!in_cross_site_transition_); | 60 DCHECK(!in_cross_site_transition_); |
| 59 has_started_response_ = true; | 61 has_started_response_ = true; |
| 60 | 62 |
| 61 // Look up the request and associated info. | 63 // Look up the request and associated info. |
| 62 GlobalRequestID global_id(render_process_host_id_, request_id); | 64 GlobalRequestID global_id(render_process_host_id_, request_id); |
| 63 net::URLRequest* request = rdh_->GetURLRequest(global_id); | 65 net::URLRequest* request = rdh_->GetURLRequest(global_id); |
| 64 if (!request) { | 66 if (!request) { |
| 65 DLOG(WARNING) << "Request wasn't found"; | 67 DLOG(WARNING) << "Request wasn't found"; |
| 66 return false; | 68 return false; |
| 67 } | 69 } |
| 68 ResourceDispatcherHostRequestInfo* info = | 70 ResourceDispatcherHostRequestInfo* info = |
| 69 ResourceDispatcherHost::InfoForRequest(request); | 71 ResourceDispatcherHost::InfoForRequest(request); |
| 70 | 72 |
| 71 // If this is a download, just pass the response through without doing a | 73 // If this is a download, just pass the response through without doing a |
| 72 // cross-site check. The renderer will see it is a download and abort the | 74 // cross-site check. The renderer will see it is a download and abort the |
| 73 // request. | 75 // request. |
| 74 // | 76 // |
| 75 // Similarly, HTTP 204 (No Content) responses leave us showing the previous | 77 // Similarly, HTTP 204 (No Content) responses leave us showing the previous |
| 76 // page. We should allow the navigation to finish without running the unload | 78 // page. We should allow the navigation to finish without running the unload |
| 77 // handler or swapping in the pending RenderViewHost. | 79 // handler or swapping in the pending RenderViewHost. |
| 78 // | 80 // |
| 79 // In both cases, the pending RenderViewHost will stick around until the next | 81 // In both cases, the pending RenderViewHost will stick around until the next |
| 80 // cross-site navigation, since we are unable to tell when to destroy it. | 82 // cross-site navigation, since we are unable to tell when to destroy it. |
| 81 // See RenderViewHostManager::RendererAbortedProvisionalLoad. | 83 // See RenderViewHostManager::RendererAbortedProvisionalLoad. |
| 82 if (info->is_download() || | 84 if (info->is_download() || |
| 83 (response->response_head.headers && | 85 (response->headers && response->headers->response_code() == 204)) { |
| 84 response->response_head.headers->response_code() == 204)) { | |
| 85 return next_handler_->OnResponseStarted(request_id, response); | 86 return next_handler_->OnResponseStarted(request_id, response); |
| 86 } | 87 } |
| 87 | 88 |
| 88 // Tell the renderer to run the onunload event handler, and wait for the | 89 // Tell the renderer to run the onunload event handler, and wait for the |
| 89 // reply. | 90 // reply. |
| 90 StartCrossSiteTransition(request_id, response, global_id); | 91 StartCrossSiteTransition(request_id, response, global_id); |
| 91 return true; | 92 return true; |
| 92 } | 93 } |
| 93 | 94 |
| 94 bool CrossSiteResourceHandler::OnWillStart(int request_id, | 95 bool CrossSiteResourceHandler::OnWillStart(int request_id, |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 rdh_->RemovePendingRequest(render_process_host_id_, request_id_); | 184 rdh_->RemovePendingRequest(render_process_host_id_, request_id_); |
| 184 } | 185 } |
| 185 } | 186 } |
| 186 | 187 |
| 187 CrossSiteResourceHandler::~CrossSiteResourceHandler() {} | 188 CrossSiteResourceHandler::~CrossSiteResourceHandler() {} |
| 188 | 189 |
| 189 // Prepare to render the cross-site response in a new RenderViewHost, by | 190 // Prepare to render the cross-site response in a new RenderViewHost, by |
| 190 // telling the old RenderViewHost to run its onunload handler. | 191 // telling the old RenderViewHost to run its onunload handler. |
| 191 void CrossSiteResourceHandler::StartCrossSiteTransition( | 192 void CrossSiteResourceHandler::StartCrossSiteTransition( |
| 192 int request_id, | 193 int request_id, |
| 193 ResourceResponse* response, | 194 content::ResourceResponse* response, |
| 194 const GlobalRequestID& global_id) { | 195 const GlobalRequestID& global_id) { |
| 195 in_cross_site_transition_ = true; | 196 in_cross_site_transition_ = true; |
| 196 request_id_ = request_id; | 197 request_id_ = request_id; |
| 197 response_ = response; | 198 response_ = response; |
| 198 | 199 |
| 199 // Store this handler on the ExtraRequestInfo, so that RDH can call our | 200 // Store this handler on the ExtraRequestInfo, so that RDH can call our |
| 200 // ResumeResponse method when the close ACK is received. | 201 // ResumeResponse method when the close ACK is received. |
| 201 net::URLRequest* request = rdh_->GetURLRequest(global_id); | 202 net::URLRequest* request = rdh_->GetURLRequest(global_id); |
| 202 if (!request) { | 203 if (!request) { |
| 203 DLOG(WARNING) << "Cross site response for a request that wasn't found"; | 204 DLOG(WARNING) << "Cross site response for a request that wasn't found"; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 220 // starting, so that it can tell its old renderer to run its onunload | 221 // starting, so that it can tell its old renderer to run its onunload |
| 221 // handler now. We will wait to hear the corresponding ClosePage_ACK. | 222 // handler now. We will wait to hear the corresponding ClosePage_ACK. |
| 222 CallRenderViewHostRendererManagementDelegate( | 223 CallRenderViewHostRendererManagementDelegate( |
| 223 render_process_host_id_, render_view_id_, | 224 render_process_host_id_, render_view_id_, |
| 224 &RenderViewHostDelegate::RendererManagement::OnCrossSiteResponse, | 225 &RenderViewHostDelegate::RendererManagement::OnCrossSiteResponse, |
| 225 render_process_host_id_, request_id); | 226 render_process_host_id_, request_id); |
| 226 | 227 |
| 227 // TODO(creis): If the above call should fail, then we need to notify the IO | 228 // TODO(creis): If the above call should fail, then we need to notify the IO |
| 228 // thread to proceed anyway, using ResourceDispatcherHost::OnClosePageACK. | 229 // thread to proceed anyway, using ResourceDispatcherHost::OnClosePageACK. |
| 229 } | 230 } |
| OLD | NEW |