OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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" | 17 #include "webkit/appcache/appcache_policy.h" |
18 | 18 |
19 namespace appcache { | 19 namespace appcache { |
20 | 20 |
21 static const int kBufferSize = 32768; | 21 static const int kBufferSize = 32768; |
22 static const size_t kMaxConcurrentUrlFetches = 2; | 22 static const size_t kMaxConcurrentUrlFetches = 2; |
23 static const int kMax503Retries = 3; | 23 static const int kMax503Retries = 3; |
24 | 24 |
25 // Extra info associated with requests for use during response processing. | 25 // Extra info associated with requests for use during response processing. |
26 // This info is deleted when the URLRequest is deleted. | 26 // This info is deleted when the net::URLRequest is deleted. |
27 class UpdateJobInfo : public URLRequest::UserData { | 27 class UpdateJobInfo : public net::URLRequest::UserData { |
28 public: | 28 public: |
29 enum RequestType { | 29 enum RequestType { |
30 MANIFEST_FETCH, | 30 MANIFEST_FETCH, |
31 URL_FETCH, | 31 URL_FETCH, |
32 MASTER_ENTRY_FETCH, | 32 MASTER_ENTRY_FETCH, |
33 MANIFEST_REFETCH, | 33 MANIFEST_REFETCH, |
34 }; | 34 }; |
35 | 35 |
36 explicit UpdateJobInfo(RequestType request_type) | 36 explicit UpdateJobInfo(RequestType request_type) |
37 : type_(request_type), | 37 : type_(request_type), |
38 buffer_(new net::IOBuffer(kBufferSize)), | 38 buffer_(new net::IOBuffer(kBufferSize)), |
39 retry_503_attempts_(0), | 39 retry_503_attempts_(0), |
40 update_job_(NULL), | 40 update_job_(NULL), |
41 request_(NULL), | 41 request_(NULL), |
42 ALLOW_THIS_IN_INITIALIZER_LIST(write_callback_( | 42 ALLOW_THIS_IN_INITIALIZER_LIST(write_callback_( |
43 this, &UpdateJobInfo::OnWriteComplete)) { | 43 this, &UpdateJobInfo::OnWriteComplete)) { |
44 } | 44 } |
45 | 45 |
46 void SetUpResponseWriter(AppCacheResponseWriter* writer, | 46 void SetUpResponseWriter(AppCacheResponseWriter* writer, |
47 AppCacheUpdateJob* update, | 47 AppCacheUpdateJob* update, |
48 URLRequest* request) { | 48 net::URLRequest* request) { |
49 DCHECK(!response_writer_.get()); | 49 DCHECK(!response_writer_.get()); |
50 response_writer_.reset(writer); | 50 response_writer_.reset(writer); |
51 update_job_ = update; | 51 update_job_ = update; |
52 request_ = request; | 52 request_ = request; |
53 } | 53 } |
54 | 54 |
55 void OnWriteComplete(int result) { | 55 void OnWriteComplete(int result) { |
56 // A completed write may delete the URL request and this object. | 56 // A completed write may delete the URL request and this object. |
57 update_job_->OnWriteResponseComplete(result, request_, this); | 57 update_job_->OnWriteResponseComplete(result, request_, this); |
58 } | 58 } |
59 | 59 |
60 RequestType type_; | 60 RequestType type_; |
61 scoped_refptr<net::IOBuffer> buffer_; | 61 scoped_refptr<net::IOBuffer> buffer_; |
62 int retry_503_attempts_; | 62 int retry_503_attempts_; |
63 | 63 |
64 // The entry from the newest cache for this url, used for 304 responses. | 64 // The entry from the newest cache for this url, used for 304 responses. |
65 AppCacheEntry existing_entry_; | 65 AppCacheEntry existing_entry_; |
66 | 66 |
67 // Info needed to write responses to storage and process callbacks. | 67 // Info needed to write responses to storage and process callbacks. |
68 scoped_ptr<AppCacheResponseWriter> response_writer_; | 68 scoped_ptr<AppCacheResponseWriter> response_writer_; |
69 AppCacheUpdateJob* update_job_; | 69 AppCacheUpdateJob* update_job_; |
70 URLRequest* request_; | 70 net::URLRequest* request_; |
71 net::CompletionCallbackImpl<UpdateJobInfo> write_callback_; | 71 net::CompletionCallbackImpl<UpdateJobInfo> write_callback_; |
72 }; | 72 }; |
73 | 73 |
74 // Helper class for collecting hosts per frontend when sending notifications | 74 // Helper class for collecting hosts per frontend when sending notifications |
75 // so that only one notification is sent for all hosts using the same frontend. | 75 // so that only one notification is sent for all hosts using the same frontend. |
76 class HostNotifier { | 76 class HostNotifier { |
77 public: | 77 public: |
78 typedef std::vector<int> HostIds; | 78 typedef std::vector<int> HostIds; |
79 typedef std::map<AppCacheFrontend*, HostIds> NotifyHostMap; | 79 typedef std::map<AppCacheFrontend*, HostIds> NotifyHostMap; |
80 | 80 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 DCHECK(!inprogress_cache_); | 167 DCHECK(!inprogress_cache_); |
168 DCHECK(pending_master_entries_.empty()); | 168 DCHECK(pending_master_entries_.empty()); |
169 DCHECK(master_entry_fetches_.empty()); | 169 DCHECK(master_entry_fetches_.empty()); |
170 | 170 |
171 if (group_) | 171 if (group_) |
172 group_->SetUpdateStatus(AppCacheGroup::IDLE); | 172 group_->SetUpdateStatus(AppCacheGroup::IDLE); |
173 | 173 |
174 policy_callback_->Cancel(); | 174 policy_callback_->Cancel(); |
175 } | 175 } |
176 | 176 |
177 UpdateJobInfo* AppCacheUpdateJob::GetUpdateJobInfo(URLRequest* request) { | 177 UpdateJobInfo* AppCacheUpdateJob::GetUpdateJobInfo(net::URLRequest* request) { |
178 return static_cast<UpdateJobInfo*>(request->GetUserData(this)); | 178 return static_cast<UpdateJobInfo*>(request->GetUserData(this)); |
179 } | 179 } |
180 | 180 |
181 void AppCacheUpdateJob::StartUpdate(AppCacheHost* host, | 181 void AppCacheUpdateJob::StartUpdate(AppCacheHost* host, |
182 const GURL& new_master_resource) { | 182 const GURL& new_master_resource) { |
183 DCHECK(group_->update_job() == this); | 183 DCHECK(group_->update_job() == this); |
184 DCHECK(!group_->is_obsolete()); | 184 DCHECK(!group_->is_obsolete()); |
185 | 185 |
186 bool is_new_pending_master_entry = false; | 186 bool is_new_pending_master_entry = false; |
187 if (!new_master_resource.is_empty()) { | 187 if (!new_master_resource.is_empty()) { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 CancelAllUrlFetches(); | 280 CancelAllUrlFetches(); |
281 CancelAllMasterEntryFetches(error_message); | 281 CancelAllMasterEntryFetches(error_message); |
282 NotifyAllError(error_message); | 282 NotifyAllError(error_message); |
283 DiscardInprogressCache(); | 283 DiscardInprogressCache(); |
284 internal_state_ = COMPLETED; | 284 internal_state_ = COMPLETED; |
285 DeleteSoon(); // To unwind the stack prior to deletion. | 285 DeleteSoon(); // To unwind the stack prior to deletion. |
286 } | 286 } |
287 | 287 |
288 void AppCacheUpdateJob::FetchManifest(bool is_first_fetch) { | 288 void AppCacheUpdateJob::FetchManifest(bool is_first_fetch) { |
289 DCHECK(!manifest_url_request_); | 289 DCHECK(!manifest_url_request_); |
290 manifest_url_request_ = new URLRequest(manifest_url_, this); | 290 manifest_url_request_ = new net::URLRequest(manifest_url_, this); |
291 UpdateJobInfo::RequestType fetch_type = is_first_fetch ? | 291 UpdateJobInfo::RequestType fetch_type = is_first_fetch ? |
292 UpdateJobInfo::MANIFEST_FETCH : UpdateJobInfo::MANIFEST_REFETCH; | 292 UpdateJobInfo::MANIFEST_FETCH : UpdateJobInfo::MANIFEST_REFETCH; |
293 manifest_url_request_->SetUserData(this, new UpdateJobInfo(fetch_type)); | 293 manifest_url_request_->SetUserData(this, new UpdateJobInfo(fetch_type)); |
294 manifest_url_request_->set_context(service_->request_context()); | 294 manifest_url_request_->set_context(service_->request_context()); |
295 manifest_url_request_->set_load_flags( | 295 manifest_url_request_->set_load_flags( |
296 manifest_url_request_->load_flags() | net::LOAD_DISABLE_INTERCEPT); | 296 manifest_url_request_->load_flags() | net::LOAD_DISABLE_INTERCEPT); |
297 | 297 |
298 // Add any necessary Http headers before sending fetch request. | 298 // Add any necessary Http headers before sending fetch request. |
299 if (is_first_fetch) { | 299 if (is_first_fetch) { |
300 AppCacheEntry* entry = (update_type_ == UPGRADE_ATTEMPT) ? | 300 AppCacheEntry* entry = (update_type_ == UPGRADE_ATTEMPT) ? |
301 group_->newest_complete_cache()->GetEntry(manifest_url_) : NULL; | 301 group_->newest_complete_cache()->GetEntry(manifest_url_) : NULL; |
302 if (entry) { | 302 if (entry) { |
303 // Asynchronously load response info for manifest from newest cache. | 303 // Asynchronously load response info for manifest from newest cache. |
304 service_->storage()->LoadResponseInfo(manifest_url_, | 304 service_->storage()->LoadResponseInfo(manifest_url_, |
305 entry->response_id(), this); | 305 entry->response_id(), this); |
306 } else { | 306 } else { |
307 manifest_url_request_->Start(); | 307 manifest_url_request_->Start(); |
308 } | 308 } |
309 } else { | 309 } else { |
310 DCHECK(internal_state_ == REFETCH_MANIFEST); | 310 DCHECK(internal_state_ == REFETCH_MANIFEST); |
311 DCHECK(manifest_response_info_.get()); | 311 DCHECK(manifest_response_info_.get()); |
312 AddConditionalHeaders(manifest_url_request_, | 312 AddConditionalHeaders(manifest_url_request_, |
313 manifest_response_info_.get()); | 313 manifest_response_info_.get()); |
314 manifest_url_request_->Start(); | 314 manifest_url_request_->Start(); |
315 } | 315 } |
316 } | 316 } |
317 | 317 |
318 void AppCacheUpdateJob::AddConditionalHeaders( | 318 void AppCacheUpdateJob::AddConditionalHeaders( |
319 URLRequest* request, const net::HttpResponseInfo* info) { | 319 net::URLRequest* request, const net::HttpResponseInfo* info) { |
320 DCHECK(request && info); | 320 DCHECK(request && info); |
321 net::HttpRequestHeaders extra_headers; | 321 net::HttpRequestHeaders extra_headers; |
322 | 322 |
323 // Add If-Modified-Since header if response info has Last-Modified header. | 323 // Add If-Modified-Since header if response info has Last-Modified header. |
324 const std::string last_modified = "Last-Modified"; | 324 const std::string last_modified = "Last-Modified"; |
325 std::string last_modified_value; | 325 std::string last_modified_value; |
326 info->headers->EnumerateHeader(NULL, last_modified, &last_modified_value); | 326 info->headers->EnumerateHeader(NULL, last_modified, &last_modified_value); |
327 if (!last_modified_value.empty()) { | 327 if (!last_modified_value.empty()) { |
328 extra_headers.SetHeader(net::HttpRequestHeaders::kIfModifiedSince, | 328 extra_headers.SetHeader(net::HttpRequestHeaders::kIfModifiedSince, |
329 last_modified_value); | 329 last_modified_value); |
330 } | 330 } |
331 | 331 |
332 // Add If-None-Match header if resposne info has ETag header. | 332 // Add If-None-Match header if resposne info has ETag header. |
333 const std::string etag = "ETag"; | 333 const std::string etag = "ETag"; |
334 std::string etag_value; | 334 std::string etag_value; |
335 info->headers->EnumerateHeader(NULL, etag, &etag_value); | 335 info->headers->EnumerateHeader(NULL, etag, &etag_value); |
336 if (!etag_value.empty()) { | 336 if (!etag_value.empty()) { |
337 extra_headers.SetHeader(net::HttpRequestHeaders::kIfNoneMatch, | 337 extra_headers.SetHeader(net::HttpRequestHeaders::kIfNoneMatch, |
338 etag_value); | 338 etag_value); |
339 } | 339 } |
340 if (!extra_headers.IsEmpty()) | 340 if (!extra_headers.IsEmpty()) |
341 request->SetExtraRequestHeaders(extra_headers); | 341 request->SetExtraRequestHeaders(extra_headers); |
342 } | 342 } |
343 | 343 |
344 void AppCacheUpdateJob::OnResponseStarted(URLRequest *request) { | 344 void AppCacheUpdateJob::OnResponseStarted(net::URLRequest *request) { |
345 if (request->status().is_success() && | 345 if (request->status().is_success() && |
346 (request->GetResponseCode() / 100) == 2) { | 346 (request->GetResponseCode() / 100) == 2) { |
347 // Write response info to storage for URL fetches. Wait for async write | 347 // Write response info to storage for URL fetches. Wait for async write |
348 // completion before reading any response data. | 348 // completion before reading any response data. |
349 UpdateJobInfo* info = GetUpdateJobInfo(request); | 349 UpdateJobInfo* info = GetUpdateJobInfo(request); |
350 if (info->type_ == UpdateJobInfo::URL_FETCH || | 350 if (info->type_ == UpdateJobInfo::URL_FETCH || |
351 info->type_ == UpdateJobInfo::MASTER_ENTRY_FETCH) { | 351 info->type_ == UpdateJobInfo::MASTER_ENTRY_FETCH) { |
352 info->SetUpResponseWriter( | 352 info->SetUpResponseWriter( |
353 service_->storage()->CreateResponseWriter(manifest_url_), | 353 service_->storage()->CreateResponseWriter(manifest_url_), |
354 this, request); | 354 this, request); |
355 stored_response_ids_.push_back(info->response_writer_->response_id()); | 355 stored_response_ids_.push_back(info->response_writer_->response_id()); |
356 scoped_refptr<HttpResponseInfoIOBuffer> io_buffer( | 356 scoped_refptr<HttpResponseInfoIOBuffer> io_buffer( |
357 new HttpResponseInfoIOBuffer( | 357 new HttpResponseInfoIOBuffer( |
358 new net::HttpResponseInfo(request->response_info()))); | 358 new net::HttpResponseInfo(request->response_info()))); |
359 info->response_writer_->WriteInfo(io_buffer, &info->write_callback_); | 359 info->response_writer_->WriteInfo(io_buffer, &info->write_callback_); |
360 } else { | 360 } else { |
361 ReadResponseData(request); | 361 ReadResponseData(request); |
362 } | 362 } |
363 } else { | 363 } else { |
364 OnResponseCompleted(request); | 364 OnResponseCompleted(request); |
365 } | 365 } |
366 } | 366 } |
367 | 367 |
368 void AppCacheUpdateJob::ReadResponseData(URLRequest* request) { | 368 void AppCacheUpdateJob::ReadResponseData(net::URLRequest* request) { |
369 if (internal_state_ == CACHE_FAILURE || internal_state_ == CANCELLED || | 369 if (internal_state_ == CACHE_FAILURE || internal_state_ == CANCELLED || |
370 internal_state_ == COMPLETED) { | 370 internal_state_ == COMPLETED) { |
371 return; | 371 return; |
372 } | 372 } |
373 | 373 |
374 int bytes_read = 0; | 374 int bytes_read = 0; |
375 UpdateJobInfo* info = GetUpdateJobInfo(request); | 375 UpdateJobInfo* info = GetUpdateJobInfo(request); |
376 request->Read(info->buffer_, kBufferSize, &bytes_read); | 376 request->Read(info->buffer_, kBufferSize, &bytes_read); |
377 OnReadCompleted(request, bytes_read); | 377 OnReadCompleted(request, bytes_read); |
378 } | 378 } |
379 | 379 |
380 void AppCacheUpdateJob::OnReadCompleted(URLRequest* request, int bytes_read) { | 380 void AppCacheUpdateJob::OnReadCompleted(net::URLRequest* request, |
| 381 int bytes_read) { |
381 bool data_consumed = true; | 382 bool data_consumed = true; |
382 if (request->status().is_success() && bytes_read > 0) { | 383 if (request->status().is_success() && bytes_read > 0) { |
383 UpdateJobInfo* info = GetUpdateJobInfo(request); | 384 UpdateJobInfo* info = GetUpdateJobInfo(request); |
384 data_consumed = ConsumeResponseData(request, info, bytes_read); | 385 data_consumed = ConsumeResponseData(request, info, bytes_read); |
385 if (data_consumed) { | 386 if (data_consumed) { |
386 bytes_read = 0; | 387 bytes_read = 0; |
387 while (request->Read(info->buffer_, kBufferSize, &bytes_read)) { | 388 while (request->Read(info->buffer_, kBufferSize, &bytes_read)) { |
388 if (bytes_read > 0) { | 389 if (bytes_read > 0) { |
389 data_consumed = ConsumeResponseData(request, info, bytes_read); | 390 data_consumed = ConsumeResponseData(request, info, bytes_read); |
390 if (!data_consumed) | 391 if (!data_consumed) |
391 break; // wait for async data processing, then read more | 392 break; // wait for async data processing, then read more |
392 } else { | 393 } else { |
393 break; | 394 break; |
394 } | 395 } |
395 } | 396 } |
396 } | 397 } |
397 } | 398 } |
398 | 399 |
399 if (data_consumed && !request->status().is_io_pending()) | 400 if (data_consumed && !request->status().is_io_pending()) |
400 OnResponseCompleted(request); | 401 OnResponseCompleted(request); |
401 } | 402 } |
402 | 403 |
403 bool AppCacheUpdateJob::ConsumeResponseData(URLRequest* request, | 404 bool AppCacheUpdateJob::ConsumeResponseData(net::URLRequest* request, |
404 UpdateJobInfo* info, | 405 UpdateJobInfo* info, |
405 int bytes_read) { | 406 int bytes_read) { |
406 DCHECK_GT(bytes_read, 0); | 407 DCHECK_GT(bytes_read, 0); |
407 switch (info->type_) { | 408 switch (info->type_) { |
408 case UpdateJobInfo::MANIFEST_FETCH: | 409 case UpdateJobInfo::MANIFEST_FETCH: |
409 manifest_data_.append(info->buffer_->data(), bytes_read); | 410 manifest_data_.append(info->buffer_->data(), bytes_read); |
410 break; | 411 break; |
411 case UpdateJobInfo::URL_FETCH: | 412 case UpdateJobInfo::URL_FETCH: |
412 case UpdateJobInfo::MASTER_ENTRY_FETCH: | 413 case UpdateJobInfo::MASTER_ENTRY_FETCH: |
413 DCHECK(info->response_writer_.get()); | 414 DCHECK(info->response_writer_.get()); |
414 info->response_writer_->WriteData(info->buffer_, bytes_read, | 415 info->response_writer_->WriteData(info->buffer_, bytes_read, |
415 &info->write_callback_); | 416 &info->write_callback_); |
416 return false; // wait for async write completion to continue reading | 417 return false; // wait for async write completion to continue reading |
417 case UpdateJobInfo::MANIFEST_REFETCH: | 418 case UpdateJobInfo::MANIFEST_REFETCH: |
418 manifest_refetch_data_.append(info->buffer_->data(), bytes_read); | 419 manifest_refetch_data_.append(info->buffer_->data(), bytes_read); |
419 break; | 420 break; |
420 default: | 421 default: |
421 NOTREACHED(); | 422 NOTREACHED(); |
422 } | 423 } |
423 return true; | 424 return true; |
424 } | 425 } |
425 | 426 |
426 void AppCacheUpdateJob::OnWriteResponseComplete(int result, | 427 void AppCacheUpdateJob::OnWriteResponseComplete(int result, |
427 URLRequest* request, | 428 net::URLRequest* request, |
428 UpdateJobInfo* info) { | 429 UpdateJobInfo* info) { |
429 if (result < 0) { | 430 if (result < 0) { |
430 request->Cancel(); | 431 request->Cancel(); |
431 OnResponseCompleted(request); | 432 OnResponseCompleted(request); |
432 return; | 433 return; |
433 } | 434 } |
434 | 435 |
435 ReadResponseData(request); | 436 ReadResponseData(request); |
436 } | 437 } |
437 | 438 |
438 void AppCacheUpdateJob::OnReceivedRedirect(URLRequest* request, | 439 void AppCacheUpdateJob::OnReceivedRedirect(net::URLRequest* request, |
439 const GURL& new_url, | 440 const GURL& new_url, |
440 bool* defer_redirect) { | 441 bool* defer_redirect) { |
441 // Redirect is not allowed by the update process. | 442 // Redirect is not allowed by the update process. |
442 request->Cancel(); | 443 request->Cancel(); |
443 OnResponseCompleted(request); | 444 OnResponseCompleted(request); |
444 } | 445 } |
445 | 446 |
446 void AppCacheUpdateJob::OnResponseCompleted(URLRequest* request) { | 447 void AppCacheUpdateJob::OnResponseCompleted(net::URLRequest* request) { |
447 // Retry for 503s where retry-after is 0. | 448 // Retry for 503s where retry-after is 0. |
448 if (request->status().is_success() && | 449 if (request->status().is_success() && |
449 request->GetResponseCode() == 503 && | 450 request->GetResponseCode() == 503 && |
450 RetryRequest(request)) { | 451 RetryRequest(request)) { |
451 return; | 452 return; |
452 } | 453 } |
453 | 454 |
454 UpdateJobInfo* info = GetUpdateJobInfo(request); | 455 UpdateJobInfo* info = GetUpdateJobInfo(request); |
455 switch (info->type_) { | 456 switch (info->type_) { |
456 case UpdateJobInfo::MANIFEST_FETCH: | 457 case UpdateJobInfo::MANIFEST_FETCH: |
457 HandleManifestFetchCompleted(request); | 458 HandleManifestFetchCompleted(request); |
458 break; | 459 break; |
459 case UpdateJobInfo::URL_FETCH: | 460 case UpdateJobInfo::URL_FETCH: |
460 HandleUrlFetchCompleted(request); | 461 HandleUrlFetchCompleted(request); |
461 break; | 462 break; |
462 case UpdateJobInfo::MASTER_ENTRY_FETCH: | 463 case UpdateJobInfo::MASTER_ENTRY_FETCH: |
463 HandleMasterEntryFetchCompleted(request); | 464 HandleMasterEntryFetchCompleted(request); |
464 break; | 465 break; |
465 case UpdateJobInfo::MANIFEST_REFETCH: | 466 case UpdateJobInfo::MANIFEST_REFETCH: |
466 HandleManifestRefetchCompleted(request); | 467 HandleManifestRefetchCompleted(request); |
467 break; | 468 break; |
468 default: | 469 default: |
469 NOTREACHED(); | 470 NOTREACHED(); |
470 } | 471 } |
471 | 472 |
472 delete request; | 473 delete request; |
473 } | 474 } |
474 | 475 |
475 bool AppCacheUpdateJob::RetryRequest(URLRequest* request) { | 476 bool AppCacheUpdateJob::RetryRequest(net::URLRequest* request) { |
476 UpdateJobInfo* info = GetUpdateJobInfo(request); | 477 UpdateJobInfo* info = GetUpdateJobInfo(request); |
477 if (info->retry_503_attempts_ >= kMax503Retries) { | 478 if (info->retry_503_attempts_ >= kMax503Retries) { |
478 return false; | 479 return false; |
479 } | 480 } |
480 | 481 |
481 if (!request->response_headers()->HasHeaderValue("retry-after", "0")) | 482 if (!request->response_headers()->HasHeaderValue("retry-after", "0")) |
482 return false; | 483 return false; |
483 | 484 |
484 const GURL& url = request->original_url(); | 485 const GURL& url = request->original_url(); |
485 URLRequest* retry = new URLRequest(url, this); | 486 net::URLRequest* retry = new net::URLRequest(url, this); |
486 UpdateJobInfo* retry_info = new UpdateJobInfo(info->type_); | 487 UpdateJobInfo* retry_info = new UpdateJobInfo(info->type_); |
487 retry_info->retry_503_attempts_ = info->retry_503_attempts_ + 1; | 488 retry_info->retry_503_attempts_ = info->retry_503_attempts_ + 1; |
488 retry_info->existing_entry_ = info->existing_entry_; | 489 retry_info->existing_entry_ = info->existing_entry_; |
489 retry->SetUserData(this, retry_info); | 490 retry->SetUserData(this, retry_info); |
490 retry->set_context(request->context()); | 491 retry->set_context(request->context()); |
491 retry->set_load_flags(request->load_flags()); | 492 retry->set_load_flags(request->load_flags()); |
492 | 493 |
493 switch (info->type_) { | 494 switch (info->type_) { |
494 case UpdateJobInfo::MANIFEST_FETCH: | 495 case UpdateJobInfo::MANIFEST_FETCH: |
495 case UpdateJobInfo::MANIFEST_REFETCH: | 496 case UpdateJobInfo::MANIFEST_REFETCH: |
(...skipping 11 matching lines...) Expand all Loading... |
507 default: | 508 default: |
508 NOTREACHED(); | 509 NOTREACHED(); |
509 } | 510 } |
510 | 511 |
511 retry->Start(); | 512 retry->Start(); |
512 | 513 |
513 delete request; | 514 delete request; |
514 return true; | 515 return true; |
515 } | 516 } |
516 | 517 |
517 void AppCacheUpdateJob::HandleManifestFetchCompleted(URLRequest* request) { | 518 void AppCacheUpdateJob::HandleManifestFetchCompleted(net::URLRequest* request) { |
518 DCHECK(internal_state_ == FETCH_MANIFEST); | 519 DCHECK(internal_state_ == FETCH_MANIFEST); |
519 manifest_url_request_ = NULL; | 520 manifest_url_request_ = NULL; |
520 | 521 |
521 int response_code = -1; | 522 int response_code = -1; |
522 std::string mime_type; | 523 std::string mime_type; |
523 bool is_valid_response_code = false; | 524 bool is_valid_response_code = false; |
524 bool is_valid_mime_type = false; | 525 bool is_valid_mime_type = false; |
525 if (request->status().is_success()) { | 526 if (request->status().is_success()) { |
526 response_code = request->GetResponseCode(); | 527 response_code = request->GetResponseCode(); |
527 is_valid_response_code = (response_code / 100 == 2); | 528 is_valid_response_code = (response_code / 100 == 2); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 } | 615 } |
615 } | 616 } |
616 | 617 |
617 group_->SetUpdateStatus(AppCacheGroup::DOWNLOADING); | 618 group_->SetUpdateStatus(AppCacheGroup::DOWNLOADING); |
618 NotifyAllAssociatedHosts(DOWNLOADING_EVENT); | 619 NotifyAllAssociatedHosts(DOWNLOADING_EVENT); |
619 FetchUrls(); | 620 FetchUrls(); |
620 FetchMasterEntries(); | 621 FetchMasterEntries(); |
621 MaybeCompleteUpdate(); // if not done, continues when async fetches complete | 622 MaybeCompleteUpdate(); // if not done, continues when async fetches complete |
622 } | 623 } |
623 | 624 |
624 void AppCacheUpdateJob::HandleUrlFetchCompleted(URLRequest* request) { | 625 void AppCacheUpdateJob::HandleUrlFetchCompleted(net::URLRequest* request) { |
625 DCHECK(internal_state_ == DOWNLOADING); | 626 DCHECK(internal_state_ == DOWNLOADING); |
626 UpdateJobInfo* info = GetUpdateJobInfo(request); | 627 UpdateJobInfo* info = GetUpdateJobInfo(request); |
627 | 628 |
628 const GURL& url = request->original_url(); | 629 const GURL& url = request->original_url(); |
629 pending_url_fetches_.erase(url); | 630 pending_url_fetches_.erase(url); |
630 NotifyAllProgress(url); | 631 NotifyAllProgress(url); |
631 ++url_fetches_completed_; | 632 ++url_fetches_completed_; |
632 | 633 |
633 int response_code = request->status().is_success() | 634 int response_code = request->status().is_success() |
634 ? request->GetResponseCode() : -1; | 635 ? request->GetResponseCode() : -1; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
677 inprogress_cache_->AddOrModifyEntry(url, entry); | 678 inprogress_cache_->AddOrModifyEntry(url, entry); |
678 } | 679 } |
679 } | 680 } |
680 | 681 |
681 // Fetch another URL now that one request has completed. | 682 // Fetch another URL now that one request has completed. |
682 DCHECK(internal_state_ != CACHE_FAILURE); | 683 DCHECK(internal_state_ != CACHE_FAILURE); |
683 FetchUrls(); | 684 FetchUrls(); |
684 MaybeCompleteUpdate(); | 685 MaybeCompleteUpdate(); |
685 } | 686 } |
686 | 687 |
687 void AppCacheUpdateJob::HandleMasterEntryFetchCompleted(URLRequest* request) { | 688 void AppCacheUpdateJob::HandleMasterEntryFetchCompleted( |
| 689 net::URLRequest* request) { |
688 DCHECK(internal_state_ == NO_UPDATE || internal_state_ == DOWNLOADING); | 690 DCHECK(internal_state_ == NO_UPDATE || internal_state_ == DOWNLOADING); |
689 | 691 |
690 // TODO(jennb): Handle downloads completing during cache failure when update | 692 // TODO(jennb): Handle downloads completing during cache failure when update |
691 // no longer fetches master entries directly. For now, we cancel all pending | 693 // no longer fetches master entries directly. For now, we cancel all pending |
692 // master entry fetches when entering cache failure state so this will never | 694 // master entry fetches when entering cache failure state so this will never |
693 // be called in CACHE_FAILURE state. | 695 // be called in CACHE_FAILURE state. |
694 | 696 |
695 const GURL& url = request->original_url(); | 697 const GURL& url = request->original_url(); |
696 master_entry_fetches_.erase(url); | 698 master_entry_fetches_.erase(url); |
697 ++master_entries_completed_; | 699 ++master_entries_completed_; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
760 return; | 762 return; |
761 } | 763 } |
762 } | 764 } |
763 } | 765 } |
764 | 766 |
765 DCHECK(internal_state_ != CACHE_FAILURE); | 767 DCHECK(internal_state_ != CACHE_FAILURE); |
766 FetchMasterEntries(); | 768 FetchMasterEntries(); |
767 MaybeCompleteUpdate(); | 769 MaybeCompleteUpdate(); |
768 } | 770 } |
769 | 771 |
770 void AppCacheUpdateJob::HandleManifestRefetchCompleted(URLRequest* request) { | 772 void AppCacheUpdateJob::HandleManifestRefetchCompleted( |
| 773 net::URLRequest* request) { |
771 DCHECK(internal_state_ == REFETCH_MANIFEST); | 774 DCHECK(internal_state_ == REFETCH_MANIFEST); |
772 manifest_url_request_ = NULL; | 775 manifest_url_request_ = NULL; |
773 | 776 |
774 int response_code = request->status().is_success() | 777 int response_code = request->status().is_success() |
775 ? request->GetResponseCode() : -1; | 778 ? request->GetResponseCode() : -1; |
776 if (response_code == 304 || manifest_data_ == manifest_refetch_data_) { | 779 if (response_code == 304 || manifest_data_ == manifest_refetch_data_) { |
777 // Only need to store response in storage if manifest is not already | 780 // Only need to store response in storage if manifest is not already |
778 // an entry in the cache. | 781 // an entry in the cache. |
779 AppCacheEntry* entry = inprogress_cache_->GetEntry(manifest_url_); | 782 AppCacheEntry* entry = inprogress_cache_->GetEntry(manifest_url_); |
780 if (entry) { | 783 if (entry) { |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1014 AppCacheEntry* existing_entry = | 1017 AppCacheEntry* existing_entry = |
1015 group_->newest_complete_cache()->GetEntry(url_to_fetch.url); | 1018 group_->newest_complete_cache()->GetEntry(url_to_fetch.url); |
1016 DCHECK(existing_entry); | 1019 DCHECK(existing_entry); |
1017 DCHECK(existing_entry->response_id() == | 1020 DCHECK(existing_entry->response_id() == |
1018 url_to_fetch.existing_response_info->response_id()); | 1021 url_to_fetch.existing_response_info->response_id()); |
1019 info->existing_entry_ = *existing_entry; | 1022 info->existing_entry_ = *existing_entry; |
1020 http_info = url_to_fetch.existing_response_info->http_response_info(); | 1023 http_info = url_to_fetch.existing_response_info->http_response_info(); |
1021 } | 1024 } |
1022 | 1025 |
1023 // Send URL request for the resource. | 1026 // Send URL request for the resource. |
1024 URLRequest* request = new URLRequest(url_to_fetch.url, this); | 1027 net::URLRequest* request = new net::URLRequest(url_to_fetch.url, this); |
1025 request->SetUserData(this, info); | 1028 request->SetUserData(this, info); |
1026 request->set_context(service_->request_context()); | 1029 request->set_context(service_->request_context()); |
1027 request->set_load_flags( | 1030 request->set_load_flags( |
1028 request->load_flags() | net::LOAD_DISABLE_INTERCEPT); | 1031 request->load_flags() | net::LOAD_DISABLE_INTERCEPT); |
1029 if (http_info) | 1032 if (http_info) |
1030 AddConditionalHeaders(request, http_info); | 1033 AddConditionalHeaders(request, http_info); |
1031 request->Start(); | 1034 request->Start(); |
1032 pending_url_fetches_.insert( | 1035 pending_url_fetches_.insert( |
1033 PendingUrlFetches::value_type(url_to_fetch.url, request)); | 1036 PendingUrlFetches::value_type(url_to_fetch.url, request)); |
1034 } | 1037 } |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1129 PendingMasters::iterator found = pending_master_entries_.find(url); | 1132 PendingMasters::iterator found = pending_master_entries_.find(url); |
1130 DCHECK(found != pending_master_entries_.end()); | 1133 DCHECK(found != pending_master_entries_.end()); |
1131 PendingHosts& hosts = found->second; | 1134 PendingHosts& hosts = found->second; |
1132 for (PendingHosts::iterator host_it = hosts.begin(); | 1135 for (PendingHosts::iterator host_it = hosts.begin(); |
1133 host_it != hosts.end(); ++host_it) { | 1136 host_it != hosts.end(); ++host_it) { |
1134 (*host_it)->AssociateCache(cache); | 1137 (*host_it)->AssociateCache(cache); |
1135 } | 1138 } |
1136 } | 1139 } |
1137 } else { | 1140 } else { |
1138 // Send URL request for the master entry. | 1141 // Send URL request for the master entry. |
1139 URLRequest* request = new URLRequest(url, this); | 1142 net::URLRequest* request = new net::URLRequest(url, this); |
1140 request->SetUserData(this, | 1143 request->SetUserData(this, |
1141 new UpdateJobInfo(UpdateJobInfo::MASTER_ENTRY_FETCH)); | 1144 new UpdateJobInfo(UpdateJobInfo::MASTER_ENTRY_FETCH)); |
1142 request->set_context(service_->request_context()); | 1145 request->set_context(service_->request_context()); |
1143 request->set_load_flags( | 1146 request->set_load_flags( |
1144 request->load_flags() | net::LOAD_DISABLE_INTERCEPT); | 1147 request->load_flags() | net::LOAD_DISABLE_INTERCEPT); |
1145 request->Start(); | 1148 request->Start(); |
1146 master_entry_fetches_.insert(PendingUrlFetches::value_type(url, request)); | 1149 master_entry_fetches_.insert(PendingUrlFetches::value_type(url, request)); |
1147 } | 1150 } |
1148 | 1151 |
1149 master_entries_to_fetch_.erase(master_entries_to_fetch_.begin()); | 1152 master_entries_to_fetch_.erase(master_entries_to_fetch_.begin()); |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1407 | 1410 |
1408 // Break the connection with the group so the group cannot call delete | 1411 // Break the connection with the group so the group cannot call delete |
1409 // on this object after we've posted a task to delete ourselves. | 1412 // on this object after we've posted a task to delete ourselves. |
1410 group_->SetUpdateStatus(AppCacheGroup::IDLE); | 1413 group_->SetUpdateStatus(AppCacheGroup::IDLE); |
1411 group_ = NULL; | 1414 group_ = NULL; |
1412 | 1415 |
1413 MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 1416 MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
1414 } | 1417 } |
1415 | 1418 |
1416 } // namespace appcache | 1419 } // namespace appcache |
OLD | NEW |