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 "content/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" |
11 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
12 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
| 13 #include "content/browser/appcache/appcache_group.h" |
| 14 #include "content/browser/appcache/appcache_histograms.h" |
13 #include "net/base/io_buffer.h" | 15 #include "net/base/io_buffer.h" |
14 #include "net/base/load_flags.h" | 16 #include "net/base/load_flags.h" |
15 #include "net/base/net_errors.h" | 17 #include "net/base/net_errors.h" |
16 #include "net/base/request_priority.h" | 18 #include "net/base/request_priority.h" |
17 #include "net/http/http_request_headers.h" | 19 #include "net/http/http_request_headers.h" |
18 #include "net/http/http_response_headers.h" | 20 #include "net/http/http_response_headers.h" |
19 #include "net/url_request/url_request_context.h" | 21 #include "net/url_request/url_request_context.h" |
20 #include "webkit/browser/appcache/appcache_group.h" | |
21 #include "webkit/browser/appcache/appcache_histograms.h" | |
22 | 22 |
23 namespace appcache { | 23 namespace content { |
24 | 24 |
25 static const int kBufferSize = 32768; | 25 static const int kBufferSize = 32768; |
26 static const size_t kMaxConcurrentUrlFetches = 2; | 26 static const size_t kMaxConcurrentUrlFetches = 2; |
27 static const int kMax503Retries = 3; | 27 static const int kMax503Retries = 3; |
28 | 28 |
29 static std::string FormatUrlErrorMessage( | 29 static std::string FormatUrlErrorMessage( |
30 const char* format, const GURL& url, | 30 const char* format, const GURL& url, |
31 AppCacheUpdateJob::ResultType error, | 31 AppCacheUpdateJob::ResultType error, |
32 int response_code) { | 32 int response_code) { |
33 // Show the net response code if we have one. | 33 // Show the net response code if we have one. |
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 } else if (response_code == 304 && update_type_ == UPGRADE_ATTEMPT) { | 519 } else if (response_code == 304 && update_type_ == UPGRADE_ATTEMPT) { |
520 ContinueHandleManifestFetchCompleted(false); | 520 ContinueHandleManifestFetchCompleted(false); |
521 } else if ((response_code == 404 || response_code == 410) && | 521 } else if ((response_code == 404 || response_code == 410) && |
522 update_type_ == UPGRADE_ATTEMPT) { | 522 update_type_ == UPGRADE_ATTEMPT) { |
523 storage_->MakeGroupObsolete(group_, this, response_code); // async | 523 storage_->MakeGroupObsolete(group_, this, response_code); // async |
524 } else { | 524 } else { |
525 const char* kFormatString = "Manifest fetch failed (%d) %s"; | 525 const char* kFormatString = "Manifest fetch failed (%d) %s"; |
526 std::string message = FormatUrlErrorMessage( | 526 std::string message = FormatUrlErrorMessage( |
527 kFormatString, manifest_url_, fetcher->result(), response_code); | 527 kFormatString, manifest_url_, fetcher->result(), response_code); |
528 HandleCacheFailure(AppCacheErrorDetails(message, | 528 HandleCacheFailure(AppCacheErrorDetails(message, |
529 appcache::APPCACHE_MANIFEST_ERROR, | 529 APPCACHE_MANIFEST_ERROR, |
530 manifest_url_, | 530 manifest_url_, |
531 response_code, | 531 response_code, |
532 false /*is_cross_origin*/), | 532 false /*is_cross_origin*/), |
533 fetcher->result(), | 533 fetcher->result(), |
534 GURL()); | 534 GURL()); |
535 } | 535 } |
536 } | 536 } |
537 | 537 |
538 void AppCacheUpdateJob::OnGroupMadeObsolete(AppCacheGroup* group, | 538 void AppCacheUpdateJob::OnGroupMadeObsolete(AppCacheGroup* group, |
539 bool success, | 539 bool success, |
540 int response_code) { | 540 int response_code) { |
541 DCHECK(master_entry_fetches_.empty()); | 541 DCHECK(master_entry_fetches_.empty()); |
542 CancelAllMasterEntryFetches(AppCacheErrorDetails( | 542 CancelAllMasterEntryFetches(AppCacheErrorDetails( |
543 "The cache has been made obsolete, " | 543 "The cache has been made obsolete, " |
544 "the manifest file returned 404 or 410", | 544 "the manifest file returned 404 or 410", |
545 appcache::APPCACHE_MANIFEST_ERROR, | 545 APPCACHE_MANIFEST_ERROR, |
546 GURL(), | 546 GURL(), |
547 response_code, | 547 response_code, |
548 false /*is_cross_origin*/)); | 548 false /*is_cross_origin*/)); |
549 if (success) { | 549 if (success) { |
550 DCHECK(group->is_obsolete()); | 550 DCHECK(group->is_obsolete()); |
551 NotifyAllAssociatedHosts(APPCACHE_OBSOLETE_EVENT); | 551 NotifyAllAssociatedHosts(APPCACHE_OBSOLETE_EVENT); |
552 internal_state_ = COMPLETED; | 552 internal_state_ = COMPLETED; |
553 MaybeCompleteUpdate(); | 553 MaybeCompleteUpdate(); |
554 } else { | 554 } else { |
555 // Treat failure to mark group obsolete as a cache failure. | 555 // Treat failure to mark group obsolete as a cache failure. |
(...skipping 28 matching lines...) Expand all Loading... |
584 PARSE_MANIFEST_ALLOWING_INTERCEPTS : | 584 PARSE_MANIFEST_ALLOWING_INTERCEPTS : |
585 PARSE_MANIFEST_PER_STANDARD, | 585 PARSE_MANIFEST_PER_STANDARD, |
586 manifest)) { | 586 manifest)) { |
587 const char* kFormatString = "Failed to parse manifest %s"; | 587 const char* kFormatString = "Failed to parse manifest %s"; |
588 const std::string message = base::StringPrintf(kFormatString, | 588 const std::string message = base::StringPrintf(kFormatString, |
589 manifest_url_.spec().c_str()); | 589 manifest_url_.spec().c_str()); |
590 HandleCacheFailure( | 590 HandleCacheFailure( |
591 AppCacheErrorDetails( | 591 AppCacheErrorDetails( |
592 message, APPCACHE_SIGNATURE_ERROR, GURL(), 0, | 592 message, APPCACHE_SIGNATURE_ERROR, GURL(), 0, |
593 false /*is_cross_origin*/), | 593 false /*is_cross_origin*/), |
594 APPCACHE_MANIFEST_ERROR, | 594 MANIFEST_ERROR, |
595 GURL()); | 595 GURL()); |
596 VLOG(1) << message; | 596 VLOG(1) << message; |
597 return; | 597 return; |
598 } | 598 } |
599 | 599 |
600 // Proceed with update process. Section 6.9.4 steps 8-20. | 600 // Proceed with update process. Section 6.9.4 steps 8-20. |
601 internal_state_ = DOWNLOADING; | 601 internal_state_ = DOWNLOADING; |
602 inprogress_cache_ = new AppCache(storage_, storage_->NewCacheId()); | 602 inprogress_cache_ = new AppCache(storage_, storage_->NewCacheId()); |
603 BuildUrlFileList(manifest); | 603 BuildUrlFileList(manifest); |
604 inprogress_cache_->InitializeWithManifest(&manifest); | 604 inprogress_cache_->InitializeWithManifest(&manifest); |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
783 | 783 |
784 host->RemoveObserver(this); | 784 host->RemoveObserver(this); |
785 } | 785 } |
786 hosts.clear(); | 786 hosts.clear(); |
787 | 787 |
788 const char* kFormatString = "Manifest fetch failed (%d) %s"; | 788 const char* kFormatString = "Manifest fetch failed (%d) %s"; |
789 std::string message = FormatUrlErrorMessage( | 789 std::string message = FormatUrlErrorMessage( |
790 kFormatString, request->url(), fetcher->result(), response_code); | 790 kFormatString, request->url(), fetcher->result(), response_code); |
791 host_notifier.SendErrorNotifications( | 791 host_notifier.SendErrorNotifications( |
792 AppCacheErrorDetails(message, | 792 AppCacheErrorDetails(message, |
793 appcache::APPCACHE_MANIFEST_ERROR, | 793 APPCACHE_MANIFEST_ERROR, |
794 request->url(), | 794 request->url(), |
795 response_code, | 795 response_code, |
796 false /*is_cross_origin*/)); | 796 false /*is_cross_origin*/)); |
797 | 797 |
798 // In downloading case, update result is different if all master entries | 798 // In downloading case, update result is different if all master entries |
799 // failed vs. only some failing. | 799 // failed vs. only some failing. |
800 if (inprogress_cache_.get()) { | 800 if (inprogress_cache_.get()) { |
801 // Only count successful downloads to know if all master entries failed. | 801 // Only count successful downloads to know if all master entries failed. |
802 pending_master_entries_.erase(found); | 802 pending_master_entries_.erase(found); |
803 --master_entries_completed_; | 803 --master_entries_completed_; |
804 | 804 |
805 // Section 6.9.4, step 22.3. | 805 // Section 6.9.4, step 22.3. |
806 if (update_type_ == CACHE_ATTEMPT && pending_master_entries_.empty()) { | 806 if (update_type_ == CACHE_ATTEMPT && pending_master_entries_.empty()) { |
807 HandleCacheFailure(AppCacheErrorDetails(message, | 807 HandleCacheFailure(AppCacheErrorDetails(message, |
808 appcache::APPCACHE_MANIFEST_ERROR, | 808 APPCACHE_MANIFEST_ERROR, |
809 request->url(), | 809 request->url(), |
810 response_code, | 810 response_code, |
811 false /*is_cross_origin*/), | 811 false /*is_cross_origin*/), |
812 fetcher->result(), | 812 fetcher->result(), |
813 GURL()); | 813 GURL()); |
814 return; | 814 return; |
815 } | 815 } |
816 } | 816 } |
817 } | 817 } |
818 | 818 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
850 VLOG(1) << "Request status: " << request->status().status() | 850 VLOG(1) << "Request status: " << request->status().status() |
851 << " error: " << request->status().error() | 851 << " error: " << request->status().error() |
852 << " response code: " << response_code; | 852 << " response code: " << response_code; |
853 ScheduleUpdateRetry(kRerunDelayMs); | 853 ScheduleUpdateRetry(kRerunDelayMs); |
854 if (response_code == 200) { | 854 if (response_code == 200) { |
855 HandleCacheFailure(AppCacheErrorDetails("Manifest changed during update", | 855 HandleCacheFailure(AppCacheErrorDetails("Manifest changed during update", |
856 APPCACHE_CHANGED_ERROR, | 856 APPCACHE_CHANGED_ERROR, |
857 GURL(), | 857 GURL(), |
858 0, | 858 0, |
859 false /*is_cross_origin*/), | 859 false /*is_cross_origin*/), |
860 APPCACHE_MANIFEST_ERROR, | 860 MANIFEST_ERROR, |
861 GURL()); | 861 GURL()); |
862 } else { | 862 } else { |
863 const char* kFormatString = "Manifest re-fetch failed (%d) %s"; | 863 const char* kFormatString = "Manifest re-fetch failed (%d) %s"; |
864 std::string message = FormatUrlErrorMessage( | 864 std::string message = FormatUrlErrorMessage( |
865 kFormatString, manifest_url_, fetcher->result(), response_code); | 865 kFormatString, manifest_url_, fetcher->result(), response_code); |
866 HandleCacheFailure(AppCacheErrorDetails(message, | 866 HandleCacheFailure(AppCacheErrorDetails(message, |
867 appcache::APPCACHE_MANIFEST_ERROR, | 867 APPCACHE_MANIFEST_ERROR, |
868 GURL(), | 868 GURL(), |
869 response_code, | 869 response_code, |
870 false /*is_cross_origin*/), | 870 false /*is_cross_origin*/), |
871 fetcher->result(), | 871 fetcher->result(), |
872 GURL()); | 872 GURL()); |
873 } | 873 } |
874 } | 874 } |
875 } | 875 } |
876 | 876 |
877 void AppCacheUpdateJob::OnManifestInfoWriteComplete(int result) { | 877 void AppCacheUpdateJob::OnManifestInfoWriteComplete(int result) { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
944 // Restore inprogress_cache_ to get the proper events delivered | 944 // Restore inprogress_cache_ to get the proper events delivered |
945 // and the proper cleanup to occur. | 945 // and the proper cleanup to occur. |
946 if (newest_cache != group->newest_complete_cache()) | 946 if (newest_cache != group->newest_complete_cache()) |
947 inprogress_cache_ = newest_cache; | 947 inprogress_cache_ = newest_cache; |
948 | 948 |
949 ResultType result = DB_ERROR; | 949 ResultType result = DB_ERROR; |
950 AppCacheErrorReason reason = APPCACHE_UNKNOWN_ERROR; | 950 AppCacheErrorReason reason = APPCACHE_UNKNOWN_ERROR; |
951 std::string message("Failed to commit new cache to storage"); | 951 std::string message("Failed to commit new cache to storage"); |
952 if (would_exceed_quota) { | 952 if (would_exceed_quota) { |
953 message.append(", would exceed quota"); | 953 message.append(", would exceed quota"); |
954 result = APPCACHE_QUOTA_ERROR; | 954 result = QUOTA_ERROR; |
955 reason = appcache::APPCACHE_QUOTA_ERROR; | 955 reason = APPCACHE_QUOTA_ERROR; |
956 } | 956 } |
957 HandleCacheFailure( | 957 HandleCacheFailure( |
958 AppCacheErrorDetails(message, reason, GURL(), 0, | 958 AppCacheErrorDetails(message, reason, GURL(), 0, |
959 false /*is_cross_origin*/), | 959 false /*is_cross_origin*/), |
960 result, | 960 result, |
961 GURL()); | 961 GURL()); |
962 } | 962 } |
963 } | 963 } |
964 | 964 |
965 void AppCacheUpdateJob::NotifySingleHost(AppCacheHost* host, | 965 void AppCacheUpdateJob::NotifySingleHost(AppCacheHost* host, |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1092 } | 1092 } |
1093 } | 1093 } |
1094 | 1094 |
1095 void AppCacheUpdateJob::BuildUrlFileList(const Manifest& manifest) { | 1095 void AppCacheUpdateJob::BuildUrlFileList(const Manifest& manifest) { |
1096 for (base::hash_set<std::string>::const_iterator it = | 1096 for (base::hash_set<std::string>::const_iterator it = |
1097 manifest.explicit_urls.begin(); | 1097 manifest.explicit_urls.begin(); |
1098 it != manifest.explicit_urls.end(); ++it) { | 1098 it != manifest.explicit_urls.end(); ++it) { |
1099 AddUrlToFileList(GURL(*it), AppCacheEntry::EXPLICIT); | 1099 AddUrlToFileList(GURL(*it), AppCacheEntry::EXPLICIT); |
1100 } | 1100 } |
1101 | 1101 |
1102 const std::vector<Namespace>& intercepts = | 1102 const std::vector<AppCacheNamespace>& intercepts = |
1103 manifest.intercept_namespaces; | 1103 manifest.intercept_namespaces; |
1104 for (std::vector<Namespace>::const_iterator it = intercepts.begin(); | 1104 for (std::vector<AppCacheNamespace>::const_iterator it = intercepts.begin(); |
1105 it != intercepts.end(); ++it) { | 1105 it != intercepts.end(); ++it) { |
1106 int flags = AppCacheEntry::INTERCEPT; | 1106 int flags = AppCacheEntry::INTERCEPT; |
1107 if (it->is_executable) | 1107 if (it->is_executable) |
1108 flags |= AppCacheEntry::EXECUTABLE; | 1108 flags |= AppCacheEntry::EXECUTABLE; |
1109 AddUrlToFileList(it->target_url, flags); | 1109 AddUrlToFileList(it->target_url, flags); |
1110 } | 1110 } |
1111 | 1111 |
1112 const std::vector<Namespace>& fallbacks = | 1112 const std::vector<AppCacheNamespace>& fallbacks = |
1113 manifest.fallback_namespaces; | 1113 manifest.fallback_namespaces; |
1114 for (std::vector<Namespace>::const_iterator it = fallbacks.begin(); | 1114 for (std::vector<AppCacheNamespace>::const_iterator it = fallbacks.begin(); |
1115 it != fallbacks.end(); ++it) { | 1115 it != fallbacks.end(); ++it) { |
1116 AddUrlToFileList(it->target_url, AppCacheEntry::FALLBACK); | 1116 AddUrlToFileList(it->target_url, AppCacheEntry::FALLBACK); |
1117 } | 1117 } |
1118 | 1118 |
1119 // Add all master entries from newest complete cache. | 1119 // Add all master entries from newest complete cache. |
1120 if (update_type_ == UPGRADE_ATTEMPT) { | 1120 if (update_type_ == UPGRADE_ATTEMPT) { |
1121 const AppCache::EntryMap& entries = | 1121 const AppCache::EntryMap& entries = |
1122 group_->newest_complete_cache()->entries(); | 1122 group_->newest_complete_cache()->entries(); |
1123 for (AppCache::EntryMap::const_iterator it = entries.begin(); | 1123 for (AppCache::EntryMap::const_iterator it = entries.begin(); |
1124 it != entries.end(); ++it) { | 1124 it != entries.end(); ++it) { |
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1601 service_ = NULL; | 1601 service_ = NULL; |
1602 | 1602 |
1603 // Break the connection with the group so the group cannot call delete | 1603 // Break the connection with the group so the group cannot call delete |
1604 // on this object after we've posted a task to delete ourselves. | 1604 // on this object after we've posted a task to delete ourselves. |
1605 group_->SetUpdateAppCacheStatus(AppCacheGroup::IDLE); | 1605 group_->SetUpdateAppCacheStatus(AppCacheGroup::IDLE); |
1606 group_ = NULL; | 1606 group_ = NULL; |
1607 | 1607 |
1608 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 1608 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
1609 } | 1609 } |
1610 | 1610 |
1611 } // namespace appcache | 1611 } // namespace content |
OLD | NEW |