| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 int render_process_host_id, | 40 int render_process_host_id, |
| 41 int render_view_id, | 41 int render_view_id, |
| 42 ResourceDispatcherHostImpl* rdh) | 42 ResourceDispatcherHostImpl* rdh) |
| 43 : LayeredResourceHandler(next_handler.Pass()), | 43 : LayeredResourceHandler(next_handler.Pass()), |
| 44 render_process_host_id_(render_process_host_id), | 44 render_process_host_id_(render_process_host_id), |
| 45 render_view_id_(render_view_id), | 45 render_view_id_(render_view_id), |
| 46 has_started_response_(false), | 46 has_started_response_(false), |
| 47 in_cross_site_transition_(false), | 47 in_cross_site_transition_(false), |
| 48 request_id_(-1), | 48 request_id_(-1), |
| 49 completed_during_transition_(false), | 49 completed_during_transition_(false), |
| 50 did_defer_(false), |
| 50 completed_status_(), | 51 completed_status_(), |
| 51 response_(NULL), | 52 response_(NULL), |
| 52 rdh_(rdh) { | 53 rdh_(rdh) { |
| 53 } | 54 } |
| 54 | 55 |
| 55 CrossSiteResourceHandler::~CrossSiteResourceHandler() { | 56 CrossSiteResourceHandler::~CrossSiteResourceHandler() { |
| 56 } | 57 } |
| 57 | 58 |
| 58 bool CrossSiteResourceHandler::OnRequestRedirected( | 59 bool CrossSiteResourceHandler::OnRequestRedirected( |
| 59 int request_id, | 60 int request_id, |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 if (!request) { | 164 if (!request) { |
| 164 DLOG(WARNING) << "Resuming a request that wasn't found"; | 165 DLOG(WARNING) << "Resuming a request that wasn't found"; |
| 165 return; | 166 return; |
| 166 } | 167 } |
| 167 | 168 |
| 168 if (has_started_response_) { | 169 if (has_started_response_) { |
| 169 // Send OnResponseStarted to the new renderer. | 170 // Send OnResponseStarted to the new renderer. |
| 170 DCHECK(response_); | 171 DCHECK(response_); |
| 171 bool defer = false; | 172 bool defer = false; |
| 172 if (!next_handler_->OnResponseStarted(request_id_, response_, &defer)) { | 173 if (!next_handler_->OnResponseStarted(request_id_, response_, &defer)) { |
| 173 rdh_->CancelRequest(render_process_host_id_, request_id_, false); | 174 controller()->Cancel(); |
| 174 } else if (!defer) { | 175 } else if (!defer) { |
| 175 // Unpause the request to resume reading. Any further reads will be | 176 // Unpause the request to resume reading. Any further reads will be |
| 176 // directed toward the new renderer. | 177 // directed toward the new renderer. |
| 177 rdh_->ResumeDeferredRequest(render_process_host_id_, request_id_); | 178 ResumeIfDeferred(); |
| 178 } | 179 } |
| 179 } | 180 } |
| 180 | 181 |
| 181 // Remove ourselves from the ExtraRequestInfo. | 182 // Remove ourselves from the ExtraRequestInfo. |
| 182 ResourceRequestInfoImpl* info = | 183 ResourceRequestInfoImpl* info = |
| 183 ResourceRequestInfoImpl::ForRequest(request); | 184 ResourceRequestInfoImpl::ForRequest(request); |
| 184 info->set_cross_site_handler(NULL); | 185 info->set_cross_site_handler(NULL); |
| 185 | 186 |
| 186 // If the response completed during the transition, notify the next | 187 // If the response completed during the transition, notify the next |
| 187 // event handler. | 188 // event handler. |
| 188 if (completed_during_transition_) { | 189 if (completed_during_transition_) { |
| 189 next_handler_->OnResponseCompleted(request_id_, completed_status_, | 190 if (next_handler_->OnResponseCompleted(request_id_, completed_status_, |
| 190 completed_security_info_); | 191 completed_security_info_)) { |
| 191 // TODO(darin): OnResponseCompleted can return false to defer | 192 ResumeIfDeferred(); |
| 192 // RemovePendingRequest. | 193 } |
| 193 rdh_->RemovePendingRequest(render_process_host_id_, request_id_); | |
| 194 } | 194 } |
| 195 } | 195 } |
| 196 | 196 |
| 197 // Prepare to render the cross-site response in a new RenderViewHost, by | 197 // Prepare to render the cross-site response in a new RenderViewHost, by |
| 198 // telling the old RenderViewHost to run its onunload handler. | 198 // telling the old RenderViewHost to run its onunload handler. |
| 199 void CrossSiteResourceHandler::StartCrossSiteTransition( | 199 void CrossSiteResourceHandler::StartCrossSiteTransition( |
| 200 int request_id, | 200 int request_id, |
| 201 ResourceResponse* response, | 201 ResourceResponse* response, |
| 202 const GlobalRequestID& global_id, | 202 const GlobalRequestID& global_id, |
| 203 bool* defer) { | 203 bool* defer) { |
| 204 in_cross_site_transition_ = true; | 204 in_cross_site_transition_ = true; |
| 205 request_id_ = request_id; | 205 request_id_ = request_id; |
| 206 response_ = response; | 206 response_ = response; |
| 207 | 207 |
| 208 // Store this handler on the ExtraRequestInfo, so that RDH can call our | 208 // Store this handler on the ExtraRequestInfo, so that RDH can call our |
| 209 // ResumeResponse method when the close ACK is received. | 209 // ResumeResponse method when the close ACK is received. |
| 210 net::URLRequest* request = rdh_->GetURLRequest(global_id); | 210 net::URLRequest* request = rdh_->GetURLRequest(global_id); |
| 211 if (!request) { | 211 if (!request) { |
| 212 DLOG(WARNING) << "Cross site response for a request that wasn't found"; | 212 DLOG(WARNING) << "Cross site response for a request that wasn't found"; |
| 213 return; | 213 return; |
| 214 } | 214 } |
| 215 ResourceRequestInfoImpl* info = | 215 ResourceRequestInfoImpl* info = |
| 216 ResourceRequestInfoImpl::ForRequest(request); | 216 ResourceRequestInfoImpl::ForRequest(request); |
| 217 info->set_cross_site_handler(this); | 217 info->set_cross_site_handler(this); |
| 218 | 218 |
| 219 if (has_started_response_) { | 219 if (has_started_response_) { |
| 220 // Defer the request until the old renderer is finished and the new | 220 // Defer the request until the old renderer is finished and the new |
| 221 // renderer is ready. | 221 // renderer is ready. |
| 222 *defer = true; | 222 did_defer_ = *defer = true; |
| 223 } | 223 } |
| 224 // If our OnResponseStarted wasn't called, then we're being called by | 224 // If our OnResponseStarted wasn't called, then we're being called by |
| 225 // OnResponseCompleted after a failure. We don't need to pause, because | 225 // OnResponseCompleted after a failure. We don't need to pause, because |
| 226 // there will be no reads. | 226 // there will be no reads. |
| 227 | 227 |
| 228 // Tell the contents responsible for this request that a cross-site response | 228 // Tell the contents responsible for this request that a cross-site response |
| 229 // is starting, so that it can tell its old renderer to run its onunload | 229 // is starting, so that it can tell its old renderer to run its onunload |
| 230 // handler now. We will wait to hear the corresponding ClosePage_ACK. | 230 // handler now. We will wait to hear the corresponding ClosePage_ACK. |
| 231 BrowserThread::PostTask( | 231 BrowserThread::PostTask( |
| 232 BrowserThread::UI, | 232 BrowserThread::UI, |
| 233 FROM_HERE, | 233 FROM_HERE, |
| 234 base::Bind( | 234 base::Bind( |
| 235 &OnCrossSiteResponseHelper, | 235 &OnCrossSiteResponseHelper, |
| 236 render_process_host_id_, | 236 render_process_host_id_, |
| 237 render_view_id_, | 237 render_view_id_, |
| 238 request_id)); | 238 request_id)); |
| 239 | 239 |
| 240 // TODO(creis): If the above call should fail, then we need to notify the IO | 240 // TODO(creis): If the above call should fail, then we need to notify the IO |
| 241 // thread to proceed anyway, using ResourceDispatcherHost::OnClosePageACK. | 241 // thread to proceed anyway, using ResourceDispatcherHost::OnClosePageACK. |
| 242 } | 242 } |
| 243 | 243 |
| 244 void CrossSiteResourceHandler::ResumeIfDeferred() { |
| 245 if (did_defer_) { |
| 246 did_defer_ = false; |
| 247 controller()->Resume(); |
| 248 } |
| 249 } |
| 250 |
| 244 } // namespace content | 251 } // namespace content |
| OLD | NEW |