| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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" |
| 8 #include "base/bind_helpers.h" |
| 7 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 8 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| 9 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 10 #include "base/stringprintf.h" | 12 #include "base/stringprintf.h" |
| 11 #include "net/base/io_buffer.h" | 13 #include "net/base/io_buffer.h" |
| 12 #include "net/base/load_flags.h" | 14 #include "net/base/load_flags.h" |
| 13 #include "net/base/net_errors.h" | 15 #include "net/base/net_errors.h" |
| 14 #include "net/http/http_request_headers.h" | 16 #include "net/http/http_request_headers.h" |
| 15 #include "net/http/http_response_headers.h" | 17 #include "net/http/http_response_headers.h" |
| 16 #include "webkit/appcache/appcache_group.h" | 18 #include "webkit/appcache/appcache_group.h" |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 } | 84 } |
| 83 | 85 |
| 84 AppCacheUpdateJob::UrlToFetch::~UrlToFetch() { | 86 AppCacheUpdateJob::UrlToFetch::~UrlToFetch() { |
| 85 } | 87 } |
| 86 | 88 |
| 87 // Helper class to fetch resources. Depending on the fetch type, | 89 // Helper class to fetch resources. Depending on the fetch type, |
| 88 // can either fetch to an in-memory string or write the response | 90 // can either fetch to an in-memory string or write the response |
| 89 // data out to the disk cache. | 91 // data out to the disk cache. |
| 90 AppCacheUpdateJob::URLFetcher::URLFetcher( | 92 AppCacheUpdateJob::URLFetcher::URLFetcher( |
| 91 const GURL& url, FetchType fetch_type, AppCacheUpdateJob* job) | 93 const GURL& url, FetchType fetch_type, AppCacheUpdateJob* job) |
| 92 : url_(url), job_(job), fetch_type_(fetch_type), retry_503_attempts_(0), | 94 : url_(url), |
| 95 job_(job), |
| 96 fetch_type_(fetch_type), |
| 97 retry_503_attempts_(0), |
| 93 buffer_(new net::IOBuffer(kBufferSize)), | 98 buffer_(new net::IOBuffer(kBufferSize)), |
| 94 ALLOW_THIS_IN_INITIALIZER_LIST( | 99 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 95 request_(new net::URLRequest(url, this))), | 100 request_(new net::URLRequest(url, this))) { |
| 96 ALLOW_THIS_IN_INITIALIZER_LIST( | |
| 97 write_callback_(this, &URLFetcher::OnWriteComplete)) { | |
| 98 } | 101 } |
| 99 | 102 |
| 100 AppCacheUpdateJob::URLFetcher::~URLFetcher() { | 103 AppCacheUpdateJob::URLFetcher::~URLFetcher() { |
| 101 } | 104 } |
| 102 | 105 |
| 103 void AppCacheUpdateJob::URLFetcher::Start() { | 106 void AppCacheUpdateJob::URLFetcher::Start() { |
| 104 request_->set_context(job_->service_->request_context()); | 107 request_->set_context(job_->service_->request_context()); |
| 105 request_->set_load_flags(request_->load_flags() | | 108 request_->set_load_flags(request_->load_flags() | |
| 106 net::LOAD_DISABLE_INTERCEPT); | 109 net::LOAD_DISABLE_INTERCEPT); |
| 107 if (existing_response_headers_) | 110 if (existing_response_headers_) |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 } | 143 } |
| 141 } | 144 } |
| 142 | 145 |
| 143 // Write response info to storage for URL fetches. Wait for async write | 146 // Write response info to storage for URL fetches. Wait for async write |
| 144 // completion before reading any response data. | 147 // completion before reading any response data. |
| 145 if (fetch_type_ == URL_FETCH || fetch_type_ == MASTER_ENTRY_FETCH) { | 148 if (fetch_type_ == URL_FETCH || fetch_type_ == MASTER_ENTRY_FETCH) { |
| 146 response_writer_.reset(job_->CreateResponseWriter()); | 149 response_writer_.reset(job_->CreateResponseWriter()); |
| 147 scoped_refptr<HttpResponseInfoIOBuffer> io_buffer( | 150 scoped_refptr<HttpResponseInfoIOBuffer> io_buffer( |
| 148 new HttpResponseInfoIOBuffer( | 151 new HttpResponseInfoIOBuffer( |
| 149 new net::HttpResponseInfo(request->response_info()))); | 152 new net::HttpResponseInfo(request->response_info()))); |
| 150 response_writer_->WriteInfo(io_buffer, &write_callback_); | 153 response_writer_->WriteInfo( |
| 154 io_buffer, |
| 155 base::Bind(&URLFetcher::OnWriteComplete, base::Unretained(this))); |
| 151 } else { | 156 } else { |
| 152 ReadResponseData(); | 157 ReadResponseData(); |
| 153 } | 158 } |
| 154 } else { | 159 } else { |
| 155 OnResponseCompleted(); | 160 OnResponseCompleted(); |
| 156 } | 161 } |
| 157 } | 162 } |
| 158 | 163 |
| 159 void AppCacheUpdateJob::URLFetcher::OnReadCompleted( | 164 void AppCacheUpdateJob::URLFetcher::OnReadCompleted( |
| 160 net::URLRequest* request, int bytes_read) { | 165 net::URLRequest* request, int bytes_read) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 bool AppCacheUpdateJob::URLFetcher::ConsumeResponseData(int bytes_read) { | 234 bool AppCacheUpdateJob::URLFetcher::ConsumeResponseData(int bytes_read) { |
| 230 DCHECK_GT(bytes_read, 0); | 235 DCHECK_GT(bytes_read, 0); |
| 231 switch (fetch_type_) { | 236 switch (fetch_type_) { |
| 232 case MANIFEST_FETCH: | 237 case MANIFEST_FETCH: |
| 233 case MANIFEST_REFETCH: | 238 case MANIFEST_REFETCH: |
| 234 manifest_data_.append(buffer_->data(), bytes_read); | 239 manifest_data_.append(buffer_->data(), bytes_read); |
| 235 break; | 240 break; |
| 236 case URL_FETCH: | 241 case URL_FETCH: |
| 237 case MASTER_ENTRY_FETCH: | 242 case MASTER_ENTRY_FETCH: |
| 238 DCHECK(response_writer_.get()); | 243 DCHECK(response_writer_.get()); |
| 239 response_writer_->WriteData(buffer_, bytes_read, &write_callback_); | 244 response_writer_->WriteData( |
| 245 buffer_, bytes_read, |
| 246 base::Bind(&URLFetcher::OnWriteComplete, base::Unretained(this))); |
| 240 return false; // wait for async write completion to continue reading | 247 return false; // wait for async write completion to continue reading |
| 241 default: | 248 default: |
| 242 NOTREACHED(); | 249 NOTREACHED(); |
| 243 } | 250 } |
| 244 return true; | 251 return true; |
| 245 } | 252 } |
| 246 | 253 |
| 247 void AppCacheUpdateJob::URLFetcher::OnResponseCompleted() { | 254 void AppCacheUpdateJob::URLFetcher::OnResponseCompleted() { |
| 248 // Retry for 503s where retry-after is 0. | 255 // Retry for 503s where retry-after is 0. |
| 249 if (request_->status().is_success() && | 256 if (request_->status().is_success() && |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 AppCacheUpdateJob::AppCacheUpdateJob(AppCacheService* service, | 293 AppCacheUpdateJob::AppCacheUpdateJob(AppCacheService* service, |
| 287 AppCacheGroup* group) | 294 AppCacheGroup* group) |
| 288 : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), | 295 : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), |
| 289 service_(service), | 296 service_(service), |
| 290 group_(group), | 297 group_(group), |
| 291 update_type_(UNKNOWN_TYPE), | 298 update_type_(UNKNOWN_TYPE), |
| 292 internal_state_(FETCH_MANIFEST), | 299 internal_state_(FETCH_MANIFEST), |
| 293 master_entries_completed_(0), | 300 master_entries_completed_(0), |
| 294 url_fetches_completed_(0), | 301 url_fetches_completed_(0), |
| 295 manifest_fetcher_(NULL), | 302 manifest_fetcher_(NULL), |
| 296 stored_state_(UNSTORED), | 303 stored_state_(UNSTORED) { |
| 297 ALLOW_THIS_IN_INITIALIZER_LIST(manifest_info_write_callback_( | |
| 298 this, &AppCacheUpdateJob::OnManifestInfoWriteComplete)), | |
| 299 ALLOW_THIS_IN_INITIALIZER_LIST(manifest_data_write_callback_( | |
| 300 this, &AppCacheUpdateJob::OnManifestDataWriteComplete)), | |
| 301 ALLOW_THIS_IN_INITIALIZER_LIST(manifest_data_read_callback_( | |
| 302 this, &AppCacheUpdateJob::OnManifestDataReadComplete)) { | |
| 303 DCHECK(group_); | 304 DCHECK(group_); |
| 304 manifest_url_ = group_->manifest_url(); | 305 manifest_url_ = group_->manifest_url(); |
| 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()); |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 694 // Only need to store response in storage if manifest is not already | 695 // Only need to store response in storage if manifest is not already |
| 695 // an entry in the cache. | 696 // an entry in the cache. |
| 696 AppCacheEntry* entry = inprogress_cache_->GetEntry(manifest_url_); | 697 AppCacheEntry* entry = inprogress_cache_->GetEntry(manifest_url_); |
| 697 if (entry) { | 698 if (entry) { |
| 698 entry->add_types(AppCacheEntry::MANIFEST); | 699 entry->add_types(AppCacheEntry::MANIFEST); |
| 699 StoreGroupAndCache(); | 700 StoreGroupAndCache(); |
| 700 } else { | 701 } else { |
| 701 manifest_response_writer_.reset(CreateResponseWriter()); | 702 manifest_response_writer_.reset(CreateResponseWriter()); |
| 702 scoped_refptr<HttpResponseInfoIOBuffer> io_buffer( | 703 scoped_refptr<HttpResponseInfoIOBuffer> io_buffer( |
| 703 new HttpResponseInfoIOBuffer(manifest_response_info_.release())); | 704 new HttpResponseInfoIOBuffer(manifest_response_info_.release())); |
| 704 manifest_response_writer_->WriteInfo(io_buffer, | 705 manifest_response_writer_->WriteInfo( |
| 705 &manifest_info_write_callback_); | 706 io_buffer, |
| 707 base::Bind(&AppCacheUpdateJob::OnManifestInfoWriteComplete, |
| 708 base::Unretained(this))); |
| 706 } | 709 } |
| 707 } else { | 710 } else { |
| 708 VLOG(1) << "Request status: " << request->status().status() | 711 VLOG(1) << "Request status: " << request->status().status() |
| 709 << " error: " << request->status().error() | 712 << " error: " << request->status().error() |
| 710 << " response code: " << response_code; | 713 << " response code: " << response_code; |
| 711 ScheduleUpdateRetry(kRerunDelayMs); | 714 ScheduleUpdateRetry(kRerunDelayMs); |
| 712 HandleCacheFailure("Manifest changed during update, scheduling retry"); | 715 HandleCacheFailure("Manifest changed during update, scheduling retry"); |
| 713 } | 716 } |
| 714 } | 717 } |
| 715 | 718 |
| 716 void AppCacheUpdateJob::OnManifestInfoWriteComplete(int result) { | 719 void AppCacheUpdateJob::OnManifestInfoWriteComplete(int result) { |
| 717 if (result > 0) { | 720 if (result > 0) { |
| 718 scoped_refptr<net::StringIOBuffer> io_buffer( | 721 scoped_refptr<net::StringIOBuffer> io_buffer( |
| 719 new net::StringIOBuffer(manifest_data_)); | 722 new net::StringIOBuffer(manifest_data_)); |
| 720 manifest_response_writer_->WriteData(io_buffer, manifest_data_.length(), | 723 manifest_response_writer_->WriteData( |
| 721 &manifest_data_write_callback_); | 724 io_buffer, manifest_data_.length(), |
| 725 base::Bind(&AppCacheUpdateJob::OnManifestDataWriteComplete, |
| 726 base::Unretained(this))); |
| 722 } else { | 727 } else { |
| 723 HandleCacheFailure("Failed to write the manifest headers to storage"); | 728 HandleCacheFailure("Failed to write the manifest headers to storage"); |
| 724 } | 729 } |
| 725 } | 730 } |
| 726 | 731 |
| 727 void AppCacheUpdateJob::OnManifestDataWriteComplete(int result) { | 732 void AppCacheUpdateJob::OnManifestDataWriteComplete(int result) { |
| 728 if (result > 0) { | 733 if (result > 0) { |
| 729 AppCacheEntry entry(AppCacheEntry::MANIFEST, | 734 AppCacheEntry entry(AppCacheEntry::MANIFEST, |
| 730 manifest_response_writer_->response_id(), | 735 manifest_response_writer_->response_id(), |
| 731 manifest_response_writer_->amount_written()); | 736 manifest_response_writer_->amount_written()); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 838 AppCacheEntry* entry = | 843 AppCacheEntry* entry = |
| 839 group_->newest_complete_cache()->GetEntry(manifest_url_); | 844 group_->newest_complete_cache()->GetEntry(manifest_url_); |
| 840 DCHECK(entry); | 845 DCHECK(entry); |
| 841 | 846 |
| 842 // Load manifest data from storage to compare against fetched manifest. | 847 // Load manifest data from storage to compare against fetched manifest. |
| 843 manifest_response_reader_.reset( | 848 manifest_response_reader_.reset( |
| 844 service_->storage()->CreateResponseReader(manifest_url_, | 849 service_->storage()->CreateResponseReader(manifest_url_, |
| 845 group_->group_id(), | 850 group_->group_id(), |
| 846 entry->response_id())); | 851 entry->response_id())); |
| 847 read_manifest_buffer_ = new net::IOBuffer(kBufferSize); | 852 read_manifest_buffer_ = new net::IOBuffer(kBufferSize); |
| 848 manifest_response_reader_->ReadData(read_manifest_buffer_, kBufferSize, | 853 manifest_response_reader_->ReadData( |
| 849 &manifest_data_read_callback_); // async read | 854 read_manifest_buffer_, kBufferSize, |
| 855 base::Bind(&AppCacheUpdateJob::OnManifestDataReadComplete, |
| 856 base::Unretained(this))); // async read |
| 850 } | 857 } |
| 851 | 858 |
| 852 void AppCacheUpdateJob::OnManifestDataReadComplete(int result) { | 859 void AppCacheUpdateJob::OnManifestDataReadComplete(int result) { |
| 853 if (result > 0) { | 860 if (result > 0) { |
| 854 loaded_manifest_data_.append(read_manifest_buffer_->data(), result); | 861 loaded_manifest_data_.append(read_manifest_buffer_->data(), result); |
| 855 manifest_response_reader_->ReadData(read_manifest_buffer_, kBufferSize, | 862 manifest_response_reader_->ReadData( |
| 856 &manifest_data_read_callback_); // read more | 863 read_manifest_buffer_, kBufferSize, |
| 864 base::Bind(&AppCacheUpdateJob::OnManifestDataReadComplete, |
| 865 base::Unretained(this))); // read more |
| 857 } else { | 866 } else { |
| 858 read_manifest_buffer_ = NULL; | 867 read_manifest_buffer_ = NULL; |
| 859 manifest_response_reader_.reset(); | 868 manifest_response_reader_.reset(); |
| 860 ContinueHandleManifestFetchCompleted( | 869 ContinueHandleManifestFetchCompleted( |
| 861 result < 0 || manifest_data_ != loaded_manifest_data_); | 870 result < 0 || manifest_data_ != loaded_manifest_data_); |
| 862 } | 871 } |
| 863 } | 872 } |
| 864 | 873 |
| 865 void AppCacheUpdateJob::BuildUrlFileList(const Manifest& manifest) { | 874 void AppCacheUpdateJob::BuildUrlFileList(const Manifest& manifest) { |
| 866 for (base::hash_set<std::string>::const_iterator it = | 875 for (base::hash_set<std::string>::const_iterator it = |
| (...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1320 | 1329 |
| 1321 // Break the connection with the group so the group cannot call delete | 1330 // Break the connection with the group so the group cannot call delete |
| 1322 // on this object after we've posted a task to delete ourselves. | 1331 // on this object after we've posted a task to delete ourselves. |
| 1323 group_->SetUpdateStatus(AppCacheGroup::IDLE); | 1332 group_->SetUpdateStatus(AppCacheGroup::IDLE); |
| 1324 group_ = NULL; | 1333 group_ = NULL; |
| 1325 | 1334 |
| 1326 MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 1335 MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
| 1327 } | 1336 } |
| 1328 | 1337 |
| 1329 } // namespace appcache | 1338 } // namespace appcache |
| OLD | NEW |