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 "webkit/browser/appcache/appcache_update_job.h" | 5 #include "webkit/browser/appcache/appcache_update_job.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 69 void SendProgressNotifications( | 69 void SendProgressNotifications( |
| 70 const GURL& url, int num_total, int num_complete) { | 70 const GURL& url, int num_total, int num_complete) { |
| 71 for (NotifyHostMap::iterator it = hosts_to_notify.begin(); | 71 for (NotifyHostMap::iterator it = hosts_to_notify.begin(); |
| 72 it != hosts_to_notify.end(); ++it) { | 72 it != hosts_to_notify.end(); ++it) { |
| 73 AppCacheFrontend* frontend = it->first; | 73 AppCacheFrontend* frontend = it->first; |
| 74 frontend->OnProgressEventRaised(it->second, url, | 74 frontend->OnProgressEventRaised(it->second, url, |
| 75 num_total, num_complete); | 75 num_total, num_complete); |
| 76 } | 76 } |
| 77 } | 77 } |
| 78 | 78 |
| 79 void SendErrorNotifications(const std::string& error_message) { | 79 void SendErrorNotifications(const std::string& error_message, |
| 80 appcache::ErrorReason reason, | |
| 81 const GURL& url, | |
| 82 int status) { | |
| 80 DCHECK(!error_message.empty()); | 83 DCHECK(!error_message.empty()); |
| 81 for (NotifyHostMap::iterator it = hosts_to_notify.begin(); | 84 for (NotifyHostMap::iterator it = hosts_to_notify.begin(); |
| 82 it != hosts_to_notify.end(); ++it) { | 85 it != hosts_to_notify.end(); ++it) { |
| 83 AppCacheFrontend* frontend = it->first; | 86 AppCacheFrontend* frontend = it->first; |
| 84 frontend->OnErrorEventRaised(it->second, error_message); | 87 frontend->OnErrorEventRaised( |
| 88 it->second, error_message, reason, url, status); | |
| 85 } | 89 } |
| 86 } | 90 } |
| 87 | 91 |
| 88 private: | 92 private: |
| 89 NotifyHostMap hosts_to_notify; | 93 NotifyHostMap hosts_to_notify; |
| 90 }; | 94 }; |
| 91 | 95 |
| 92 AppCacheUpdateJob::UrlToFetch::UrlToFetch(const GURL& url, | 96 AppCacheUpdateJob::UrlToFetch::UrlToFetch(const GURL& url, |
| 93 bool checked, | 97 bool checked, |
| 94 AppCacheResponseInfo* info) | 98 AppCacheResponseInfo* info) |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 124 net::LOAD_DISABLE_INTERCEPT); | 128 net::LOAD_DISABLE_INTERCEPT); |
| 125 if (existing_response_headers_.get()) | 129 if (existing_response_headers_.get()) |
| 126 AddConditionalHeaders(existing_response_headers_.get()); | 130 AddConditionalHeaders(existing_response_headers_.get()); |
| 127 request_->Start(); | 131 request_->Start(); |
| 128 } | 132 } |
| 129 | 133 |
| 130 void AppCacheUpdateJob::URLFetcher::OnReceivedRedirect( | 134 void AppCacheUpdateJob::URLFetcher::OnReceivedRedirect( |
| 131 net::URLRequest* request, const GURL& new_url, bool* defer_redirect) { | 135 net::URLRequest* request, const GURL& new_url, bool* defer_redirect) { |
| 132 DCHECK(request_ == request); | 136 DCHECK(request_ == request); |
| 133 // Redirect is not allowed by the update process. | 137 // Redirect is not allowed by the update process. |
| 134 request->Cancel(); | 138 request->Cancel(); |
|
michaeln
2014/03/01 00:20:02
It might be a matter of not calling cancel here, s
| |
| 135 result_ = REDIRECT_ERROR; | 139 result_ = REDIRECT_ERROR; |
| 136 OnResponseCompleted(); | 140 OnResponseCompleted(); |
| 137 } | 141 } |
| 138 | 142 |
| 139 void AppCacheUpdateJob::URLFetcher::OnResponseStarted( | 143 void AppCacheUpdateJob::URLFetcher::OnResponseStarted( |
| 140 net::URLRequest *request) { | 144 net::URLRequest *request) { |
| 141 DCHECK(request == request_); | 145 DCHECK(request == request_); |
| 142 int response_code = -1; | 146 int response_code = -1; |
| 143 if (request->status().is_success()) | 147 if (request->status().is_success()) |
| 144 response_code = request->GetResponseCode(); | 148 response_code = request->GetResponseCode(); |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 413 } | 417 } |
| 414 | 418 |
| 415 AppCacheResponseWriter* AppCacheUpdateJob::CreateResponseWriter() { | 419 AppCacheResponseWriter* AppCacheUpdateJob::CreateResponseWriter() { |
| 416 AppCacheResponseWriter* writer = | 420 AppCacheResponseWriter* writer = |
| 417 storage_->CreateResponseWriter(manifest_url_, | 421 storage_->CreateResponseWriter(manifest_url_, |
| 418 group_->group_id()); | 422 group_->group_id()); |
| 419 stored_response_ids_.push_back(writer->response_id()); | 423 stored_response_ids_.push_back(writer->response_id()); |
| 420 return writer; | 424 return writer; |
| 421 } | 425 } |
| 422 | 426 |
| 423 void AppCacheUpdateJob::HandleCacheFailure( | 427 void AppCacheUpdateJob::HandleCacheFailure(const std::string& error_message, |
| 424 const std::string& error_message, | 428 ErrorReason reason, |
| 425 ResultType result) { | 429 const GURL& resource_url, |
| 430 int resource_status, | |
| 431 ResultType result) { | |
| 426 // 6.9.4 cache failure steps 2-8. | 432 // 6.9.4 cache failure steps 2-8. |
| 427 DCHECK(internal_state_ != CACHE_FAILURE); | 433 DCHECK(internal_state_ != CACHE_FAILURE); |
| 428 DCHECK(!error_message.empty()); | 434 DCHECK(!error_message.empty()); |
| 429 DCHECK(result != UPDATE_OK); | 435 DCHECK(result != UPDATE_OK); |
| 430 internal_state_ = CACHE_FAILURE; | 436 internal_state_ = CACHE_FAILURE; |
| 431 CancelAllUrlFetches(); | 437 CancelAllUrlFetches(); |
| 432 CancelAllMasterEntryFetches(error_message); | 438 CancelAllMasterEntryFetches( |
| 433 NotifyAllError(error_message); | 439 error_message, reason, resource_url, resource_status); |
| 440 NotifyAllError(error_message, reason, resource_url, resource_status); | |
| 434 DiscardInprogressCache(); | 441 DiscardInprogressCache(); |
| 435 internal_state_ = COMPLETED; | 442 internal_state_ = COMPLETED; |
| 436 AppCacheHistograms::CountUpdateJobResult( | 443 AppCacheHistograms::CountUpdateJobResult( |
| 437 result, manifest_url_.GetOrigin()); | 444 result, manifest_url_.GetOrigin()); |
| 438 DeleteSoon(); // To unwind the stack prior to deletion. | 445 DeleteSoon(); // To unwind the stack prior to deletion. |
| 439 } | 446 } |
| 440 | 447 |
| 441 void AppCacheUpdateJob::FetchManifest(bool is_first_fetch) { | 448 void AppCacheUpdateJob::FetchManifest(bool is_first_fetch) { |
| 442 DCHECK(!manifest_fetcher_); | 449 DCHECK(!manifest_fetcher_); |
| 443 manifest_fetcher_ = new URLFetcher( | 450 manifest_fetcher_ = new URLFetcher( |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 491 ContinueHandleManifestFetchCompleted(true); | 498 ContinueHandleManifestFetchCompleted(true); |
| 492 } else if (response_code == 304 && update_type_ == UPGRADE_ATTEMPT) { | 499 } else if (response_code == 304 && update_type_ == UPGRADE_ATTEMPT) { |
| 493 ContinueHandleManifestFetchCompleted(false); | 500 ContinueHandleManifestFetchCompleted(false); |
| 494 } else if ((response_code == 404 || response_code == 410) && | 501 } else if ((response_code == 404 || response_code == 410) && |
| 495 update_type_ == UPGRADE_ATTEMPT) { | 502 update_type_ == UPGRADE_ATTEMPT) { |
| 496 storage_->MakeGroupObsolete(group_, this); // async | 503 storage_->MakeGroupObsolete(group_, this); // async |
| 497 } else { | 504 } else { |
| 498 const char* kFormatString = "Manifest fetch failed (%d) %s"; | 505 const char* kFormatString = "Manifest fetch failed (%d) %s"; |
| 499 std::string message = FormatUrlErrorMessage( | 506 std::string message = FormatUrlErrorMessage( |
| 500 kFormatString, manifest_url_, fetcher->result(), response_code); | 507 kFormatString, manifest_url_, fetcher->result(), response_code); |
| 501 HandleCacheFailure(message, fetcher->result()); | 508 HandleCacheFailure(message, |
| 509 ERROR_MANIFEST_FETCH, | |
| 510 manifest_url_, | |
| 511 response_code, | |
| 512 fetcher->result()); | |
| 502 } | 513 } |
| 503 } | 514 } |
| 504 | 515 |
| 505 void AppCacheUpdateJob::OnGroupMadeObsolete(AppCacheGroup* group, | 516 void AppCacheUpdateJob::OnGroupMadeObsolete(AppCacheGroup* group, |
| 506 bool success) { | 517 bool success) { |
| 507 DCHECK(master_entry_fetches_.empty()); | 518 DCHECK(master_entry_fetches_.empty()); |
| 508 CancelAllMasterEntryFetches("The cache has been made obsolete, " | 519 CancelAllMasterEntryFetches( |
| 509 "the manifest file returned 404 or 410"); | 520 "The cache has been made obsolete, " |
| 521 "the manifest file returned 404 or 410", | |
| 522 ERROR_MANIFEST_OBSOLETE, | |
| 523 GURL(), | |
| 524 0); | |
| 510 if (success) { | 525 if (success) { |
| 511 DCHECK(group->is_obsolete()); | 526 DCHECK(group->is_obsolete()); |
| 512 NotifyAllAssociatedHosts(OBSOLETE_EVENT); | 527 NotifyAllAssociatedHosts(OBSOLETE_EVENT); |
| 513 internal_state_ = COMPLETED; | 528 internal_state_ = COMPLETED; |
| 514 MaybeCompleteUpdate(); | 529 MaybeCompleteUpdate(); |
| 515 } else { | 530 } else { |
| 516 // Treat failure to mark group obsolete as a cache failure. | 531 // Treat failure to mark group obsolete as a cache failure. |
| 517 HandleCacheFailure("Failed to mark the cache as obsolete", DB_ERROR); | 532 HandleCacheFailure("Failed to mark the cache as obsolete", |
| 533 ERROR_INTERNAL, | |
| 534 GURL(), | |
| 535 0, | |
| 536 DB_ERROR); | |
| 518 } | 537 } |
| 519 } | 538 } |
| 520 | 539 |
| 521 void AppCacheUpdateJob::ContinueHandleManifestFetchCompleted(bool changed) { | 540 void AppCacheUpdateJob::ContinueHandleManifestFetchCompleted(bool changed) { |
| 522 DCHECK(internal_state_ == FETCH_MANIFEST); | 541 DCHECK(internal_state_ == FETCH_MANIFEST); |
| 523 | 542 |
| 524 if (!changed) { | 543 if (!changed) { |
| 525 DCHECK(update_type_ == UPGRADE_ATTEMPT); | 544 DCHECK(update_type_ == UPGRADE_ATTEMPT); |
| 526 internal_state_ = NO_UPDATE; | 545 internal_state_ = NO_UPDATE; |
| 527 | 546 |
| 528 // Wait for pending master entries to download. | 547 // Wait for pending master entries to download. |
| 529 FetchMasterEntries(); | 548 FetchMasterEntries(); |
| 530 MaybeCompleteUpdate(); // if not done, run async 6.9.4 step 7 substeps | 549 MaybeCompleteUpdate(); // if not done, run async 6.9.4 step 7 substeps |
| 531 return; | 550 return; |
| 532 } | 551 } |
| 533 | 552 |
| 534 Manifest manifest; | 553 Manifest manifest; |
| 535 if (!ParseManifest(manifest_url_, manifest_data_.data(), | 554 if (!ParseManifest(manifest_url_, manifest_data_.data(), |
| 536 manifest_data_.length(), manifest)) { | 555 manifest_data_.length(), manifest)) { |
| 537 const char* kFormatString = "Failed to parse manifest %s"; | 556 const char* kFormatString = "Failed to parse manifest %s"; |
| 538 const std::string message = base::StringPrintf(kFormatString, | 557 const std::string message = base::StringPrintf(kFormatString, |
| 539 manifest_url_.spec().c_str()); | 558 manifest_url_.spec().c_str()); |
| 540 HandleCacheFailure(message, MANIFEST_ERROR); | 559 HandleCacheFailure( |
| 560 message, ERROR_MANIFEST_INVALID, manifest_url_, 0, MANIFEST_ERROR); | |
|
michaeln
2014/03/01 00:20:02
maybe use an empty GURL() here too?
jsbell
2014/03/01 00:53:07
Will do.
| |
| 541 VLOG(1) << message; | 561 VLOG(1) << message; |
| 542 return; | 562 return; |
| 543 } | 563 } |
| 544 | 564 |
| 545 // Proceed with update process. Section 6.9.4 steps 8-20. | 565 // Proceed with update process. Section 6.9.4 steps 8-20. |
| 546 internal_state_ = DOWNLOADING; | 566 internal_state_ = DOWNLOADING; |
| 547 inprogress_cache_ = new AppCache(storage_, storage_->NewCacheId()); | 567 inprogress_cache_ = new AppCache(storage_, storage_->NewCacheId()); |
| 548 BuildUrlFileList(manifest); | 568 BuildUrlFileList(manifest); |
| 549 inprogress_cache_->InitializeWithManifest(&manifest); | 569 inprogress_cache_->InitializeWithManifest(&manifest); |
| 550 | 570 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 604 if (entry.IsExplicit() || entry.IsFallback() || entry.IsIntercept()) { | 624 if (entry.IsExplicit() || entry.IsFallback() || entry.IsIntercept()) { |
| 605 if (response_code == 304 && fetcher->existing_entry().has_response_id()) { | 625 if (response_code == 304 && fetcher->existing_entry().has_response_id()) { |
| 606 // Keep the existing response. | 626 // Keep the existing response. |
| 607 entry.set_response_id(fetcher->existing_entry().response_id()); | 627 entry.set_response_id(fetcher->existing_entry().response_id()); |
| 608 entry.set_response_size(fetcher->existing_entry().response_size()); | 628 entry.set_response_size(fetcher->existing_entry().response_size()); |
| 609 inprogress_cache_->AddOrModifyEntry(url, entry); | 629 inprogress_cache_->AddOrModifyEntry(url, entry); |
| 610 } else { | 630 } else { |
| 611 const char* kFormatString = "Resource fetch failed (%d) %s"; | 631 const char* kFormatString = "Resource fetch failed (%d) %s"; |
| 612 std::string message = FormatUrlErrorMessage( | 632 std::string message = FormatUrlErrorMessage( |
| 613 kFormatString, url, fetcher->result(), response_code); | 633 kFormatString, url, fetcher->result(), response_code); |
| 614 HandleCacheFailure(message, fetcher->result()); | 634 ResultType result = fetcher->result(); |
| 635 HandleCacheFailure( | |
| 636 message, | |
| 637 result == DISKCACHE_ERROR ? ERROR_INTERNAL : ERROR_RESOURCE_FETCH, | |
|
michaeln
2014/03/01 00:20:02
This looks reasonable to me, there is something th
jsbell
2014/03/01 00:53:07
D'oh, right. I'll fix.
BTW, I'm making the minima
| |
| 638 url, | |
| 639 response_code, | |
| 640 result); | |
| 615 return; | 641 return; |
| 616 } | 642 } |
| 617 } else if (response_code == 404 || response_code == 410) { | 643 } else if (response_code == 404 || response_code == 410) { |
| 618 // Entry is skipped. They are dropped from the cache. | 644 // Entry is skipped. They are dropped from the cache. |
| 619 } else if (update_type_ == UPGRADE_ATTEMPT && | 645 } else if (update_type_ == UPGRADE_ATTEMPT && |
| 620 fetcher->existing_entry().has_response_id()) { | 646 fetcher->existing_entry().has_response_id()) { |
| 621 // Keep the existing response. | 647 // Keep the existing response. |
| 622 // TODO(michaeln): Not sure this is a good idea. This is spec compliant | 648 // TODO(michaeln): Not sure this is a good idea. This is spec compliant |
| 623 // but the old resource may or may not be compatible with the new contents | 649 // but the old resource may or may not be compatible with the new contents |
| 624 // of the cache. Impossible to know one way or the other. | 650 // of the cache. Impossible to know one way or the other. |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 641 // TODO(jennb): Handle downloads completing during cache failure when update | 667 // TODO(jennb): Handle downloads completing during cache failure when update |
| 642 // no longer fetches master entries directly. For now, we cancel all pending | 668 // no longer fetches master entries directly. For now, we cancel all pending |
| 643 // master entry fetches when entering cache failure state so this will never | 669 // master entry fetches when entering cache failure state so this will never |
| 644 // be called in CACHE_FAILURE state. | 670 // be called in CACHE_FAILURE state. |
| 645 | 671 |
| 646 net::URLRequest* request = fetcher->request(); | 672 net::URLRequest* request = fetcher->request(); |
| 647 const GURL& url = request->original_url(); | 673 const GURL& url = request->original_url(); |
| 648 master_entry_fetches_.erase(url); | 674 master_entry_fetches_.erase(url); |
| 649 ++master_entries_completed_; | 675 ++master_entries_completed_; |
| 650 | 676 |
| 651 int response_code = request->status().is_success() | 677 int response_code = request->status().is_success() |
|
michaeln
2014/03/01 00:20:02
in cases when the fetcher cancels the request, i t
jsbell
2014/03/01 00:53:07
Okay, I'll try and trace this through. We'll need
michaeln
2014/03/01 01:34:56
There are a lot of updatejob unittests. Checking o
jsbell
2014/03/03 23:10:18
Nice find. Hrm.... spec's table (6.7.1.2 Event sum
| |
| 652 ? request->GetResponseCode() : -1; | 678 ? request->GetResponseCode() : -1; |
| 653 | 679 |
| 654 PendingMasters::iterator found = pending_master_entries_.find(url); | 680 PendingMasters::iterator found = pending_master_entries_.find(url); |
| 655 DCHECK(found != pending_master_entries_.end()); | 681 DCHECK(found != pending_master_entries_.end()); |
| 656 PendingHosts& hosts = found->second; | 682 PendingHosts& hosts = found->second; |
| 657 | 683 |
| 658 // Section 6.9.4. No update case: step 7.3, else step 22. | 684 // Section 6.9.4. No update case: step 7.3, else step 22. |
| 659 if (response_code / 100 == 2) { | 685 if (response_code / 100 == 2) { |
| 660 // Add fetched master entry to the appropriate cache. | 686 // Add fetched master entry to the appropriate cache. |
| 661 AppCache* cache = inprogress_cache_.get() ? inprogress_cache_.get() | 687 AppCache* cache = inprogress_cache_.get() ? inprogress_cache_.get() |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 689 if (inprogress_cache_.get()) | 715 if (inprogress_cache_.get()) |
| 690 host->AssociateNoCache(GURL()); | 716 host->AssociateNoCache(GURL()); |
| 691 | 717 |
| 692 host->RemoveObserver(this); | 718 host->RemoveObserver(this); |
| 693 } | 719 } |
| 694 hosts.clear(); | 720 hosts.clear(); |
| 695 | 721 |
| 696 const char* kFormatString = "Manifest fetch failed (%d) %s"; | 722 const char* kFormatString = "Manifest fetch failed (%d) %s"; |
| 697 std::string message = FormatUrlErrorMessage( | 723 std::string message = FormatUrlErrorMessage( |
| 698 kFormatString, request->url(), fetcher->result(), response_code); | 724 kFormatString, request->url(), fetcher->result(), response_code); |
| 699 host_notifier.SendErrorNotifications(message); | 725 host_notifier.SendErrorNotifications( |
| 726 message, ERROR_MANIFEST_FETCH, request->url(), response_code); | |
| 700 | 727 |
| 701 // In downloading case, update result is different if all master entries | 728 // In downloading case, update result is different if all master entries |
| 702 // failed vs. only some failing. | 729 // failed vs. only some failing. |
| 703 if (inprogress_cache_.get()) { | 730 if (inprogress_cache_.get()) { |
| 704 // Only count successful downloads to know if all master entries failed. | 731 // Only count successful downloads to know if all master entries failed. |
| 705 pending_master_entries_.erase(found); | 732 pending_master_entries_.erase(found); |
| 706 --master_entries_completed_; | 733 --master_entries_completed_; |
| 707 | 734 |
| 708 // Section 6.9.4, step 22.3. | 735 // Section 6.9.4, step 22.3. |
| 709 if (update_type_ == CACHE_ATTEMPT && pending_master_entries_.empty()) { | 736 if (update_type_ == CACHE_ATTEMPT && pending_master_entries_.empty()) { |
| 710 HandleCacheFailure(message, fetcher->result()); | 737 HandleCacheFailure(message, |
| 738 ERROR_MANIFEST_FETCH, | |
| 739 request->url(), | |
| 740 response_code, | |
| 741 fetcher->result()); | |
| 711 return; | 742 return; |
| 712 } | 743 } |
| 713 } | 744 } |
| 714 } | 745 } |
| 715 | 746 |
| 716 DCHECK(internal_state_ != CACHE_FAILURE); | 747 DCHECK(internal_state_ != CACHE_FAILURE); |
| 717 FetchMasterEntries(); | 748 FetchMasterEntries(); |
| 718 MaybeCompleteUpdate(); | 749 MaybeCompleteUpdate(); |
| 719 } | 750 } |
| 720 | 751 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 742 io_buffer.get(), | 773 io_buffer.get(), |
| 743 base::Bind(&AppCacheUpdateJob::OnManifestInfoWriteComplete, | 774 base::Bind(&AppCacheUpdateJob::OnManifestInfoWriteComplete, |
| 744 base::Unretained(this))); | 775 base::Unretained(this))); |
| 745 } | 776 } |
| 746 } else { | 777 } else { |
| 747 VLOG(1) << "Request status: " << request->status().status() | 778 VLOG(1) << "Request status: " << request->status().status() |
| 748 << " error: " << request->status().error() | 779 << " error: " << request->status().error() |
| 749 << " response code: " << response_code; | 780 << " response code: " << response_code; |
| 750 ScheduleUpdateRetry(kRerunDelayMs); | 781 ScheduleUpdateRetry(kRerunDelayMs); |
| 751 if (response_code == 200) { | 782 if (response_code == 200) { |
| 752 HandleCacheFailure("Manifest changed during update", MANIFEST_ERROR); | 783 HandleCacheFailure("Manifest changed during update", |
| 784 ERROR_MANIFEST_CHANGED, | |
| 785 manifest_url_, | |
| 786 response_code, | |
| 787 MANIFEST_ERROR); | |
| 753 } else { | 788 } else { |
| 754 const char* kFormatString = "Manifest re-fetch failed (%d) %s"; | 789 const char* kFormatString = "Manifest re-fetch failed (%d) %s"; |
| 755 std::string message = FormatUrlErrorMessage( | 790 std::string message = FormatUrlErrorMessage( |
| 756 kFormatString, manifest_url_, fetcher->result(), response_code); | 791 kFormatString, manifest_url_, fetcher->result(), response_code); |
| 757 HandleCacheFailure(message, fetcher->result()); | 792 HandleCacheFailure(message, |
| 793 ERROR_MANIFEST_FETCH, | |
| 794 manifest_url_, | |
| 795 response_code, | |
| 796 fetcher->result()); | |
| 758 } | 797 } |
| 759 } | 798 } |
| 760 } | 799 } |
| 761 | 800 |
| 762 void AppCacheUpdateJob::OnManifestInfoWriteComplete(int result) { | 801 void AppCacheUpdateJob::OnManifestInfoWriteComplete(int result) { |
| 763 if (result > 0) { | 802 if (result > 0) { |
| 764 scoped_refptr<net::StringIOBuffer> io_buffer( | 803 scoped_refptr<net::StringIOBuffer> io_buffer( |
| 765 new net::StringIOBuffer(manifest_data_)); | 804 new net::StringIOBuffer(manifest_data_)); |
| 766 manifest_response_writer_->WriteData( | 805 manifest_response_writer_->WriteData( |
| 767 io_buffer.get(), | 806 io_buffer.get(), |
| 768 manifest_data_.length(), | 807 manifest_data_.length(), |
| 769 base::Bind(&AppCacheUpdateJob::OnManifestDataWriteComplete, | 808 base::Bind(&AppCacheUpdateJob::OnManifestDataWriteComplete, |
| 770 base::Unretained(this))); | 809 base::Unretained(this))); |
| 771 } else { | 810 } else { |
| 772 HandleCacheFailure("Failed to write the manifest headers to storage", | 811 HandleCacheFailure("Failed to write the manifest headers to storage", |
| 812 ERROR_INTERNAL, | |
| 813 GURL(), | |
| 814 0, | |
| 773 DISKCACHE_ERROR); | 815 DISKCACHE_ERROR); |
| 774 } | 816 } |
| 775 } | 817 } |
| 776 | 818 |
| 777 void AppCacheUpdateJob::OnManifestDataWriteComplete(int result) { | 819 void AppCacheUpdateJob::OnManifestDataWriteComplete(int result) { |
| 778 if (result > 0) { | 820 if (result > 0) { |
| 779 AppCacheEntry entry(AppCacheEntry::MANIFEST, | 821 AppCacheEntry entry(AppCacheEntry::MANIFEST, |
| 780 manifest_response_writer_->response_id(), | 822 manifest_response_writer_->response_id(), |
| 781 manifest_response_writer_->amount_written()); | 823 manifest_response_writer_->amount_written()); |
| 782 if (!inprogress_cache_->AddOrModifyEntry(manifest_url_, entry)) | 824 if (!inprogress_cache_->AddOrModifyEntry(manifest_url_, entry)) |
| 783 duplicate_response_ids_.push_back(entry.response_id()); | 825 duplicate_response_ids_.push_back(entry.response_id()); |
| 784 StoreGroupAndCache(); | 826 StoreGroupAndCache(); |
| 785 } else { | 827 } else { |
| 786 HandleCacheFailure("Failed to write the manifest data to storage", | 828 HandleCacheFailure("Failed to write the manifest data to storage", |
| 829 ERROR_INTERNAL, | |
| 830 GURL(), | |
| 831 0, | |
| 787 DISKCACHE_ERROR); | 832 DISKCACHE_ERROR); |
| 788 } | 833 } |
| 789 } | 834 } |
| 790 | 835 |
| 791 void AppCacheUpdateJob::StoreGroupAndCache() { | 836 void AppCacheUpdateJob::StoreGroupAndCache() { |
| 792 DCHECK(stored_state_ == UNSTORED); | 837 DCHECK(stored_state_ == UNSTORED); |
| 793 stored_state_ = STORING; | 838 stored_state_ = STORING; |
| 794 scoped_refptr<AppCache> newest_cache; | 839 scoped_refptr<AppCache> newest_cache; |
| 795 if (inprogress_cache_.get()) | 840 if (inprogress_cache_.get()) |
| 796 newest_cache.swap(inprogress_cache_); | 841 newest_cache.swap(inprogress_cache_); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 818 // and the proper cleanup to occur. | 863 // and the proper cleanup to occur. |
| 819 if (newest_cache != group->newest_complete_cache()) | 864 if (newest_cache != group->newest_complete_cache()) |
| 820 inprogress_cache_ = newest_cache; | 865 inprogress_cache_ = newest_cache; |
| 821 | 866 |
| 822 ResultType result = DB_ERROR; | 867 ResultType result = DB_ERROR; |
| 823 std::string message("Failed to commit new cache to storage"); | 868 std::string message("Failed to commit new cache to storage"); |
| 824 if (would_exceed_quota) { | 869 if (would_exceed_quota) { |
| 825 message.append(", would exceed quota"); | 870 message.append(", would exceed quota"); |
| 826 result = QUOTA_ERROR; | 871 result = QUOTA_ERROR; |
| 827 } | 872 } |
| 828 HandleCacheFailure(message, result); | 873 HandleCacheFailure( |
| 874 message, | |
| 875 would_exceed_quota ? ERROR_QUOTA_EXCEEDED : ERROR_INTERNAL, | |
| 876 GURL(), | |
| 877 0, | |
| 878 result); | |
| 829 } | 879 } |
| 830 } | 880 } |
| 831 | 881 |
| 832 void AppCacheUpdateJob::NotifySingleHost(AppCacheHost* host, | 882 void AppCacheUpdateJob::NotifySingleHost(AppCacheHost* host, |
| 833 EventID event_id) { | 883 EventID event_id) { |
| 834 std::vector<int> ids(1, host->host_id()); | 884 std::vector<int> ids(1, host->host_id()); |
| 835 host->frontend()->OnEventRaised(ids, event_id); | 885 host->frontend()->OnEventRaised(ids, event_id); |
| 836 } | 886 } |
| 837 | 887 |
| 838 void AppCacheUpdateJob::NotifyAllAssociatedHosts(EventID event_id) { | 888 void AppCacheUpdateJob::NotifyAllAssociatedHosts(EventID event_id) { |
| 839 HostNotifier host_notifier; | 889 HostNotifier host_notifier; |
| 840 AddAllAssociatedHostsToNotifier(&host_notifier); | 890 AddAllAssociatedHostsToNotifier(&host_notifier); |
| 841 host_notifier.SendNotifications(event_id); | 891 host_notifier.SendNotifications(event_id); |
| 842 } | 892 } |
| 843 | 893 |
| 844 void AppCacheUpdateJob::NotifyAllProgress(const GURL& url) { | 894 void AppCacheUpdateJob::NotifyAllProgress(const GURL& url) { |
| 845 HostNotifier host_notifier; | 895 HostNotifier host_notifier; |
| 846 AddAllAssociatedHostsToNotifier(&host_notifier); | 896 AddAllAssociatedHostsToNotifier(&host_notifier); |
| 847 host_notifier.SendProgressNotifications( | 897 host_notifier.SendProgressNotifications( |
| 848 url, url_file_list_.size(), url_fetches_completed_); | 898 url, url_file_list_.size(), url_fetches_completed_); |
| 849 } | 899 } |
| 850 | 900 |
| 851 void AppCacheUpdateJob::NotifyAllFinalProgress() { | 901 void AppCacheUpdateJob::NotifyAllFinalProgress() { |
| 852 DCHECK(url_file_list_.size() == url_fetches_completed_); | 902 DCHECK(url_file_list_.size() == url_fetches_completed_); |
| 853 NotifyAllProgress(GURL()); | 903 NotifyAllProgress(GURL()); |
| 854 } | 904 } |
| 855 | 905 |
| 856 void AppCacheUpdateJob::NotifyAllError(const std::string& error_message) { | 906 void AppCacheUpdateJob::NotifyAllError(const std::string& error_message, |
| 907 ErrorReason reason, | |
| 908 const GURL& resource_url, | |
| 909 int resource_status) { | |
| 857 HostNotifier host_notifier; | 910 HostNotifier host_notifier; |
| 858 AddAllAssociatedHostsToNotifier(&host_notifier); | 911 AddAllAssociatedHostsToNotifier(&host_notifier); |
| 859 host_notifier.SendErrorNotifications(error_message); | 912 host_notifier.SendErrorNotifications( |
| 913 error_message, reason, resource_url, resource_status); | |
| 860 } | 914 } |
| 861 | 915 |
| 862 void AppCacheUpdateJob::AddAllAssociatedHostsToNotifier( | 916 void AppCacheUpdateJob::AddAllAssociatedHostsToNotifier( |
| 863 HostNotifier* host_notifier) { | 917 HostNotifier* host_notifier) { |
| 864 // Collect hosts so we only send one notification per frontend. | 918 // Collect hosts so we only send one notification per frontend. |
| 865 // A host can only be associated with a single cache so no need to worry | 919 // A host can only be associated with a single cache so no need to worry |
| 866 // about duplicate hosts being added to the notifier. | 920 // about duplicate hosts being added to the notifier. |
| 867 if (inprogress_cache_.get()) { | 921 if (inprogress_cache_.get()) { |
| 868 DCHECK(internal_state_ == DOWNLOADING || internal_state_ == CACHE_FAILURE); | 922 DCHECK(internal_state_ == DOWNLOADING || internal_state_ == CACHE_FAILURE); |
| 869 host_notifier->AddHosts(inprogress_cache_->associated_hosts()); | 923 host_notifier->AddHosts(inprogress_cache_->associated_hosts()); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 904 AppCacheEntry* entry = NULL; | 958 AppCacheEntry* entry = NULL; |
| 905 if (group_->newest_complete_cache()) | 959 if (group_->newest_complete_cache()) |
| 906 entry = group_->newest_complete_cache()->GetEntry(manifest_url_); | 960 entry = group_->newest_complete_cache()->GetEntry(manifest_url_); |
| 907 if (!entry) { | 961 if (!entry) { |
| 908 // TODO(michaeln): This is just a bandaid to avoid a crash. | 962 // TODO(michaeln): This is just a bandaid to avoid a crash. |
| 909 // http://code.google.com/p/chromium/issues/detail?id=95101 | 963 // http://code.google.com/p/chromium/issues/detail?id=95101 |
| 910 if (service_->storage() == storage_) { | 964 if (service_->storage() == storage_) { |
| 911 // Use a local variable because service_ is reset in HandleCacheFailure. | 965 // Use a local variable because service_ is reset in HandleCacheFailure. |
| 912 AppCacheService* service = service_; | 966 AppCacheService* service = service_; |
| 913 HandleCacheFailure("Manifest entry not found in existing cache", | 967 HandleCacheFailure("Manifest entry not found in existing cache", |
| 968 ERROR_INTERNAL, | |
| 969 GURL(), | |
| 970 0, | |
| 914 DB_ERROR); | 971 DB_ERROR); |
| 915 AppCacheHistograms::AddMissingManifestEntrySample(); | 972 AppCacheHistograms::AddMissingManifestEntrySample(); |
| 916 service->DeleteAppCacheGroup(manifest_url_, net::CompletionCallback()); | 973 service->DeleteAppCacheGroup(manifest_url_, net::CompletionCallback()); |
| 917 } | 974 } |
| 918 return; | 975 return; |
| 919 } | 976 } |
| 920 | 977 |
| 921 // Load manifest data from storage to compare against fetched manifest. | 978 // Load manifest data from storage to compare against fetched manifest. |
| 922 manifest_response_reader_.reset( | 979 manifest_response_reader_.reset( |
| 923 storage_->CreateResponseReader(manifest_url_, | 980 storage_->CreateResponseReader(manifest_url_, |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1145 url, URLFetcher::MASTER_ENTRY_FETCH, this); | 1202 url, URLFetcher::MASTER_ENTRY_FETCH, this); |
| 1146 fetcher->Start(); | 1203 fetcher->Start(); |
| 1147 master_entry_fetches_.insert(PendingUrlFetches::value_type(url, fetcher)); | 1204 master_entry_fetches_.insert(PendingUrlFetches::value_type(url, fetcher)); |
| 1148 } | 1205 } |
| 1149 | 1206 |
| 1150 master_entries_to_fetch_.erase(master_entries_to_fetch_.begin()); | 1207 master_entries_to_fetch_.erase(master_entries_to_fetch_.begin()); |
| 1151 } | 1208 } |
| 1152 } | 1209 } |
| 1153 | 1210 |
| 1154 void AppCacheUpdateJob::CancelAllMasterEntryFetches( | 1211 void AppCacheUpdateJob::CancelAllMasterEntryFetches( |
| 1155 const std::string& error_message) { | 1212 const std::string& error_message, |
| 1213 ErrorReason reason, | |
| 1214 const GURL& resource_url, | |
| 1215 int resource_status) { | |
| 1156 // For now, cancel all in-progress fetches for master entries and pretend | 1216 // For now, cancel all in-progress fetches for master entries and pretend |
| 1157 // all master entries fetches have completed. | 1217 // all master entries fetches have completed. |
| 1158 // TODO(jennb): Delete this when update no longer fetches master entries | 1218 // TODO(jennb): Delete this when update no longer fetches master entries |
| 1159 // directly. | 1219 // directly. |
| 1160 | 1220 |
| 1161 // Cancel all in-progress fetches. | 1221 // Cancel all in-progress fetches. |
| 1162 for (PendingUrlFetches::iterator it = master_entry_fetches_.begin(); | 1222 for (PendingUrlFetches::iterator it = master_entry_fetches_.begin(); |
| 1163 it != master_entry_fetches_.end(); ++it) { | 1223 it != master_entry_fetches_.end(); ++it) { |
| 1164 delete it->second; | 1224 delete it->second; |
| 1165 master_entries_to_fetch_.insert(it->first); // back in unfetched list | 1225 master_entries_to_fetch_.insert(it->first); // back in unfetched list |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1181 host_it != hosts.end(); ++host_it) { | 1241 host_it != hosts.end(); ++host_it) { |
| 1182 AppCacheHost* host = *host_it; | 1242 AppCacheHost* host = *host_it; |
| 1183 host->AssociateNoCache(GURL()); | 1243 host->AssociateNoCache(GURL()); |
| 1184 host_notifier.AddHost(host); | 1244 host_notifier.AddHost(host); |
| 1185 host->RemoveObserver(this); | 1245 host->RemoveObserver(this); |
| 1186 } | 1246 } |
| 1187 hosts.clear(); | 1247 hosts.clear(); |
| 1188 | 1248 |
| 1189 master_entries_to_fetch_.erase(master_entries_to_fetch_.begin()); | 1249 master_entries_to_fetch_.erase(master_entries_to_fetch_.begin()); |
| 1190 } | 1250 } |
| 1191 host_notifier.SendErrorNotifications(error_message); | 1251 host_notifier.SendErrorNotifications( |
| 1252 error_message, reason, resource_url, resource_status); | |
| 1192 } | 1253 } |
| 1193 | 1254 |
| 1194 bool AppCacheUpdateJob::MaybeLoadFromNewestCache(const GURL& url, | 1255 bool AppCacheUpdateJob::MaybeLoadFromNewestCache(const GURL& url, |
| 1195 AppCacheEntry& entry) { | 1256 AppCacheEntry& entry) { |
| 1196 if (update_type_ != UPGRADE_ATTEMPT) | 1257 if (update_type_ != UPGRADE_ATTEMPT) |
| 1197 return false; | 1258 return false; |
| 1198 | 1259 |
| 1199 AppCache* newest = group_->newest_complete_cache(); | 1260 AppCache* newest = group_->newest_complete_cache(); |
| 1200 AppCacheEntry* copy_me = newest->GetEntry(url); | 1261 AppCacheEntry* copy_me = newest->GetEntry(url); |
| 1201 if (!copy_me || !copy_me->has_response_id()) | 1262 if (!copy_me || !copy_me->has_response_id()) |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1425 | 1486 |
| 1426 // Break the connection with the group so the group cannot call delete | 1487 // Break the connection with the group so the group cannot call delete |
| 1427 // on this object after we've posted a task to delete ourselves. | 1488 // on this object after we've posted a task to delete ourselves. |
| 1428 group_->SetUpdateStatus(AppCacheGroup::IDLE); | 1489 group_->SetUpdateStatus(AppCacheGroup::IDLE); |
| 1429 group_ = NULL; | 1490 group_ = NULL; |
| 1430 | 1491 |
| 1431 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 1492 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
| 1432 } | 1493 } |
| 1433 | 1494 |
| 1434 } // namespace appcache | 1495 } // namespace appcache |
| OLD | NEW |