| 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 | 78 |
| 79 void SendErrorNotifications(const ErrorDetails& details) { | 79 void SendErrorNotifications(const ErrorDetails& 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) { |
| 89 for (NotifyHostMap::iterator it = hosts_to_notify.begin(); |
| 90 it != hosts_to_notify.end(); ++it) { |
| 91 AppCacheFrontend* frontend = it->first; |
| 92 for (HostIds::iterator id = it->second.begin(); |
| 93 id != it->second.end(); ++id) { |
| 94 frontend->OnLogMessage(*id, LOG_WARNING, message); |
| 95 } |
| 96 } |
| 97 } |
| 98 |
| 88 private: | 99 private: |
| 89 NotifyHostMap hosts_to_notify; | 100 NotifyHostMap hosts_to_notify; |
| 90 }; | 101 }; |
| 91 | 102 |
| 92 AppCacheUpdateJob::UrlToFetch::UrlToFetch(const GURL& url, | 103 AppCacheUpdateJob::UrlToFetch::UrlToFetch(const GURL& url, |
| 93 bool checked, | 104 bool checked, |
| 94 AppCacheResponseInfo* info) | 105 AppCacheResponseInfo* info) |
| 95 : url(url), | 106 : url(url), |
| 96 storage_checked(checked), | 107 storage_checked(checked), |
| 97 existing_response_info(info) { | 108 existing_response_info(info) { |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 AppCacheUpdateJob::AppCacheUpdateJob(AppCacheService* service, | 343 AppCacheUpdateJob::AppCacheUpdateJob(AppCacheService* service, |
| 333 AppCacheGroup* group) | 344 AppCacheGroup* group) |
| 334 : service_(service), | 345 : service_(service), |
| 335 manifest_url_(group->manifest_url()), | 346 manifest_url_(group->manifest_url()), |
| 336 group_(group), | 347 group_(group), |
| 337 update_type_(UNKNOWN_TYPE), | 348 update_type_(UNKNOWN_TYPE), |
| 338 internal_state_(FETCH_MANIFEST), | 349 internal_state_(FETCH_MANIFEST), |
| 339 master_entries_completed_(0), | 350 master_entries_completed_(0), |
| 340 url_fetches_completed_(0), | 351 url_fetches_completed_(0), |
| 341 manifest_fetcher_(NULL), | 352 manifest_fetcher_(NULL), |
| 353 manifest_has_valid_mime_type_(false), |
| 342 stored_state_(UNSTORED), | 354 stored_state_(UNSTORED), |
| 343 storage_(service->storage()) { | 355 storage_(service->storage()) { |
| 344 service_->AddObserver(this); | 356 service_->AddObserver(this); |
| 345 } | 357 } |
| 346 | 358 |
| 347 AppCacheUpdateJob::~AppCacheUpdateJob() { | 359 AppCacheUpdateJob::~AppCacheUpdateJob() { |
| 348 if (service_) | 360 if (service_) |
| 349 service_->RemoveObserver(this); | 361 service_->RemoveObserver(this); |
| 350 if (internal_state_ != COMPLETED) | 362 if (internal_state_ != COMPLETED) |
| 351 Cancel(); | 363 Cancel(); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 DCHECK_EQ(internal_state_, FETCH_MANIFEST); | 494 DCHECK_EQ(internal_state_, FETCH_MANIFEST); |
| 483 DCHECK_EQ(manifest_fetcher_, fetcher); | 495 DCHECK_EQ(manifest_fetcher_, fetcher); |
| 484 manifest_fetcher_ = NULL; | 496 manifest_fetcher_ = NULL; |
| 485 | 497 |
| 486 net::URLRequest* request = fetcher->request(); | 498 net::URLRequest* request = fetcher->request(); |
| 487 int response_code = -1; | 499 int response_code = -1; |
| 488 bool is_valid_response_code = false; | 500 bool is_valid_response_code = false; |
| 489 if (request->status().is_success()) { | 501 if (request->status().is_success()) { |
| 490 response_code = request->GetResponseCode(); | 502 response_code = request->GetResponseCode(); |
| 491 is_valid_response_code = (response_code / 100 == 2); | 503 is_valid_response_code = (response_code / 100 == 2); |
| 504 |
| 505 std::string mime_type; |
| 506 request->GetMimeType(&mime_type); |
| 507 manifest_has_valid_mime_type_ = (mime_type == "text/cache-manifest"); |
| 492 } | 508 } |
| 493 | 509 |
| 494 if (is_valid_response_code) { | 510 if (is_valid_response_code) { |
| 495 manifest_data_ = fetcher->manifest_data(); | 511 manifest_data_ = fetcher->manifest_data(); |
| 496 manifest_response_info_.reset( | 512 manifest_response_info_.reset( |
| 497 new net::HttpResponseInfo(request->response_info())); | 513 new net::HttpResponseInfo(request->response_info())); |
| 498 if (update_type_ == UPGRADE_ATTEMPT) | 514 if (update_type_ == UPGRADE_ATTEMPT) |
| 499 CheckIfManifestChanged(); // continues asynchronously | 515 CheckIfManifestChanged(); // continues asynchronously |
| 500 else | 516 else |
| 501 ContinueHandleManifestFetchCompleted(true); | 517 ContinueHandleManifestFetchCompleted(true); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 554 internal_state_ = NO_UPDATE; | 570 internal_state_ = NO_UPDATE; |
| 555 | 571 |
| 556 // Wait for pending master entries to download. | 572 // Wait for pending master entries to download. |
| 557 FetchMasterEntries(); | 573 FetchMasterEntries(); |
| 558 MaybeCompleteUpdate(); // if not done, run async 6.9.4 step 7 substeps | 574 MaybeCompleteUpdate(); // if not done, run async 6.9.4 step 7 substeps |
| 559 return; | 575 return; |
| 560 } | 576 } |
| 561 | 577 |
| 562 Manifest manifest; | 578 Manifest manifest; |
| 563 if (!ParseManifest(manifest_url_, manifest_data_.data(), | 579 if (!ParseManifest(manifest_url_, manifest_data_.data(), |
| 564 manifest_data_.length(), manifest)) { | 580 manifest_data_.length(), |
| 581 manifest_has_valid_mime_type_ ? |
| 582 PARSE_MANIFEST_ALLOWING_INTERCEPTS : |
| 583 PARSE_MANIFEST_PER_STANDARD, |
| 584 manifest)) { |
| 565 const char* kFormatString = "Failed to parse manifest %s"; | 585 const char* kFormatString = "Failed to parse manifest %s"; |
| 566 const std::string message = base::StringPrintf(kFormatString, | 586 const std::string message = base::StringPrintf(kFormatString, |
| 567 manifest_url_.spec().c_str()); | 587 manifest_url_.spec().c_str()); |
| 568 HandleCacheFailure( | 588 HandleCacheFailure( |
| 569 ErrorDetails( | 589 ErrorDetails( |
| 570 message, SIGNATURE_ERROR, GURL(), 0, false /*is_cross_origin*/), | 590 message, SIGNATURE_ERROR, GURL(), 0, false /*is_cross_origin*/), |
| 571 MANIFEST_ERROR, | 591 MANIFEST_ERROR, |
| 572 GURL()); | 592 GURL()); |
| 573 VLOG(1) << message; | 593 VLOG(1) << message; |
| 574 return; | 594 return; |
| 575 } | 595 } |
| 576 | 596 |
| 577 // Proceed with update process. Section 6.9.4 steps 8-20. | 597 // Proceed with update process. Section 6.9.4 steps 8-20. |
| 578 internal_state_ = DOWNLOADING; | 598 internal_state_ = DOWNLOADING; |
| 579 inprogress_cache_ = new AppCache(storage_, storage_->NewCacheId()); | 599 inprogress_cache_ = new AppCache(storage_, storage_->NewCacheId()); |
| 580 BuildUrlFileList(manifest); | 600 BuildUrlFileList(manifest); |
| 581 inprogress_cache_->InitializeWithManifest(&manifest); | 601 inprogress_cache_->InitializeWithManifest(&manifest); |
| 582 | 602 |
| 583 // Associate all pending master hosts with the newly created cache. | 603 // Associate all pending master hosts with the newly created cache. |
| 584 for (PendingMasters::iterator it = pending_master_entries_.begin(); | 604 for (PendingMasters::iterator it = pending_master_entries_.begin(); |
| 585 it != pending_master_entries_.end(); ++it) { | 605 it != pending_master_entries_.end(); ++it) { |
| 586 PendingHosts& hosts = it->second; | 606 PendingHosts& hosts = it->second; |
| 587 for (PendingHosts::iterator host_it = hosts.begin(); | 607 for (PendingHosts::iterator host_it = hosts.begin(); |
| 588 host_it != hosts.end(); ++host_it) { | 608 host_it != hosts.end(); ++host_it) { |
| 589 (*host_it) | 609 (*host_it) |
| 590 ->AssociateIncompleteCache(inprogress_cache_.get(), manifest_url_); | 610 ->AssociateIncompleteCache(inprogress_cache_.get(), manifest_url_); |
| 591 } | 611 } |
| 592 } | 612 } |
| 593 | 613 |
| 614 if (manifest.did_ignore_intercept_namespaces) { |
| 615 // Must be done after associating all pending master hosts. |
| 616 std::string message( |
| 617 "Ignoring the INTERCEPT section of the application cache manifest " |
| 618 "because the content type is not text/cache-manifest"); |
| 619 LogConsoleMessageToAll(message); |
| 620 } |
| 621 |
| 594 group_->SetUpdateStatus(AppCacheGroup::DOWNLOADING); | 622 group_->SetUpdateStatus(AppCacheGroup::DOWNLOADING); |
| 595 NotifyAllAssociatedHosts(DOWNLOADING_EVENT); | 623 NotifyAllAssociatedHosts(DOWNLOADING_EVENT); |
| 596 FetchUrls(); | 624 FetchUrls(); |
| 597 FetchMasterEntries(); | 625 FetchMasterEntries(); |
| 598 MaybeCompleteUpdate(); // if not done, continues when async fetches complete | 626 MaybeCompleteUpdate(); // if not done, continues when async fetches complete |
| 599 } | 627 } |
| 600 | 628 |
| 601 void AppCacheUpdateJob::HandleUrlFetchCompleted(URLFetcher* fetcher) { | 629 void AppCacheUpdateJob::HandleUrlFetchCompleted(URLFetcher* fetcher) { |
| 602 DCHECK(internal_state_ == DOWNLOADING); | 630 DCHECK(internal_state_ == DOWNLOADING); |
| 603 | 631 |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 951 DCHECK(url_file_list_.size() == url_fetches_completed_); | 979 DCHECK(url_file_list_.size() == url_fetches_completed_); |
| 952 NotifyAllProgress(GURL()); | 980 NotifyAllProgress(GURL()); |
| 953 } | 981 } |
| 954 | 982 |
| 955 void AppCacheUpdateJob::NotifyAllError(const ErrorDetails& details) { | 983 void AppCacheUpdateJob::NotifyAllError(const ErrorDetails& details) { |
| 956 HostNotifier host_notifier; | 984 HostNotifier host_notifier; |
| 957 AddAllAssociatedHostsToNotifier(&host_notifier); | 985 AddAllAssociatedHostsToNotifier(&host_notifier); |
| 958 host_notifier.SendErrorNotifications(details); | 986 host_notifier.SendErrorNotifications(details); |
| 959 } | 987 } |
| 960 | 988 |
| 989 void AppCacheUpdateJob::LogConsoleMessageToAll(const std::string& message) { |
| 990 HostNotifier host_notifier; |
| 991 AddAllAssociatedHostsToNotifier(&host_notifier); |
| 992 host_notifier.SendLogMessage(message); |
| 993 } |
| 994 |
| 961 void AppCacheUpdateJob::AddAllAssociatedHostsToNotifier( | 995 void AppCacheUpdateJob::AddAllAssociatedHostsToNotifier( |
| 962 HostNotifier* host_notifier) { | 996 HostNotifier* host_notifier) { |
| 963 // Collect hosts so we only send one notification per frontend. | 997 // Collect hosts so we only send one notification per frontend. |
| 964 // A host can only be associated with a single cache so no need to worry | 998 // A host can only be associated with a single cache so no need to worry |
| 965 // about duplicate hosts being added to the notifier. | 999 // about duplicate hosts being added to the notifier. |
| 966 if (inprogress_cache_.get()) { | 1000 if (inprogress_cache_.get()) { |
| 967 DCHECK(internal_state_ == DOWNLOADING || internal_state_ == CACHE_FAILURE); | 1001 DCHECK(internal_state_ == DOWNLOADING || internal_state_ == CACHE_FAILURE); |
| 968 host_notifier->AddHosts(inprogress_cache_->associated_hosts()); | 1002 host_notifier->AddHosts(inprogress_cache_->associated_hosts()); |
| 969 } | 1003 } |
| 970 | 1004 |
| (...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1562 | 1596 |
| 1563 // Break the connection with the group so the group cannot call delete | 1597 // Break the connection with the group so the group cannot call delete |
| 1564 // on this object after we've posted a task to delete ourselves. | 1598 // on this object after we've posted a task to delete ourselves. |
| 1565 group_->SetUpdateStatus(AppCacheGroup::IDLE); | 1599 group_->SetUpdateStatus(AppCacheGroup::IDLE); |
| 1566 group_ = NULL; | 1600 group_ = NULL; |
| 1567 | 1601 |
| 1568 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 1602 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
| 1569 } | 1603 } |
| 1570 | 1604 |
| 1571 } // namespace appcache | 1605 } // namespace appcache |
| OLD | NEW |