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 |