| 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 ret.first->second.push_back(host->host_id()); | 51 ret.first->second.push_back(host->host_id()); |
| 52 } | 52 } |
| 53 | 53 |
| 54 void AddHosts(const std::set<AppCacheHost*>& hosts) { | 54 void AddHosts(const std::set<AppCacheHost*>& hosts) { |
| 55 for (std::set<AppCacheHost*>::const_iterator it = hosts.begin(); | 55 for (std::set<AppCacheHost*>::const_iterator it = hosts.begin(); |
| 56 it != hosts.end(); ++it) { | 56 it != hosts.end(); ++it) { |
| 57 AddHost(*it); | 57 AddHost(*it); |
| 58 } | 58 } |
| 59 } | 59 } |
| 60 | 60 |
| 61 void SendNotifications(EventID event_id) { | 61 void SendNotifications(AppCacheEventID event_id) { |
| 62 for (NotifyHostMap::iterator it = hosts_to_notify.begin(); | 62 for (NotifyHostMap::iterator it = hosts_to_notify.begin(); |
| 63 it != hosts_to_notify.end(); ++it) { | 63 it != hosts_to_notify.end(); ++it) { |
| 64 AppCacheFrontend* frontend = it->first; | 64 AppCacheFrontend* frontend = it->first; |
| 65 frontend->OnEventRaised(it->second, event_id); | 65 frontend->OnEventRaised(it->second, event_id); |
| 66 } | 66 } |
| 67 } | 67 } |
| 68 | 68 |
| 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 ErrorDetails& details) { | 79 void SendErrorNotifications(const AppCacheErrorDetails& details) { |
| 80 DCHECK(!details.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, details); | 84 frontend->OnErrorEventRaised(it->second, details); |
| 85 } | 85 } |
| 86 } | 86 } |
| 87 | 87 |
| 88 void SendLogMessage(const std::string& message) { | 88 void SendLogMessage(const std::string& message) { |
| 89 for (NotifyHostMap::iterator it = hosts_to_notify.begin(); | 89 for (NotifyHostMap::iterator it = hosts_to_notify.begin(); |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 if (internal_state_ != COMPLETED) | 362 if (internal_state_ != COMPLETED) |
| 363 Cancel(); | 363 Cancel(); |
| 364 | 364 |
| 365 DCHECK(!manifest_fetcher_); | 365 DCHECK(!manifest_fetcher_); |
| 366 DCHECK(pending_url_fetches_.empty()); | 366 DCHECK(pending_url_fetches_.empty()); |
| 367 DCHECK(!inprogress_cache_.get()); | 367 DCHECK(!inprogress_cache_.get()); |
| 368 DCHECK(pending_master_entries_.empty()); | 368 DCHECK(pending_master_entries_.empty()); |
| 369 DCHECK(master_entry_fetches_.empty()); | 369 DCHECK(master_entry_fetches_.empty()); |
| 370 | 370 |
| 371 if (group_) | 371 if (group_) |
| 372 group_->SetUpdateStatus(AppCacheGroup::IDLE); | 372 group_->SetUpdateAppCacheStatus(AppCacheGroup::IDLE); |
| 373 } | 373 } |
| 374 | 374 |
| 375 void AppCacheUpdateJob::StartUpdate(AppCacheHost* host, | 375 void AppCacheUpdateJob::StartUpdate(AppCacheHost* host, |
| 376 const GURL& new_master_resource) { | 376 const GURL& new_master_resource) { |
| 377 DCHECK(group_->update_job() == this); | 377 DCHECK(group_->update_job() == this); |
| 378 DCHECK(!group_->is_obsolete()); | 378 DCHECK(!group_->is_obsolete()); |
| 379 | 379 |
| 380 bool is_new_pending_master_entry = false; | 380 bool is_new_pending_master_entry = false; |
| 381 if (!new_master_resource.is_empty()) { | 381 if (!new_master_resource.is_empty()) { |
| 382 DCHECK(new_master_resource == host->pending_master_entry_url()); | 382 DCHECK(new_master_resource == host->pending_master_entry_url()); |
| 383 DCHECK(!new_master_resource.has_ref()); | 383 DCHECK(!new_master_resource.has_ref()); |
| 384 DCHECK(new_master_resource.GetOrigin() == manifest_url_.GetOrigin()); | 384 DCHECK(new_master_resource.GetOrigin() == manifest_url_.GetOrigin()); |
| 385 | 385 |
| 386 // Cannot add more to this update if already terminating. | 386 // Cannot add more to this update if already terminating. |
| 387 if (IsTerminating()) { | 387 if (IsTerminating()) { |
| 388 group_->QueueUpdate(host, new_master_resource); | 388 group_->QueueUpdate(host, new_master_resource); |
| 389 return; | 389 return; |
| 390 } | 390 } |
| 391 | 391 |
| 392 std::pair<PendingMasters::iterator, bool> ret = | 392 std::pair<PendingMasters::iterator, bool> ret = |
| 393 pending_master_entries_.insert( | 393 pending_master_entries_.insert( |
| 394 PendingMasters::value_type(new_master_resource, PendingHosts())); | 394 PendingMasters::value_type(new_master_resource, PendingHosts())); |
| 395 is_new_pending_master_entry = ret.second; | 395 is_new_pending_master_entry = ret.second; |
| 396 ret.first->second.push_back(host); | 396 ret.first->second.push_back(host); |
| 397 host->AddObserver(this); | 397 host->AddObserver(this); |
| 398 } | 398 } |
| 399 | 399 |
| 400 // Notify host (if any) if already checking or downloading. | 400 // Notify host (if any) if already checking or downloading. |
| 401 AppCacheGroup::UpdateStatus update_status = group_->update_status(); | 401 AppCacheGroup::UpdateAppCacheStatus update_status = group_->update_status(); |
| 402 if (update_status == AppCacheGroup::CHECKING || | 402 if (update_status == AppCacheGroup::CHECKING || |
| 403 update_status == AppCacheGroup::DOWNLOADING) { | 403 update_status == AppCacheGroup::DOWNLOADING) { |
| 404 if (host) { | 404 if (host) { |
| 405 NotifySingleHost(host, CHECKING_EVENT); | 405 NotifySingleHost(host, CHECKING_EVENT); |
| 406 if (update_status == AppCacheGroup::DOWNLOADING) | 406 if (update_status == AppCacheGroup::DOWNLOADING) |
| 407 NotifySingleHost(host, DOWNLOADING_EVENT); | 407 NotifySingleHost(host, DOWNLOADING_EVENT); |
| 408 | 408 |
| 409 // Add to fetch list or an existing entry if already fetched. | 409 // Add to fetch list or an existing entry if already fetched. |
| 410 if (!new_master_resource.is_empty()) { | 410 if (!new_master_resource.is_empty()) { |
| 411 AddMasterEntryToFetchList(host, new_master_resource, | 411 AddMasterEntryToFetchList(host, new_master_resource, |
| 412 is_new_pending_master_entry); | 412 is_new_pending_master_entry); |
| 413 } | 413 } |
| 414 } | 414 } |
| 415 return; | 415 return; |
| 416 } | 416 } |
| 417 | 417 |
| 418 // Begin update process for the group. | 418 // Begin update process for the group. |
| 419 MadeProgress(); | 419 MadeProgress(); |
| 420 group_->SetUpdateStatus(AppCacheGroup::CHECKING); | 420 group_->SetUpdateAppCacheStatus(AppCacheGroup::CHECKING); |
| 421 if (group_->HasCache()) { | 421 if (group_->HasCache()) { |
| 422 update_type_ = UPGRADE_ATTEMPT; | 422 update_type_ = UPGRADE_ATTEMPT; |
| 423 NotifyAllAssociatedHosts(CHECKING_EVENT); | 423 NotifyAllAssociatedHosts(CHECKING_EVENT); |
| 424 } else { | 424 } else { |
| 425 update_type_ = CACHE_ATTEMPT; | 425 update_type_ = CACHE_ATTEMPT; |
| 426 DCHECK(host); | 426 DCHECK(host); |
| 427 NotifySingleHost(host, CHECKING_EVENT); | 427 NotifySingleHost(host, CHECKING_EVENT); |
| 428 } | 428 } |
| 429 | 429 |
| 430 if (!new_master_resource.is_empty()) { | 430 if (!new_master_resource.is_empty()) { |
| 431 AddMasterEntryToFetchList(host, new_master_resource, | 431 AddMasterEntryToFetchList(host, new_master_resource, |
| 432 is_new_pending_master_entry); | 432 is_new_pending_master_entry); |
| 433 } | 433 } |
| 434 | 434 |
| 435 FetchManifest(true); | 435 FetchManifest(true); |
| 436 } | 436 } |
| 437 | 437 |
| 438 AppCacheResponseWriter* AppCacheUpdateJob::CreateResponseWriter() { | 438 AppCacheResponseWriter* AppCacheUpdateJob::CreateResponseWriter() { |
| 439 AppCacheResponseWriter* writer = | 439 AppCacheResponseWriter* writer = |
| 440 storage_->CreateResponseWriter(manifest_url_, | 440 storage_->CreateResponseWriter(manifest_url_, |
| 441 group_->group_id()); | 441 group_->group_id()); |
| 442 stored_response_ids_.push_back(writer->response_id()); | 442 stored_response_ids_.push_back(writer->response_id()); |
| 443 return writer; | 443 return writer; |
| 444 } | 444 } |
| 445 | 445 |
| 446 void AppCacheUpdateJob::HandleCacheFailure(const ErrorDetails& error_details, | 446 void AppCacheUpdateJob::HandleCacheFailure( |
| 447 ResultType result, | 447 const AppCacheErrorDetails& error_details, |
| 448 const GURL& failed_resource_url) { | 448 ResultType result, |
| 449 const GURL& failed_resource_url) { |
| 449 // 6.9.4 cache failure steps 2-8. | 450 // 6.9.4 cache failure steps 2-8. |
| 450 DCHECK(internal_state_ != CACHE_FAILURE); | 451 DCHECK(internal_state_ != CACHE_FAILURE); |
| 451 DCHECK(!error_details.message.empty()); | 452 DCHECK(!error_details.message.empty()); |
| 452 DCHECK(result != UPDATE_OK); | 453 DCHECK(result != UPDATE_OK); |
| 453 internal_state_ = CACHE_FAILURE; | 454 internal_state_ = CACHE_FAILURE; |
| 454 LogHistogramStats(result, failed_resource_url); | 455 LogHistogramStats(result, failed_resource_url); |
| 455 CancelAllUrlFetches(); | 456 CancelAllUrlFetches(); |
| 456 CancelAllMasterEntryFetches(error_details); | 457 CancelAllMasterEntryFetches(error_details); |
| 457 NotifyAllError(error_details); | 458 NotifyAllError(error_details); |
| 458 DiscardInprogressCache(); | 459 DiscardInprogressCache(); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 517 ContinueHandleManifestFetchCompleted(true); | 518 ContinueHandleManifestFetchCompleted(true); |
| 518 } else if (response_code == 304 && update_type_ == UPGRADE_ATTEMPT) { | 519 } else if (response_code == 304 && update_type_ == UPGRADE_ATTEMPT) { |
| 519 ContinueHandleManifestFetchCompleted(false); | 520 ContinueHandleManifestFetchCompleted(false); |
| 520 } else if ((response_code == 404 || response_code == 410) && | 521 } else if ((response_code == 404 || response_code == 410) && |
| 521 update_type_ == UPGRADE_ATTEMPT) { | 522 update_type_ == UPGRADE_ATTEMPT) { |
| 522 storage_->MakeGroupObsolete(group_, this, response_code); // async | 523 storage_->MakeGroupObsolete(group_, this, response_code); // async |
| 523 } else { | 524 } else { |
| 524 const char* kFormatString = "Manifest fetch failed (%d) %s"; | 525 const char* kFormatString = "Manifest fetch failed (%d) %s"; |
| 525 std::string message = FormatUrlErrorMessage( | 526 std::string message = FormatUrlErrorMessage( |
| 526 kFormatString, manifest_url_, fetcher->result(), response_code); | 527 kFormatString, manifest_url_, fetcher->result(), response_code); |
| 527 HandleCacheFailure(ErrorDetails(message, | 528 HandleCacheFailure(AppCacheErrorDetails(message, |
| 528 appcache::MANIFEST_ERROR, | 529 appcache::MANIFEST_ERROR, |
| 529 manifest_url_, | 530 manifest_url_, |
| 530 response_code, | 531 response_code, |
| 531 false /*is_cross_origin*/), | 532 false /*is_cross_origin*/), |
| 532 fetcher->result(), | 533 fetcher->result(), |
| 533 GURL()); | 534 GURL()); |
| 534 } | 535 } |
| 535 } | 536 } |
| 536 | 537 |
| 537 void AppCacheUpdateJob::OnGroupMadeObsolete(AppCacheGroup* group, | 538 void AppCacheUpdateJob::OnGroupMadeObsolete(AppCacheGroup* group, |
| 538 bool success, | 539 bool success, |
| 539 int response_code) { | 540 int response_code) { |
| 540 DCHECK(master_entry_fetches_.empty()); | 541 DCHECK(master_entry_fetches_.empty()); |
| 541 CancelAllMasterEntryFetches(ErrorDetails( | 542 CancelAllMasterEntryFetches(AppCacheErrorDetails( |
| 542 "The cache has been made obsolete, " | 543 "The cache has been made obsolete, " |
| 543 "the manifest file returned 404 or 410", | 544 "the manifest file returned 404 or 410", |
| 544 appcache::MANIFEST_ERROR, | 545 appcache::MANIFEST_ERROR, |
| 545 GURL(), | 546 GURL(), |
| 546 response_code, | 547 response_code, |
| 547 false /*is_cross_origin*/)); | 548 false /*is_cross_origin*/)); |
| 548 if (success) { | 549 if (success) { |
| 549 DCHECK(group->is_obsolete()); | 550 DCHECK(group->is_obsolete()); |
| 550 NotifyAllAssociatedHosts(OBSOLETE_EVENT); | 551 NotifyAllAssociatedHosts(OBSOLETE_EVENT); |
| 551 internal_state_ = COMPLETED; | 552 internal_state_ = COMPLETED; |
| 552 MaybeCompleteUpdate(); | 553 MaybeCompleteUpdate(); |
| 553 } else { | 554 } else { |
| 554 // Treat failure to mark group obsolete as a cache failure. | 555 // Treat failure to mark group obsolete as a cache failure. |
| 555 HandleCacheFailure(ErrorDetails("Failed to mark the cache as obsolete", | 556 HandleCacheFailure(AppCacheErrorDetails( |
| 556 UNKNOWN_ERROR, | 557 "Failed to mark the cache as obsolete", |
| 557 GURL(), | 558 UNKNOWN_ERROR, |
| 558 0, | 559 GURL(), |
| 559 false /*is_cross_origin*/), | 560 0, |
| 561 false /*is_cross_origin*/), |
| 560 DB_ERROR, | 562 DB_ERROR, |
| 561 GURL()); | 563 GURL()); |
| 562 } | 564 } |
| 563 } | 565 } |
| 564 | 566 |
| 565 void AppCacheUpdateJob::ContinueHandleManifestFetchCompleted(bool changed) { | 567 void AppCacheUpdateJob::ContinueHandleManifestFetchCompleted(bool changed) { |
| 566 DCHECK(internal_state_ == FETCH_MANIFEST); | 568 DCHECK(internal_state_ == FETCH_MANIFEST); |
| 567 | 569 |
| 568 if (!changed) { | 570 if (!changed) { |
| 569 DCHECK(update_type_ == UPGRADE_ATTEMPT); | 571 DCHECK(update_type_ == UPGRADE_ATTEMPT); |
| 570 internal_state_ = NO_UPDATE; | 572 internal_state_ = NO_UPDATE; |
| 571 | 573 |
| 572 // Wait for pending master entries to download. | 574 // Wait for pending master entries to download. |
| 573 FetchMasterEntries(); | 575 FetchMasterEntries(); |
| 574 MaybeCompleteUpdate(); // if not done, run async 6.9.4 step 7 substeps | 576 MaybeCompleteUpdate(); // if not done, run async 6.9.4 step 7 substeps |
| 575 return; | 577 return; |
| 576 } | 578 } |
| 577 | 579 |
| 578 Manifest manifest; | 580 Manifest manifest; |
| 579 if (!ParseManifest(manifest_url_, manifest_data_.data(), | 581 if (!ParseManifest(manifest_url_, manifest_data_.data(), |
| 580 manifest_data_.length(), | 582 manifest_data_.length(), |
| 581 manifest_has_valid_mime_type_ ? | 583 manifest_has_valid_mime_type_ ? |
| 582 PARSE_MANIFEST_ALLOWING_INTERCEPTS : | 584 PARSE_MANIFEST_ALLOWING_INTERCEPTS : |
| 583 PARSE_MANIFEST_PER_STANDARD, | 585 PARSE_MANIFEST_PER_STANDARD, |
| 584 manifest)) { | 586 manifest)) { |
| 585 const char* kFormatString = "Failed to parse manifest %s"; | 587 const char* kFormatString = "Failed to parse manifest %s"; |
| 586 const std::string message = base::StringPrintf(kFormatString, | 588 const std::string message = base::StringPrintf(kFormatString, |
| 587 manifest_url_.spec().c_str()); | 589 manifest_url_.spec().c_str()); |
| 588 HandleCacheFailure( | 590 HandleCacheFailure( |
| 589 ErrorDetails( | 591 AppCacheErrorDetails( |
| 590 message, SIGNATURE_ERROR, GURL(), 0, false /*is_cross_origin*/), | 592 message, SIGNATURE_ERROR, GURL(), 0, false /*is_cross_origin*/), |
| 591 MANIFEST_ERROR, | 593 MANIFEST_ERROR, |
| 592 GURL()); | 594 GURL()); |
| 593 VLOG(1) << message; | 595 VLOG(1) << message; |
| 594 return; | 596 return; |
| 595 } | 597 } |
| 596 | 598 |
| 597 // Proceed with update process. Section 6.9.4 steps 8-20. | 599 // Proceed with update process. Section 6.9.4 steps 8-20. |
| 598 internal_state_ = DOWNLOADING; | 600 internal_state_ = DOWNLOADING; |
| 599 inprogress_cache_ = new AppCache(storage_, storage_->NewCacheId()); | 601 inprogress_cache_ = new AppCache(storage_, storage_->NewCacheId()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 612 } | 614 } |
| 613 | 615 |
| 614 if (manifest.did_ignore_intercept_namespaces) { | 616 if (manifest.did_ignore_intercept_namespaces) { |
| 615 // Must be done after associating all pending master hosts. | 617 // Must be done after associating all pending master hosts. |
| 616 std::string message( | 618 std::string message( |
| 617 "Ignoring the INTERCEPT section of the application cache manifest " | 619 "Ignoring the INTERCEPT section of the application cache manifest " |
| 618 "because the content type is not text/cache-manifest"); | 620 "because the content type is not text/cache-manifest"); |
| 619 LogConsoleMessageToAll(message); | 621 LogConsoleMessageToAll(message); |
| 620 } | 622 } |
| 621 | 623 |
| 622 group_->SetUpdateStatus(AppCacheGroup::DOWNLOADING); | 624 group_->SetUpdateAppCacheStatus(AppCacheGroup::DOWNLOADING); |
| 623 NotifyAllAssociatedHosts(DOWNLOADING_EVENT); | 625 NotifyAllAssociatedHosts(DOWNLOADING_EVENT); |
| 624 FetchUrls(); | 626 FetchUrls(); |
| 625 FetchMasterEntries(); | 627 FetchMasterEntries(); |
| 626 MaybeCompleteUpdate(); // if not done, continues when async fetches complete | 628 MaybeCompleteUpdate(); // if not done, continues when async fetches complete |
| 627 } | 629 } |
| 628 | 630 |
| 629 void AppCacheUpdateJob::HandleUrlFetchCompleted(URLFetcher* fetcher) { | 631 void AppCacheUpdateJob::HandleUrlFetchCompleted(URLFetcher* fetcher) { |
| 630 DCHECK(internal_state_ == DOWNLOADING); | 632 DCHECK(internal_state_ == DOWNLOADING); |
| 631 | 633 |
| 632 net::URLRequest* request = fetcher->request(); | 634 net::URLRequest* request = fetcher->request(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 671 inprogress_cache_->AddOrModifyEntry(url, entry); | 673 inprogress_cache_->AddOrModifyEntry(url, entry); |
| 672 } else { | 674 } else { |
| 673 const char* kFormatString = "Resource fetch failed (%d) %s"; | 675 const char* kFormatString = "Resource fetch failed (%d) %s"; |
| 674 std::string message = FormatUrlErrorMessage( | 676 std::string message = FormatUrlErrorMessage( |
| 675 kFormatString, url, fetcher->result(), response_code); | 677 kFormatString, url, fetcher->result(), response_code); |
| 676 ResultType result = fetcher->result(); | 678 ResultType result = fetcher->result(); |
| 677 bool is_cross_origin = url.GetOrigin() != manifest_url_.GetOrigin(); | 679 bool is_cross_origin = url.GetOrigin() != manifest_url_.GetOrigin(); |
| 678 switch (result) { | 680 switch (result) { |
| 679 case DISKCACHE_ERROR: | 681 case DISKCACHE_ERROR: |
| 680 HandleCacheFailure( | 682 HandleCacheFailure( |
| 681 ErrorDetails( | 683 AppCacheErrorDetails( |
| 682 message, UNKNOWN_ERROR, GURL(), 0, is_cross_origin), | 684 message, UNKNOWN_ERROR, GURL(), 0, is_cross_origin), |
| 683 result, | 685 result, |
| 684 url); | 686 url); |
| 685 break; | 687 break; |
| 686 case NETWORK_ERROR: | 688 case NETWORK_ERROR: |
| 687 HandleCacheFailure( | 689 HandleCacheFailure( |
| 688 ErrorDetails(message, RESOURCE_ERROR, url, 0, is_cross_origin), | 690 AppCacheErrorDetails(message, RESOURCE_ERROR, url, 0, |
| 691 is_cross_origin), |
| 689 result, | 692 result, |
| 690 url); | 693 url); |
| 691 break; | 694 break; |
| 692 default: | 695 default: |
| 693 HandleCacheFailure(ErrorDetails(message, | 696 HandleCacheFailure(AppCacheErrorDetails(message, |
| 694 RESOURCE_ERROR, | 697 RESOURCE_ERROR, |
| 695 url, | 698 url, |
| 696 response_code, | 699 response_code, |
| 697 is_cross_origin), | 700 is_cross_origin), |
| 698 result, | 701 result, |
| 699 url); | 702 url); |
| 700 break; | 703 break; |
| 701 } | 704 } |
| 702 return; | 705 return; |
| 703 } | 706 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 777 host->AssociateNoCache(GURL()); | 780 host->AssociateNoCache(GURL()); |
| 778 | 781 |
| 779 host->RemoveObserver(this); | 782 host->RemoveObserver(this); |
| 780 } | 783 } |
| 781 hosts.clear(); | 784 hosts.clear(); |
| 782 | 785 |
| 783 const char* kFormatString = "Manifest fetch failed (%d) %s"; | 786 const char* kFormatString = "Manifest fetch failed (%d) %s"; |
| 784 std::string message = FormatUrlErrorMessage( | 787 std::string message = FormatUrlErrorMessage( |
| 785 kFormatString, request->url(), fetcher->result(), response_code); | 788 kFormatString, request->url(), fetcher->result(), response_code); |
| 786 host_notifier.SendErrorNotifications( | 789 host_notifier.SendErrorNotifications( |
| 787 ErrorDetails(message, | 790 AppCacheErrorDetails(message, |
| 788 appcache::MANIFEST_ERROR, | 791 appcache::MANIFEST_ERROR, |
| 789 request->url(), | 792 request->url(), |
| 790 response_code, | 793 response_code, |
| 791 false /*is_cross_origin*/)); | 794 false /*is_cross_origin*/)); |
| 792 | 795 |
| 793 // In downloading case, update result is different if all master entries | 796 // In downloading case, update result is different if all master entries |
| 794 // failed vs. only some failing. | 797 // failed vs. only some failing. |
| 795 if (inprogress_cache_.get()) { | 798 if (inprogress_cache_.get()) { |
| 796 // Only count successful downloads to know if all master entries failed. | 799 // Only count successful downloads to know if all master entries failed. |
| 797 pending_master_entries_.erase(found); | 800 pending_master_entries_.erase(found); |
| 798 --master_entries_completed_; | 801 --master_entries_completed_; |
| 799 | 802 |
| 800 // Section 6.9.4, step 22.3. | 803 // Section 6.9.4, step 22.3. |
| 801 if (update_type_ == CACHE_ATTEMPT && pending_master_entries_.empty()) { | 804 if (update_type_ == CACHE_ATTEMPT && pending_master_entries_.empty()) { |
| 802 HandleCacheFailure(ErrorDetails(message, | 805 HandleCacheFailure(AppCacheErrorDetails(message, |
| 803 appcache::MANIFEST_ERROR, | 806 appcache::MANIFEST_ERROR, |
| 804 request->url(), | 807 request->url(), |
| 805 response_code, | 808 response_code, |
| 806 false /*is_cross_origin*/), | 809 false /*is_cross_origin*/), |
| 807 fetcher->result(), | 810 fetcher->result(), |
| 808 GURL()); | 811 GURL()); |
| 809 return; | 812 return; |
| 810 } | 813 } |
| 811 } | 814 } |
| 812 } | 815 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 840 io_buffer.get(), | 843 io_buffer.get(), |
| 841 base::Bind(&AppCacheUpdateJob::OnManifestInfoWriteComplete, | 844 base::Bind(&AppCacheUpdateJob::OnManifestInfoWriteComplete, |
| 842 base::Unretained(this))); | 845 base::Unretained(this))); |
| 843 } | 846 } |
| 844 } else { | 847 } else { |
| 845 VLOG(1) << "Request status: " << request->status().status() | 848 VLOG(1) << "Request status: " << request->status().status() |
| 846 << " error: " << request->status().error() | 849 << " error: " << request->status().error() |
| 847 << " response code: " << response_code; | 850 << " response code: " << response_code; |
| 848 ScheduleUpdateRetry(kRerunDelayMs); | 851 ScheduleUpdateRetry(kRerunDelayMs); |
| 849 if (response_code == 200) { | 852 if (response_code == 200) { |
| 850 HandleCacheFailure(ErrorDetails("Manifest changed during update", | 853 HandleCacheFailure(AppCacheErrorDetails("Manifest changed during update", |
| 851 CHANGED_ERROR, | 854 CHANGED_ERROR, |
| 852 GURL(), | 855 GURL(), |
| 853 0, | 856 0, |
| 854 false /*is_cross_origin*/), | 857 false /*is_cross_origin*/), |
| 855 MANIFEST_ERROR, | 858 MANIFEST_ERROR, |
| 856 GURL()); | 859 GURL()); |
| 857 } else { | 860 } else { |
| 858 const char* kFormatString = "Manifest re-fetch failed (%d) %s"; | 861 const char* kFormatString = "Manifest re-fetch failed (%d) %s"; |
| 859 std::string message = FormatUrlErrorMessage( | 862 std::string message = FormatUrlErrorMessage( |
| 860 kFormatString, manifest_url_, fetcher->result(), response_code); | 863 kFormatString, manifest_url_, fetcher->result(), response_code); |
| 861 HandleCacheFailure(ErrorDetails(message, | 864 HandleCacheFailure(AppCacheErrorDetails(message, |
| 862 appcache::MANIFEST_ERROR, | 865 appcache::MANIFEST_ERROR, |
| 863 GURL(), | 866 GURL(), |
| 864 response_code, | 867 response_code, |
| 865 false /*is_cross_origin*/), | 868 false /*is_cross_origin*/), |
| 866 fetcher->result(), | 869 fetcher->result(), |
| 867 GURL()); | 870 GURL()); |
| 868 } | 871 } |
| 869 } | 872 } |
| 870 } | 873 } |
| 871 | 874 |
| 872 void AppCacheUpdateJob::OnManifestInfoWriteComplete(int result) { | 875 void AppCacheUpdateJob::OnManifestInfoWriteComplete(int result) { |
| 873 if (result > 0) { | 876 if (result > 0) { |
| 874 scoped_refptr<net::StringIOBuffer> io_buffer( | 877 scoped_refptr<net::StringIOBuffer> io_buffer( |
| 875 new net::StringIOBuffer(manifest_data_)); | 878 new net::StringIOBuffer(manifest_data_)); |
| 876 manifest_response_writer_->WriteData( | 879 manifest_response_writer_->WriteData( |
| 877 io_buffer.get(), | 880 io_buffer.get(), |
| 878 manifest_data_.length(), | 881 manifest_data_.length(), |
| 879 base::Bind(&AppCacheUpdateJob::OnManifestDataWriteComplete, | 882 base::Bind(&AppCacheUpdateJob::OnManifestDataWriteComplete, |
| 880 base::Unretained(this))); | 883 base::Unretained(this))); |
| 881 } else { | 884 } else { |
| 882 HandleCacheFailure( | 885 HandleCacheFailure( |
| 883 ErrorDetails("Failed to write the manifest headers to storage", | 886 AppCacheErrorDetails("Failed to write the manifest headers to storage", |
| 884 UNKNOWN_ERROR, | 887 UNKNOWN_ERROR, |
| 885 GURL(), | 888 GURL(), |
| 886 0, | 889 0, |
| 887 false /*is_cross_origin*/), | 890 false /*is_cross_origin*/), |
| 888 DISKCACHE_ERROR, | 891 DISKCACHE_ERROR, |
| 889 GURL()); | 892 GURL()); |
| 890 } | 893 } |
| 891 } | 894 } |
| 892 | 895 |
| 893 void AppCacheUpdateJob::OnManifestDataWriteComplete(int result) { | 896 void AppCacheUpdateJob::OnManifestDataWriteComplete(int result) { |
| 894 if (result > 0) { | 897 if (result > 0) { |
| 895 AppCacheEntry entry(AppCacheEntry::MANIFEST, | 898 AppCacheEntry entry(AppCacheEntry::MANIFEST, |
| 896 manifest_response_writer_->response_id(), | 899 manifest_response_writer_->response_id(), |
| 897 manifest_response_writer_->amount_written()); | 900 manifest_response_writer_->amount_written()); |
| 898 if (!inprogress_cache_->AddOrModifyEntry(manifest_url_, entry)) | 901 if (!inprogress_cache_->AddOrModifyEntry(manifest_url_, entry)) |
| 899 duplicate_response_ids_.push_back(entry.response_id()); | 902 duplicate_response_ids_.push_back(entry.response_id()); |
| 900 StoreGroupAndCache(); | 903 StoreGroupAndCache(); |
| 901 } else { | 904 } else { |
| 902 HandleCacheFailure( | 905 HandleCacheFailure( |
| 903 ErrorDetails("Failed to write the manifest data to storage", | 906 AppCacheErrorDetails("Failed to write the manifest data to storage", |
| 904 UNKNOWN_ERROR, | 907 UNKNOWN_ERROR, |
| 905 GURL(), | 908 GURL(), |
| 906 0, | 909 0, |
| 907 false /*is_cross_origin*/), | 910 false /*is_cross_origin*/), |
| 908 DISKCACHE_ERROR, | 911 DISKCACHE_ERROR, |
| 909 GURL()); | 912 GURL()); |
| 910 } | 913 } |
| 911 } | 914 } |
| 912 | 915 |
| 913 void AppCacheUpdateJob::StoreGroupAndCache() { | 916 void AppCacheUpdateJob::StoreGroupAndCache() { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 935 MaybeCompleteUpdate(); // will definitely complete | 938 MaybeCompleteUpdate(); // will definitely complete |
| 936 } else { | 939 } else { |
| 937 stored_state_ = UNSTORED; | 940 stored_state_ = UNSTORED; |
| 938 | 941 |
| 939 // Restore inprogress_cache_ to get the proper events delivered | 942 // Restore inprogress_cache_ to get the proper events delivered |
| 940 // and the proper cleanup to occur. | 943 // and the proper cleanup to occur. |
| 941 if (newest_cache != group->newest_complete_cache()) | 944 if (newest_cache != group->newest_complete_cache()) |
| 942 inprogress_cache_ = newest_cache; | 945 inprogress_cache_ = newest_cache; |
| 943 | 946 |
| 944 ResultType result = DB_ERROR; | 947 ResultType result = DB_ERROR; |
| 945 ErrorReason reason = UNKNOWN_ERROR; | 948 AppCacheErrorReason reason = UNKNOWN_ERROR; |
| 946 std::string message("Failed to commit new cache to storage"); | 949 std::string message("Failed to commit new cache to storage"); |
| 947 if (would_exceed_quota) { | 950 if (would_exceed_quota) { |
| 948 message.append(", would exceed quota"); | 951 message.append(", would exceed quota"); |
| 949 result = QUOTA_ERROR; | 952 result = QUOTA_ERROR; |
| 950 reason = appcache::QUOTA_ERROR; | 953 reason = appcache::QUOTA_ERROR; |
| 951 } | 954 } |
| 952 HandleCacheFailure( | 955 HandleCacheFailure( |
| 953 ErrorDetails(message, reason, GURL(), 0, false /*is_cross_origin*/), | 956 AppCacheErrorDetails(message, reason, GURL(), 0, |
| 957 false /*is_cross_origin*/), |
| 954 result, | 958 result, |
| 955 GURL()); | 959 GURL()); |
| 956 } | 960 } |
| 957 } | 961 } |
| 958 | 962 |
| 959 void AppCacheUpdateJob::NotifySingleHost(AppCacheHost* host, | 963 void AppCacheUpdateJob::NotifySingleHost(AppCacheHost* host, |
| 960 EventID event_id) { | 964 AppCacheEventID event_id) { |
| 961 std::vector<int> ids(1, host->host_id()); | 965 std::vector<int> ids(1, host->host_id()); |
| 962 host->frontend()->OnEventRaised(ids, event_id); | 966 host->frontend()->OnEventRaised(ids, event_id); |
| 963 } | 967 } |
| 964 | 968 |
| 965 void AppCacheUpdateJob::NotifyAllAssociatedHosts(EventID event_id) { | 969 void AppCacheUpdateJob::NotifyAllAssociatedHosts(AppCacheEventID event_id) { |
| 966 HostNotifier host_notifier; | 970 HostNotifier host_notifier; |
| 967 AddAllAssociatedHostsToNotifier(&host_notifier); | 971 AddAllAssociatedHostsToNotifier(&host_notifier); |
| 968 host_notifier.SendNotifications(event_id); | 972 host_notifier.SendNotifications(event_id); |
| 969 } | 973 } |
| 970 | 974 |
| 971 void AppCacheUpdateJob::NotifyAllProgress(const GURL& url) { | 975 void AppCacheUpdateJob::NotifyAllProgress(const GURL& url) { |
| 972 HostNotifier host_notifier; | 976 HostNotifier host_notifier; |
| 973 AddAllAssociatedHostsToNotifier(&host_notifier); | 977 AddAllAssociatedHostsToNotifier(&host_notifier); |
| 974 host_notifier.SendProgressNotifications( | 978 host_notifier.SendProgressNotifications( |
| 975 url, url_file_list_.size(), url_fetches_completed_); | 979 url, url_file_list_.size(), url_fetches_completed_); |
| 976 } | 980 } |
| 977 | 981 |
| 978 void AppCacheUpdateJob::NotifyAllFinalProgress() { | 982 void AppCacheUpdateJob::NotifyAllFinalProgress() { |
| 979 DCHECK(url_file_list_.size() == url_fetches_completed_); | 983 DCHECK(url_file_list_.size() == url_fetches_completed_); |
| 980 NotifyAllProgress(GURL()); | 984 NotifyAllProgress(GURL()); |
| 981 } | 985 } |
| 982 | 986 |
| 983 void AppCacheUpdateJob::NotifyAllError(const ErrorDetails& details) { | 987 void AppCacheUpdateJob::NotifyAllError(const AppCacheErrorDetails& details) { |
| 984 HostNotifier host_notifier; | 988 HostNotifier host_notifier; |
| 985 AddAllAssociatedHostsToNotifier(&host_notifier); | 989 AddAllAssociatedHostsToNotifier(&host_notifier); |
| 986 host_notifier.SendErrorNotifications(details); | 990 host_notifier.SendErrorNotifications(details); |
| 987 } | 991 } |
| 988 | 992 |
| 989 void AppCacheUpdateJob::LogConsoleMessageToAll(const std::string& message) { | 993 void AppCacheUpdateJob::LogConsoleMessageToAll(const std::string& message) { |
| 990 HostNotifier host_notifier; | 994 HostNotifier host_notifier; |
| 991 AddAllAssociatedHostsToNotifier(&host_notifier); | 995 AddAllAssociatedHostsToNotifier(&host_notifier); |
| 992 host_notifier.SendLogMessage(message); | 996 host_notifier.SendLogMessage(message); |
| 993 } | 997 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1037 AppCacheEntry* entry = NULL; | 1041 AppCacheEntry* entry = NULL; |
| 1038 if (group_->newest_complete_cache()) | 1042 if (group_->newest_complete_cache()) |
| 1039 entry = group_->newest_complete_cache()->GetEntry(manifest_url_); | 1043 entry = group_->newest_complete_cache()->GetEntry(manifest_url_); |
| 1040 if (!entry) { | 1044 if (!entry) { |
| 1041 // TODO(michaeln): This is just a bandaid to avoid a crash. | 1045 // TODO(michaeln): This is just a bandaid to avoid a crash. |
| 1042 // http://code.google.com/p/chromium/issues/detail?id=95101 | 1046 // http://code.google.com/p/chromium/issues/detail?id=95101 |
| 1043 if (service_->storage() == storage_) { | 1047 if (service_->storage() == storage_) { |
| 1044 // Use a local variable because service_ is reset in HandleCacheFailure. | 1048 // Use a local variable because service_ is reset in HandleCacheFailure. |
| 1045 AppCacheServiceImpl* service = service_; | 1049 AppCacheServiceImpl* service = service_; |
| 1046 HandleCacheFailure( | 1050 HandleCacheFailure( |
| 1047 ErrorDetails("Manifest entry not found in existing cache", | 1051 AppCacheErrorDetails("Manifest entry not found in existing cache", |
| 1048 UNKNOWN_ERROR, | 1052 UNKNOWN_ERROR, |
| 1049 GURL(), | 1053 GURL(), |
| 1050 0, | 1054 0, |
| 1051 false /*is_cross_origin*/), | 1055 false /*is_cross_origin*/), |
| 1052 DB_ERROR, | 1056 DB_ERROR, |
| 1053 GURL()); | 1057 GURL()); |
| 1054 AppCacheHistograms::AddMissingManifestEntrySample(); | 1058 AppCacheHistograms::AddMissingManifestEntrySample(); |
| 1055 service->DeleteAppCacheGroup(manifest_url_, net::CompletionCallback()); | 1059 service->DeleteAppCacheGroup(manifest_url_, net::CompletionCallback()); |
| 1056 } | 1060 } |
| 1057 return; | 1061 return; |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1284 url, URLFetcher::MASTER_ENTRY_FETCH, this); | 1288 url, URLFetcher::MASTER_ENTRY_FETCH, this); |
| 1285 fetcher->Start(); | 1289 fetcher->Start(); |
| 1286 master_entry_fetches_.insert(PendingUrlFetches::value_type(url, fetcher)); | 1290 master_entry_fetches_.insert(PendingUrlFetches::value_type(url, fetcher)); |
| 1287 } | 1291 } |
| 1288 | 1292 |
| 1289 master_entries_to_fetch_.erase(master_entries_to_fetch_.begin()); | 1293 master_entries_to_fetch_.erase(master_entries_to_fetch_.begin()); |
| 1290 } | 1294 } |
| 1291 } | 1295 } |
| 1292 | 1296 |
| 1293 void AppCacheUpdateJob::CancelAllMasterEntryFetches( | 1297 void AppCacheUpdateJob::CancelAllMasterEntryFetches( |
| 1294 const ErrorDetails& error_details) { | 1298 const AppCacheErrorDetails& error_details) { |
| 1295 // For now, cancel all in-progress fetches for master entries and pretend | 1299 // For now, cancel all in-progress fetches for master entries and pretend |
| 1296 // all master entries fetches have completed. | 1300 // all master entries fetches have completed. |
| 1297 // TODO(jennb): Delete this when update no longer fetches master entries | 1301 // TODO(jennb): Delete this when update no longer fetches master entries |
| 1298 // directly. | 1302 // directly. |
| 1299 | 1303 |
| 1300 // Cancel all in-progress fetches. | 1304 // Cancel all in-progress fetches. |
| 1301 for (PendingUrlFetches::iterator it = master_entry_fetches_.begin(); | 1305 for (PendingUrlFetches::iterator it = master_entry_fetches_.begin(); |
| 1302 it != master_entry_fetches_.end(); ++it) { | 1306 it != master_entry_fetches_.end(); ++it) { |
| 1303 delete it->second; | 1307 delete it->second; |
| 1304 master_entries_to_fetch_.insert(it->first); // back in unfetched list | 1308 master_entries_to_fetch_.insert(it->first); // back in unfetched list |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1589 | 1593 |
| 1590 void AppCacheUpdateJob::DeleteSoon() { | 1594 void AppCacheUpdateJob::DeleteSoon() { |
| 1591 ClearPendingMasterEntries(); | 1595 ClearPendingMasterEntries(); |
| 1592 manifest_response_writer_.reset(); | 1596 manifest_response_writer_.reset(); |
| 1593 storage_->CancelDelegateCallbacks(this); | 1597 storage_->CancelDelegateCallbacks(this); |
| 1594 service_->RemoveObserver(this); | 1598 service_->RemoveObserver(this); |
| 1595 service_ = NULL; | 1599 service_ = NULL; |
| 1596 | 1600 |
| 1597 // Break the connection with the group so the group cannot call delete | 1601 // Break the connection with the group so the group cannot call delete |
| 1598 // on this object after we've posted a task to delete ourselves. | 1602 // on this object after we've posted a task to delete ourselves. |
| 1599 group_->SetUpdateStatus(AppCacheGroup::IDLE); | 1603 group_->SetUpdateAppCacheStatus(AppCacheGroup::IDLE); |
| 1600 group_ = NULL; | 1604 group_ = NULL; |
| 1601 | 1605 |
| 1602 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 1606 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
| 1603 } | 1607 } |
| 1604 | 1608 |
| 1605 } // namespace appcache | 1609 } // namespace appcache |
| OLD | NEW |