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/appcache/appcache_update_job.h" | 5 #include "webkit/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.h" | 10 #include "base/message_loop.h" |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 request_(job->service_->request_context()->CreateRequest(url, this)) { | 101 request_(job->service_->request_context()->CreateRequest(url, this)) { |
102 } | 102 } |
103 | 103 |
104 AppCacheUpdateJob::URLFetcher::~URLFetcher() { | 104 AppCacheUpdateJob::URLFetcher::~URLFetcher() { |
105 } | 105 } |
106 | 106 |
107 void AppCacheUpdateJob::URLFetcher::Start() { | 107 void AppCacheUpdateJob::URLFetcher::Start() { |
108 request_->set_first_party_for_cookies(job_->manifest_url_); | 108 request_->set_first_party_for_cookies(job_->manifest_url_); |
109 request_->set_load_flags(request_->load_flags() | | 109 request_->set_load_flags(request_->load_flags() | |
110 net::LOAD_DISABLE_INTERCEPT); | 110 net::LOAD_DISABLE_INTERCEPT); |
111 if (existing_response_headers_) | 111 if (existing_response_headers_.get()) |
112 AddConditionalHeaders(existing_response_headers_); | 112 AddConditionalHeaders(existing_response_headers_.get()); |
113 request_->Start(); | 113 request_->Start(); |
114 } | 114 } |
115 | 115 |
116 void AppCacheUpdateJob::URLFetcher::OnReceivedRedirect( | 116 void AppCacheUpdateJob::URLFetcher::OnReceivedRedirect( |
117 net::URLRequest* request, const GURL& new_url, bool* defer_redirect) { | 117 net::URLRequest* request, const GURL& new_url, bool* defer_redirect) { |
118 DCHECK(request_ == request); | 118 DCHECK(request_ == request); |
119 // Redirect is not allowed by the update process. | 119 // Redirect is not allowed by the update process. |
120 request->Cancel(); | 120 request->Cancel(); |
121 OnResponseCompleted(); | 121 OnResponseCompleted(); |
122 } | 122 } |
(...skipping 22 matching lines...) Expand all Loading... |
145 } | 145 } |
146 | 146 |
147 // Write response info to storage for URL fetches. Wait for async write | 147 // Write response info to storage for URL fetches. Wait for async write |
148 // completion before reading any response data. | 148 // completion before reading any response data. |
149 if (fetch_type_ == URL_FETCH || fetch_type_ == MASTER_ENTRY_FETCH) { | 149 if (fetch_type_ == URL_FETCH || fetch_type_ == MASTER_ENTRY_FETCH) { |
150 response_writer_.reset(job_->CreateResponseWriter()); | 150 response_writer_.reset(job_->CreateResponseWriter()); |
151 scoped_refptr<HttpResponseInfoIOBuffer> io_buffer( | 151 scoped_refptr<HttpResponseInfoIOBuffer> io_buffer( |
152 new HttpResponseInfoIOBuffer( | 152 new HttpResponseInfoIOBuffer( |
153 new net::HttpResponseInfo(request->response_info()))); | 153 new net::HttpResponseInfo(request->response_info()))); |
154 response_writer_->WriteInfo( | 154 response_writer_->WriteInfo( |
155 io_buffer, | 155 io_buffer.get(), |
156 base::Bind(&URLFetcher::OnWriteComplete, base::Unretained(this))); | 156 base::Bind(&URLFetcher::OnWriteComplete, base::Unretained(this))); |
157 } else { | 157 } else { |
158 ReadResponseData(); | 158 ReadResponseData(); |
159 } | 159 } |
160 } else { | 160 } else { |
161 OnResponseCompleted(); | 161 OnResponseCompleted(); |
162 } | 162 } |
163 } | 163 } |
164 | 164 |
165 void AppCacheUpdateJob::URLFetcher::OnReadCompleted( | 165 void AppCacheUpdateJob::URLFetcher::OnReadCompleted( |
166 net::URLRequest* request, int bytes_read) { | 166 net::URLRequest* request, int bytes_read) { |
167 DCHECK(request_ == request); | 167 DCHECK(request_ == request); |
168 bool data_consumed = true; | 168 bool data_consumed = true; |
169 if (request->status().is_success() && bytes_read > 0) { | 169 if (request->status().is_success() && bytes_read > 0) { |
170 data_consumed = ConsumeResponseData(bytes_read); | 170 data_consumed = ConsumeResponseData(bytes_read); |
171 if (data_consumed) { | 171 if (data_consumed) { |
172 bytes_read = 0; | 172 bytes_read = 0; |
173 while (request->Read(buffer_, kBufferSize, &bytes_read)) { | 173 while (request->Read(buffer_.get(), kBufferSize, &bytes_read)) { |
174 if (bytes_read > 0) { | 174 if (bytes_read > 0) { |
175 data_consumed = ConsumeResponseData(bytes_read); | 175 data_consumed = ConsumeResponseData(bytes_read); |
176 if (!data_consumed) | 176 if (!data_consumed) |
177 break; // wait for async data processing, then read more | 177 break; // wait for async data processing, then read more |
178 } else { | 178 } else { |
179 break; | 179 break; |
180 } | 180 } |
181 } | 181 } |
182 } | 182 } |
183 } | 183 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 return; | 218 return; |
219 } | 219 } |
220 ReadResponseData(); | 220 ReadResponseData(); |
221 } | 221 } |
222 | 222 |
223 void AppCacheUpdateJob::URLFetcher::ReadResponseData() { | 223 void AppCacheUpdateJob::URLFetcher::ReadResponseData() { |
224 InternalUpdateState state = job_->internal_state_; | 224 InternalUpdateState state = job_->internal_state_; |
225 if (state == CACHE_FAILURE || state == CANCELLED || state == COMPLETED) | 225 if (state == CACHE_FAILURE || state == CANCELLED || state == COMPLETED) |
226 return; | 226 return; |
227 int bytes_read = 0; | 227 int bytes_read = 0; |
228 request_->Read(buffer_, kBufferSize, &bytes_read); | 228 request_->Read(buffer_.get(), kBufferSize, &bytes_read); |
229 OnReadCompleted(request_.get(), bytes_read); | 229 OnReadCompleted(request_.get(), bytes_read); |
230 } | 230 } |
231 | 231 |
232 // Returns false if response data is processed asynchronously, in which | 232 // Returns false if response data is processed asynchronously, in which |
233 // case ReadResponseData will be invoked when it is safe to continue | 233 // case ReadResponseData will be invoked when it is safe to continue |
234 // reading more response data from the request. | 234 // reading more response data from the request. |
235 bool AppCacheUpdateJob::URLFetcher::ConsumeResponseData(int bytes_read) { | 235 bool AppCacheUpdateJob::URLFetcher::ConsumeResponseData(int bytes_read) { |
236 DCHECK_GT(bytes_read, 0); | 236 DCHECK_GT(bytes_read, 0); |
237 switch (fetch_type_) { | 237 switch (fetch_type_) { |
238 case MANIFEST_FETCH: | 238 case MANIFEST_FETCH: |
239 case MANIFEST_REFETCH: | 239 case MANIFEST_REFETCH: |
240 manifest_data_.append(buffer_->data(), bytes_read); | 240 manifest_data_.append(buffer_->data(), bytes_read); |
241 break; | 241 break; |
242 case URL_FETCH: | 242 case URL_FETCH: |
243 case MASTER_ENTRY_FETCH: | 243 case MASTER_ENTRY_FETCH: |
244 DCHECK(response_writer_.get()); | 244 DCHECK(response_writer_.get()); |
245 response_writer_->WriteData( | 245 response_writer_->WriteData( |
246 buffer_, bytes_read, | 246 buffer_.get(), |
| 247 bytes_read, |
247 base::Bind(&URLFetcher::OnWriteComplete, base::Unretained(this))); | 248 base::Bind(&URLFetcher::OnWriteComplete, base::Unretained(this))); |
248 return false; // wait for async write completion to continue reading | 249 return false; // wait for async write completion to continue reading |
249 default: | 250 default: |
250 NOTREACHED(); | 251 NOTREACHED(); |
251 } | 252 } |
252 return true; | 253 return true; |
253 } | 254 } |
254 | 255 |
255 void AppCacheUpdateJob::URLFetcher::OnResponseCompleted() { | 256 void AppCacheUpdateJob::URLFetcher::OnResponseCompleted() { |
256 // Retry for 503s where retry-after is 0. | 257 // Retry for 503s where retry-after is 0. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 manifest_fetcher_(NULL), | 304 manifest_fetcher_(NULL), |
304 stored_state_(UNSTORED) { | 305 stored_state_(UNSTORED) { |
305 } | 306 } |
306 | 307 |
307 AppCacheUpdateJob::~AppCacheUpdateJob() { | 308 AppCacheUpdateJob::~AppCacheUpdateJob() { |
308 if (internal_state_ != COMPLETED) | 309 if (internal_state_ != COMPLETED) |
309 Cancel(); | 310 Cancel(); |
310 | 311 |
311 DCHECK(!manifest_fetcher_); | 312 DCHECK(!manifest_fetcher_); |
312 DCHECK(pending_url_fetches_.empty()); | 313 DCHECK(pending_url_fetches_.empty()); |
313 DCHECK(!inprogress_cache_); | 314 DCHECK(!inprogress_cache_.get()); |
314 DCHECK(pending_master_entries_.empty()); | 315 DCHECK(pending_master_entries_.empty()); |
315 DCHECK(master_entry_fetches_.empty()); | 316 DCHECK(master_entry_fetches_.empty()); |
316 | 317 |
317 if (group_) | 318 if (group_) |
318 group_->SetUpdateStatus(AppCacheGroup::IDLE); | 319 group_->SetUpdateStatus(AppCacheGroup::IDLE); |
319 } | 320 } |
320 | 321 |
321 void AppCacheUpdateJob::StartUpdate(AppCacheHost* host, | 322 void AppCacheUpdateJob::StartUpdate(AppCacheHost* host, |
322 const GURL& new_master_resource) { | 323 const GURL& new_master_resource) { |
323 DCHECK(group_->update_job() == this); | 324 DCHECK(group_->update_job() == this); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 // Asynchronously load response info for manifest from newest cache. | 418 // Asynchronously load response info for manifest from newest cache. |
418 service_->storage()->LoadResponseInfo(manifest_url_, group_->group_id(), | 419 service_->storage()->LoadResponseInfo(manifest_url_, group_->group_id(), |
419 entry->response_id(), this); | 420 entry->response_id(), this); |
420 } else { | 421 } else { |
421 manifest_fetcher_->Start(); | 422 manifest_fetcher_->Start(); |
422 } | 423 } |
423 } else { | 424 } else { |
424 DCHECK(internal_state_ == REFETCH_MANIFEST); | 425 DCHECK(internal_state_ == REFETCH_MANIFEST); |
425 DCHECK(manifest_response_info_.get()); | 426 DCHECK(manifest_response_info_.get()); |
426 manifest_fetcher_->set_existing_response_headers( | 427 manifest_fetcher_->set_existing_response_headers( |
427 manifest_response_info_->headers); | 428 manifest_response_info_->headers.get()); |
428 manifest_fetcher_->Start(); | 429 manifest_fetcher_->Start(); |
429 } | 430 } |
430 } | 431 } |
431 | 432 |
432 | 433 |
433 void AppCacheUpdateJob::HandleManifestFetchCompleted( | 434 void AppCacheUpdateJob::HandleManifestFetchCompleted( |
434 URLFetcher* fetcher) { | 435 URLFetcher* fetcher) { |
435 DCHECK_EQ(internal_state_, FETCH_MANIFEST); | 436 DCHECK_EQ(internal_state_, FETCH_MANIFEST); |
436 DCHECK_EQ(manifest_fetcher_, fetcher); | 437 DCHECK_EQ(manifest_fetcher_, fetcher); |
437 manifest_fetcher_ = NULL; | 438 manifest_fetcher_ = NULL; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 service_->storage()->NewCacheId()); | 512 service_->storage()->NewCacheId()); |
512 BuildUrlFileList(manifest); | 513 BuildUrlFileList(manifest); |
513 inprogress_cache_->InitializeWithManifest(&manifest); | 514 inprogress_cache_->InitializeWithManifest(&manifest); |
514 | 515 |
515 // Associate all pending master hosts with the newly created cache. | 516 // Associate all pending master hosts with the newly created cache. |
516 for (PendingMasters::iterator it = pending_master_entries_.begin(); | 517 for (PendingMasters::iterator it = pending_master_entries_.begin(); |
517 it != pending_master_entries_.end(); ++it) { | 518 it != pending_master_entries_.end(); ++it) { |
518 PendingHosts& hosts = it->second; | 519 PendingHosts& hosts = it->second; |
519 for (PendingHosts::iterator host_it = hosts.begin(); | 520 for (PendingHosts::iterator host_it = hosts.begin(); |
520 host_it != hosts.end(); ++host_it) { | 521 host_it != hosts.end(); ++host_it) { |
521 (*host_it)->AssociateIncompleteCache(inprogress_cache_, manifest_url_); | 522 (*host_it) |
| 523 ->AssociateIncompleteCache(inprogress_cache_.get(), manifest_url_); |
522 } | 524 } |
523 } | 525 } |
524 | 526 |
525 group_->SetUpdateStatus(AppCacheGroup::DOWNLOADING); | 527 group_->SetUpdateStatus(AppCacheGroup::DOWNLOADING); |
526 NotifyAllAssociatedHosts(DOWNLOADING_EVENT); | 528 NotifyAllAssociatedHosts(DOWNLOADING_EVENT); |
527 FetchUrls(); | 529 FetchUrls(); |
528 FetchMasterEntries(); | 530 FetchMasterEntries(); |
529 MaybeCompleteUpdate(); // if not done, continues when async fetches complete | 531 MaybeCompleteUpdate(); // if not done, continues when async fetches complete |
530 } | 532 } |
531 | 533 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 int response_code = request->status().is_success() | 616 int response_code = request->status().is_success() |
615 ? request->GetResponseCode() : -1; | 617 ? request->GetResponseCode() : -1; |
616 | 618 |
617 PendingMasters::iterator found = pending_master_entries_.find(url); | 619 PendingMasters::iterator found = pending_master_entries_.find(url); |
618 DCHECK(found != pending_master_entries_.end()); | 620 DCHECK(found != pending_master_entries_.end()); |
619 PendingHosts& hosts = found->second; | 621 PendingHosts& hosts = found->second; |
620 | 622 |
621 // Section 6.9.4. No update case: step 7.3, else step 22. | 623 // Section 6.9.4. No update case: step 7.3, else step 22. |
622 if (response_code / 100 == 2) { | 624 if (response_code / 100 == 2) { |
623 // Add fetched master entry to the appropriate cache. | 625 // Add fetched master entry to the appropriate cache. |
624 AppCache* cache = inprogress_cache_ ? inprogress_cache_.get() : | 626 AppCache* cache = inprogress_cache_.get() ? inprogress_cache_.get() |
625 group_->newest_complete_cache(); | 627 : group_->newest_complete_cache(); |
626 DCHECK(fetcher->response_writer()); | 628 DCHECK(fetcher->response_writer()); |
627 AppCacheEntry master_entry(AppCacheEntry::MASTER, | 629 AppCacheEntry master_entry(AppCacheEntry::MASTER, |
628 fetcher->response_writer()->response_id(), | 630 fetcher->response_writer()->response_id(), |
629 fetcher->response_writer()->amount_written()); | 631 fetcher->response_writer()->amount_written()); |
630 if (cache->AddOrModifyEntry(url, master_entry)) | 632 if (cache->AddOrModifyEntry(url, master_entry)) |
631 added_master_entries_.push_back(url); | 633 added_master_entries_.push_back(url); |
632 else | 634 else |
633 duplicate_response_ids_.push_back(master_entry.response_id()); | 635 duplicate_response_ids_.push_back(master_entry.response_id()); |
634 | 636 |
635 // In no-update case, associate host with the newest cache. | 637 // In no-update case, associate host with the newest cache. |
636 if (!inprogress_cache_) { | 638 if (!inprogress_cache_.get()) { |
637 // TODO(michaeln): defer until the updated cache has been stored | 639 // TODO(michaeln): defer until the updated cache has been stored |
638 DCHECK(cache == group_->newest_complete_cache()); | 640 DCHECK(cache == group_->newest_complete_cache()); |
639 for (PendingHosts::iterator host_it = hosts.begin(); | 641 for (PendingHosts::iterator host_it = hosts.begin(); |
640 host_it != hosts.end(); ++host_it) { | 642 host_it != hosts.end(); ++host_it) { |
641 (*host_it)->AssociateCompleteCache(cache); | 643 (*host_it)->AssociateCompleteCache(cache); |
642 } | 644 } |
643 } | 645 } |
644 } else { | 646 } else { |
645 HostNotifier host_notifier; | 647 HostNotifier host_notifier; |
646 for (PendingHosts::iterator host_it = hosts.begin(); | 648 for (PendingHosts::iterator host_it = hosts.begin(); |
647 host_it != hosts.end(); ++host_it) { | 649 host_it != hosts.end(); ++host_it) { |
648 AppCacheHost* host = *host_it; | 650 AppCacheHost* host = *host_it; |
649 host_notifier.AddHost(host); | 651 host_notifier.AddHost(host); |
650 | 652 |
651 // In downloading case, disassociate host from inprogress cache. | 653 // In downloading case, disassociate host from inprogress cache. |
652 if (inprogress_cache_) | 654 if (inprogress_cache_.get()) |
653 host->AssociateNoCache(GURL()); | 655 host->AssociateNoCache(GURL()); |
654 | 656 |
655 host->RemoveObserver(this); | 657 host->RemoveObserver(this); |
656 } | 658 } |
657 hosts.clear(); | 659 hosts.clear(); |
658 | 660 |
659 const char* kFormatString = "Master entry fetch failed (%d) %s"; | 661 const char* kFormatString = "Master entry fetch failed (%d) %s"; |
660 const std::string message = base::StringPrintf(kFormatString, | 662 const std::string message = base::StringPrintf(kFormatString, |
661 response_code, request->url().spec().c_str()); | 663 response_code, request->url().spec().c_str()); |
662 host_notifier.SendErrorNotifications(message); | 664 host_notifier.SendErrorNotifications(message); |
663 | 665 |
664 // In downloading case, update result is different if all master entries | 666 // In downloading case, update result is different if all master entries |
665 // failed vs. only some failing. | 667 // failed vs. only some failing. |
666 if (inprogress_cache_) { | 668 if (inprogress_cache_.get()) { |
667 // Only count successful downloads to know if all master entries failed. | 669 // Only count successful downloads to know if all master entries failed. |
668 pending_master_entries_.erase(found); | 670 pending_master_entries_.erase(found); |
669 --master_entries_completed_; | 671 --master_entries_completed_; |
670 | 672 |
671 // Section 6.9.4, step 22.3. | 673 // Section 6.9.4, step 22.3. |
672 if (update_type_ == CACHE_ATTEMPT && pending_master_entries_.empty()) { | 674 if (update_type_ == CACHE_ATTEMPT && pending_master_entries_.empty()) { |
673 HandleCacheFailure(message); | 675 HandleCacheFailure(message); |
674 return; | 676 return; |
675 } | 677 } |
676 } | 678 } |
(...skipping 18 matching lines...) Expand all Loading... |
695 // an entry in the cache. | 697 // an entry in the cache. |
696 AppCacheEntry* entry = inprogress_cache_->GetEntry(manifest_url_); | 698 AppCacheEntry* entry = inprogress_cache_->GetEntry(manifest_url_); |
697 if (entry) { | 699 if (entry) { |
698 entry->add_types(AppCacheEntry::MANIFEST); | 700 entry->add_types(AppCacheEntry::MANIFEST); |
699 StoreGroupAndCache(); | 701 StoreGroupAndCache(); |
700 } else { | 702 } else { |
701 manifest_response_writer_.reset(CreateResponseWriter()); | 703 manifest_response_writer_.reset(CreateResponseWriter()); |
702 scoped_refptr<HttpResponseInfoIOBuffer> io_buffer( | 704 scoped_refptr<HttpResponseInfoIOBuffer> io_buffer( |
703 new HttpResponseInfoIOBuffer(manifest_response_info_.release())); | 705 new HttpResponseInfoIOBuffer(manifest_response_info_.release())); |
704 manifest_response_writer_->WriteInfo( | 706 manifest_response_writer_->WriteInfo( |
705 io_buffer, | 707 io_buffer.get(), |
706 base::Bind(&AppCacheUpdateJob::OnManifestInfoWriteComplete, | 708 base::Bind(&AppCacheUpdateJob::OnManifestInfoWriteComplete, |
707 base::Unretained(this))); | 709 base::Unretained(this))); |
708 } | 710 } |
709 } else { | 711 } else { |
710 VLOG(1) << "Request status: " << request->status().status() | 712 VLOG(1) << "Request status: " << request->status().status() |
711 << " error: " << request->status().error() | 713 << " error: " << request->status().error() |
712 << " response code: " << response_code; | 714 << " response code: " << response_code; |
713 ScheduleUpdateRetry(kRerunDelayMs); | 715 ScheduleUpdateRetry(kRerunDelayMs); |
714 HandleCacheFailure("Manifest changed during update, scheduling retry"); | 716 HandleCacheFailure("Manifest changed during update, scheduling retry"); |
715 } | 717 } |
716 } | 718 } |
717 | 719 |
718 void AppCacheUpdateJob::OnManifestInfoWriteComplete(int result) { | 720 void AppCacheUpdateJob::OnManifestInfoWriteComplete(int result) { |
719 if (result > 0) { | 721 if (result > 0) { |
720 scoped_refptr<net::StringIOBuffer> io_buffer( | 722 scoped_refptr<net::StringIOBuffer> io_buffer( |
721 new net::StringIOBuffer(manifest_data_)); | 723 new net::StringIOBuffer(manifest_data_)); |
722 manifest_response_writer_->WriteData( | 724 manifest_response_writer_->WriteData( |
723 io_buffer, manifest_data_.length(), | 725 io_buffer.get(), |
| 726 manifest_data_.length(), |
724 base::Bind(&AppCacheUpdateJob::OnManifestDataWriteComplete, | 727 base::Bind(&AppCacheUpdateJob::OnManifestDataWriteComplete, |
725 base::Unretained(this))); | 728 base::Unretained(this))); |
726 } else { | 729 } else { |
727 HandleCacheFailure("Failed to write the manifest headers to storage"); | 730 HandleCacheFailure("Failed to write the manifest headers to storage"); |
728 } | 731 } |
729 } | 732 } |
730 | 733 |
731 void AppCacheUpdateJob::OnManifestDataWriteComplete(int result) { | 734 void AppCacheUpdateJob::OnManifestDataWriteComplete(int result) { |
732 if (result > 0) { | 735 if (result > 0) { |
733 AppCacheEntry entry(AppCacheEntry::MANIFEST, | 736 AppCacheEntry entry(AppCacheEntry::MANIFEST, |
734 manifest_response_writer_->response_id(), | 737 manifest_response_writer_->response_id(), |
735 manifest_response_writer_->amount_written()); | 738 manifest_response_writer_->amount_written()); |
736 if (!inprogress_cache_->AddOrModifyEntry(manifest_url_, entry)) | 739 if (!inprogress_cache_->AddOrModifyEntry(manifest_url_, entry)) |
737 duplicate_response_ids_.push_back(entry.response_id()); | 740 duplicate_response_ids_.push_back(entry.response_id()); |
738 StoreGroupAndCache(); | 741 StoreGroupAndCache(); |
739 } else { | 742 } else { |
740 HandleCacheFailure("Failed to write the manifest data to storage"); | 743 HandleCacheFailure("Failed to write the manifest data to storage"); |
741 } | 744 } |
742 } | 745 } |
743 | 746 |
744 void AppCacheUpdateJob::StoreGroupAndCache() { | 747 void AppCacheUpdateJob::StoreGroupAndCache() { |
745 DCHECK(stored_state_ == UNSTORED); | 748 DCHECK(stored_state_ == UNSTORED); |
746 stored_state_ = STORING; | 749 stored_state_ = STORING; |
747 scoped_refptr<AppCache> newest_cache; | 750 scoped_refptr<AppCache> newest_cache; |
748 if (inprogress_cache_) | 751 if (inprogress_cache_.get()) |
749 newest_cache.swap(inprogress_cache_); | 752 newest_cache.swap(inprogress_cache_); |
750 else | 753 else |
751 newest_cache = group_->newest_complete_cache(); | 754 newest_cache = group_->newest_complete_cache(); |
752 newest_cache->set_update_time(base::Time::Now()); | 755 newest_cache->set_update_time(base::Time::Now()); |
753 | 756 |
754 // TODO(michaeln): dcheck is fishing for clues to crbug/95101 | 757 // TODO(michaeln): dcheck is fishing for clues to crbug/95101 |
755 DCHECK_EQ(manifest_url_, group_->manifest_url()); | 758 DCHECK_EQ(manifest_url_, group_->manifest_url()); |
756 service_->storage()->StoreGroupAndNewestCache(group_, newest_cache, | 759 service_->storage() |
757 this); // async | 760 ->StoreGroupAndNewestCache(group_, newest_cache.get(), this); // async |
758 } | 761 } |
759 | 762 |
760 void AppCacheUpdateJob::OnGroupAndNewestCacheStored(AppCacheGroup* group, | 763 void AppCacheUpdateJob::OnGroupAndNewestCacheStored(AppCacheGroup* group, |
761 AppCache* newest_cache, | 764 AppCache* newest_cache, |
762 bool success, | 765 bool success, |
763 bool would_exceed_quota) { | 766 bool would_exceed_quota) { |
764 DCHECK(stored_state_ == STORING); | 767 DCHECK(stored_state_ == STORING); |
765 if (success) { | 768 if (success) { |
766 stored_state_ = STORED; | 769 stored_state_ = STORED; |
767 MaybeCompleteUpdate(); // will definitely complete | 770 MaybeCompleteUpdate(); // will definitely complete |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
806 HostNotifier host_notifier; | 809 HostNotifier host_notifier; |
807 AddAllAssociatedHostsToNotifier(&host_notifier); | 810 AddAllAssociatedHostsToNotifier(&host_notifier); |
808 host_notifier.SendErrorNotifications(error_message); | 811 host_notifier.SendErrorNotifications(error_message); |
809 } | 812 } |
810 | 813 |
811 void AppCacheUpdateJob::AddAllAssociatedHostsToNotifier( | 814 void AppCacheUpdateJob::AddAllAssociatedHostsToNotifier( |
812 HostNotifier* host_notifier) { | 815 HostNotifier* host_notifier) { |
813 // Collect hosts so we only send one notification per frontend. | 816 // Collect hosts so we only send one notification per frontend. |
814 // A host can only be associated with a single cache so no need to worry | 817 // A host can only be associated with a single cache so no need to worry |
815 // about duplicate hosts being added to the notifier. | 818 // about duplicate hosts being added to the notifier. |
816 if (inprogress_cache_) { | 819 if (inprogress_cache_.get()) { |
817 DCHECK(internal_state_ == DOWNLOADING || internal_state_ == CACHE_FAILURE); | 820 DCHECK(internal_state_ == DOWNLOADING || internal_state_ == CACHE_FAILURE); |
818 host_notifier->AddHosts(inprogress_cache_->associated_hosts()); | 821 host_notifier->AddHosts(inprogress_cache_->associated_hosts()); |
819 } | 822 } |
820 | 823 |
821 AppCacheGroup::Caches old_caches = group_->old_caches(); | 824 AppCacheGroup::Caches old_caches = group_->old_caches(); |
822 for (AppCacheGroup::Caches::const_iterator it = old_caches.begin(); | 825 for (AppCacheGroup::Caches::const_iterator it = old_caches.begin(); |
823 it != old_caches.end(); ++it) { | 826 it != old_caches.end(); ++it) { |
824 host_notifier->AddHosts((*it)->associated_hosts()); | 827 host_notifier->AddHosts((*it)->associated_hosts()); |
825 } | 828 } |
826 | 829 |
(...skipping 26 matching lines...) Expand all Loading... |
853 return; | 856 return; |
854 } | 857 } |
855 | 858 |
856 // Load manifest data from storage to compare against fetched manifest. | 859 // Load manifest data from storage to compare against fetched manifest. |
857 manifest_response_reader_.reset( | 860 manifest_response_reader_.reset( |
858 service_->storage()->CreateResponseReader(manifest_url_, | 861 service_->storage()->CreateResponseReader(manifest_url_, |
859 group_->group_id(), | 862 group_->group_id(), |
860 entry->response_id())); | 863 entry->response_id())); |
861 read_manifest_buffer_ = new net::IOBuffer(kBufferSize); | 864 read_manifest_buffer_ = new net::IOBuffer(kBufferSize); |
862 manifest_response_reader_->ReadData( | 865 manifest_response_reader_->ReadData( |
863 read_manifest_buffer_, kBufferSize, | 866 read_manifest_buffer_.get(), |
| 867 kBufferSize, |
864 base::Bind(&AppCacheUpdateJob::OnManifestDataReadComplete, | 868 base::Bind(&AppCacheUpdateJob::OnManifestDataReadComplete, |
865 base::Unretained(this))); // async read | 869 base::Unretained(this))); // async read |
866 } | 870 } |
867 | 871 |
868 void AppCacheUpdateJob::OnManifestDataReadComplete(int result) { | 872 void AppCacheUpdateJob::OnManifestDataReadComplete(int result) { |
869 if (result > 0) { | 873 if (result > 0) { |
870 loaded_manifest_data_.append(read_manifest_buffer_->data(), result); | 874 loaded_manifest_data_.append(read_manifest_buffer_->data(), result); |
871 manifest_response_reader_->ReadData( | 875 manifest_response_reader_->ReadData( |
872 read_manifest_buffer_, kBufferSize, | 876 read_manifest_buffer_.get(), |
| 877 kBufferSize, |
873 base::Bind(&AppCacheUpdateJob::OnManifestDataReadComplete, | 878 base::Bind(&AppCacheUpdateJob::OnManifestDataReadComplete, |
874 base::Unretained(this))); // read more | 879 base::Unretained(this))); // read more |
875 } else { | 880 } else { |
876 read_manifest_buffer_ = NULL; | 881 read_manifest_buffer_ = NULL; |
877 manifest_response_reader_.reset(); | 882 manifest_response_reader_.reset(); |
878 ContinueHandleManifestFetchCompleted( | 883 ContinueHandleManifestFetchCompleted( |
879 result < 0 || manifest_data_ != loaded_manifest_data_); | 884 result < 0 || manifest_data_ != loaded_manifest_data_); |
880 } | 885 } |
881 } | 886 } |
882 | 887 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
946 ++url_fetches_completed_; | 951 ++url_fetches_completed_; |
947 } else if (AlreadyFetchedEntry(url_to_fetch.url, entry.types())) { | 952 } else if (AlreadyFetchedEntry(url_to_fetch.url, entry.types())) { |
948 NotifyAllProgress(url_to_fetch.url); | 953 NotifyAllProgress(url_to_fetch.url); |
949 ++url_fetches_completed_; // saved a URL request | 954 ++url_fetches_completed_; // saved a URL request |
950 } else if (!url_to_fetch.storage_checked && | 955 } else if (!url_to_fetch.storage_checked && |
951 MaybeLoadFromNewestCache(url_to_fetch.url, entry)) { | 956 MaybeLoadFromNewestCache(url_to_fetch.url, entry)) { |
952 // Continues asynchronously after data is loaded from newest cache. | 957 // Continues asynchronously after data is loaded from newest cache. |
953 } else { | 958 } else { |
954 URLFetcher* fetcher = new URLFetcher( | 959 URLFetcher* fetcher = new URLFetcher( |
955 url_to_fetch.url, URLFetcher::URL_FETCH, this); | 960 url_to_fetch.url, URLFetcher::URL_FETCH, this); |
956 if (url_to_fetch.existing_response_info) { | 961 if (url_to_fetch.existing_response_info.get()) { |
957 DCHECK(group_->newest_complete_cache()); | 962 DCHECK(group_->newest_complete_cache()); |
958 AppCacheEntry* existing_entry = | 963 AppCacheEntry* existing_entry = |
959 group_->newest_complete_cache()->GetEntry(url_to_fetch.url); | 964 group_->newest_complete_cache()->GetEntry(url_to_fetch.url); |
960 DCHECK(existing_entry); | 965 DCHECK(existing_entry); |
961 DCHECK(existing_entry->response_id() == | 966 DCHECK(existing_entry->response_id() == |
962 url_to_fetch.existing_response_info->response_id()); | 967 url_to_fetch.existing_response_info->response_id()); |
963 fetcher->set_existing_response_headers( | 968 fetcher->set_existing_response_headers( |
964 url_to_fetch.existing_response_info->http_response_info()->headers); | 969 url_to_fetch.existing_response_info->http_response_info()->headers |
| 970 .get()); |
965 fetcher->set_existing_entry(*existing_entry); | 971 fetcher->set_existing_entry(*existing_entry); |
966 } | 972 } |
967 fetcher->Start(); | 973 fetcher->Start(); |
968 pending_url_fetches_.insert( | 974 pending_url_fetches_.insert( |
969 PendingUrlFetches::value_type(url_to_fetch.url, fetcher)); | 975 PendingUrlFetches::value_type(url_to_fetch.url, fetcher)); |
970 } | 976 } |
971 } | 977 } |
972 } | 978 } |
973 | 979 |
974 void AppCacheUpdateJob::CancelAllUrlFetches() { | 980 void AppCacheUpdateJob::CancelAllUrlFetches() { |
(...skipping 17 matching lines...) Expand all Loading... |
992 if (entry.IsExplicit() || entry.IsFallback() || entry.IsIntercept()) | 998 if (entry.IsExplicit() || entry.IsFallback() || entry.IsIntercept()) |
993 return false; | 999 return false; |
994 | 1000 |
995 // TODO(jennb): decide if entry should be skipped to expire it from cache | 1001 // TODO(jennb): decide if entry should be skipped to expire it from cache |
996 return false; | 1002 return false; |
997 } | 1003 } |
998 | 1004 |
999 bool AppCacheUpdateJob::AlreadyFetchedEntry(const GURL& url, | 1005 bool AppCacheUpdateJob::AlreadyFetchedEntry(const GURL& url, |
1000 int entry_type) { | 1006 int entry_type) { |
1001 DCHECK(internal_state_ == DOWNLOADING || internal_state_ == NO_UPDATE); | 1007 DCHECK(internal_state_ == DOWNLOADING || internal_state_ == NO_UPDATE); |
1002 AppCacheEntry* existing = inprogress_cache_ ? | 1008 AppCacheEntry* existing = |
1003 inprogress_cache_->GetEntry(url) : | 1009 inprogress_cache_.get() ? inprogress_cache_->GetEntry(url) |
1004 group_->newest_complete_cache()->GetEntry(url); | 1010 : group_->newest_complete_cache()->GetEntry(url); |
1005 if (existing) { | 1011 if (existing) { |
1006 existing->add_types(entry_type); | 1012 existing->add_types(entry_type); |
1007 return true; | 1013 return true; |
1008 } | 1014 } |
1009 return false; | 1015 return false; |
1010 } | 1016 } |
1011 | 1017 |
1012 void AppCacheUpdateJob::AddMasterEntryToFetchList(AppCacheHost* host, | 1018 void AppCacheUpdateJob::AddMasterEntryToFetchList(AppCacheHost* host, |
1013 const GURL& url, | 1019 const GURL& url, |
1014 bool is_new) { | 1020 bool is_new) { |
1015 DCHECK(!IsTerminating()); | 1021 DCHECK(!IsTerminating()); |
1016 | 1022 |
1017 if (internal_state_ == DOWNLOADING || internal_state_ == NO_UPDATE) { | 1023 if (internal_state_ == DOWNLOADING || internal_state_ == NO_UPDATE) { |
1018 AppCache* cache; | 1024 AppCache* cache; |
1019 if (inprogress_cache_) { | 1025 if (inprogress_cache_.get()) { |
1020 // always associate | 1026 // always associate |
1021 host->AssociateIncompleteCache(inprogress_cache_, manifest_url_); | 1027 host->AssociateIncompleteCache(inprogress_cache_.get(), manifest_url_); |
1022 cache = inprogress_cache_.get(); | 1028 cache = inprogress_cache_.get(); |
1023 } else { | 1029 } else { |
1024 cache = group_->newest_complete_cache(); | 1030 cache = group_->newest_complete_cache(); |
1025 } | 1031 } |
1026 | 1032 |
1027 // Update existing entry if it has already been fetched. | 1033 // Update existing entry if it has already been fetched. |
1028 AppCacheEntry* entry = cache->GetEntry(url); | 1034 AppCacheEntry* entry = cache->GetEntry(url); |
1029 if (entry) { | 1035 if (entry) { |
1030 entry->add_types(AppCacheEntry::MASTER); | 1036 entry->add_types(AppCacheEntry::MASTER); |
1031 if (internal_state_ == NO_UPDATE && !inprogress_cache_) { | 1037 if (internal_state_ == NO_UPDATE && !inprogress_cache_.get()) { |
1032 // only associate if have entry | 1038 // only associate if have entry |
1033 host->AssociateCompleteCache(cache); | 1039 host->AssociateCompleteCache(cache); |
1034 } | 1040 } |
1035 if (is_new) | 1041 if (is_new) |
1036 ++master_entries_completed_; // pretend fetching completed | 1042 ++master_entries_completed_; // pretend fetching completed |
1037 return; | 1043 return; |
1038 } | 1044 } |
1039 } | 1045 } |
1040 | 1046 |
1041 // Add to fetch list if not already fetching. | 1047 // Add to fetch list if not already fetching. |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1144 } | 1150 } |
1145 | 1151 |
1146 void AppCacheUpdateJob::OnResponseInfoLoaded( | 1152 void AppCacheUpdateJob::OnResponseInfoLoaded( |
1147 AppCacheResponseInfo* response_info, int64 response_id) { | 1153 AppCacheResponseInfo* response_info, int64 response_id) { |
1148 const net::HttpResponseInfo* http_info = response_info ? | 1154 const net::HttpResponseInfo* http_info = response_info ? |
1149 response_info->http_response_info() : NULL; | 1155 response_info->http_response_info() : NULL; |
1150 | 1156 |
1151 // Needed response info for a manifest fetch request. | 1157 // Needed response info for a manifest fetch request. |
1152 if (internal_state_ == FETCH_MANIFEST) { | 1158 if (internal_state_ == FETCH_MANIFEST) { |
1153 if (http_info) | 1159 if (http_info) |
1154 manifest_fetcher_->set_existing_response_headers(http_info->headers); | 1160 manifest_fetcher_->set_existing_response_headers( |
| 1161 http_info->headers.get()); |
1155 manifest_fetcher_->Start(); | 1162 manifest_fetcher_->Start(); |
1156 return; | 1163 return; |
1157 } | 1164 } |
1158 | 1165 |
1159 LoadingResponses::iterator found = loading_responses_.find(response_id); | 1166 LoadingResponses::iterator found = loading_responses_.find(response_id); |
1160 DCHECK(found != loading_responses_.end()); | 1167 DCHECK(found != loading_responses_.end()); |
1161 const GURL& url = found->second; | 1168 const GURL& url = found->second; |
1162 | 1169 |
1163 if (!http_info) { | 1170 if (!http_info) { |
1164 LoadFromNewestCacheFailed(url, NULL); // no response found | 1171 LoadFromNewestCacheFailed(url, NULL); // no response found |
1165 } else { | 1172 } else { |
1166 // Check if response can be re-used according to HTTP caching semantics. | 1173 // Check if response can be re-used according to HTTP caching semantics. |
1167 // Responses with a "vary" header get treated as expired. | 1174 // Responses with a "vary" header get treated as expired. |
1168 const std::string name = "vary"; | 1175 const std::string name = "vary"; |
1169 std::string value; | 1176 std::string value; |
1170 void* iter = NULL; | 1177 void* iter = NULL; |
1171 if (!http_info->headers || | 1178 if (!http_info->headers.get() || |
1172 http_info->headers->RequiresValidation(http_info->request_time, | 1179 http_info->headers->RequiresValidation(http_info->request_time, |
1173 http_info->response_time, | 1180 http_info->response_time, |
1174 base::Time::Now()) || | 1181 base::Time::Now()) || |
1175 http_info->headers->EnumerateHeader(&iter, name, &value)) { | 1182 http_info->headers->EnumerateHeader(&iter, name, &value)) { |
1176 LoadFromNewestCacheFailed(url, response_info); | 1183 LoadFromNewestCacheFailed(url, response_info); |
1177 } else { | 1184 } else { |
1178 DCHECK(group_->newest_complete_cache()); | 1185 DCHECK(group_->newest_complete_cache()); |
1179 AppCacheEntry* copy_me = group_->newest_complete_cache()->GetEntry(url); | 1186 AppCacheEntry* copy_me = group_->newest_complete_cache()->GetEntry(url); |
1180 DCHECK(copy_me); | 1187 DCHECK(copy_me); |
1181 DCHECK(copy_me->response_id() == response_id); | 1188 DCHECK(copy_me->response_id() == response_id); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1305 (*host_it)->RemoveObserver(this); | 1312 (*host_it)->RemoveObserver(this); |
1306 } | 1313 } |
1307 } | 1314 } |
1308 | 1315 |
1309 pending_master_entries_.clear(); | 1316 pending_master_entries_.clear(); |
1310 } | 1317 } |
1311 | 1318 |
1312 void AppCacheUpdateJob::DiscardInprogressCache() { | 1319 void AppCacheUpdateJob::DiscardInprogressCache() { |
1313 service_->storage()->DoomResponses(manifest_url_, stored_response_ids_); | 1320 service_->storage()->DoomResponses(manifest_url_, stored_response_ids_); |
1314 | 1321 |
1315 if (!inprogress_cache_) { | 1322 if (!inprogress_cache_.get()) { |
1316 // We have to undo the changes we made, if any, to the existing cache. | 1323 // We have to undo the changes we made, if any, to the existing cache. |
1317 for (std::vector<GURL>::iterator iter = added_master_entries_.begin(); | 1324 for (std::vector<GURL>::iterator iter = added_master_entries_.begin(); |
1318 iter != added_master_entries_.end(); ++iter) { | 1325 iter != added_master_entries_.end(); ++iter) { |
1319 DCHECK(group_->newest_complete_cache()); | 1326 DCHECK(group_->newest_complete_cache()); |
1320 group_->newest_complete_cache()->RemoveEntry(*iter); | 1327 group_->newest_complete_cache()->RemoveEntry(*iter); |
1321 } | 1328 } |
1322 return; | 1329 return; |
1323 } | 1330 } |
1324 | 1331 |
1325 AppCache::AppCacheHosts& hosts = inprogress_cache_->associated_hosts(); | 1332 AppCache::AppCacheHosts& hosts = inprogress_cache_->associated_hosts(); |
(...skipping 14 matching lines...) Expand all Loading... |
1340 | 1347 |
1341 // Break the connection with the group so the group cannot call delete | 1348 // Break the connection with the group so the group cannot call delete |
1342 // on this object after we've posted a task to delete ourselves. | 1349 // on this object after we've posted a task to delete ourselves. |
1343 group_->SetUpdateStatus(AppCacheGroup::IDLE); | 1350 group_->SetUpdateStatus(AppCacheGroup::IDLE); |
1344 group_ = NULL; | 1351 group_ = NULL; |
1345 | 1352 |
1346 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 1353 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
1347 } | 1354 } |
1348 | 1355 |
1349 } // namespace appcache | 1356 } // namespace appcache |
OLD | NEW |