Chromium Code Reviews| 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.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" |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 52 | 52 |
| 53 ResourceLoader::ResourceLoader(scoped_ptr<net::URLRequest> request, | 53 ResourceLoader::ResourceLoader(scoped_ptr<net::URLRequest> request, |
| 54 scoped_ptr<ResourceHandler> handler, | 54 scoped_ptr<ResourceHandler> handler, |
| 55 ResourceLoaderDelegate* delegate) | 55 ResourceLoaderDelegate* 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 called_on_response_started_(false), | |
| 63 has_started_reading_(false), | |
| 64 is_paused_(false), | |
| 65 pause_count_(0), | |
| 66 paused_read_bytes_(0), | |
| 67 is_transferring_(false) { | 62 is_transferring_(false) { |
| 68 request_->set_delegate(this); | 63 request_->set_delegate(this); |
| 69 handler_->SetController(this); | 64 handler_->SetController(this); |
| 70 } | 65 } |
| 71 | 66 |
| 72 ResourceLoader::~ResourceLoader() { | 67 ResourceLoader::~ResourceLoader() { |
| 73 if (login_delegate_) | 68 if (login_delegate_) |
| 74 login_delegate_->OnRequestCancelled(); | 69 login_delegate_->OnRequestCancelled(); |
| 75 if (ssl_client_auth_handler_) | 70 if (ssl_client_auth_handler_) |
| 76 ssl_client_auth_handler_->OnRequestCancelled(); | 71 ssl_client_auth_handler_->OnRequestCancelled(); |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 206 CancelRequestInternal(net::ERR_UNKNOWN_URL_SCHEME, false); | 201 CancelRequestInternal(net::ERR_UNKNOWN_URL_SCHEME, false); |
| 207 return; | 202 return; |
| 208 } | 203 } |
| 209 | 204 |
| 210 scoped_refptr<ResourceResponse> response(new ResourceResponse()); | 205 scoped_refptr<ResourceResponse> response(new ResourceResponse()); |
| 211 PopulateResourceResponse(request_.get(), response); | 206 PopulateResourceResponse(request_.get(), response); |
| 212 | 207 |
| 213 if (!handler_->OnRequestRedirected(info->GetRequestID(), new_url, response, | 208 if (!handler_->OnRequestRedirected(info->GetRequestID(), new_url, response, |
| 214 defer)) { | 209 defer)) { |
| 215 Cancel(); | 210 Cancel(); |
| 211 } else if (*defer) { | |
| 212 deferred_stage_ = DEFERRED_REDIRECT; // Follow redirect when resumed. | |
| 216 } | 213 } |
| 217 | |
| 218 if (*defer) | |
| 219 deferred_stage_ = DEFERRED_REDIRECT; | |
| 220 } | 214 } |
| 221 | 215 |
| 222 void ResourceLoader::OnAuthRequired(net::URLRequest* unused, | 216 void ResourceLoader::OnAuthRequired(net::URLRequest* unused, |
| 223 net::AuthChallengeInfo* auth_info) { | 217 net::AuthChallengeInfo* auth_info) { |
| 224 DCHECK_EQ(request_.get(), unused); | 218 DCHECK_EQ(request_.get(), unused); |
| 225 | 219 |
| 226 if (request_->load_flags() & net::LOAD_DO_NOT_PROMPT_FOR_LOGIN) { | 220 if (request_->load_flags() & net::LOAD_DO_NOT_PROMPT_FOR_LOGIN) { |
| 227 request_->CancelAuth(); | 221 request_->CancelAuth(); |
| 228 return; | 222 return; |
| 229 } | 223 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 285 render_view_id, | 279 render_view_id, |
| 286 ssl_info, | 280 ssl_info, |
| 287 fatal); | 281 fatal); |
| 288 } | 282 } |
| 289 | 283 |
| 290 void ResourceLoader::OnResponseStarted(net::URLRequest* unused) { | 284 void ResourceLoader::OnResponseStarted(net::URLRequest* unused) { |
| 291 DCHECK_EQ(request_.get(), unused); | 285 DCHECK_EQ(request_.get(), unused); |
| 292 | 286 |
| 293 VLOG(1) << "OnResponseStarted: " << request_->url().spec(); | 287 VLOG(1) << "OnResponseStarted: " << request_->url().spec(); |
| 294 | 288 |
| 289 if (!request_->status().is_success()) { | |
| 290 ResponseCompleted(); | |
| 291 return; | |
| 292 } | |
| 293 | |
| 294 // We want to send a final upload progress message prior to sending the | |
| 295 // response complete message even if we're waiting for an ack to to a | |
| 296 // previous upload progress message. | |
| 297 waiting_for_upload_progress_ack_ = false; | |
| 298 ReportUploadProgress(); | |
| 299 | |
| 300 CompleteResponseStarted(); | |
| 301 | |
| 302 if (is_deferred()) | |
| 303 return; | |
| 304 | |
| 295 if (request_->status().is_success()) { | 305 if (request_->status().is_success()) { |
| 296 if (PauseRequestIfNeeded()) { | 306 StartReading(false); // Read the first chunk. |
| 297 VLOG(1) << "OnResponseStarted pausing: " << request_->url().spec(); | |
| 298 return; | |
| 299 } | |
| 300 | |
| 301 // We want to send a final upload progress message prior to sending the | |
| 302 // response complete message even if we're waiting for an ack to to a | |
| 303 // previous upload progress message. | |
| 304 waiting_for_upload_progress_ack_ = false; | |
| 305 ReportUploadProgress(); | |
| 306 | |
| 307 if (!CompleteResponseStarted()) { | |
| 308 Cancel(); | |
| 309 } else { | |
| 310 // Check if the handler paused the request in their OnResponseStarted. | |
| 311 if (PauseRequestIfNeeded()) { | |
| 312 VLOG(1) << "OnResponseStarted pausing2: " << request_->url().spec(); | |
| 313 return; | |
| 314 } | |
| 315 | |
| 316 StartReading(); | |
| 317 } | |
| 318 } else { | 307 } else { |
| 319 ResponseCompleted(); | 308 ResponseCompleted(); |
| 320 } | 309 } |
| 321 } | 310 } |
| 322 | 311 |
| 323 void ResourceLoader::OnReadCompleted(net::URLRequest* unused, int bytes_read) { | 312 void ResourceLoader::OnReadCompleted(net::URLRequest* unused, int bytes_read) { |
| 324 DCHECK_EQ(request_.get(), unused); | 313 DCHECK_EQ(request_.get(), unused); |
| 325 VLOG(1) << "OnReadCompleted: \"" << request_->url().spec() << "\"" | 314 VLOG(1) << "OnReadCompleted: \"" << request_->url().spec() << "\"" |
| 326 << " bytes_read = " << bytes_read; | 315 << " bytes_read = " << bytes_read; |
| 327 | 316 |
| 328 // bytes_read == -1 always implies an error, so we want to skip the pause | 317 // bytes_read == -1 always implies an error. |
| 329 // checks and just call ResponseCompleted. | 318 if (bytes_read == -1 || !request_->status().is_success()) { |
| 330 if (bytes_read == -1) { | |
| 331 DCHECK(!request_->status().is_success()); | |
| 332 | |
| 333 ResponseCompleted(); | 319 ResponseCompleted(); |
| 334 return; | 320 return; |
| 335 } | 321 } |
| 336 | 322 |
| 337 // OnReadCompleted can be called without Read (e.g., for chrome:// URLs). | 323 CompleteRead(bytes_read); |
| 338 // Make sure we know that a read has begun. | |
| 339 has_started_reading_ = true; | |
| 340 | 324 |
| 341 if (PauseRequestIfNeeded()) { | 325 if (is_deferred()) |
| 342 paused_read_bytes_ = bytes_read; | |
| 343 VLOG(1) << "OnReadCompleted pausing: \"" << request_->url().spec() << "\"" | |
| 344 << " bytes_read = " << bytes_read; | |
| 345 return; | 326 return; |
| 327 | |
| 328 if (request_->status().is_success() && bytes_read > 0) { | |
| 329 StartReading(true); // Read the next chunk. | |
| 330 } else { | |
| 331 ResponseCompleted(); | |
| 346 } | 332 } |
| 347 | |
| 348 if (request_->status().is_success() && CompleteRead(&bytes_read)) { | |
| 349 // The request can be paused if we realize that the renderer is not | |
| 350 // servicing messages fast enough. | |
| 351 if (pause_count_ == 0 && ReadMore(&bytes_read) && | |
| 352 request_->status().is_success()) { | |
| 353 if (bytes_read == 0) { | |
| 354 CompleteRead(&bytes_read); | |
| 355 } else { | |
| 356 // Force the next CompleteRead / Read pair to run as a separate task. | |
| 357 // This avoids a fast, large network request from monopolizing the IO | |
| 358 // thread and starving other IO operations from running. | |
| 359 VLOG(1) << "OnReadCompleted postponing: \"" | |
| 360 << request_->url().spec() << "\"" | |
| 361 << " bytes_read = " << bytes_read; | |
| 362 | |
| 363 paused_read_bytes_ = bytes_read; | |
| 364 is_paused_ = true; | |
| 365 | |
| 366 MessageLoop::current()->PostTask( | |
| 367 FROM_HERE, base::Bind(&ResourceLoader::ResumeRequest, AsWeakPtr())); | |
| 368 return; | |
| 369 } | |
| 370 } | |
| 371 } | |
| 372 | |
| 373 if (PauseRequestIfNeeded()) { | |
| 374 paused_read_bytes_ = bytes_read; | |
| 375 VLOG(1) << "OnReadCompleted (CompleteRead) pausing: \"" | |
| 376 << request_->url().spec() << "\"" | |
| 377 << " bytes_read = " << bytes_read; | |
| 378 return; | |
| 379 } | |
| 380 | |
| 381 // If the status is not IO pending then we've either finished (success) or we | |
| 382 // had an error. Either way, we're done! | |
| 383 if (!request_->status().is_io_pending()) | |
| 384 ResponseCompleted(); | |
| 385 } | 333 } |
| 386 | 334 |
| 387 void ResourceLoader::CancelSSLRequest(const GlobalRequestID& id, | 335 void ResourceLoader::CancelSSLRequest(const GlobalRequestID& id, |
| 388 int error, | 336 int error, |
| 389 const net::SSLInfo* ssl_info) { | 337 const net::SSLInfo* ssl_info) { |
| 390 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 338 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 391 | 339 |
| 392 // The request can be NULL if it was cancelled by the renderer (as the | 340 // The request can be NULL if it was cancelled by the renderer (as the |
| 393 // request of the user navigating to a new page from the location bar). | 341 // request of the user navigating to a new page from the location bar). |
| 394 if (!request_->is_pending()) | 342 if (!request_->is_pending()) |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 418 switch (stage) { | 366 switch (stage) { |
| 419 case DEFERRED_NONE: | 367 case DEFERRED_NONE: |
| 420 NOTREACHED(); | 368 NOTREACHED(); |
| 421 break; | 369 break; |
| 422 case DEFERRED_START: | 370 case DEFERRED_START: |
| 423 StartRequestInternal(); | 371 StartRequestInternal(); |
| 424 break; | 372 break; |
| 425 case DEFERRED_REDIRECT: | 373 case DEFERRED_REDIRECT: |
| 426 request_->FollowDeferredRedirect(); | 374 request_->FollowDeferredRedirect(); |
| 427 break; | 375 break; |
| 428 case DEFERRED_RESPONSE: | |
| 429 case DEFERRED_READ: | 376 case DEFERRED_READ: |
| 430 PauseRequest(false); | 377 MessageLoop::current()->PostTask( |
| 378 FROM_HERE, | |
| 379 base::Bind(&ResourceLoader::ResumeReading, AsWeakPtr())); | |
| 431 break; | 380 break; |
| 432 case DEFERRED_FINISH: | 381 case DEFERRED_FINISH: |
| 433 // Delay self-destruction since we don't know how we were reached. | 382 // Delay self-destruction since we don't know how we were reached. |
| 434 MessageLoop::current()->PostTask( | 383 MessageLoop::current()->PostTask( |
| 435 FROM_HERE, | 384 FROM_HERE, |
| 436 base::Bind(&ResourceLoader::CallDidFinishLoading, AsWeakPtr())); | 385 base::Bind(&ResourceLoader::CallDidFinishLoading, AsWeakPtr())); |
| 437 break; | 386 break; |
| 438 } | 387 } |
| 439 } | 388 } |
| 440 | 389 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 453 VLOG(1) << "CancelRequestInternal: " << request_->url().spec(); | 402 VLOG(1) << "CancelRequestInternal: " << request_->url().spec(); |
| 454 | 403 |
| 455 ResourceRequestInfoImpl* info = GetRequestInfo(); | 404 ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 456 | 405 |
| 457 // WebKit will send us a cancel for downloads since it no longer handles | 406 // WebKit will send us a cancel for downloads since it no longer handles |
| 458 // them. In this case, ignore the cancel since we handle downloads in the | 407 // them. In this case, ignore the cancel since we handle downloads in the |
| 459 // browser. | 408 // browser. |
| 460 if (from_renderer && info->is_download()) | 409 if (from_renderer && info->is_download()) |
| 461 return; | 410 return; |
| 462 | 411 |
| 412 // XXX Perhaps we should really be looking to see if the status is IO_PENDING? | |
|
darin (slow to review)
2012/06/28 21:49:53
Whoops, I need to change this to a TODO(darin).
| |
| 463 bool was_pending = request_->is_pending(); | 413 bool was_pending = request_->is_pending(); |
| 464 | 414 |
| 465 if (login_delegate_) { | 415 if (login_delegate_) { |
| 466 login_delegate_->OnRequestCancelled(); | 416 login_delegate_->OnRequestCancelled(); |
| 467 login_delegate_ = NULL; | 417 login_delegate_ = NULL; |
| 468 } | 418 } |
| 469 if (ssl_client_auth_handler_) { | 419 if (ssl_client_auth_handler_) { |
| 470 ssl_client_auth_handler_->OnRequestCancelled(); | 420 ssl_client_auth_handler_->OnRequestCancelled(); |
| 471 ssl_client_auth_handler_ = NULL; | 421 ssl_client_auth_handler_ = NULL; |
| 472 } | 422 } |
| 473 | 423 |
| 474 request_->CancelWithError(error); | 424 request_->CancelWithError(error); |
| 475 | 425 |
| 476 if (!was_pending) { | 426 if (!was_pending) { |
| 477 // If the request isn't in flight, then we won't get an asynchronous | 427 // If the request isn't in flight, then we won't get an asynchronous |
| 478 // notification from the request, so we have to signal ourselves to finish | 428 // notification from the request, so we have to signal ourselves to finish |
| 479 // this request. | 429 // this request. |
| 480 MessageLoop::current()->PostTask( | 430 MessageLoop::current()->PostTask( |
| 481 FROM_HERE, base::Bind(&ResourceLoader::ResponseCompleted, AsWeakPtr())); | 431 FROM_HERE, base::Bind(&ResourceLoader::ResponseCompleted, AsWeakPtr())); |
| 482 } | 432 } |
| 483 } | 433 } |
| 484 | 434 |
| 485 bool ResourceLoader::CompleteResponseStarted() { | 435 void ResourceLoader::CompleteResponseStarted() { |
| 486 ResourceRequestInfoImpl* info = GetRequestInfo(); | 436 ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 487 | 437 |
| 488 scoped_refptr<ResourceResponse> response(new ResourceResponse()); | 438 scoped_refptr<ResourceResponse> response(new ResourceResponse()); |
| 489 PopulateResourceResponse(request_.get(), response); | 439 PopulateResourceResponse(request_.get(), response); |
| 490 | 440 |
| 491 if (request_->ssl_info().cert) { | 441 if (request_->ssl_info().cert) { |
| 492 int cert_id = | 442 int cert_id = |
| 493 CertStore::GetInstance()->StoreCert(request_->ssl_info().cert, | 443 CertStore::GetInstance()->StoreCert(request_->ssl_info().cert, |
| 494 info->GetChildID()); | 444 info->GetChildID()); |
| 495 response->head.security_info = SerializeSecurityInfo( | 445 response->head.security_info = SerializeSecurityInfo( |
| 496 cert_id, | 446 cert_id, |
| 497 request_->ssl_info().cert_status, | 447 request_->ssl_info().cert_status, |
| 498 request_->ssl_info().security_bits, | 448 request_->ssl_info().security_bits, |
| 499 request_->ssl_info().connection_status); | 449 request_->ssl_info().connection_status); |
| 500 } else { | 450 } else { |
| 501 // We should not have any SSL state. | 451 // We should not have any SSL state. |
| 502 DCHECK(!request_->ssl_info().cert_status && | 452 DCHECK(!request_->ssl_info().cert_status && |
| 503 request_->ssl_info().security_bits == -1 && | 453 request_->ssl_info().security_bits == -1 && |
| 504 !request_->ssl_info().connection_status); | 454 !request_->ssl_info().connection_status); |
| 505 } | 455 } |
| 506 | 456 |
| 507 delegate_->DidReceiveResponse(this); | 457 delegate_->DidReceiveResponse(this); |
| 508 called_on_response_started_ = true; | |
| 509 | 458 |
| 510 bool defer = false; | 459 bool defer = false; |
| 511 if (!handler_->OnResponseStarted(info->GetRequestID(), response, &defer)) | 460 if (!handler_->OnResponseStarted(info->GetRequestID(), response, &defer)) { |
| 512 return false; | 461 Cancel(); |
| 513 | 462 } else if (defer) { |
| 514 if (defer) { | 463 deferred_stage_ = DEFERRED_READ; // Read first chunk when resumed. |
| 515 deferred_stage_ = DEFERRED_RESPONSE; | |
| 516 PauseRequest(true); | |
| 517 } | 464 } |
| 518 | |
| 519 return true; | |
| 520 } | 465 } |
| 521 | 466 |
| 522 void ResourceLoader::StartReading() { | 467 void ResourceLoader::StartReading(bool is_continuation) { |
|
darin (slow to review)
2012/06/28 21:49:53
NOTE: The old code tried to avoid going back to th
| |
| 523 int bytes_read = 0; | 468 int bytes_read = 0; |
| 524 if (ReadMore(&bytes_read)) { | 469 ReadMore(&bytes_read); |
| 470 | |
| 471 // If IO is pending, wait for the URLRequest to call OnReadCompleted. | |
| 472 if (request_->status().is_io_pending()) | |
| 473 return; | |
| 474 | |
| 475 if (!is_continuation || bytes_read <= 0) { | |
| 525 OnReadCompleted(request_.get(), bytes_read); | 476 OnReadCompleted(request_.get(), bytes_read); |
| 526 } else if (!request_->status().is_io_pending()) { | 477 } else { |
| 527 DCHECK(!is_paused_); | 478 // Else, trigger OnReadCompleted asynchronously to avoid starving the IO |
| 528 // If the error is not an IO pending, then we're done reading. | 479 // thread in case the URLRequest can provide data synchronously. |
| 480 MessageLoop::current()->PostTask( | |
| 481 FROM_HERE, | |
| 482 base::Bind(&ResourceLoader::OnReadCompleted, AsWeakPtr(), | |
| 483 request_.get(), bytes_read)); | |
| 484 } | |
| 485 } | |
| 486 | |
| 487 void ResourceLoader::ResumeReading() { | |
| 488 DCHECK(!is_deferred()); | |
| 489 | |
| 490 if (request_->status().is_success()) { | |
| 491 StartReading(false); // Read the next chunk (OK to complete synchronously). | |
| 492 } else { | |
| 529 ResponseCompleted(); | 493 ResponseCompleted(); |
| 530 } | 494 } |
| 531 } | 495 } |
| 532 | 496 |
| 533 bool ResourceLoader::ReadMore(int* bytes_read) { | 497 void ResourceLoader::ReadMore(int* bytes_read) { |
| 534 ResourceRequestInfoImpl* info = GetRequestInfo(); | 498 ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 535 DCHECK(!is_paused_); | 499 DCHECK(!is_deferred()); |
| 536 | 500 |
| 537 net::IOBuffer* buf; | 501 net::IOBuffer* buf; |
| 538 int buf_size; | 502 int buf_size; |
| 539 if (!handler_->OnWillRead(info->GetRequestID(), &buf, &buf_size, -1)) | 503 if (!handler_->OnWillRead(info->GetRequestID(), &buf, &buf_size, -1)) { |
| 540 return false; | 504 Cancel(); |
| 505 return; | |
| 506 } | |
| 541 | 507 |
| 542 DCHECK(buf); | 508 DCHECK(buf); |
| 543 DCHECK(buf_size > 0); | 509 DCHECK(buf_size > 0); |
| 544 | 510 |
| 545 has_started_reading_ = true; | 511 request_->Read(buf, buf_size, bytes_read); |
| 546 return request_->Read(buf, buf_size, bytes_read); | 512 |
| 513 // No need to check the return value here as we'll detect errors by | |
| 514 // inspecting the URLRequest's status. | |
| 547 } | 515 } |
| 548 | 516 |
| 549 bool ResourceLoader::CompleteRead(int* bytes_read) { | 517 void ResourceLoader::CompleteRead(int bytes_read) { |
| 550 if (!request_.get() || !request_->status().is_success()) { | 518 DCHECK(bytes_read >= 0); |
| 551 NOTREACHED(); | 519 DCHECK(request_->status().is_success()); |
| 552 return false; | |
| 553 } | |
| 554 | 520 |
| 555 ResourceRequestInfoImpl* info = GetRequestInfo(); | 521 ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 556 | 522 |
| 557 bool defer = false; | 523 bool defer = false; |
| 558 if (!handler_->OnReadCompleted(info->GetRequestID(), bytes_read, &defer)) { | 524 if (!handler_->OnReadCompleted(info->GetRequestID(), bytes_read, &defer)) { |
| 559 Cancel(); | 525 Cancel(); |
| 560 return false; | 526 } else if (defer) { |
| 527 deferred_stage_ = DEFERRED_READ; // Read next chunk when resumed. | |
| 561 } | 528 } |
| 562 | |
| 563 if (defer) { | |
| 564 deferred_stage_ = DEFERRED_READ; | |
| 565 PauseRequest(true); | |
| 566 } | |
| 567 | |
| 568 return *bytes_read != 0; | |
| 569 } | 529 } |
| 570 | 530 |
| 571 void ResourceLoader::ResponseCompleted() { | 531 void ResourceLoader::ResponseCompleted() { |
| 572 VLOG(1) << "ResponseCompleted: " << request_->url().spec(); | 532 VLOG(1) << "ResponseCompleted: " << request_->url().spec(); |
| 573 ResourceRequestInfoImpl* info = GetRequestInfo(); | 533 ResourceRequestInfoImpl* info = GetRequestInfo(); |
| 574 | 534 |
| 575 std::string security_info; | 535 std::string security_info; |
| 576 const net::SSLInfo& ssl_info = request_->ssl_info(); | 536 const net::SSLInfo& ssl_info = request_->ssl_info(); |
| 577 if (ssl_info.cert != NULL) { | 537 if (ssl_info.cert != NULL) { |
| 578 int cert_id = CertStore::GetInstance()->StoreCert(ssl_info.cert, | 538 int cert_id = CertStore::GetInstance()->StoreCert(ssl_info.cert, |
| 579 info->GetChildID()); | 539 info->GetChildID()); |
| 580 security_info = SerializeSecurityInfo( | 540 security_info = SerializeSecurityInfo( |
| 581 cert_id, ssl_info.cert_status, ssl_info.security_bits, | 541 cert_id, ssl_info.cert_status, ssl_info.security_bits, |
| 582 ssl_info.connection_status); | 542 ssl_info.connection_status); |
| 583 } | 543 } |
| 584 | 544 |
| 585 if (handler_->OnResponseCompleted(info->GetRequestID(), request_->status(), | 545 if (handler_->OnResponseCompleted(info->GetRequestID(), request_->status(), |
| 586 security_info)) { | 546 security_info)) { |
| 587 // This will result in our destruction. | 547 // This will result in our destruction. |
| 588 CallDidFinishLoading(); | 548 CallDidFinishLoading(); |
| 589 } else { | 549 } else { |
| 590 // The handler is not ready to die yet. We will call DidFinishLoading when | 550 // The handler is not ready to die yet. We will call DidFinishLoading when |
| 591 // we resume. | 551 // we resume. |
| 592 deferred_stage_ = DEFERRED_FINISH; | 552 deferred_stage_ = DEFERRED_FINISH; |
| 593 } | 553 } |
| 594 } | 554 } |
| 595 | 555 |
| 596 bool ResourceLoader::PauseRequestIfNeeded() { | |
| 597 if (pause_count_ > 0) | |
| 598 is_paused_ = true; | |
| 599 return is_paused_; | |
| 600 } | |
| 601 | |
| 602 void ResourceLoader::PauseRequest(bool pause) { | |
| 603 int pause_count = pause_count_ + (pause ? 1 : -1); | |
| 604 if (pause_count < 0) { | |
| 605 NOTREACHED(); // Unbalanced call to pause. | |
| 606 return; | |
| 607 } | |
| 608 pause_count_ = pause_count; | |
| 609 | |
| 610 VLOG(1) << "To pause (" << pause << "): " << request_->url().spec(); | |
| 611 | |
| 612 // If we're resuming, kick the request to start reading again. Run the read | |
| 613 // asynchronously to avoid recursion problems. | |
| 614 if (pause_count_ == 0) { | |
| 615 MessageLoop::current()->PostTask( | |
| 616 FROM_HERE, base::Bind(&ResourceLoader::ResumeRequest, AsWeakPtr())); | |
| 617 } | |
| 618 } | |
| 619 | |
| 620 void ResourceLoader::ResumeRequest() { | |
| 621 // We may already be unpaused, or the pause count may have increased since we | |
| 622 // posted the task to call ResumeRequest. | |
| 623 if (!is_paused_) | |
| 624 return; | |
| 625 is_paused_ = false; | |
| 626 if (PauseRequestIfNeeded()) | |
| 627 return; | |
| 628 | |
| 629 VLOG(1) << "Resuming: \"" << request_->url().spec() << "\"" | |
| 630 << " paused_read_bytes = " << paused_read_bytes_ | |
| 631 << " called response started = " << called_on_response_started_ | |
| 632 << " started reading = " << has_started_reading_; | |
| 633 | |
| 634 if (called_on_response_started_) { | |
| 635 if (has_started_reading_) { | |
| 636 OnReadCompleted(request_.get(), paused_read_bytes_); | |
| 637 } else { | |
| 638 StartReading(); | |
| 639 } | |
| 640 } else { | |
| 641 OnResponseStarted(request_.get()); | |
| 642 } | |
| 643 } | |
| 644 | |
| 645 void ResourceLoader::CallDidFinishLoading() { | 556 void ResourceLoader::CallDidFinishLoading() { |
| 646 delegate_->DidFinishLoading(this); | 557 delegate_->DidFinishLoading(this); |
| 647 } | 558 } |
| 648 | 559 |
| 649 } // namespace content | 560 } // namespace content |
| OLD | NEW |