| 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/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
| 11 #include "net/base/io_buffer.h" | 11 #include "net/base/io_buffer.h" |
| 12 #include "net/base/load_flags.h" | 12 #include "net/base/load_flags.h" |
| 13 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
| 14 #include "net/http/http_request_headers.h" | 14 #include "net/http/http_request_headers.h" |
| 15 #include "net/http/http_response_headers.h" | 15 #include "net/http/http_response_headers.h" |
| 16 #include "webkit/appcache/appcache_group.h" | 16 #include "webkit/appcache/appcache_group.h" |
| 17 #include "webkit/appcache/appcache_policy.h" | |
| 18 | 17 |
| 19 namespace appcache { | 18 namespace appcache { |
| 20 | 19 |
| 21 static const int kBufferSize = 32768; | 20 static const int kBufferSize = 32768; |
| 22 static const size_t kMaxConcurrentUrlFetches = 2; | 21 static const size_t kMaxConcurrentUrlFetches = 2; |
| 23 static const int kMax503Retries = 3; | 22 static const int kMax503Retries = 3; |
| 24 | 23 |
| 25 // Helper class for collecting hosts per frontend when sending notifications | 24 // Helper class for collecting hosts per frontend when sending notifications |
| 26 // so that only one notification is sent for all hosts using the same frontend. | 25 // so that only one notification is sent for all hosts using the same frontend. |
| 27 class HostNotifier { | 26 class HostNotifier { |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 internal_state_(FETCH_MANIFEST), | 292 internal_state_(FETCH_MANIFEST), |
| 294 master_entries_completed_(0), | 293 master_entries_completed_(0), |
| 295 url_fetches_completed_(0), | 294 url_fetches_completed_(0), |
| 296 manifest_fetcher_(NULL), | 295 manifest_fetcher_(NULL), |
| 297 stored_state_(UNSTORED), | 296 stored_state_(UNSTORED), |
| 298 ALLOW_THIS_IN_INITIALIZER_LIST(manifest_info_write_callback_( | 297 ALLOW_THIS_IN_INITIALIZER_LIST(manifest_info_write_callback_( |
| 299 this, &AppCacheUpdateJob::OnManifestInfoWriteComplete)), | 298 this, &AppCacheUpdateJob::OnManifestInfoWriteComplete)), |
| 300 ALLOW_THIS_IN_INITIALIZER_LIST(manifest_data_write_callback_( | 299 ALLOW_THIS_IN_INITIALIZER_LIST(manifest_data_write_callback_( |
| 301 this, &AppCacheUpdateJob::OnManifestDataWriteComplete)), | 300 this, &AppCacheUpdateJob::OnManifestDataWriteComplete)), |
| 302 ALLOW_THIS_IN_INITIALIZER_LIST(manifest_data_read_callback_( | 301 ALLOW_THIS_IN_INITIALIZER_LIST(manifest_data_read_callback_( |
| 303 this, &AppCacheUpdateJob::OnManifestDataReadComplete)), | 302 this, &AppCacheUpdateJob::OnManifestDataReadComplete)) { |
| 304 ALLOW_THIS_IN_INITIALIZER_LIST(policy_callback_( | |
| 305 new net::CancelableCompletionCallback<AppCacheUpdateJob>( | |
| 306 this, &AppCacheUpdateJob::OnPolicyCheckComplete))) { | |
| 307 DCHECK(group_); | 303 DCHECK(group_); |
| 308 manifest_url_ = group_->manifest_url(); | 304 manifest_url_ = group_->manifest_url(); |
| 309 } | 305 } |
| 310 | 306 |
| 311 AppCacheUpdateJob::~AppCacheUpdateJob() { | 307 AppCacheUpdateJob::~AppCacheUpdateJob() { |
| 312 if (internal_state_ != COMPLETED) | 308 if (internal_state_ != COMPLETED) |
| 313 Cancel(); | 309 Cancel(); |
| 314 | 310 |
| 315 DCHECK(!manifest_fetcher_); | 311 DCHECK(!manifest_fetcher_); |
| 316 DCHECK(pending_url_fetches_.empty()); | 312 DCHECK(pending_url_fetches_.empty()); |
| 317 DCHECK(!inprogress_cache_); | 313 DCHECK(!inprogress_cache_); |
| 318 DCHECK(pending_master_entries_.empty()); | 314 DCHECK(pending_master_entries_.empty()); |
| 319 DCHECK(master_entry_fetches_.empty()); | 315 DCHECK(master_entry_fetches_.empty()); |
| 320 | 316 |
| 321 if (group_) | 317 if (group_) |
| 322 group_->SetUpdateStatus(AppCacheGroup::IDLE); | 318 group_->SetUpdateStatus(AppCacheGroup::IDLE); |
| 323 | |
| 324 policy_callback_->Cancel(); | |
| 325 } | 319 } |
| 326 | 320 |
| 327 void AppCacheUpdateJob::StartUpdate(AppCacheHost* host, | 321 void AppCacheUpdateJob::StartUpdate(AppCacheHost* host, |
| 328 const GURL& new_master_resource) { | 322 const GURL& new_master_resource) { |
| 329 DCHECK(group_->update_job() == this); | 323 DCHECK(group_->update_job() == this); |
| 330 DCHECK(!group_->is_obsolete()); | 324 DCHECK(!group_->is_obsolete()); |
| 331 | 325 |
| 332 bool is_new_pending_master_entry = false; | 326 bool is_new_pending_master_entry = false; |
| 333 if (!new_master_resource.is_empty()) { | 327 if (!new_master_resource.is_empty()) { |
| 334 DCHECK(new_master_resource == host->pending_master_entry_url()); | 328 DCHECK(new_master_resource == host->pending_master_entry_url()); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 update_type_ = CACHE_ATTEMPT; | 370 update_type_ = CACHE_ATTEMPT; |
| 377 DCHECK(host); | 371 DCHECK(host); |
| 378 NotifySingleHost(host, CHECKING_EVENT); | 372 NotifySingleHost(host, CHECKING_EVENT); |
| 379 } | 373 } |
| 380 | 374 |
| 381 if (!new_master_resource.is_empty()) { | 375 if (!new_master_resource.is_empty()) { |
| 382 AddMasterEntryToFetchList(host, new_master_resource, | 376 AddMasterEntryToFetchList(host, new_master_resource, |
| 383 is_new_pending_master_entry); | 377 is_new_pending_master_entry); |
| 384 } | 378 } |
| 385 | 379 |
| 386 if (update_type_ == CACHE_ATTEMPT) | 380 FetchManifest(true); |
| 387 CheckPolicy(); | |
| 388 else | |
| 389 FetchManifest(true); | |
| 390 } | |
| 391 | |
| 392 void AppCacheUpdateJob::CheckPolicy() { | |
| 393 int rv = net::OK; | |
| 394 policy_callback_->AddRef(); // Balanced in OnPolicyCheckComplete. | |
| 395 AppCachePolicy* policy = service_->appcache_policy(); | |
| 396 if (policy) { | |
| 397 rv = policy->CanCreateAppCache(manifest_url_, policy_callback_); | |
| 398 if (rv == net::ERR_IO_PENDING) | |
| 399 return; | |
| 400 } | |
| 401 OnPolicyCheckComplete(rv); | |
| 402 } | |
| 403 | |
| 404 void AppCacheUpdateJob::OnPolicyCheckComplete(int rv) { | |
| 405 policy_callback_->Release(); // Balanced in CheckPolicy. | |
| 406 if (rv == net::OK) { | |
| 407 FetchManifest(true); | |
| 408 return; | |
| 409 } | |
| 410 | |
| 411 group_->NotifyContentBlocked(); | |
| 412 | |
| 413 const char* kErrorMessage = | |
| 414 "Cache creation was blocked by the content policy"; | |
| 415 MessageLoop::current()->PostTask(FROM_HERE, | |
| 416 method_factory_.NewRunnableMethod( | |
| 417 &AppCacheUpdateJob::HandleCacheFailure, | |
| 418 kErrorMessage)); | |
| 419 } | 381 } |
| 420 | 382 |
| 421 AppCacheResponseWriter* AppCacheUpdateJob::CreateResponseWriter() { | 383 AppCacheResponseWriter* AppCacheUpdateJob::CreateResponseWriter() { |
| 422 AppCacheResponseWriter* writer = | 384 AppCacheResponseWriter* writer = |
| 423 service_->storage()->CreateResponseWriter(manifest_url_); | 385 service_->storage()->CreateResponseWriter(manifest_url_); |
| 424 stored_response_ids_.push_back(writer->response_id()); | 386 stored_response_ids_.push_back(writer->response_id()); |
| 425 return writer; | 387 return writer; |
| 426 } | 388 } |
| 427 | 389 |
| 428 void AppCacheUpdateJob::HandleCacheFailure(const std::string& error_message) { | 390 void AppCacheUpdateJob::HandleCacheFailure(const std::string& error_message) { |
| (...skipping 870 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1299 master_entry_fetches_.clear(); | 1261 master_entry_fetches_.clear(); |
| 1300 | 1262 |
| 1301 ClearPendingMasterEntries(); | 1263 ClearPendingMasterEntries(); |
| 1302 DiscardInprogressCache(); | 1264 DiscardInprogressCache(); |
| 1303 | 1265 |
| 1304 // Delete response writer to avoid any callbacks. | 1266 // Delete response writer to avoid any callbacks. |
| 1305 if (manifest_response_writer_.get()) | 1267 if (manifest_response_writer_.get()) |
| 1306 manifest_response_writer_.reset(); | 1268 manifest_response_writer_.reset(); |
| 1307 | 1269 |
| 1308 service_->storage()->CancelDelegateCallbacks(this); | 1270 service_->storage()->CancelDelegateCallbacks(this); |
| 1309 | |
| 1310 policy_callback_->Cancel(); | |
| 1311 } | 1271 } |
| 1312 | 1272 |
| 1313 void AppCacheUpdateJob::ClearPendingMasterEntries() { | 1273 void AppCacheUpdateJob::ClearPendingMasterEntries() { |
| 1314 for (PendingMasters::iterator it = pending_master_entries_.begin(); | 1274 for (PendingMasters::iterator it = pending_master_entries_.begin(); |
| 1315 it != pending_master_entries_.end(); ++it) { | 1275 it != pending_master_entries_.end(); ++it) { |
| 1316 PendingHosts& hosts = it->second; | 1276 PendingHosts& hosts = it->second; |
| 1317 for (PendingHosts::iterator host_it = hosts.begin(); | 1277 for (PendingHosts::iterator host_it = hosts.begin(); |
| 1318 host_it != hosts.end(); ++host_it) { | 1278 host_it != hosts.end(); ++host_it) { |
| 1319 (*host_it)->RemoveObserver(this); | 1279 (*host_it)->RemoveObserver(this); |
| 1320 } | 1280 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1354 | 1314 |
| 1355 // Break the connection with the group so the group cannot call delete | 1315 // Break the connection with the group so the group cannot call delete |
| 1356 // on this object after we've posted a task to delete ourselves. | 1316 // on this object after we've posted a task to delete ourselves. |
| 1357 group_->SetUpdateStatus(AppCacheGroup::IDLE); | 1317 group_->SetUpdateStatus(AppCacheGroup::IDLE); |
| 1358 group_ = NULL; | 1318 group_ = NULL; |
| 1359 | 1319 |
| 1360 MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 1320 MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
| 1361 } | 1321 } |
| 1362 | 1322 |
| 1363 } // namespace appcache | 1323 } // namespace appcache |
| OLD | NEW |