Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Side by Side Diff: webkit/browser/appcache/appcache_update_job.cc

Issue 164933002: Expose details for appcache error events [Chromium] (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review feedback Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « webkit/browser/appcache/appcache_update_job.h ('k') | webkit/browser/appcache/appcache_update_job_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698