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

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: Don't leak details cross-origin 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 ErrorDetails& details) {
80 DCHECK(!error_message.empty()); 80 DCHECK(!details.message.empty());
81 for (NotifyHostMap::iterator it = hosts_to_notify.begin(); 81 for (NotifyHostMap::iterator it = hosts_to_notify.begin();
82 it != hosts_to_notify.end(); ++it) { 82 it != hosts_to_notify.end(); ++it) {
83 AppCacheFrontend* frontend = it->first; 83 AppCacheFrontend* frontend = it->first;
84 frontend->OnErrorEventRaised(it->second, error_message); 84 frontend->OnErrorEventRaised(it->second, details);
85 } 85 }
86 } 86 }
87 87
88 private: 88 private:
89 NotifyHostMap hosts_to_notify; 89 NotifyHostMap hosts_to_notify;
90 }; 90 };
91 91
92 AppCacheUpdateJob::UrlToFetch::UrlToFetch(const GURL& url, 92 AppCacheUpdateJob::UrlToFetch::UrlToFetch(const GURL& url,
93 bool checked, 93 bool checked,
94 AppCacheResponseInfo* info) 94 AppCacheResponseInfo* info)
(...skipping 10 matching lines...) Expand all
105 // data out to the disk cache. 105 // data out to the disk cache.
106 AppCacheUpdateJob::URLFetcher::URLFetcher(const GURL& url, 106 AppCacheUpdateJob::URLFetcher::URLFetcher(const GURL& url,
107 FetchType fetch_type, 107 FetchType fetch_type,
108 AppCacheUpdateJob* job) 108 AppCacheUpdateJob* job)
109 : url_(url), 109 : url_(url),
110 job_(job), 110 job_(job),
111 fetch_type_(fetch_type), 111 fetch_type_(fetch_type),
112 retry_503_attempts_(0), 112 retry_503_attempts_(0),
113 buffer_(new net::IOBuffer(kBufferSize)), 113 buffer_(new net::IOBuffer(kBufferSize)),
114 request_(job->service_->request_context() 114 request_(job->service_->request_context()
115 ->CreateRequest(url, net::DEFAULT_PRIORITY, this, NULL)), 115 ->CreateRequest(url, net::DEFAULT_PRIORITY, this, NULL)),
116 result_(UPDATE_OK) {} 116 result_(UPDATE_OK),
117 canceled_response_code_(-1) {}
michaeln 2014/03/27 01:05:37 redirect_response_code_ might be a better name?
jsbell 2014/03/27 19:23:23 Done.
117 118
118 AppCacheUpdateJob::URLFetcher::~URLFetcher() { 119 AppCacheUpdateJob::URLFetcher::~URLFetcher() {
119 } 120 }
120 121
121 void AppCacheUpdateJob::URLFetcher::Start() { 122 void AppCacheUpdateJob::URLFetcher::Start() {
122 request_->set_first_party_for_cookies(job_->manifest_url_); 123 request_->set_first_party_for_cookies(job_->manifest_url_);
123 request_->SetLoadFlags(request_->load_flags() | 124 request_->SetLoadFlags(request_->load_flags() |
124 net::LOAD_DISABLE_INTERCEPT); 125 net::LOAD_DISABLE_INTERCEPT);
125 if (existing_response_headers_.get()) 126 if (existing_response_headers_.get())
126 AddConditionalHeaders(existing_response_headers_.get()); 127 AddConditionalHeaders(existing_response_headers_.get());
127 request_->Start(); 128 request_->Start();
128 } 129 }
129 130
130 void AppCacheUpdateJob::URLFetcher::OnReceivedRedirect( 131 void AppCacheUpdateJob::URLFetcher::OnReceivedRedirect(
131 net::URLRequest* request, const GURL& new_url, bool* defer_redirect) { 132 net::URLRequest* request, const GURL& new_url, bool* defer_redirect) {
132 DCHECK(request_ == request); 133 DCHECK(request_ == request);
133 // Redirect is not allowed by the update process. 134 // Redirect is not allowed by the update process.
135 canceled_response_code_ = request->GetResponseCode();
134 request->Cancel(); 136 request->Cancel();
135 result_ = REDIRECT_ERROR; 137 result_ = REDIRECT_ERROR;
136 OnResponseCompleted(); 138 OnResponseCompleted();
137 } 139 }
138 140
139 void AppCacheUpdateJob::URLFetcher::OnResponseStarted( 141 void AppCacheUpdateJob::URLFetcher::OnResponseStarted(
140 net::URLRequest *request) { 142 net::URLRequest *request) {
141 DCHECK(request == request_); 143 DCHECK(request == request_);
142 int response_code = -1; 144 int response_code = -1;
143 if (request->status().is_success()) 145 if (request->status().is_success())
144 response_code = request->GetResponseCode(); 146 response_code = request->GetResponseCode();
145 if ((response_code / 100) == 2) { 147 if ((response_code / 100) == 2) {
146 148
147 // See http://code.google.com/p/chromium/issues/detail?id=69594 149 // See http://code.google.com/p/chromium/issues/detail?id=69594
148 // We willfully violate the HTML5 spec at this point in order 150 // We willfully violate the HTML5 spec at this point in order
149 // to support the appcaching of cross-origin HTTPS resources. 151 // to support the appcaching of cross-origin HTTPS resources.
150 // We've opted for a milder constraint and allow caching unless 152 // We've opted for a milder constraint and allow caching unless
151 // the resource has a "no-store" header. A spec change has been 153 // the resource has a "no-store" header. A spec change has been
152 // requested on the whatwg list. 154 // requested on the whatwg list.
153 // TODO(michaeln): Consider doing this for cross-origin HTTP resources too. 155 // TODO(michaeln): Consider doing this for cross-origin HTTP resources too.
154 if (url_.SchemeIsSecure() && 156 if (url_.SchemeIsSecure() &&
155 url_.GetOrigin() != job_->manifest_url_.GetOrigin()) { 157 url_.GetOrigin() != job_->manifest_url_.GetOrigin()) {
156 if (request->response_headers()-> 158 if (request->response_headers()->
157 HasHeaderValue("cache-control", "no-store")) { 159 HasHeaderValue("cache-control", "no-store")) {
160 DCHECK_EQ(-1, canceled_response_code_);
158 request->Cancel(); 161 request->Cancel();
159 result_ = SERVER_ERROR; // Not the best match? 162 result_ = SERVER_ERROR; // Not the best match?
160 OnResponseCompleted(); 163 OnResponseCompleted();
161 return; 164 return;
162 } 165 }
163 } 166 }
164 167
165 // Write response info to storage for URL fetches. Wait for async write 168 // Write response info to storage for URL fetches. Wait for async write
166 // completion before reading any response data. 169 // completion before reading any response data.
167 if (fetch_type_ == URL_FETCH || fetch_type_ == MASTER_ENTRY_FETCH) { 170 if (fetch_type_ == URL_FETCH || fetch_type_ == MASTER_ENTRY_FETCH) {
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 } 416 }
414 417
415 AppCacheResponseWriter* AppCacheUpdateJob::CreateResponseWriter() { 418 AppCacheResponseWriter* AppCacheUpdateJob::CreateResponseWriter() {
416 AppCacheResponseWriter* writer = 419 AppCacheResponseWriter* writer =
417 storage_->CreateResponseWriter(manifest_url_, 420 storage_->CreateResponseWriter(manifest_url_,
418 group_->group_id()); 421 group_->group_id());
419 stored_response_ids_.push_back(writer->response_id()); 422 stored_response_ids_.push_back(writer->response_id());
420 return writer; 423 return writer;
421 } 424 }
422 425
423 void AppCacheUpdateJob::HandleCacheFailure( 426 void AppCacheUpdateJob::HandleCacheFailure(const ErrorDetails& error_details,
424 const std::string& error_message, 427 ResultType result) {
425 ResultType result) {
426 // 6.9.4 cache failure steps 2-8. 428 // 6.9.4 cache failure steps 2-8.
427 DCHECK(internal_state_ != CACHE_FAILURE); 429 DCHECK(internal_state_ != CACHE_FAILURE);
428 DCHECK(!error_message.empty()); 430 DCHECK(!error_details.message.empty());
429 DCHECK(result != UPDATE_OK); 431 DCHECK(result != UPDATE_OK);
430 internal_state_ = CACHE_FAILURE; 432 internal_state_ = CACHE_FAILURE;
431 CancelAllUrlFetches(); 433 CancelAllUrlFetches();
432 CancelAllMasterEntryFetches(error_message); 434 CancelAllMasterEntryFetches(error_details);
433 NotifyAllError(error_message); 435 NotifyAllError(error_details);
434 DiscardInprogressCache(); 436 DiscardInprogressCache();
435 internal_state_ = COMPLETED; 437 internal_state_ = COMPLETED;
436 AppCacheHistograms::CountUpdateJobResult( 438 AppCacheHistograms::CountUpdateJobResult(
437 result, manifest_url_.GetOrigin()); 439 result, manifest_url_.GetOrigin());
438 DeleteSoon(); // To unwind the stack prior to deletion. 440 DeleteSoon(); // To unwind the stack prior to deletion.
439 } 441 }
440 442
441 void AppCacheUpdateJob::FetchManifest(bool is_first_fetch) { 443 void AppCacheUpdateJob::FetchManifest(bool is_first_fetch) {
442 DCHECK(!manifest_fetcher_); 444 DCHECK(!manifest_fetcher_);
443 manifest_fetcher_ = new URLFetcher( 445 manifest_fetcher_ = new URLFetcher(
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 manifest_response_info_.reset( 488 manifest_response_info_.reset(
487 new net::HttpResponseInfo(request->response_info())); 489 new net::HttpResponseInfo(request->response_info()));
488 if (update_type_ == UPGRADE_ATTEMPT) 490 if (update_type_ == UPGRADE_ATTEMPT)
489 CheckIfManifestChanged(); // continues asynchronously 491 CheckIfManifestChanged(); // continues asynchronously
490 else 492 else
491 ContinueHandleManifestFetchCompleted(true); 493 ContinueHandleManifestFetchCompleted(true);
492 } else if (response_code == 304 && update_type_ == UPGRADE_ATTEMPT) { 494 } else if (response_code == 304 && update_type_ == UPGRADE_ATTEMPT) {
493 ContinueHandleManifestFetchCompleted(false); 495 ContinueHandleManifestFetchCompleted(false);
494 } else if ((response_code == 404 || response_code == 410) && 496 } else if ((response_code == 404 || response_code == 410) &&
495 update_type_ == UPGRADE_ATTEMPT) { 497 update_type_ == UPGRADE_ATTEMPT) {
496 storage_->MakeGroupObsolete(group_, this); // async 498 storage_->MakeGroupObsolete(group_, this, response_code); // async
497 } else { 499 } else {
498 const char* kFormatString = "Manifest fetch failed (%d) %s"; 500 const char* kFormatString = "Manifest fetch failed (%d) %s";
499 std::string message = FormatUrlErrorMessage( 501 std::string message = FormatUrlErrorMessage(
500 kFormatString, manifest_url_, fetcher->result(), response_code); 502 kFormatString, manifest_url_, fetcher->result(), response_code);
501 HandleCacheFailure(message, fetcher->result()); 503 HandleCacheFailure(ErrorDetails(message,
504 appcache::MANIFEST_ERROR,
505 manifest_url_,
506 response_code,
507 false /*is_cross_origin*/),
508 fetcher->result());
502 } 509 }
503 } 510 }
504 511
505 void AppCacheUpdateJob::OnGroupMadeObsolete(AppCacheGroup* group, 512 void AppCacheUpdateJob::OnGroupMadeObsolete(AppCacheGroup* group,
506 bool success) { 513 bool success,
514 int response_code) {
507 DCHECK(master_entry_fetches_.empty()); 515 DCHECK(master_entry_fetches_.empty());
508 CancelAllMasterEntryFetches("The cache has been made obsolete, " 516 CancelAllMasterEntryFetches(ErrorDetails(
509 "the manifest file returned 404 or 410"); 517 "The cache has been made obsolete, "
518 "the manifest file returned 404 or 410",
519 appcache::MANIFEST_ERROR,
520 GURL(),
521 response_code,
522 false /*is_cross_origin*/));
510 if (success) { 523 if (success) {
511 DCHECK(group->is_obsolete()); 524 DCHECK(group->is_obsolete());
512 NotifyAllAssociatedHosts(OBSOLETE_EVENT); 525 NotifyAllAssociatedHosts(OBSOLETE_EVENT);
513 internal_state_ = COMPLETED; 526 internal_state_ = COMPLETED;
514 MaybeCompleteUpdate(); 527 MaybeCompleteUpdate();
515 } else { 528 } else {
516 // Treat failure to mark group obsolete as a cache failure. 529 // Treat failure to mark group obsolete as a cache failure.
517 HandleCacheFailure("Failed to mark the cache as obsolete", DB_ERROR); 530 HandleCacheFailure(ErrorDetails("Failed to mark the cache as obsolete",
531 UNKNOWN_ERROR,
532 GURL(),
533 0,
534 false /*is_cross_origin*/),
535 DB_ERROR);
518 } 536 }
519 } 537 }
520 538
521 void AppCacheUpdateJob::ContinueHandleManifestFetchCompleted(bool changed) { 539 void AppCacheUpdateJob::ContinueHandleManifestFetchCompleted(bool changed) {
522 DCHECK(internal_state_ == FETCH_MANIFEST); 540 DCHECK(internal_state_ == FETCH_MANIFEST);
523 541
524 if (!changed) { 542 if (!changed) {
525 DCHECK(update_type_ == UPGRADE_ATTEMPT); 543 DCHECK(update_type_ == UPGRADE_ATTEMPT);
526 internal_state_ = NO_UPDATE; 544 internal_state_ = NO_UPDATE;
527 545
528 // Wait for pending master entries to download. 546 // Wait for pending master entries to download.
529 FetchMasterEntries(); 547 FetchMasterEntries();
530 MaybeCompleteUpdate(); // if not done, run async 6.9.4 step 7 substeps 548 MaybeCompleteUpdate(); // if not done, run async 6.9.4 step 7 substeps
531 return; 549 return;
532 } 550 }
533 551
534 Manifest manifest; 552 Manifest manifest;
535 if (!ParseManifest(manifest_url_, manifest_data_.data(), 553 if (!ParseManifest(manifest_url_, manifest_data_.data(),
536 manifest_data_.length(), manifest)) { 554 manifest_data_.length(), manifest)) {
537 const char* kFormatString = "Failed to parse manifest %s"; 555 const char* kFormatString = "Failed to parse manifest %s";
538 const std::string message = base::StringPrintf(kFormatString, 556 const std::string message = base::StringPrintf(kFormatString,
539 manifest_url_.spec().c_str()); 557 manifest_url_.spec().c_str());
540 HandleCacheFailure(message, MANIFEST_ERROR); 558 HandleCacheFailure(
559 ErrorDetails(
560 message, SIGNATURE_ERROR, GURL(), 0, false /*is_cross_origin*/),
561 MANIFEST_ERROR);
541 VLOG(1) << message; 562 VLOG(1) << message;
542 return; 563 return;
543 } 564 }
544 565
545 // Proceed with update process. Section 6.9.4 steps 8-20. 566 // Proceed with update process. Section 6.9.4 steps 8-20.
546 internal_state_ = DOWNLOADING; 567 internal_state_ = DOWNLOADING;
547 inprogress_cache_ = new AppCache(storage_, storage_->NewCacheId()); 568 inprogress_cache_ = new AppCache(storage_, storage_->NewCacheId());
548 BuildUrlFileList(manifest); 569 BuildUrlFileList(manifest);
549 inprogress_cache_->InitializeWithManifest(&manifest); 570 inprogress_cache_->InitializeWithManifest(&manifest);
550 571
(...skipping 18 matching lines...) Expand all
569 void AppCacheUpdateJob::HandleUrlFetchCompleted(URLFetcher* fetcher) { 590 void AppCacheUpdateJob::HandleUrlFetchCompleted(URLFetcher* fetcher) {
570 DCHECK(internal_state_ == DOWNLOADING); 591 DCHECK(internal_state_ == DOWNLOADING);
571 592
572 net::URLRequest* request = fetcher->request(); 593 net::URLRequest* request = fetcher->request();
573 const GURL& url = request->original_url(); 594 const GURL& url = request->original_url();
574 pending_url_fetches_.erase(url); 595 pending_url_fetches_.erase(url);
575 NotifyAllProgress(url); 596 NotifyAllProgress(url);
576 ++url_fetches_completed_; 597 ++url_fetches_completed_;
577 598
578 int response_code = request->status().is_success() 599 int response_code = request->status().is_success()
579 ? request->GetResponseCode() : -1; 600 ? request->GetResponseCode()
601 : fetcher->canceled_response_code();
580 AppCacheEntry& entry = url_file_list_.find(url)->second; 602 AppCacheEntry& entry = url_file_list_.find(url)->second;
581 603
582 if (response_code / 100 == 2) { 604 if (response_code / 100 == 2) {
583 // Associate storage with the new entry. 605 // Associate storage with the new entry.
584 DCHECK(fetcher->response_writer()); 606 DCHECK(fetcher->response_writer());
585 entry.set_response_id(fetcher->response_writer()->response_id()); 607 entry.set_response_id(fetcher->response_writer()->response_id());
586 entry.set_response_size(fetcher->response_writer()->amount_written()); 608 entry.set_response_size(fetcher->response_writer()->amount_written());
587 if (!inprogress_cache_->AddOrModifyEntry(url, entry)) 609 if (!inprogress_cache_->AddOrModifyEntry(url, entry))
588 duplicate_response_ids_.push_back(entry.response_id()); 610 duplicate_response_ids_.push_back(entry.response_id());
589 611
(...skipping 14 matching lines...) Expand all
604 if (entry.IsExplicit() || entry.IsFallback() || entry.IsIntercept()) { 626 if (entry.IsExplicit() || entry.IsFallback() || entry.IsIntercept()) {
605 if (response_code == 304 && fetcher->existing_entry().has_response_id()) { 627 if (response_code == 304 && fetcher->existing_entry().has_response_id()) {
606 // Keep the existing response. 628 // Keep the existing response.
607 entry.set_response_id(fetcher->existing_entry().response_id()); 629 entry.set_response_id(fetcher->existing_entry().response_id());
608 entry.set_response_size(fetcher->existing_entry().response_size()); 630 entry.set_response_size(fetcher->existing_entry().response_size());
609 inprogress_cache_->AddOrModifyEntry(url, entry); 631 inprogress_cache_->AddOrModifyEntry(url, entry);
610 } else { 632 } else {
611 const char* kFormatString = "Resource fetch failed (%d) %s"; 633 const char* kFormatString = "Resource fetch failed (%d) %s";
612 std::string message = FormatUrlErrorMessage( 634 std::string message = FormatUrlErrorMessage(
613 kFormatString, url, fetcher->result(), response_code); 635 kFormatString, url, fetcher->result(), response_code);
614 HandleCacheFailure(message, fetcher->result()); 636 ResultType result = fetcher->result();
637 bool is_cross_origin = url.GetOrigin() != manifest_url_.GetOrigin();
638 switch (result) {
639 case DISKCACHE_ERROR:
640 HandleCacheFailure(
641 ErrorDetails(
642 message, UNKNOWN_ERROR, GURL(), 0, is_cross_origin),
643 result);
644 break;
645 case NETWORK_ERROR:
646 HandleCacheFailure(
647 ErrorDetails(message, RESOURCE_ERROR, url, 0, is_cross_origin),
648 result);
649 break;
650 default:
651 HandleCacheFailure(ErrorDetails(message,
652 RESOURCE_ERROR,
653 url,
654 response_code,
655 is_cross_origin),
656 result);
657 break;
658 }
615 return; 659 return;
616 } 660 }
617 } else if (response_code == 404 || response_code == 410) { 661 } else if (response_code == 404 || response_code == 410) {
618 // Entry is skipped. They are dropped from the cache. 662 // Entry is skipped. They are dropped from the cache.
619 } else if (update_type_ == UPGRADE_ATTEMPT && 663 } else if (update_type_ == UPGRADE_ATTEMPT &&
620 fetcher->existing_entry().has_response_id()) { 664 fetcher->existing_entry().has_response_id()) {
621 // Keep the existing response. 665 // Keep the existing response.
622 // TODO(michaeln): Not sure this is a good idea. This is spec compliant 666 // 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 667 // 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. 668 // of the cache. Impossible to know one way or the other.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
689 if (inprogress_cache_.get()) 733 if (inprogress_cache_.get())
690 host->AssociateNoCache(GURL()); 734 host->AssociateNoCache(GURL());
691 735
692 host->RemoveObserver(this); 736 host->RemoveObserver(this);
693 } 737 }
694 hosts.clear(); 738 hosts.clear();
695 739
696 const char* kFormatString = "Manifest fetch failed (%d) %s"; 740 const char* kFormatString = "Manifest fetch failed (%d) %s";
697 std::string message = FormatUrlErrorMessage( 741 std::string message = FormatUrlErrorMessage(
698 kFormatString, request->url(), fetcher->result(), response_code); 742 kFormatString, request->url(), fetcher->result(), response_code);
699 host_notifier.SendErrorNotifications(message); 743 host_notifier.SendErrorNotifications(
744 ErrorDetails(message,
745 appcache::MANIFEST_ERROR,
746 request->url(),
747 response_code,
748 false /*is_cross_origin*/));
700 749
701 // In downloading case, update result is different if all master entries 750 // In downloading case, update result is different if all master entries
702 // failed vs. only some failing. 751 // failed vs. only some failing.
703 if (inprogress_cache_.get()) { 752 if (inprogress_cache_.get()) {
704 // Only count successful downloads to know if all master entries failed. 753 // Only count successful downloads to know if all master entries failed.
705 pending_master_entries_.erase(found); 754 pending_master_entries_.erase(found);
706 --master_entries_completed_; 755 --master_entries_completed_;
707 756
708 // Section 6.9.4, step 22.3. 757 // Section 6.9.4, step 22.3.
709 if (update_type_ == CACHE_ATTEMPT && pending_master_entries_.empty()) { 758 if (update_type_ == CACHE_ATTEMPT && pending_master_entries_.empty()) {
710 HandleCacheFailure(message, fetcher->result()); 759 HandleCacheFailure(ErrorDetails(message,
760 appcache::MANIFEST_ERROR,
761 request->url(),
762 response_code,
763 false /*is_cross_origin*/),
764 fetcher->result());
711 return; 765 return;
712 } 766 }
713 } 767 }
714 } 768 }
715 769
716 DCHECK(internal_state_ != CACHE_FAILURE); 770 DCHECK(internal_state_ != CACHE_FAILURE);
717 FetchMasterEntries(); 771 FetchMasterEntries();
718 MaybeCompleteUpdate(); 772 MaybeCompleteUpdate();
719 } 773 }
720 774
(...skipping 21 matching lines...) Expand all
742 io_buffer.get(), 796 io_buffer.get(),
743 base::Bind(&AppCacheUpdateJob::OnManifestInfoWriteComplete, 797 base::Bind(&AppCacheUpdateJob::OnManifestInfoWriteComplete,
744 base::Unretained(this))); 798 base::Unretained(this)));
745 } 799 }
746 } else { 800 } else {
747 VLOG(1) << "Request status: " << request->status().status() 801 VLOG(1) << "Request status: " << request->status().status()
748 << " error: " << request->status().error() 802 << " error: " << request->status().error()
749 << " response code: " << response_code; 803 << " response code: " << response_code;
750 ScheduleUpdateRetry(kRerunDelayMs); 804 ScheduleUpdateRetry(kRerunDelayMs);
751 if (response_code == 200) { 805 if (response_code == 200) {
752 HandleCacheFailure("Manifest changed during update", MANIFEST_ERROR); 806 HandleCacheFailure(ErrorDetails("Manifest changed during update",
807 CHANGED_ERROR,
808 GURL(),
809 0,
810 false /*is_cross_origin*/),
811 MANIFEST_ERROR);
753 } else { 812 } else {
754 const char* kFormatString = "Manifest re-fetch failed (%d) %s"; 813 const char* kFormatString = "Manifest re-fetch failed (%d) %s";
755 std::string message = FormatUrlErrorMessage( 814 std::string message = FormatUrlErrorMessage(
756 kFormatString, manifest_url_, fetcher->result(), response_code); 815 kFormatString, manifest_url_, fetcher->result(), response_code);
757 HandleCacheFailure(message, fetcher->result()); 816 HandleCacheFailure(ErrorDetails(message,
817 appcache::MANIFEST_ERROR,
818 GURL(),
819 response_code,
820 false /*is_cross_origin*/),
821 fetcher->result());
758 } 822 }
759 } 823 }
760 } 824 }
761 825
762 void AppCacheUpdateJob::OnManifestInfoWriteComplete(int result) { 826 void AppCacheUpdateJob::OnManifestInfoWriteComplete(int result) {
763 if (result > 0) { 827 if (result > 0) {
764 scoped_refptr<net::StringIOBuffer> io_buffer( 828 scoped_refptr<net::StringIOBuffer> io_buffer(
765 new net::StringIOBuffer(manifest_data_)); 829 new net::StringIOBuffer(manifest_data_));
766 manifest_response_writer_->WriteData( 830 manifest_response_writer_->WriteData(
767 io_buffer.get(), 831 io_buffer.get(),
768 manifest_data_.length(), 832 manifest_data_.length(),
769 base::Bind(&AppCacheUpdateJob::OnManifestDataWriteComplete, 833 base::Bind(&AppCacheUpdateJob::OnManifestDataWriteComplete,
770 base::Unretained(this))); 834 base::Unretained(this)));
771 } else { 835 } else {
772 HandleCacheFailure("Failed to write the manifest headers to storage", 836 HandleCacheFailure(
773 DISKCACHE_ERROR); 837 ErrorDetails("Failed to write the manifest headers to storage",
838 UNKNOWN_ERROR,
839 GURL(),
840 0,
841 false /*is_cross_origin*/),
842 DISKCACHE_ERROR);
774 } 843 }
775 } 844 }
776 845
777 void AppCacheUpdateJob::OnManifestDataWriteComplete(int result) { 846 void AppCacheUpdateJob::OnManifestDataWriteComplete(int result) {
778 if (result > 0) { 847 if (result > 0) {
779 AppCacheEntry entry(AppCacheEntry::MANIFEST, 848 AppCacheEntry entry(AppCacheEntry::MANIFEST,
780 manifest_response_writer_->response_id(), 849 manifest_response_writer_->response_id(),
781 manifest_response_writer_->amount_written()); 850 manifest_response_writer_->amount_written());
782 if (!inprogress_cache_->AddOrModifyEntry(manifest_url_, entry)) 851 if (!inprogress_cache_->AddOrModifyEntry(manifest_url_, entry))
783 duplicate_response_ids_.push_back(entry.response_id()); 852 duplicate_response_ids_.push_back(entry.response_id());
784 StoreGroupAndCache(); 853 StoreGroupAndCache();
785 } else { 854 } else {
786 HandleCacheFailure("Failed to write the manifest data to storage", 855 HandleCacheFailure(
787 DISKCACHE_ERROR); 856 ErrorDetails("Failed to write the manifest data to storage",
857 UNKNOWN_ERROR,
858 GURL(),
859 0,
860 false /*is_cross_origin*/),
861 DISKCACHE_ERROR);
788 } 862 }
789 } 863 }
790 864
791 void AppCacheUpdateJob::StoreGroupAndCache() { 865 void AppCacheUpdateJob::StoreGroupAndCache() {
792 DCHECK(stored_state_ == UNSTORED); 866 DCHECK(stored_state_ == UNSTORED);
793 stored_state_ = STORING; 867 stored_state_ = STORING;
794 scoped_refptr<AppCache> newest_cache; 868 scoped_refptr<AppCache> newest_cache;
795 if (inprogress_cache_.get()) 869 if (inprogress_cache_.get())
796 newest_cache.swap(inprogress_cache_); 870 newest_cache.swap(inprogress_cache_);
797 else 871 else
(...skipping 15 matching lines...) Expand all
813 MaybeCompleteUpdate(); // will definitely complete 887 MaybeCompleteUpdate(); // will definitely complete
814 } else { 888 } else {
815 stored_state_ = UNSTORED; 889 stored_state_ = UNSTORED;
816 890
817 // Restore inprogress_cache_ to get the proper events delivered 891 // Restore inprogress_cache_ to get the proper events delivered
818 // and the proper cleanup to occur. 892 // and the proper cleanup to occur.
819 if (newest_cache != group->newest_complete_cache()) 893 if (newest_cache != group->newest_complete_cache())
820 inprogress_cache_ = newest_cache; 894 inprogress_cache_ = newest_cache;
821 895
822 ResultType result = DB_ERROR; 896 ResultType result = DB_ERROR;
897 ErrorReason reason = UNKNOWN_ERROR;
823 std::string message("Failed to commit new cache to storage"); 898 std::string message("Failed to commit new cache to storage");
824 if (would_exceed_quota) { 899 if (would_exceed_quota) {
825 message.append(", would exceed quota"); 900 message.append(", would exceed quota");
826 result = QUOTA_ERROR; 901 result = QUOTA_ERROR;
902 reason = appcache::QUOTA_ERROR;
827 } 903 }
828 HandleCacheFailure(message, result); 904 HandleCacheFailure(
905 ErrorDetails(message, reason, GURL(), 0, false /*is_cross_origin*/),
906 result);
829 } 907 }
830 } 908 }
831 909
832 void AppCacheUpdateJob::NotifySingleHost(AppCacheHost* host, 910 void AppCacheUpdateJob::NotifySingleHost(AppCacheHost* host,
833 EventID event_id) { 911 EventID event_id) {
834 std::vector<int> ids(1, host->host_id()); 912 std::vector<int> ids(1, host->host_id());
835 host->frontend()->OnEventRaised(ids, event_id); 913 host->frontend()->OnEventRaised(ids, event_id);
836 } 914 }
837 915
838 void AppCacheUpdateJob::NotifyAllAssociatedHosts(EventID event_id) { 916 void AppCacheUpdateJob::NotifyAllAssociatedHosts(EventID event_id) {
839 HostNotifier host_notifier; 917 HostNotifier host_notifier;
840 AddAllAssociatedHostsToNotifier(&host_notifier); 918 AddAllAssociatedHostsToNotifier(&host_notifier);
841 host_notifier.SendNotifications(event_id); 919 host_notifier.SendNotifications(event_id);
842 } 920 }
843 921
844 void AppCacheUpdateJob::NotifyAllProgress(const GURL& url) { 922 void AppCacheUpdateJob::NotifyAllProgress(const GURL& url) {
845 HostNotifier host_notifier; 923 HostNotifier host_notifier;
846 AddAllAssociatedHostsToNotifier(&host_notifier); 924 AddAllAssociatedHostsToNotifier(&host_notifier);
847 host_notifier.SendProgressNotifications( 925 host_notifier.SendProgressNotifications(
848 url, url_file_list_.size(), url_fetches_completed_); 926 url, url_file_list_.size(), url_fetches_completed_);
849 } 927 }
850 928
851 void AppCacheUpdateJob::NotifyAllFinalProgress() { 929 void AppCacheUpdateJob::NotifyAllFinalProgress() {
852 DCHECK(url_file_list_.size() == url_fetches_completed_); 930 DCHECK(url_file_list_.size() == url_fetches_completed_);
853 NotifyAllProgress(GURL()); 931 NotifyAllProgress(GURL());
854 } 932 }
855 933
856 void AppCacheUpdateJob::NotifyAllError(const std::string& error_message) { 934 void AppCacheUpdateJob::NotifyAllError(const ErrorDetails& details) {
857 HostNotifier host_notifier; 935 HostNotifier host_notifier;
858 AddAllAssociatedHostsToNotifier(&host_notifier); 936 AddAllAssociatedHostsToNotifier(&host_notifier);
859 host_notifier.SendErrorNotifications(error_message); 937 host_notifier.SendErrorNotifications(details);
860 } 938 }
861 939
862 void AppCacheUpdateJob::AddAllAssociatedHostsToNotifier( 940 void AppCacheUpdateJob::AddAllAssociatedHostsToNotifier(
863 HostNotifier* host_notifier) { 941 HostNotifier* host_notifier) {
864 // Collect hosts so we only send one notification per frontend. 942 // 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 943 // A host can only be associated with a single cache so no need to worry
866 // about duplicate hosts being added to the notifier. 944 // about duplicate hosts being added to the notifier.
867 if (inprogress_cache_.get()) { 945 if (inprogress_cache_.get()) {
868 DCHECK(internal_state_ == DOWNLOADING || internal_state_ == CACHE_FAILURE); 946 DCHECK(internal_state_ == DOWNLOADING || internal_state_ == CACHE_FAILURE);
869 host_notifier->AddHosts(inprogress_cache_->associated_hosts()); 947 host_notifier->AddHosts(inprogress_cache_->associated_hosts());
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 DCHECK(update_type_ == UPGRADE_ATTEMPT); 981 DCHECK(update_type_ == UPGRADE_ATTEMPT);
904 AppCacheEntry* entry = NULL; 982 AppCacheEntry* entry = NULL;
905 if (group_->newest_complete_cache()) 983 if (group_->newest_complete_cache())
906 entry = group_->newest_complete_cache()->GetEntry(manifest_url_); 984 entry = group_->newest_complete_cache()->GetEntry(manifest_url_);
907 if (!entry) { 985 if (!entry) {
908 // TODO(michaeln): This is just a bandaid to avoid a crash. 986 // TODO(michaeln): This is just a bandaid to avoid a crash.
909 // http://code.google.com/p/chromium/issues/detail?id=95101 987 // http://code.google.com/p/chromium/issues/detail?id=95101
910 if (service_->storage() == storage_) { 988 if (service_->storage() == storage_) {
911 // Use a local variable because service_ is reset in HandleCacheFailure. 989 // Use a local variable because service_ is reset in HandleCacheFailure.
912 AppCacheService* service = service_; 990 AppCacheService* service = service_;
913 HandleCacheFailure("Manifest entry not found in existing cache", 991 HandleCacheFailure(
914 DB_ERROR); 992 ErrorDetails("Manifest entry not found in existing cache",
993 UNKNOWN_ERROR,
994 GURL(),
995 0,
996 false /*is_cross_origin*/),
997 DB_ERROR);
915 AppCacheHistograms::AddMissingManifestEntrySample(); 998 AppCacheHistograms::AddMissingManifestEntrySample();
916 service->DeleteAppCacheGroup(manifest_url_, net::CompletionCallback()); 999 service->DeleteAppCacheGroup(manifest_url_, net::CompletionCallback());
917 } 1000 }
918 return; 1001 return;
919 } 1002 }
920 1003
921 // Load manifest data from storage to compare against fetched manifest. 1004 // Load manifest data from storage to compare against fetched manifest.
922 manifest_response_reader_.reset( 1005 manifest_response_reader_.reset(
923 storage_->CreateResponseReader(manifest_url_, 1006 storage_->CreateResponseReader(manifest_url_,
924 group_->group_id(), 1007 group_->group_id(),
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
1145 url, URLFetcher::MASTER_ENTRY_FETCH, this); 1228 url, URLFetcher::MASTER_ENTRY_FETCH, this);
1146 fetcher->Start(); 1229 fetcher->Start();
1147 master_entry_fetches_.insert(PendingUrlFetches::value_type(url, fetcher)); 1230 master_entry_fetches_.insert(PendingUrlFetches::value_type(url, fetcher));
1148 } 1231 }
1149 1232
1150 master_entries_to_fetch_.erase(master_entries_to_fetch_.begin()); 1233 master_entries_to_fetch_.erase(master_entries_to_fetch_.begin());
1151 } 1234 }
1152 } 1235 }
1153 1236
1154 void AppCacheUpdateJob::CancelAllMasterEntryFetches( 1237 void AppCacheUpdateJob::CancelAllMasterEntryFetches(
1155 const std::string& error_message) { 1238 const ErrorDetails& error_details) {
1156 // For now, cancel all in-progress fetches for master entries and pretend 1239 // For now, cancel all in-progress fetches for master entries and pretend
1157 // all master entries fetches have completed. 1240 // all master entries fetches have completed.
1158 // TODO(jennb): Delete this when update no longer fetches master entries 1241 // TODO(jennb): Delete this when update no longer fetches master entries
1159 // directly. 1242 // directly.
1160 1243
1161 // Cancel all in-progress fetches. 1244 // Cancel all in-progress fetches.
1162 for (PendingUrlFetches::iterator it = master_entry_fetches_.begin(); 1245 for (PendingUrlFetches::iterator it = master_entry_fetches_.begin();
1163 it != master_entry_fetches_.end(); ++it) { 1246 it != master_entry_fetches_.end(); ++it) {
1164 delete it->second; 1247 delete it->second;
1165 master_entries_to_fetch_.insert(it->first); // back in unfetched list 1248 master_entries_to_fetch_.insert(it->first); // back in unfetched list
(...skipping 15 matching lines...) Expand all
1181 host_it != hosts.end(); ++host_it) { 1264 host_it != hosts.end(); ++host_it) {
1182 AppCacheHost* host = *host_it; 1265 AppCacheHost* host = *host_it;
1183 host->AssociateNoCache(GURL()); 1266 host->AssociateNoCache(GURL());
1184 host_notifier.AddHost(host); 1267 host_notifier.AddHost(host);
1185 host->RemoveObserver(this); 1268 host->RemoveObserver(this);
1186 } 1269 }
1187 hosts.clear(); 1270 hosts.clear();
1188 1271
1189 master_entries_to_fetch_.erase(master_entries_to_fetch_.begin()); 1272 master_entries_to_fetch_.erase(master_entries_to_fetch_.begin());
1190 } 1273 }
1191 host_notifier.SendErrorNotifications(error_message); 1274 host_notifier.SendErrorNotifications(error_details);
1192 } 1275 }
1193 1276
1194 bool AppCacheUpdateJob::MaybeLoadFromNewestCache(const GURL& url, 1277 bool AppCacheUpdateJob::MaybeLoadFromNewestCache(const GURL& url,
1195 AppCacheEntry& entry) { 1278 AppCacheEntry& entry) {
1196 if (update_type_ != UPGRADE_ATTEMPT) 1279 if (update_type_ != UPGRADE_ATTEMPT)
1197 return false; 1280 return false;
1198 1281
1199 AppCache* newest = group_->newest_complete_cache(); 1282 AppCache* newest = group_->newest_complete_cache();
1200 AppCacheEntry* copy_me = newest->GetEntry(url); 1283 AppCacheEntry* copy_me = newest->GetEntry(url);
1201 if (!copy_me || !copy_me->has_response_id()) 1284 if (!copy_me || !copy_me->has_response_id())
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
1425 1508
1426 // Break the connection with the group so the group cannot call delete 1509 // 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. 1510 // on this object after we've posted a task to delete ourselves.
1428 group_->SetUpdateStatus(AppCacheGroup::IDLE); 1511 group_->SetUpdateStatus(AppCacheGroup::IDLE);
1429 group_ = NULL; 1512 group_ = NULL;
1430 1513
1431 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); 1514 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
1432 } 1515 }
1433 1516
1434 } // namespace appcache 1517 } // namespace appcache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698