| 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 "content/browser/renderer_host/resource_loader.h" | 5 #include "content/browser/renderer_host/resource_loader_impl.h" |
| 6 | 6 |
| 7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
| 8 #include "base/time.h" | 8 #include "base/time.h" |
| 9 #include "content/browser/child_process_security_policy_impl.h" | 9 #include "content/browser/child_process_security_policy_impl.h" |
| 10 #include "content/browser/renderer_host/doomed_resource_handler.h" | 10 #include "content/browser/renderer_host/doomed_resource_handler.h" |
| 11 #include "content/browser/renderer_host/resource_loader_delegate.h" | 11 #include "content/browser/renderer_host/resource_loader_impl_delegate.h" |
| 12 #include "content/browser/renderer_host/resource_request_info_impl.h" | 12 #include "content/browser/renderer_host/resource_request_info_impl.h" |
| 13 #include "content/browser/ssl/ssl_client_auth_handler.h" | 13 #include "content/browser/ssl/ssl_client_auth_handler.h" |
| 14 #include "content/browser/ssl/ssl_manager.h" | 14 #include "content/browser/ssl/ssl_manager.h" |
| 15 #include "content/common/ssl_status_serialization.h" | 15 #include "content/common/ssl_status_serialization.h" |
| 16 #include "content/public/browser/cert_store.h" | 16 #include "content/public/browser/cert_store.h" |
| 17 #include "content/public/browser/resource_dispatcher_host_login_delegate.h" | 17 #include "content/public/browser/resource_dispatcher_host_login_delegate.h" |
| 18 #include "content/public/common/resource_response.h" | 18 #include "content/public/common/resource_response.h" |
| 19 #include "net/base/load_flags.h" | 19 #include "net/base/load_flags.h" |
| 20 #include "net/http/http_response_headers.h" | 20 #include "net/http/http_response_headers.h" |
| 21 #include "webkit/appcache/appcache_interceptor.h" | 21 #include "webkit/appcache/appcache_interceptor.h" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 43 response->head.was_fetched_via_proxy = request->was_fetched_via_proxy(); | 43 response->head.was_fetched_via_proxy = request->was_fetched_via_proxy(); |
| 44 response->head.socket_address = request->GetSocketAddress(); | 44 response->head.socket_address = request->GetSocketAddress(); |
| 45 appcache::AppCacheInterceptor::GetExtraResponseInfo( | 45 appcache::AppCacheInterceptor::GetExtraResponseInfo( |
| 46 request, | 46 request, |
| 47 &response->head.appcache_id, | 47 &response->head.appcache_id, |
| 48 &response->head.appcache_manifest_url); | 48 &response->head.appcache_manifest_url); |
| 49 } | 49 } |
| 50 | 50 |
| 51 } // namespace | 51 } // namespace |
| 52 | 52 |
| 53 ResourceLoader::ResourceLoader(scoped_ptr<net::URLRequest> request, | 53 ResourceLoaderImpl::ResourceLoaderImpl(scoped_ptr<net::URLRequest> request, |
| 54 scoped_ptr<ResourceHandler> handler, | 54 scoped_ptr<ResourceHandler> handler, |
| 55 ResourceLoaderDelegate* delegate) | 55 ResourceLoaderImplDelegate* delegate) |
| 56 : deferred_stage_(DEFERRED_NONE), | 56 : deferred_stage_(DEFERRED_NONE), |
| 57 request_(request.Pass()), | 57 request_(request.Pass()), |
| 58 handler_(handler.Pass()), | 58 handler_(handler.Pass()), |
| 59 delegate_(delegate), | 59 delegate_(delegate), |
| 60 last_upload_position_(0), | 60 last_upload_position_(0), |
| 61 waiting_for_upload_progress_ack_(false), | 61 waiting_for_upload_progress_ack_(false), |
| 62 is_transferring_(false), | 62 is_transferring_(false), |
| 63 weak_ptr_factory_(this) { | 63 weak_ptr_factory_(this) { |
| 64 request_->set_delegate(this); | 64 request_->set_delegate(this); |
| 65 handler_->SetController(this); | 65 handler_->SetController(this); |
| 66 } | 66 } |
| 67 | 67 |
| 68 ResourceLoader::~ResourceLoader() { | 68 ResourceLoaderImpl::~ResourceLoaderImpl() { |
| 69 if (login_delegate_) | 69 if (login_delegate_) |
| 70 login_delegate_->OnRequestCancelled(); | 70 login_delegate_->OnRequestCancelled(); |
| 71 if (ssl_client_auth_handler_) | 71 if (ssl_client_auth_handler_) |
| 72 ssl_client_auth_handler_->OnRequestCancelled(); | 72 ssl_client_auth_handler_->OnRequestCancelled(); |
| 73 | 73 |
| 74 // Run ResourceHandler destructor before we tear-down the rest of our state | 74 // Run ResourceHandler destructor before we tear-down the rest of our state |
| 75 // as the ResourceHandler may want to inspect the URLRequest and other state. | 75 // as the ResourceHandler may want to inspect the URLRequest and other state. |
| 76 handler_.reset(); | 76 handler_.reset(); |
| 77 } | 77 } |
| 78 | 78 |
| 79 void ResourceLoader::StartRequest() { | 79 void ResourceLoaderImpl::StartRequest() { |
| 80 if (delegate_->HandleExternalProtocol(this, request_->url())) { | 80 if (delegate_->HandleExternalProtocol(this, request_->url())) { |
| 81 CancelAndIgnore(); | 81 CancelAndIgnore(); |
| 82 return; | 82 return; |
| 83 } | 83 } |
| 84 | 84 |
| 85 // Give the handler a chance to delay the URLRequest from being started. | 85 // Give the handler a chance to delay the URLRequest from being started. |
| 86 bool defer_start = false; | 86 bool defer_start = false; |
| 87 if (!handler_->OnWillStart(GetRequestInfo()->GetRequestID(), request_->url(), | 87 if (!handler_->OnWillStart(GetRequestInfo()->GetRequestID(), request_->url(), |
| 88 &defer_start)) { | 88 &defer_start)) { |
| 89 Cancel(); | 89 Cancel(); |
| 90 return; | 90 return; |
| 91 } | 91 } |
| 92 | 92 |
| 93 if (defer_start) { | 93 if (defer_start) { |
| 94 deferred_stage_ = DEFERRED_START; | 94 deferred_stage_ = DEFERRED_START; |
| 95 } else { | 95 } else { |
| 96 StartRequestInternal(); | 96 StartRequestInternal(); |
| 97 } | 97 } |
| 98 } | 98 } |
| 99 | 99 |
| 100 void ResourceLoader::CancelRequest(bool from_renderer) { | 100 void ResourceLoaderImpl::CancelRequest(bool from_renderer) { |
| 101 CancelRequestInternal(net::ERR_ABORTED, from_renderer); | 101 CancelRequestInternal(net::ERR_ABORTED, from_renderer); |
| 102 } | 102 } |
| 103 | 103 |
| 104 void ResourceLoader::CancelAndIgnore() { | 104 void ResourceLoaderImpl::CancelAndIgnore() { |
| 105 ResourceRequestInfoImpl* info = GetRequestInfo(); | 105 ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 106 info->set_was_ignored_by_handler(true); | 106 info->set_was_ignored_by_handler(true); |
| 107 CancelRequest(false); | 107 CancelRequest(false); |
| 108 } | 108 } |
| 109 | 109 |
| 110 void ResourceLoader::CancelWithError(int error_code) { | 110 void ResourceLoaderImpl::CancelWithError(int error_code) { |
| 111 CancelRequestInternal(error_code, false); | 111 CancelRequestInternal(error_code, false); |
| 112 } | 112 } |
| 113 | 113 |
| 114 void ResourceLoader::ReportUploadProgress() { | 114 void ResourceLoaderImpl::ReportUploadProgress() { |
| 115 ResourceRequestInfoImpl* info = GetRequestInfo(); | 115 ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 116 | 116 |
| 117 if (waiting_for_upload_progress_ack_) | 117 if (waiting_for_upload_progress_ack_) |
| 118 return; // Send one progress event at a time. | 118 return; // Send one progress event at a time. |
| 119 | 119 |
| 120 net::UploadProgress progress = request_->GetUploadProgress(); | 120 net::UploadProgress progress = request_->GetUploadProgress(); |
| 121 if (!progress.size()) | 121 if (!progress.size()) |
| 122 return; // Nothing to upload. | 122 return; // Nothing to upload. |
| 123 | 123 |
| 124 if (progress.position() == last_upload_position_) | 124 if (progress.position() == last_upload_position_) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 139 if (request_->load_flags() & net::LOAD_ENABLE_UPLOAD_PROGRESS) { | 139 if (request_->load_flags() & net::LOAD_ENABLE_UPLOAD_PROGRESS) { |
| 140 handler_->OnUploadProgress( | 140 handler_->OnUploadProgress( |
| 141 info->GetRequestID(), progress.position(), progress.size()); | 141 info->GetRequestID(), progress.position(), progress.size()); |
| 142 waiting_for_upload_progress_ack_ = true; | 142 waiting_for_upload_progress_ack_ = true; |
| 143 } | 143 } |
| 144 last_upload_ticks_ = TimeTicks::Now(); | 144 last_upload_ticks_ = TimeTicks::Now(); |
| 145 last_upload_position_ = progress.position(); | 145 last_upload_position_ = progress.position(); |
| 146 } | 146 } |
| 147 } | 147 } |
| 148 | 148 |
| 149 void ResourceLoader::MarkAsTransferring() { | 149 void ResourceLoaderImpl::MarkAsTransferring() { |
| 150 is_transferring_ = true; | 150 is_transferring_ = true; |
| 151 | 151 |
| 152 // When an URLRequest is transferred to a new RenderViewHost, its | 152 // When an URLRequest is transferred to a new RenderViewHost, its |
| 153 // ResourceHandler should not receive any notifications because it may depend | 153 // ResourceHandler should not receive any notifications because it may depend |
| 154 // on the state of the old RVH. We set a ResourceHandler that only allows | 154 // on the state of the old RVH. We set a ResourceHandler that only allows |
| 155 // canceling requests, because on shutdown of the RDH all pending requests | 155 // canceling requests, because on shutdown of the RDH all pending requests |
| 156 // are canceled. The RVH of requests that are being transferred may be gone | 156 // are canceled. The RVH of requests that are being transferred may be gone |
| 157 // by that time. In CompleteTransfer, the ResoureHandlers are substituted | 157 // by that time. In CompleteTransfer, the ResoureHandlers are substituted |
| 158 // again. | 158 // again. |
| 159 handler_.reset(new DoomedResourceHandler(handler_.Pass())); | 159 handler_.reset(new DoomedResourceHandler(handler_.Pass())); |
| 160 } | 160 } |
| 161 | 161 |
| 162 void ResourceLoader::WillCompleteTransfer() { | 162 void ResourceLoaderImpl::WillCompleteTransfer() { |
| 163 handler_.reset(); | 163 handler_.reset(); |
| 164 } | 164 } |
| 165 | 165 |
| 166 void ResourceLoader::CompleteTransfer(scoped_ptr<ResourceHandler> new_handler) { | 166 void ResourceLoaderImpl::CompleteTransfer( |
| 167 scoped_ptr<ResourceHandler> new_handler) { |
| 167 DCHECK_EQ(DEFERRED_REDIRECT, deferred_stage_); | 168 DCHECK_EQ(DEFERRED_REDIRECT, deferred_stage_); |
| 168 DCHECK(!handler_.get()); | 169 DCHECK(!handler_.get()); |
| 169 | 170 |
| 170 handler_ = new_handler.Pass(); | 171 handler_ = new_handler.Pass(); |
| 171 handler_->SetController(this); | 172 handler_->SetController(this); |
| 172 is_transferring_ = false; | 173 is_transferring_ = false; |
| 173 | 174 |
| 174 Resume(); | 175 Resume(); |
| 175 } | 176 } |
| 176 | 177 |
| 177 ResourceRequestInfoImpl* ResourceLoader::GetRequestInfo() { | 178 ResourceRequestInfoImpl* ResourceLoaderImpl::GetRequestInfo() { |
| 178 return ResourceRequestInfoImpl::ForRequest(request_.get()); | 179 return ResourceRequestInfoImpl::ForRequest(request_.get()); |
| 179 } | 180 } |
| 180 | 181 |
| 181 void ResourceLoader::ClearLoginDelegate() { | 182 void ResourceLoaderImpl::ClearLoginDelegate() { |
| 182 login_delegate_ = NULL; | 183 login_delegate_ = NULL; |
| 183 } | 184 } |
| 184 | 185 |
| 185 void ResourceLoader::ClearSSLClientAuthHandler() { | 186 void ResourceLoaderImpl::ClearSSLClientAuthHandler() { |
| 186 ssl_client_auth_handler_ = NULL; | 187 ssl_client_auth_handler_ = NULL; |
| 187 } | 188 } |
| 188 | 189 |
| 189 void ResourceLoader::OnUploadProgressACK() { | 190 void ResourceLoaderImpl::OnUploadProgressACK() { |
| 190 waiting_for_upload_progress_ack_ = false; | 191 waiting_for_upload_progress_ack_ = false; |
| 191 } | 192 } |
| 192 | 193 |
| 193 void ResourceLoader::OnReceivedRedirect(net::URLRequest* unused, | 194 void ResourceLoaderImpl::OnReceivedRedirect(net::URLRequest* unused, |
| 194 const GURL& new_url, | 195 const GURL& new_url, |
| 195 bool* defer) { | 196 bool* defer) { |
| 196 DCHECK_EQ(request_.get(), unused); | 197 DCHECK_EQ(request_.get(), unused); |
| 197 | 198 |
| 198 VLOG(1) << "OnReceivedRedirect: " << request_->url().spec(); | 199 VLOG(1) << "OnReceivedRedirect: " << request_->url().spec(); |
| 199 DCHECK(request_->status().is_success()); | 200 DCHECK(request_->status().is_success()); |
| 200 | 201 |
| 201 ResourceRequestInfoImpl* info = GetRequestInfo(); | 202 ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 202 | 203 |
| 203 if (info->process_type() != PROCESS_TYPE_PLUGIN && | 204 if (info->process_type() != PROCESS_TYPE_PLUGIN && |
| 204 !ChildProcessSecurityPolicyImpl::GetInstance()-> | 205 !ChildProcessSecurityPolicyImpl::GetInstance()-> |
| 205 CanRequestURL(info->GetChildID(), new_url)) { | 206 CanRequestURL(info->GetChildID(), new_url)) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 223 PopulateResourceResponse(request_.get(), response); | 224 PopulateResourceResponse(request_.get(), response); |
| 224 | 225 |
| 225 if (!handler_->OnRequestRedirected(info->GetRequestID(), new_url, response, | 226 if (!handler_->OnRequestRedirected(info->GetRequestID(), new_url, response, |
| 226 defer)) { | 227 defer)) { |
| 227 Cancel(); | 228 Cancel(); |
| 228 } else if (*defer) { | 229 } else if (*defer) { |
| 229 deferred_stage_ = DEFERRED_REDIRECT; // Follow redirect when resumed. | 230 deferred_stage_ = DEFERRED_REDIRECT; // Follow redirect when resumed. |
| 230 } | 231 } |
| 231 } | 232 } |
| 232 | 233 |
| 233 void ResourceLoader::OnAuthRequired(net::URLRequest* unused, | 234 void ResourceLoaderImpl::OnAuthRequired(net::URLRequest* unused, |
| 234 net::AuthChallengeInfo* auth_info) { | 235 net::AuthChallengeInfo* auth_info) { |
| 235 DCHECK_EQ(request_.get(), unused); | 236 DCHECK_EQ(request_.get(), unused); |
| 236 | 237 |
| 237 if (request_->load_flags() & net::LOAD_DO_NOT_PROMPT_FOR_LOGIN) { | 238 if (request_->load_flags() & net::LOAD_DO_NOT_PROMPT_FOR_LOGIN) { |
| 238 request_->CancelAuth(); | 239 request_->CancelAuth(); |
| 239 return; | 240 return; |
| 240 } | 241 } |
| 241 | 242 |
| 242 if (!delegate_->AcceptAuthRequest(this, auth_info)) { | 243 if (!delegate_->AcceptAuthRequest(this, auth_info)) { |
| 243 request_->CancelAuth(); | 244 request_->CancelAuth(); |
| 244 return; | 245 return; |
| 245 } | 246 } |
| 246 | 247 |
| 247 // Create a login dialog on the UI thread to get authentication data, or pull | 248 // Create a login dialog on the UI thread to get authentication data, or pull |
| 248 // from cache and continue on the IO thread. | 249 // from cache and continue on the IO thread. |
| 249 | 250 |
| 250 DCHECK(!login_delegate_) << | 251 DCHECK(!login_delegate_) << |
| 251 "OnAuthRequired called with login_delegate pending"; | 252 "OnAuthRequired called with login_delegate pending"; |
| 252 login_delegate_ = delegate_->CreateLoginDelegate(this, auth_info); | 253 login_delegate_ = delegate_->CreateLoginDelegate(this, auth_info); |
| 253 if (!login_delegate_) | 254 if (!login_delegate_) |
| 254 request_->CancelAuth(); | 255 request_->CancelAuth(); |
| 255 } | 256 } |
| 256 | 257 |
| 257 void ResourceLoader::OnCertificateRequested( | 258 void ResourceLoaderImpl::OnCertificateRequested( |
| 258 net::URLRequest* unused, | 259 net::URLRequest* unused, |
| 259 net::SSLCertRequestInfo* cert_info) { | 260 net::SSLCertRequestInfo* cert_info) { |
| 260 DCHECK_EQ(request_.get(), unused); | 261 DCHECK_EQ(request_.get(), unused); |
| 261 | 262 |
| 262 if (!delegate_->AcceptSSLClientCertificateRequest(this, cert_info)) { | 263 if (!delegate_->AcceptSSLClientCertificateRequest(this, cert_info)) { |
| 263 request_->Cancel(); | 264 request_->Cancel(); |
| 264 return; | 265 return; |
| 265 } | 266 } |
| 266 | 267 |
| 267 if (cert_info->client_certs.empty()) { | 268 if (cert_info->client_certs.empty()) { |
| 268 // No need to query the user if there are no certs to choose from. | 269 // No need to query the user if there are no certs to choose from. |
| 269 request_->ContinueWithCertificate(NULL); | 270 request_->ContinueWithCertificate(NULL); |
| 270 return; | 271 return; |
| 271 } | 272 } |
| 272 | 273 |
| 273 DCHECK(!ssl_client_auth_handler_) << | 274 DCHECK(!ssl_client_auth_handler_) << |
| 274 "OnCertificateRequested called with ssl_client_auth_handler pending"; | 275 "OnCertificateRequested called with ssl_client_auth_handler pending"; |
| 275 ssl_client_auth_handler_ = new SSLClientAuthHandler(request_.get(), | 276 ssl_client_auth_handler_ = new SSLClientAuthHandler(request_.get(), |
| 276 cert_info); | 277 cert_info); |
| 277 ssl_client_auth_handler_->SelectCertificate(); | 278 ssl_client_auth_handler_->SelectCertificate(); |
| 278 } | 279 } |
| 279 | 280 |
| 280 void ResourceLoader::OnSSLCertificateError(net::URLRequest* request, | 281 void ResourceLoaderImpl::OnSSLCertificateError(net::URLRequest* request, |
| 281 const net::SSLInfo& ssl_info, | 282 const net::SSLInfo& ssl_info, |
| 282 bool fatal) { | 283 bool fatal) { |
| 283 ResourceRequestInfoImpl* info = GetRequestInfo(); | 284 ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 284 | 285 |
| 285 int render_process_id; | 286 int render_process_id; |
| 286 int render_view_id; | 287 int render_view_id; |
| 287 if (!info->GetAssociatedRenderView(&render_process_id, &render_view_id)) | 288 if (!info->GetAssociatedRenderView(&render_process_id, &render_view_id)) |
| 288 NOTREACHED(); | 289 NOTREACHED(); |
| 289 | 290 |
| 290 SSLManager::OnSSLCertificateError( | 291 SSLManager::OnSSLCertificateError( |
| 291 weak_ptr_factory_.GetWeakPtr(), | 292 weak_ptr_factory_.GetWeakPtr(), |
| 292 info->GetGlobalRequestID(), | 293 info->GetGlobalRequestID(), |
| 293 info->GetResourceType(), | 294 info->GetResourceType(), |
| 294 request_->url(), | 295 request_->url(), |
| 295 render_process_id, | 296 render_process_id, |
| 296 render_view_id, | 297 render_view_id, |
| 297 ssl_info, | 298 ssl_info, |
| 298 fatal); | 299 fatal); |
| 299 } | 300 } |
| 300 | 301 |
| 301 void ResourceLoader::OnResponseStarted(net::URLRequest* unused) { | 302 void ResourceLoaderImpl::OnResponseStarted(net::URLRequest* unused) { |
| 302 DCHECK_EQ(request_.get(), unused); | 303 DCHECK_EQ(request_.get(), unused); |
| 303 | 304 |
| 304 VLOG(1) << "OnResponseStarted: " << request_->url().spec(); | 305 VLOG(1) << "OnResponseStarted: " << request_->url().spec(); |
| 305 | 306 |
| 306 if (!request_->status().is_success()) { | 307 if (!request_->status().is_success()) { |
| 307 ResponseCompleted(); | 308 ResponseCompleted(); |
| 308 return; | 309 return; |
| 309 } | 310 } |
| 310 | 311 |
| 311 // We want to send a final upload progress message prior to sending the | 312 // We want to send a final upload progress message prior to sending the |
| 312 // response complete message even if we're waiting for an ack to to a | 313 // response complete message even if we're waiting for an ack to to a |
| 313 // previous upload progress message. | 314 // previous upload progress message. |
| 314 waiting_for_upload_progress_ack_ = false; | 315 waiting_for_upload_progress_ack_ = false; |
| 315 ReportUploadProgress(); | 316 ReportUploadProgress(); |
| 316 | 317 |
| 317 CompleteResponseStarted(); | 318 CompleteResponseStarted(); |
| 318 | 319 |
| 319 if (is_deferred()) | 320 if (is_deferred()) |
| 320 return; | 321 return; |
| 321 | 322 |
| 322 if (request_->status().is_success()) { | 323 if (request_->status().is_success()) { |
| 323 StartReading(false); // Read the first chunk. | 324 StartReading(false); // Read the first chunk. |
| 324 } else { | 325 } else { |
| 325 ResponseCompleted(); | 326 ResponseCompleted(); |
| 326 } | 327 } |
| 327 } | 328 } |
| 328 | 329 |
| 329 void ResourceLoader::OnReadCompleted(net::URLRequest* unused, int bytes_read) { | 330 void ResourceLoaderImpl::OnReadCompleted(net::URLRequest* unused, |
| 331 int bytes_read) { |
| 330 DCHECK_EQ(request_.get(), unused); | 332 DCHECK_EQ(request_.get(), unused); |
| 331 VLOG(1) << "OnReadCompleted: \"" << request_->url().spec() << "\"" | 333 VLOG(1) << "OnReadCompleted: \"" << request_->url().spec() << "\"" |
| 332 << " bytes_read = " << bytes_read; | 334 << " bytes_read = " << bytes_read; |
| 333 | 335 |
| 334 // bytes_read == -1 always implies an error. | 336 // bytes_read == -1 always implies an error. |
| 335 if (bytes_read == -1 || !request_->status().is_success()) { | 337 if (bytes_read == -1 || !request_->status().is_success()) { |
| 336 ResponseCompleted(); | 338 ResponseCompleted(); |
| 337 return; | 339 return; |
| 338 } | 340 } |
| 339 | 341 |
| 340 CompleteRead(bytes_read); | 342 CompleteRead(bytes_read); |
| 341 | 343 |
| 342 if (is_deferred()) | 344 if (is_deferred()) |
| 343 return; | 345 return; |
| 344 | 346 |
| 345 if (request_->status().is_success() && bytes_read > 0) { | 347 if (request_->status().is_success() && bytes_read > 0) { |
| 346 StartReading(true); // Read the next chunk. | 348 StartReading(true); // Read the next chunk. |
| 347 } else { | 349 } else { |
| 348 ResponseCompleted(); | 350 ResponseCompleted(); |
| 349 } | 351 } |
| 350 } | 352 } |
| 351 | 353 |
| 352 void ResourceLoader::CancelSSLRequest(const GlobalRequestID& id, | 354 void ResourceLoaderImpl::CancelSSLRequest(const GlobalRequestID& id, |
| 353 int error, | 355 int error, |
| 354 const net::SSLInfo* ssl_info) { | 356 const net::SSLInfo* ssl_info) { |
| 355 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 357 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 356 | 358 |
| 357 // The request can be NULL if it was cancelled by the renderer (as the | 359 // The request can be NULL if it was cancelled by the renderer (as the |
| 358 // request of the user navigating to a new page from the location bar). | 360 // request of the user navigating to a new page from the location bar). |
| 359 if (!request_->is_pending()) | 361 if (!request_->is_pending()) |
| 360 return; | 362 return; |
| 361 DVLOG(1) << "CancelSSLRequest() url: " << request_->url().spec(); | 363 DVLOG(1) << "CancelSSLRequest() url: " << request_->url().spec(); |
| 362 | 364 |
| 363 if (ssl_info) { | 365 if (ssl_info) { |
| 364 request_->CancelWithSSLError(error, *ssl_info); | 366 request_->CancelWithSSLError(error, *ssl_info); |
| 365 } else { | 367 } else { |
| 366 request_->CancelWithError(error); | 368 request_->CancelWithError(error); |
| 367 } | 369 } |
| 368 } | 370 } |
| 369 | 371 |
| 370 void ResourceLoader::ContinueSSLRequest(const GlobalRequestID& id) { | 372 void ResourceLoaderImpl::ContinueSSLRequest(const GlobalRequestID& id) { |
| 371 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 373 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 372 | 374 |
| 373 DVLOG(1) << "ContinueSSLRequest() url: " << request_->url().spec(); | 375 DVLOG(1) << "ContinueSSLRequest() url: " << request_->url().spec(); |
| 374 | 376 |
| 375 request_->ContinueDespiteLastError(); | 377 request_->ContinueDespiteLastError(); |
| 376 } | 378 } |
| 377 | 379 |
| 378 void ResourceLoader::Resume() { | 380 void ResourceLoaderImpl::Resume() { |
| 379 DCHECK(!is_transferring_); | 381 DCHECK(!is_transferring_); |
| 380 | 382 |
| 381 DeferredStage stage = deferred_stage_; | 383 DeferredStage stage = deferred_stage_; |
| 382 deferred_stage_ = DEFERRED_NONE; | 384 deferred_stage_ = DEFERRED_NONE; |
| 383 switch (stage) { | 385 switch (stage) { |
| 384 case DEFERRED_NONE: | 386 case DEFERRED_NONE: |
| 385 NOTREACHED(); | 387 NOTREACHED(); |
| 386 break; | 388 break; |
| 387 case DEFERRED_START: | 389 case DEFERRED_START: |
| 388 StartRequestInternal(); | 390 StartRequestInternal(); |
| 389 break; | 391 break; |
| 390 case DEFERRED_REDIRECT: | 392 case DEFERRED_REDIRECT: |
| 391 request_->FollowDeferredRedirect(); | 393 request_->FollowDeferredRedirect(); |
| 392 break; | 394 break; |
| 393 case DEFERRED_READ: | 395 case DEFERRED_READ: |
| 394 MessageLoop::current()->PostTask( | 396 MessageLoop::current()->PostTask( |
| 395 FROM_HERE, | 397 FROM_HERE, |
| 396 base::Bind(&ResourceLoader::ResumeReading, | 398 base::Bind(&ResourceLoaderImpl::ResumeReading, |
| 397 weak_ptr_factory_.GetWeakPtr())); | 399 weak_ptr_factory_.GetWeakPtr())); |
| 398 break; | 400 break; |
| 399 case DEFERRED_FINISH: | 401 case DEFERRED_FINISH: |
| 400 // Delay self-destruction since we don't know how we were reached. | 402 // Delay self-destruction since we don't know how we were reached. |
| 401 MessageLoop::current()->PostTask( | 403 MessageLoop::current()->PostTask( |
| 402 FROM_HERE, | 404 FROM_HERE, |
| 403 base::Bind(&ResourceLoader::CallDidFinishLoading, | 405 base::Bind(&ResourceLoaderImpl::CallDidFinishLoading, |
| 404 weak_ptr_factory_.GetWeakPtr())); | 406 weak_ptr_factory_.GetWeakPtr())); |
| 405 break; | 407 break; |
| 406 } | 408 } |
| 407 } | 409 } |
| 408 | 410 |
| 409 void ResourceLoader::Cancel() { | 411 void ResourceLoaderImpl::Cancel() { |
| 410 CancelRequest(false); | 412 CancelRequest(false); |
| 411 } | 413 } |
| 412 | 414 |
| 413 void ResourceLoader::StartRequestInternal() { | 415 void ResourceLoaderImpl::StartRequestInternal() { |
| 414 DCHECK(!request_->is_pending()); | 416 DCHECK(!request_->is_pending()); |
| 415 request_->Start(); | 417 request_->Start(); |
| 416 | 418 |
| 417 delegate_->DidStartRequest(this); | 419 delegate_->DidStartRequest(this); |
| 418 } | 420 } |
| 419 | 421 |
| 420 void ResourceLoader::CancelRequestInternal(int error, bool from_renderer) { | 422 void ResourceLoaderImpl::CancelRequestInternal(int error, bool from_renderer) { |
| 421 VLOG(1) << "CancelRequestInternal: " << request_->url().spec(); | 423 VLOG(1) << "CancelRequestInternal: " << request_->url().spec(); |
| 422 | 424 |
| 423 ResourceRequestInfoImpl* info = GetRequestInfo(); | 425 ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 424 | 426 |
| 425 // WebKit will send us a cancel for downloads since it no longer handles | 427 // WebKit will send us a cancel for downloads since it no longer handles |
| 426 // them. In this case, ignore the cancel since we handle downloads in the | 428 // them. In this case, ignore the cancel since we handle downloads in the |
| 427 // browser. | 429 // browser. |
| 428 if (from_renderer && info->is_download()) | 430 if (from_renderer && info->is_download()) |
| 429 return; | 431 return; |
| 430 | 432 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 441 ssl_client_auth_handler_ = NULL; | 443 ssl_client_auth_handler_ = NULL; |
| 442 } | 444 } |
| 443 | 445 |
| 444 request_->CancelWithError(error); | 446 request_->CancelWithError(error); |
| 445 | 447 |
| 446 if (!was_pending) { | 448 if (!was_pending) { |
| 447 // If the request isn't in flight, then we won't get an asynchronous | 449 // If the request isn't in flight, then we won't get an asynchronous |
| 448 // notification from the request, so we have to signal ourselves to finish | 450 // notification from the request, so we have to signal ourselves to finish |
| 449 // this request. | 451 // this request. |
| 450 MessageLoop::current()->PostTask( | 452 MessageLoop::current()->PostTask( |
| 451 FROM_HERE, base::Bind(&ResourceLoader::ResponseCompleted, | 453 FROM_HERE, base::Bind(&ResourceLoaderImpl::ResponseCompleted, |
| 452 weak_ptr_factory_.GetWeakPtr())); | 454 weak_ptr_factory_.GetWeakPtr())); |
| 453 } | 455 } |
| 454 } | 456 } |
| 455 | 457 |
| 456 void ResourceLoader::CompleteResponseStarted() { | 458 void ResourceLoaderImpl::CompleteResponseStarted() { |
| 457 ResourceRequestInfoImpl* info = GetRequestInfo(); | 459 ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 458 | 460 |
| 459 scoped_refptr<ResourceResponse> response(new ResourceResponse()); | 461 scoped_refptr<ResourceResponse> response(new ResourceResponse()); |
| 460 PopulateResourceResponse(request_.get(), response); | 462 PopulateResourceResponse(request_.get(), response); |
| 461 | 463 |
| 462 if (request_->ssl_info().cert) { | 464 if (request_->ssl_info().cert) { |
| 463 int cert_id = | 465 int cert_id = |
| 464 CertStore::GetInstance()->StoreCert(request_->ssl_info().cert, | 466 CertStore::GetInstance()->StoreCert(request_->ssl_info().cert, |
| 465 info->GetChildID()); | 467 info->GetChildID()); |
| 466 response->head.security_info = SerializeSecurityInfo( | 468 response->head.security_info = SerializeSecurityInfo( |
| (...skipping 11 matching lines...) Expand all Loading... |
| 478 delegate_->DidReceiveResponse(this); | 480 delegate_->DidReceiveResponse(this); |
| 479 | 481 |
| 480 bool defer = false; | 482 bool defer = false; |
| 481 if (!handler_->OnResponseStarted(info->GetRequestID(), response, &defer)) { | 483 if (!handler_->OnResponseStarted(info->GetRequestID(), response, &defer)) { |
| 482 Cancel(); | 484 Cancel(); |
| 483 } else if (defer) { | 485 } else if (defer) { |
| 484 deferred_stage_ = DEFERRED_READ; // Read first chunk when resumed. | 486 deferred_stage_ = DEFERRED_READ; // Read first chunk when resumed. |
| 485 } | 487 } |
| 486 } | 488 } |
| 487 | 489 |
| 488 void ResourceLoader::StartReading(bool is_continuation) { | 490 void ResourceLoaderImpl::StartReading(bool is_continuation) { |
| 489 int bytes_read = 0; | 491 int bytes_read = 0; |
| 490 ReadMore(&bytes_read); | 492 ReadMore(&bytes_read); |
| 491 | 493 |
| 492 // If IO is pending, wait for the URLRequest to call OnReadCompleted. | 494 // If IO is pending, wait for the URLRequest to call OnReadCompleted. |
| 493 if (request_->status().is_io_pending()) | 495 if (request_->status().is_io_pending()) |
| 494 return; | 496 return; |
| 495 | 497 |
| 496 if (!is_continuation || bytes_read <= 0) { | 498 if (!is_continuation || bytes_read <= 0) { |
| 497 OnReadCompleted(request_.get(), bytes_read); | 499 OnReadCompleted(request_.get(), bytes_read); |
| 498 } else { | 500 } else { |
| 499 // Else, trigger OnReadCompleted asynchronously to avoid starving the IO | 501 // Else, trigger OnReadCompleted asynchronously to avoid starving the IO |
| 500 // thread in case the URLRequest can provide data synchronously. | 502 // thread in case the URLRequest can provide data synchronously. |
| 501 MessageLoop::current()->PostTask( | 503 MessageLoop::current()->PostTask( |
| 502 FROM_HERE, | 504 FROM_HERE, |
| 503 base::Bind(&ResourceLoader::OnReadCompleted, | 505 base::Bind(&ResourceLoaderImpl::OnReadCompleted, |
| 504 weak_ptr_factory_.GetWeakPtr(), | 506 weak_ptr_factory_.GetWeakPtr(), |
| 505 request_.get(), bytes_read)); | 507 request_.get(), bytes_read)); |
| 506 } | 508 } |
| 507 } | 509 } |
| 508 | 510 |
| 509 void ResourceLoader::ResumeReading() { | 511 void ResourceLoaderImpl::ResumeReading() { |
| 510 DCHECK(!is_deferred()); | 512 DCHECK(!is_deferred()); |
| 511 | 513 |
| 512 if (request_->status().is_success()) { | 514 if (request_->status().is_success()) { |
| 513 StartReading(false); // Read the next chunk (OK to complete synchronously). | 515 StartReading(false); // Read the next chunk (OK to complete synchronously). |
| 514 } else { | 516 } else { |
| 515 ResponseCompleted(); | 517 ResponseCompleted(); |
| 516 } | 518 } |
| 517 } | 519 } |
| 518 | 520 |
| 519 void ResourceLoader::ReadMore(int* bytes_read) { | 521 void ResourceLoaderImpl::ReadMore(int* bytes_read) { |
| 520 ResourceRequestInfoImpl* info = GetRequestInfo(); | 522 ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 521 DCHECK(!is_deferred()); | 523 DCHECK(!is_deferred()); |
| 522 | 524 |
| 523 net::IOBuffer* buf; | 525 net::IOBuffer* buf; |
| 524 int buf_size; | 526 int buf_size; |
| 525 if (!handler_->OnWillRead(info->GetRequestID(), &buf, &buf_size, -1)) { | 527 if (!handler_->OnWillRead(info->GetRequestID(), &buf, &buf_size, -1)) { |
| 526 Cancel(); | 528 Cancel(); |
| 527 return; | 529 return; |
| 528 } | 530 } |
| 529 | 531 |
| 530 DCHECK(buf); | 532 DCHECK(buf); |
| 531 DCHECK(buf_size > 0); | 533 DCHECK(buf_size > 0); |
| 532 | 534 |
| 533 request_->Read(buf, buf_size, bytes_read); | 535 request_->Read(buf, buf_size, bytes_read); |
| 534 | 536 |
| 535 // No need to check the return value here as we'll detect errors by | 537 // No need to check the return value here as we'll detect errors by |
| 536 // inspecting the URLRequest's status. | 538 // inspecting the URLRequest's status. |
| 537 } | 539 } |
| 538 | 540 |
| 539 void ResourceLoader::CompleteRead(int bytes_read) { | 541 void ResourceLoaderImpl::CompleteRead(int bytes_read) { |
| 540 DCHECK(bytes_read >= 0); | 542 DCHECK(bytes_read >= 0); |
| 541 DCHECK(request_->status().is_success()); | 543 DCHECK(request_->status().is_success()); |
| 542 | 544 |
| 543 ResourceRequestInfoImpl* info = GetRequestInfo(); | 545 ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 544 | 546 |
| 545 bool defer = false; | 547 bool defer = false; |
| 546 if (!handler_->OnReadCompleted(info->GetRequestID(), bytes_read, &defer)) { | 548 if (!handler_->OnReadCompleted(info->GetRequestID(), bytes_read, &defer)) { |
| 547 Cancel(); | 549 Cancel(); |
| 548 } else if (defer) { | 550 } else if (defer) { |
| 549 deferred_stage_ = DEFERRED_READ; // Read next chunk when resumed. | 551 deferred_stage_ = DEFERRED_READ; // Read next chunk when resumed. |
| 550 } | 552 } |
| 551 } | 553 } |
| 552 | 554 |
| 553 void ResourceLoader::ResponseCompleted() { | 555 void ResourceLoaderImpl::ResponseCompleted() { |
| 554 VLOG(1) << "ResponseCompleted: " << request_->url().spec(); | 556 VLOG(1) << "ResponseCompleted: " << request_->url().spec(); |
| 555 ResourceRequestInfoImpl* info = GetRequestInfo(); | 557 ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 556 | 558 |
| 557 std::string security_info; | 559 std::string security_info; |
| 558 const net::SSLInfo& ssl_info = request_->ssl_info(); | 560 const net::SSLInfo& ssl_info = request_->ssl_info(); |
| 559 if (ssl_info.cert != NULL) { | 561 if (ssl_info.cert != NULL) { |
| 560 int cert_id = CertStore::GetInstance()->StoreCert(ssl_info.cert, | 562 int cert_id = CertStore::GetInstance()->StoreCert(ssl_info.cert, |
| 561 info->GetChildID()); | 563 info->GetChildID()); |
| 562 security_info = SerializeSecurityInfo( | 564 security_info = SerializeSecurityInfo( |
| 563 cert_id, ssl_info.cert_status, ssl_info.security_bits, | 565 cert_id, ssl_info.cert_status, ssl_info.security_bits, |
| 564 ssl_info.connection_status); | 566 ssl_info.connection_status); |
| 565 } | 567 } |
| 566 | 568 |
| 567 if (handler_->OnResponseCompleted(info->GetRequestID(), request_->status(), | 569 if (handler_->OnResponseCompleted(info->GetRequestID(), request_->status(), |
| 568 security_info)) { | 570 security_info)) { |
| 569 // This will result in our destruction. | 571 // This will result in our destruction. |
| 570 CallDidFinishLoading(); | 572 CallDidFinishLoading(); |
| 571 } else { | 573 } else { |
| 572 // The handler is not ready to die yet. We will call DidFinishLoading when | 574 // The handler is not ready to die yet. We will call DidFinishLoading when |
| 573 // we resume. | 575 // we resume. |
| 574 deferred_stage_ = DEFERRED_FINISH; | 576 deferred_stage_ = DEFERRED_FINISH; |
| 575 } | 577 } |
| 576 } | 578 } |
| 577 | 579 |
| 578 void ResourceLoader::CallDidFinishLoading() { | 580 void ResourceLoaderImpl::CallDidFinishLoading() { |
| 579 delegate_->DidFinishLoading(this); | 581 delegate_->DidFinishLoading(this); |
| 580 } | 582 } |
| 581 | 583 |
| 582 } // namespace content | 584 } // namespace content |
| OLD | NEW |