OLD | NEW |
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 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 "net/http/http_cache_transaction.h" | 5 #include "net/http/http_cache_transaction.h" |
6 | 6 |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 | 8 |
9 #if defined(OS_POSIX) | 9 #if defined(OS_POSIX) |
10 #include <unistd.h> | 10 #include <unistd.h> |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 return false; | 94 return false; |
95 } | 95 } |
96 | 96 |
97 //----------------------------------------------------------------------------- | 97 //----------------------------------------------------------------------------- |
98 | 98 |
99 HttpCache::Transaction::Transaction(HttpCache* cache, bool enable_range_support) | 99 HttpCache::Transaction::Transaction(HttpCache* cache, bool enable_range_support) |
100 : next_state_(STATE_NONE), | 100 : next_state_(STATE_NONE), |
101 request_(NULL), | 101 request_(NULL), |
102 cache_(cache->AsWeakPtr()), | 102 cache_(cache->AsWeakPtr()), |
103 entry_(NULL), | 103 entry_(NULL), |
| 104 new_entry_(NULL), |
104 network_trans_(NULL), | 105 network_trans_(NULL), |
105 callback_(NULL), | 106 callback_(NULL), |
106 mode_(NONE), | 107 mode_(NONE), |
107 reading_(false), | 108 reading_(false), |
108 invalid_range_(false), | 109 invalid_range_(false), |
109 enable_range_support_(enable_range_support), | 110 enable_range_support_(enable_range_support), |
110 truncated_(false), | 111 truncated_(false), |
111 read_offset_(0), | 112 read_offset_(0), |
112 effective_load_flags_(0), | 113 effective_load_flags_(0), |
113 final_upload_progress_(0), | 114 final_upload_progress_(0), |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 } | 150 } |
150 | 151 |
151 int HttpCache::Transaction::Start(const HttpRequestInfo* request, | 152 int HttpCache::Transaction::Start(const HttpRequestInfo* request, |
152 CompletionCallback* callback, | 153 CompletionCallback* callback, |
153 LoadLog* load_log) { | 154 LoadLog* load_log) { |
154 DCHECK(request); | 155 DCHECK(request); |
155 DCHECK(callback); | 156 DCHECK(callback); |
156 | 157 |
157 // Ensure that we only have one asynchronous call at a time. | 158 // Ensure that we only have one asynchronous call at a time. |
158 DCHECK(!callback_); | 159 DCHECK(!callback_); |
| 160 DCHECK(!reading_); |
| 161 DCHECK(!network_trans_.get()); |
| 162 DCHECK(!entry_); |
159 | 163 |
160 if (!cache_) | 164 if (!cache_) |
161 return ERR_UNEXPECTED; | 165 return ERR_UNEXPECTED; |
162 | 166 |
163 SetRequest(load_log, request); | 167 SetRequest(load_log, request); |
164 | 168 |
165 int rv; | 169 int rv; |
166 | 170 |
167 if (!ShouldPassThrough()) { | 171 if (!ShouldPassThrough()) { |
168 cache_key_ = cache_->GenerateCacheKey(request); | 172 cache_key_ = cache_->GenerateCacheKey(request); |
169 | 173 |
170 // requested cache access mode | 174 // Requested cache access mode. |
171 if (effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { | 175 if (effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { |
172 mode_ = READ; | 176 mode_ = READ; |
173 } else if (effective_load_flags_ & LOAD_BYPASS_CACHE) { | 177 } else if (effective_load_flags_ & LOAD_BYPASS_CACHE) { |
174 mode_ = WRITE; | 178 mode_ = WRITE; |
175 } else { | 179 } else { |
176 mode_ = READ_WRITE; | 180 mode_ = READ_WRITE; |
177 } | 181 } |
178 | 182 |
179 // Downgrade to UPDATE if the request has been externally conditionalized. | 183 // Downgrade to UPDATE if the request has been externally conditionalized. |
180 if (external_validation_.initialized) { | 184 if (external_validation_.initialized) { |
181 if (mode_ & WRITE) { | 185 if (mode_ & WRITE) { |
182 // Strip off the READ_DATA bit (and maybe add back a READ_META bit | 186 // Strip off the READ_DATA bit (and maybe add back a READ_META bit |
183 // in case READ was off). | 187 // in case READ was off). |
184 mode_ = UPDATE; | 188 mode_ = UPDATE; |
185 } else { | 189 } else { |
186 mode_ = NONE; | 190 mode_ = NONE; |
187 } | 191 } |
188 } | 192 } |
189 } | 193 } |
190 | 194 |
191 // if must use cache, then we must fail. this can happen for back/forward | 195 // If must use cache, then we must fail. This can happen for back/forward |
192 // navigations to a page generated via a form post. | 196 // navigations to a page generated via a form post. |
193 if (!(mode_ & READ) && effective_load_flags_ & LOAD_ONLY_FROM_CACHE) | 197 if (!(mode_ & READ) && effective_load_flags_ & LOAD_ONLY_FROM_CACHE) |
194 return ERR_CACHE_MISS; | 198 return ERR_CACHE_MISS; |
195 | 199 |
196 if (mode_ == NONE) { | 200 if (mode_ == NONE) { |
197 if (partial_.get()) | 201 if (partial_.get()) |
198 partial_->RestoreHeaders(&custom_request_->extra_headers); | 202 partial_->RestoreHeaders(&custom_request_->extra_headers); |
199 rv = BeginNetworkRequest(); | 203 rv = BeginNetworkRequest(); |
200 } else { | 204 } else { |
201 rv = AddToEntry(); | 205 rv = AddToEntry(); |
202 } | 206 } |
203 | 207 |
204 // setting this here allows us to check for the existance of a callback_ to | 208 // Setting this here allows us to check for the existance of a callback_ to |
205 // determine if we are still inside Start. | 209 // determine if we are still inside Start. |
206 if (rv == ERR_IO_PENDING) | 210 if (rv == ERR_IO_PENDING) |
207 callback_ = callback; | 211 callback_ = callback; |
208 | 212 |
209 return rv; | 213 return rv; |
210 } | 214 } |
211 | 215 |
212 int HttpCache::Transaction::RestartIgnoringLastError( | 216 int HttpCache::Transaction::RestartIgnoringLastError( |
213 CompletionCallback* callback) { | 217 CompletionCallback* callback) { |
214 DCHECK(callback); | 218 DCHECK(callback); |
215 | 219 |
216 // ensure that we only have one asynchronous call at a time. | 220 // Ensure that we only have one asynchronous call at a time. |
217 DCHECK(!callback_); | 221 DCHECK(!callback_); |
218 | 222 |
219 if (!cache_) | 223 if (!cache_) |
220 return ERR_UNEXPECTED; | 224 return ERR_UNEXPECTED; |
221 | 225 |
222 int rv = RestartNetworkRequest(); | 226 int rv = RestartNetworkRequest(); |
223 | 227 |
224 if (rv == ERR_IO_PENDING) | 228 if (rv == ERR_IO_PENDING) |
225 callback_ = callback; | 229 callback_ = callback; |
226 | 230 |
227 return rv; | 231 return rv; |
228 } | 232 } |
229 | 233 |
230 int HttpCache::Transaction::RestartWithCertificate( | 234 int HttpCache::Transaction::RestartWithCertificate( |
231 X509Certificate* client_cert, | 235 X509Certificate* client_cert, |
232 CompletionCallback* callback) { | 236 CompletionCallback* callback) { |
233 DCHECK(callback); | 237 DCHECK(callback); |
234 | 238 |
235 // ensure that we only have one asynchronous call at a time. | 239 // Ensure that we only have one asynchronous call at a time. |
236 DCHECK(!callback_); | 240 DCHECK(!callback_); |
237 | 241 |
238 if (!cache_) | 242 if (!cache_) |
239 return ERR_UNEXPECTED; | 243 return ERR_UNEXPECTED; |
240 | 244 |
241 int rv = RestartNetworkRequestWithCertificate(client_cert); | 245 int rv = RestartNetworkRequestWithCertificate(client_cert); |
242 | 246 |
243 if (rv == ERR_IO_PENDING) | 247 if (rv == ERR_IO_PENDING) |
244 callback_ = callback; | 248 callback_ = callback; |
245 | 249 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 return LOAD_STATE_WAITING_FOR_CACHE; | 347 return LOAD_STATE_WAITING_FOR_CACHE; |
344 } | 348 } |
345 | 349 |
346 uint64 HttpCache::Transaction::GetUploadProgress() const { | 350 uint64 HttpCache::Transaction::GetUploadProgress() const { |
347 if (network_trans_.get()) | 351 if (network_trans_.get()) |
348 return network_trans_->GetUploadProgress(); | 352 return network_trans_->GetUploadProgress(); |
349 return final_upload_progress_; | 353 return final_upload_progress_; |
350 } | 354 } |
351 | 355 |
352 int HttpCache::Transaction::AddToEntry() { | 356 int HttpCache::Transaction::AddToEntry() { |
353 ActiveEntry* entry = NULL; | 357 next_state_ = STATE_INIT_ENTRY; |
| 358 return DoLoop(OK); |
| 359 } |
| 360 |
| 361 int HttpCache::Transaction::DoInitEntry() { |
| 362 DCHECK(!new_entry_); |
354 | 363 |
355 if (!cache_) | 364 if (!cache_) |
356 return ERR_UNEXPECTED; | 365 return ERR_UNEXPECTED; |
357 | 366 |
358 if (mode_ == WRITE) { | 367 if (mode_ == WRITE) { |
359 cache_->DoomEntry(cache_key_); | 368 next_state_ = STATE_DOOM_ENTRY; |
360 } else { | 369 return OK; |
361 entry = cache_->FindActiveEntry(cache_key_); | 370 } |
362 if (!entry) { | |
363 LoadLog::BeginEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_OPEN_ENTRY); | |
364 entry = cache_->OpenEntry(cache_key_); | |
365 LoadLog::EndEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_OPEN_ENTRY); | |
366 if (!entry) { | |
367 if (mode_ == READ_WRITE) { | |
368 mode_ = WRITE; | |
369 } else if (mode_ == UPDATE) { | |
370 // There is no cache entry to update; proceed without caching. | |
371 mode_ = NONE; | |
372 return BeginNetworkRequest(); | |
373 } else { | |
374 if (cache_->mode() == PLAYBACK) | |
375 DLOG(INFO) << "Playback Cache Miss: " << request_->url; | |
376 | 371 |
377 // entry does not exist, and not permitted to create a new entry, so | 372 new_entry_ = cache_->FindActiveEntry(cache_key_); |
378 // we must fail. | 373 if (!new_entry_) { |
379 return HandleResult(ERR_CACHE_MISS); | 374 next_state_ = STATE_OPEN_ENTRY; |
380 } | 375 return OK; |
381 } | |
382 } | |
383 } | 376 } |
384 | 377 |
385 if (mode_ == WRITE) { | 378 if (mode_ == WRITE) { |
386 DCHECK(!entry); | 379 next_state_ = STATE_CREATE_ENTRY; |
387 LoadLog::BeginEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_CREATE_ENTRY); | 380 return OK; |
388 entry = cache_->CreateEntry(cache_key_); | |
389 LoadLog::EndEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_CREATE_ENTRY); | |
390 if (!entry) { | |
391 DLOG(WARNING) << "unable to create cache entry"; | |
392 mode_ = NONE; | |
393 if (partial_.get()) | |
394 partial_->RestoreHeaders(&custom_request_->extra_headers); | |
395 return BeginNetworkRequest(); | |
396 } | |
397 } | 381 } |
398 | 382 |
| 383 next_state_ = STATE_ADD_TO_ENTRY; |
| 384 return OK; |
| 385 } |
399 | 386 |
| 387 int HttpCache::Transaction::DoDoomEntry() { |
| 388 next_state_ = STATE_DOOM_ENTRY_COMPLETE; |
| 389 cache_->DoomEntry(cache_key_); |
| 390 return OK; |
| 391 } |
| 392 |
| 393 int HttpCache::Transaction::DoDoomEntryComplete() { |
| 394 next_state_ = STATE_CREATE_ENTRY; |
| 395 return OK; |
| 396 } |
| 397 |
| 398 int HttpCache::Transaction::DoOpenEntry() { |
| 399 DCHECK(!new_entry_); |
| 400 next_state_ = STATE_OPEN_ENTRY_COMPLETE; |
| 401 LoadLog::BeginEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_OPEN_ENTRY); |
| 402 new_entry_ = cache_->OpenEntry(cache_key_); |
| 403 return OK; |
| 404 } |
| 405 |
| 406 int HttpCache::Transaction::DoOpenEntryComplete() { |
| 407 LoadLog::EndEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_OPEN_ENTRY); |
| 408 if (new_entry_) { |
| 409 next_state_ = STATE_ADD_TO_ENTRY; |
| 410 return OK; |
| 411 } |
| 412 |
| 413 if (mode_ == READ_WRITE) { |
| 414 mode_ = WRITE; |
| 415 next_state_ = STATE_CREATE_ENTRY; |
| 416 return OK; |
| 417 } |
| 418 if (mode_ == UPDATE) { |
| 419 // There is no cache entry to update; proceed without caching. |
| 420 mode_ = NONE; |
| 421 next_state_ = STATE_SEND_REQUEST; |
| 422 return OK; |
| 423 } |
| 424 if (cache_->mode() == PLAYBACK) |
| 425 DLOG(INFO) << "Playback Cache Miss: " << request_->url; |
| 426 |
| 427 // The entry does not exist, and we are not permitted to create a new entry, |
| 428 // so we must fail. |
| 429 return ERR_CACHE_MISS; |
| 430 } |
| 431 |
| 432 int HttpCache::Transaction::DoCreateEntry() { |
| 433 DCHECK(!new_entry_); |
| 434 next_state_ = STATE_CREATE_ENTRY_COMPLETE; |
| 435 LoadLog::BeginEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_CREATE_ENTRY); |
| 436 new_entry_ = cache_->CreateEntry(cache_key_); |
| 437 return OK; |
| 438 } |
| 439 |
| 440 int HttpCache::Transaction::DoCreateEntryComplete() { |
| 441 LoadLog::EndEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_CREATE_ENTRY); |
| 442 next_state_ = STATE_ADD_TO_ENTRY; |
| 443 if (!new_entry_) { |
| 444 // We have a race here: Maybe we failed to open the entry and decided to |
| 445 // create one, but by the time we called create, another transaction already |
| 446 // created the entry. If we want to eliminate this issue, we need an atomic |
| 447 // OpenOrCreate() method exposed by the disk cache. |
| 448 DLOG(WARNING) << "Unable to create cache entry"; |
| 449 mode_ = NONE; |
| 450 if (partial_.get()) |
| 451 partial_->RestoreHeaders(&custom_request_->extra_headers); |
| 452 next_state_ = STATE_SEND_REQUEST; |
| 453 } |
| 454 return OK; |
| 455 } |
| 456 |
| 457 int HttpCache::Transaction::DoAddToEntry() { |
| 458 DCHECK(new_entry_); |
400 LoadLog::BeginEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_WAITING); | 459 LoadLog::BeginEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_WAITING); |
401 return cache_->AddTransactionToEntry(entry, this); | 460 int rv = cache_->AddTransactionToEntry(new_entry_, this); |
| 461 new_entry_ = NULL; |
| 462 return rv; |
402 } | 463 } |
403 | 464 |
404 int HttpCache::Transaction::EntryAvailable(ActiveEntry* entry) { | 465 int HttpCache::Transaction::EntryAvailable(ActiveEntry* entry) { |
405 LoadLog::EndEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_WAITING); | 466 LoadLog::EndEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_WAITING); |
| 467 entry_ = entry; |
406 | 468 |
| 469 next_state_ = STATE_ENTRY_AVAILABLE; |
| 470 if (new_entry_) { |
| 471 // We are inside AddTransactionToEntry() so avoid reentering DoLoop(). |
| 472 DCHECK_EQ(new_entry_, entry); |
| 473 return OK; |
| 474 } |
| 475 return DoLoop(OK); |
| 476 } |
| 477 |
| 478 int HttpCache::Transaction::DoEntryAvailable() { |
407 // We now have access to the cache entry. | 479 // We now have access to the cache entry. |
408 // | 480 // |
409 // o if we are the writer for the transaction, then we can start the network | 481 // o if we are the writer for the transaction, then we can start the network |
410 // transaction. | 482 // transaction. |
411 // | 483 // |
412 // o if we are a reader for the transaction, then we can start reading the | 484 // o if we are a reader for the transaction, then we can start reading the |
413 // cache entry. | 485 // cache entry. |
414 // | 486 // |
415 // o if we can read or write, then we should check if the cache entry needs | 487 // o if we can read or write, then we should check if the cache entry needs |
416 // to be validated and then issue a network request if needed or just read | 488 // to be validated and then issue a network request if needed or just read |
417 // from the cache if the cache entry is already valid. | 489 // from the cache if the cache entry is already valid. |
418 // | 490 // |
419 // o if we are set to UPDATE, then we are handling an externally | 491 // o if we are set to UPDATE, then we are handling an externally |
420 // conditionalized request (if-modified-since / if-none-match). We read | 492 // conditionalized request (if-modified-since / if-none-match). We read |
421 // the cache entry, and check if the request headers define a validation | 493 // the cache entry, and check if the request headers define a validation |
422 // request. | 494 // request. |
423 // | 495 // |
| 496 DCHECK(!new_entry_); |
424 int rv; | 497 int rv; |
425 entry_ = entry; | |
426 switch (mode_) { | 498 switch (mode_) { |
427 case READ: | 499 case READ: |
428 rv = BeginCacheRead(); | 500 rv = BeginCacheRead(); |
429 break; | 501 break; |
430 case WRITE: | 502 case WRITE: |
431 if (partial_.get()) | 503 if (partial_.get()) |
432 partial_->RestoreHeaders(&custom_request_->extra_headers); | 504 partial_->RestoreHeaders(&custom_request_->extra_headers); |
433 rv = BeginNetworkRequest(); | 505 next_state_ = STATE_SEND_REQUEST; |
| 506 rv = OK; |
434 break; | 507 break; |
435 case READ_WRITE: | 508 case READ_WRITE: |
436 rv = BeginPartialCacheValidation(); | 509 rv = BeginPartialCacheValidation(); |
437 break; | 510 break; |
438 case UPDATE: | 511 case UPDATE: |
439 rv = BeginExternallyConditionalizedRequest(); | 512 rv = BeginExternallyConditionalizedRequest(); |
440 break; | 513 break; |
441 default: | 514 default: |
442 NOTREACHED(); | 515 NOTREACHED(); |
443 rv = ERR_FAILED; | 516 rv = ERR_FAILED; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 case STATE_SEND_REQUEST_COMPLETE: | 566 case STATE_SEND_REQUEST_COMPLETE: |
494 rv = DoSendRequestComplete(rv); | 567 rv = DoSendRequestComplete(rv); |
495 break; | 568 break; |
496 case STATE_NETWORK_READ: | 569 case STATE_NETWORK_READ: |
497 DCHECK_EQ(OK, rv); | 570 DCHECK_EQ(OK, rv); |
498 rv = DoNetworkRead(); | 571 rv = DoNetworkRead(); |
499 break; | 572 break; |
500 case STATE_NETWORK_READ_COMPLETE: | 573 case STATE_NETWORK_READ_COMPLETE: |
501 rv = DoNetworkReadComplete(rv); | 574 rv = DoNetworkReadComplete(rv); |
502 break; | 575 break; |
| 576 case STATE_INIT_ENTRY: |
| 577 DCHECK_EQ(OK, rv); |
| 578 rv = DoInitEntry(); |
| 579 break; |
| 580 case STATE_OPEN_ENTRY: |
| 581 DCHECK_EQ(OK, rv); |
| 582 rv = DoOpenEntry(); |
| 583 break; |
| 584 case STATE_OPEN_ENTRY_COMPLETE: |
| 585 DCHECK_EQ(OK, rv); |
| 586 rv = DoOpenEntryComplete(); |
| 587 break; |
| 588 case STATE_CREATE_ENTRY: |
| 589 DCHECK_EQ(OK, rv); |
| 590 rv = DoCreateEntry(); |
| 591 break; |
| 592 case STATE_CREATE_ENTRY_COMPLETE: |
| 593 DCHECK_EQ(OK, rv); |
| 594 rv = DoCreateEntryComplete(); |
| 595 break; |
| 596 case STATE_DOOM_ENTRY: |
| 597 DCHECK_EQ(OK, rv); |
| 598 rv = DoDoomEntry(); |
| 599 break; |
| 600 case STATE_DOOM_ENTRY_COMPLETE: |
| 601 DCHECK_EQ(OK, rv); |
| 602 rv = DoDoomEntryComplete(); |
| 603 break; |
| 604 case STATE_ADD_TO_ENTRY: |
| 605 DCHECK_EQ(OK, rv); |
| 606 rv = DoAddToEntry(); |
| 607 break; |
| 608 case STATE_ENTRY_AVAILABLE: |
| 609 DCHECK_EQ(OK, rv); |
| 610 rv = DoEntryAvailable(); |
| 611 break; |
| 612 case STATE_PARTIAL_CACHE_VALIDATION: |
| 613 DCHECK_EQ(OK, rv); |
| 614 rv = DoPartialCacheValidation(); |
| 615 break; |
503 case STATE_CACHE_QUERY_DATA: | 616 case STATE_CACHE_QUERY_DATA: |
504 DCHECK_EQ(OK, rv); | 617 DCHECK_EQ(OK, rv); |
505 rv = DoCacheQueryData(); | 618 rv = DoCacheQueryData(); |
506 break; | 619 break; |
507 case STATE_CACHE_QUERY_DATA_COMPLETE: | 620 case STATE_CACHE_QUERY_DATA_COMPLETE: |
508 rv = DoCacheQueryDataComplete(rv); | 621 rv = DoCacheQueryDataComplete(rv); |
509 break; | 622 break; |
510 case STATE_CACHE_READ_DATA: | 623 case STATE_CACHE_READ_DATA: |
511 DCHECK_EQ(OK, rv); | 624 DCHECK_EQ(OK, rv); |
512 rv = DoCacheReadData(); | 625 rv = DoCacheReadData(); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 // TODO(darin): add support for caching HEAD responses | 787 // TODO(darin): add support for caching HEAD responses |
675 return true; | 788 return true; |
676 } | 789 } |
677 | 790 |
678 int HttpCache::Transaction::BeginCacheRead() { | 791 int HttpCache::Transaction::BeginCacheRead() { |
679 DCHECK(mode_ == READ); | 792 DCHECK(mode_ == READ); |
680 | 793 |
681 // Read response headers. | 794 // Read response headers. |
682 int rv = ReadResponseInfoFromEntry(); | 795 int rv = ReadResponseInfoFromEntry(); |
683 if (rv != OK) | 796 if (rv != OK) |
684 return HandleResult(rv); | 797 return rv; |
685 | 798 |
686 // We don't support any combination of LOAD_ONLY_FROM_CACHE and byte ranges. | 799 // We don't support any combination of LOAD_ONLY_FROM_CACHE and byte ranges. |
687 if (response_.headers->response_code() == 206 || partial_.get()) { | 800 if (response_.headers->response_code() == 206 || partial_.get()) { |
688 NOTREACHED(); | 801 NOTREACHED(); |
689 return HandleResult(ERR_CACHE_MISS); | 802 return ERR_CACHE_MISS; |
690 } | 803 } |
691 | 804 |
692 // We don't have the whole resource. | 805 // We don't have the whole resource. |
693 if (truncated_) | 806 if (truncated_) |
694 return HandleResult(ERR_CACHE_MISS); | 807 return ERR_CACHE_MISS; |
695 | 808 |
696 return HandleResult(rv); | 809 return rv; |
697 } | 810 } |
698 | 811 |
699 int HttpCache::Transaction::BeginCacheValidation() { | 812 int HttpCache::Transaction::BeginCacheValidation() { |
700 DCHECK(mode_ == READ_WRITE); | 813 DCHECK(mode_ == READ_WRITE); |
701 | 814 |
702 if ((effective_load_flags_ & LOAD_PREFERRING_CACHE || | 815 if ((effective_load_flags_ & LOAD_PREFERRING_CACHE || |
703 !RequiresValidation()) && !partial_.get()) { | 816 !RequiresValidation()) && !partial_.get()) { |
704 cache_->ConvertWriterToReader(entry_); | 817 cache_->ConvertWriterToReader(entry_); |
705 mode_ = READ; | 818 mode_ = READ; |
706 } else { | 819 } else { |
707 // Make the network request conditional, to see if we may reuse our cached | 820 // Make the network request conditional, to see if we may reuse our cached |
708 // response. If we cannot do so, then we just resort to a normal fetch. | 821 // response. If we cannot do so, then we just resort to a normal fetch. |
709 // Our mode remains READ_WRITE for a conditional request. We'll switch to | 822 // Our mode remains READ_WRITE for a conditional request. We'll switch to |
710 // either READ or WRITE mode once we hear back from the server. | 823 // either READ or WRITE mode once we hear back from the server. |
711 if (!ConditionalizeRequest()) | 824 if (!ConditionalizeRequest()) |
712 mode_ = WRITE; | 825 mode_ = WRITE; |
713 return BeginNetworkRequest(); | 826 next_state_ = STATE_SEND_REQUEST; |
714 } | 827 } |
715 return HandleResult(OK); | 828 return OK; |
716 } | 829 } |
717 | 830 |
718 int HttpCache::Transaction::BeginPartialCacheValidation() { | 831 int HttpCache::Transaction::BeginPartialCacheValidation() { |
719 DCHECK(mode_ == READ_WRITE); | 832 DCHECK(mode_ == READ_WRITE); |
720 | 833 |
721 int rv = ReadResponseInfoFromEntry(); | 834 int rv = ReadResponseInfoFromEntry(); |
722 if (rv != OK) { | 835 if (rv != OK) { |
723 DCHECK(rv != ERR_IO_PENDING); | 836 DCHECK(rv != ERR_IO_PENDING); |
724 return HandleResult(rv); | 837 return rv; |
725 } | 838 } |
726 | 839 |
727 if (response_.headers->response_code() != 206 && !partial_.get() && | 840 if (response_.headers->response_code() != 206 && !partial_.get() && |
728 !truncated_) | 841 !truncated_) |
729 return BeginCacheValidation(); | 842 return BeginCacheValidation(); |
730 | 843 |
731 if (!enable_range_support_) | 844 if (!enable_range_support_) |
732 return BeginCacheValidation(); | 845 return BeginCacheValidation(); |
733 | 846 |
734 bool byte_range_requested = partial_.get() != NULL; | 847 bool byte_range_requested = partial_.get() != NULL; |
735 if (byte_range_requested) { | 848 if (byte_range_requested) { |
736 next_state_ = STATE_CACHE_QUERY_DATA; | 849 next_state_ = STATE_CACHE_QUERY_DATA; |
737 return DoLoop(OK); | 850 return OK; |
738 } | 851 } |
739 // The request is not for a range, but we have stored just ranges. | 852 // The request is not for a range, but we have stored just ranges. |
740 partial_.reset(new PartialData()); | 853 partial_.reset(new PartialData()); |
741 partial_->SetHeaders(request_->extra_headers); | 854 partial_->SetHeaders(request_->extra_headers); |
742 if (!custom_request_.get()) { | 855 if (!custom_request_.get()) { |
743 custom_request_.reset(new HttpRequestInfo(*request_)); | 856 custom_request_.reset(new HttpRequestInfo(*request_)); |
744 request_ = custom_request_.get(); | 857 request_ = custom_request_.get(); |
745 } | 858 } |
746 | 859 |
747 return ValidateEntryHeadersAndContinue(false); | 860 return ValidateEntryHeadersAndContinue(false); |
(...skipping 21 matching lines...) Expand all Loading... |
769 bool byte_range_requested) { | 882 bool byte_range_requested) { |
770 DCHECK(mode_ == READ_WRITE); | 883 DCHECK(mode_ == READ_WRITE); |
771 | 884 |
772 if (!partial_->UpdateFromStoredHeaders(response_.headers, entry_->disk_entry, | 885 if (!partial_->UpdateFromStoredHeaders(response_.headers, entry_->disk_entry, |
773 truncated_)) { | 886 truncated_)) { |
774 // The stored data cannot be used. Get rid of it and restart this request. | 887 // The stored data cannot be used. Get rid of it and restart this request. |
775 // We need to also reset the |truncated_| flag as a new entry is created. | 888 // We need to also reset the |truncated_| flag as a new entry is created. |
776 DoomPartialEntry(!byte_range_requested); | 889 DoomPartialEntry(!byte_range_requested); |
777 mode_ = WRITE; | 890 mode_ = WRITE; |
778 truncated_ = false; | 891 truncated_ = false; |
779 return AddToEntry(); | 892 next_state_ = STATE_INIT_ENTRY; |
| 893 return OK; |
780 } | 894 } |
781 | 895 |
782 if (!partial_->IsRequestedRangeOK()) { | 896 if (!partial_->IsRequestedRangeOK()) { |
783 // The stored data is fine, but the request may be invalid. | 897 // The stored data is fine, but the request may be invalid. |
784 invalid_range_ = true; | 898 invalid_range_ = true; |
785 } | 899 } |
786 | 900 |
787 return ContinuePartialCacheValidation(); | 901 next_state_ = STATE_PARTIAL_CACHE_VALIDATION; |
| 902 return OK; |
788 } | 903 } |
789 | 904 |
790 int HttpCache::Transaction::ContinuePartialCacheValidation() { | 905 int HttpCache::Transaction::DoPartialCacheValidation() { |
791 DCHECK(mode_ == READ_WRITE); | 906 if (mode_ == NONE) |
| 907 return OK; |
| 908 |
792 int rv = partial_->PrepareCacheValidation(entry_->disk_entry, | 909 int rv = partial_->PrepareCacheValidation(entry_->disk_entry, |
793 &custom_request_->extra_headers); | 910 &custom_request_->extra_headers); |
794 | 911 |
795 if (!rv) { | 912 if (!rv) { |
796 // Don't invoke the callback before telling the cache we're done. | 913 // This is the end of the request. |
| 914 if (mode_ & WRITE) { |
| 915 DoneWritingToEntry(true); |
| 916 } else { |
| 917 cache_->DoneReadingFromEntry(entry_, this); |
| 918 entry_ = NULL; |
| 919 } |
797 return rv; | 920 return rv; |
798 } | 921 } |
799 | 922 |
800 if (rv < 0) { | 923 if (rv < 0) { |
801 DCHECK(rv != ERR_IO_PENDING); | 924 DCHECK(rv != ERR_IO_PENDING); |
802 return HandleResult(rv); | 925 return rv; |
803 } | 926 } |
804 | 927 |
805 if (reading_ && partial_->IsCurrentRangeCached()) { | 928 if (reading_ && partial_->IsCurrentRangeCached()) { |
806 rv = ReadFromEntry(read_buf_, read_buf_len_); | 929 next_state_ = STATE_CACHE_READ_DATA; |
807 | 930 return OK; |
808 // We are supposed to hanlde errors here. | |
809 if (rv < 0 && rv != ERR_IO_PENDING) | |
810 HandleResult(rv); | |
811 return rv; | |
812 } | 931 } |
813 | 932 |
814 return BeginCacheValidation(); | 933 return BeginCacheValidation(); |
815 } | 934 } |
816 | 935 |
817 int HttpCache::Transaction::BeginExternallyConditionalizedRequest() { | 936 int HttpCache::Transaction::BeginExternallyConditionalizedRequest() { |
818 DCHECK_EQ(UPDATE, mode_); | 937 DCHECK_EQ(UPDATE, mode_); |
819 DCHECK(external_validation_.initialized); | 938 DCHECK(external_validation_.initialized); |
820 | 939 |
821 // Read the cached response. | 940 // Read the cached response. |
822 int rv = ReadResponseInfoFromEntry(); | 941 int rv = ReadResponseInfoFromEntry(); |
823 if (rv != OK) { | 942 if (rv != OK) { |
824 DCHECK(rv != ERR_IO_PENDING); | 943 DCHECK(rv != ERR_IO_PENDING); |
825 return HandleResult(rv); | 944 return rv; |
826 } | 945 } |
827 | 946 |
828 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kValidationHeaders); i++) { | 947 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kValidationHeaders); i++) { |
829 if (external_validation_.values[i].empty()) | 948 if (external_validation_.values[i].empty()) |
830 continue; | 949 continue; |
831 // Retrieve either the cached response's "etag" or "last-modified" header. | 950 // Retrieve either the cached response's "etag" or "last-modified" header. |
832 std::string validator; | 951 std::string validator; |
833 response_.headers->EnumerateHeader( | 952 response_.headers->EnumerateHeader( |
834 NULL, | 953 NULL, |
835 kValidationHeaders[i].related_response_header_name, | 954 kValidationHeaders[i].related_response_header_name, |
836 &validator); | 955 &validator); |
837 | 956 |
838 if (response_.headers->response_code() != 200 || truncated_ || | 957 if (response_.headers->response_code() != 200 || truncated_ || |
839 validator.empty() || validator != external_validation_.values[i]) { | 958 validator.empty() || validator != external_validation_.values[i]) { |
840 // The externally conditionalized request is not a validation request | 959 // The externally conditionalized request is not a validation request |
841 // for our existing cache entry. Proceed with caching disabled. | 960 // for our existing cache entry. Proceed with caching disabled. |
842 DoneWritingToEntry(true); | 961 DoneWritingToEntry(true); |
843 } | 962 } |
844 } | 963 } |
845 | 964 |
846 return BeginNetworkRequest(); | 965 next_state_ = STATE_SEND_REQUEST; |
| 966 return OK; |
847 } | 967 } |
848 | 968 |
849 int HttpCache::Transaction::BeginNetworkRequest() { | 969 int HttpCache::Transaction::BeginNetworkRequest() { |
850 next_state_ = STATE_SEND_REQUEST; | 970 next_state_ = STATE_SEND_REQUEST; |
851 return DoLoop(OK); | 971 return DoLoop(OK); |
852 } | 972 } |
853 | 973 |
854 int HttpCache::Transaction::DoSendRequest() { | 974 int HttpCache::Transaction::DoSendRequest() { |
855 DCHECK(mode_ & WRITE || mode_ == NONE); | 975 DCHECK(mode_ & WRITE || mode_ == NONE); |
856 DCHECK(!network_trans_.get()); | 976 DCHECK(!network_trans_.get()); |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1254 int HttpCache::Transaction::DoCacheWriteData(int num_bytes) { | 1374 int HttpCache::Transaction::DoCacheWriteData(int num_bytes) { |
1255 next_state_ = STATE_CACHE_WRITE_DATA_COMPLETE; | 1375 next_state_ = STATE_CACHE_WRITE_DATA_COMPLETE; |
1256 cache_callback_->AddRef(); // Balanced in DoCacheWriteDataComplete. | 1376 cache_callback_->AddRef(); // Balanced in DoCacheWriteDataComplete. |
1257 | 1377 |
1258 return AppendResponseDataToEntry(read_buf_, num_bytes, cache_callback_); | 1378 return AppendResponseDataToEntry(read_buf_, num_bytes, cache_callback_); |
1259 } | 1379 } |
1260 | 1380 |
1261 int HttpCache::Transaction::DoPartialNetworkReadCompleted(int result) { | 1381 int HttpCache::Transaction::DoPartialNetworkReadCompleted(int result) { |
1262 partial_->OnNetworkReadCompleted(result); | 1382 partial_->OnNetworkReadCompleted(result); |
1263 | 1383 |
1264 if (result == 0) { // End of file. | 1384 if (result == 0) { |
1265 if (mode_ == READ_WRITE) { | 1385 // We need to move on to the next range. |
1266 // We need to move on to the next range. | 1386 network_trans_.reset(); |
1267 network_trans_.reset(); | 1387 next_state_ = STATE_PARTIAL_CACHE_VALIDATION; |
1268 result = ContinuePartialCacheValidation(); | |
1269 if (result != OK) | |
1270 // Any error was already handled. | |
1271 return result; | |
1272 } | |
1273 DoneWritingToEntry(true); | |
1274 } | 1388 } |
1275 return result; | 1389 return result; |
1276 } | 1390 } |
1277 | 1391 |
1278 int HttpCache::Transaction::DoCacheReadDataComplete(int result) { | 1392 int HttpCache::Transaction::DoCacheReadDataComplete(int result) { |
1279 cache_callback_->Release(); // Balance the AddRef from DoCacheReadData. | 1393 cache_callback_->Release(); // Balance the AddRef from DoCacheReadData. |
1280 | 1394 |
1281 if (!cache_) | 1395 if (!cache_) |
1282 return ERR_UNEXPECTED; | 1396 return ERR_UNEXPECTED; |
1283 | 1397 |
1284 if (partial_.get()) | 1398 if (partial_.get()) |
1285 return DoPartialCacheReadCompleted(result); | 1399 return DoPartialCacheReadCompleted(result); |
1286 | 1400 |
1287 if (result > 0) { | 1401 if (result > 0) { |
1288 read_offset_ += result; | 1402 read_offset_ += result; |
1289 } else if (result == 0) { // End of file. | 1403 } else if (result == 0) { // End of file. |
1290 cache_->DoneReadingFromEntry(entry_, this); | 1404 cache_->DoneReadingFromEntry(entry_, this); |
1291 entry_ = NULL; | 1405 entry_ = NULL; |
1292 } | 1406 } |
1293 return result; | 1407 return result; |
1294 } | 1408 } |
1295 | 1409 |
1296 int HttpCache::Transaction::DoPartialCacheReadCompleted(int result) { | 1410 int HttpCache::Transaction::DoPartialCacheReadCompleted(int result) { |
1297 partial_->OnCacheReadCompleted(result); | 1411 partial_->OnCacheReadCompleted(result); |
1298 | 1412 |
1299 if (result == 0) { // End of file. | 1413 if (result == 0 && mode_ == READ_WRITE) { |
1300 if (partial_.get() && mode_ == READ_WRITE) { | 1414 // We need to move on to the next range. |
1301 // We need to move on to the next range. | 1415 next_state_ = STATE_PARTIAL_CACHE_VALIDATION; |
1302 result = ContinuePartialCacheValidation(); | |
1303 if (result != OK || !entry_) { | |
1304 // Any error was already handled. | |
1305 return result; | |
1306 } | |
1307 cache_->ConvertWriterToReader(entry_); | |
1308 } | |
1309 cache_->DoneReadingFromEntry(entry_, this); | |
1310 entry_ = NULL; | |
1311 } | 1416 } |
1312 return result; | 1417 return result; |
1313 } | 1418 } |
1314 | 1419 |
1315 int HttpCache::Transaction::DoCacheWriteDataComplete(int result) { | 1420 int HttpCache::Transaction::DoCacheWriteDataComplete(int result) { |
1316 // Balance the AddRef from DoCacheWriteData. | 1421 // Balance the AddRef from DoCacheWriteData. |
1317 cache_callback_->Release(); | 1422 cache_callback_->Release(); |
1318 if (!cache_) | 1423 if (!cache_) |
1319 return ERR_UNEXPECTED; | 1424 return ERR_UNEXPECTED; |
1320 | 1425 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1413 // Truncate response data. | 1518 // Truncate response data. |
1414 TruncateResponseData(); | 1519 TruncateResponseData(); |
1415 | 1520 |
1416 // If this response is a redirect, then we can stop writing now. (We | 1521 // If this response is a redirect, then we can stop writing now. (We |
1417 // don't need to cache the response body of a redirect.) | 1522 // don't need to cache the response body of a redirect.) |
1418 if (response_.headers->IsRedirect(NULL)) | 1523 if (response_.headers->IsRedirect(NULL)) |
1419 DoneWritingToEntry(true); | 1524 DoneWritingToEntry(true); |
1420 } | 1525 } |
1421 if (reading_ && partial_.get()) { | 1526 if (reading_ && partial_.get()) { |
1422 if (network_trans_.get()) { | 1527 if (network_trans_.get()) { |
1423 next_state_ = STATE_NETWORK_READ_COMPLETE; | 1528 next_state_ = STATE_NETWORK_READ; |
1424 result = ReadFromNetwork(read_buf_, read_buf_len_); | |
1425 } else { | 1529 } else { |
1426 next_state_ = STATE_CACHE_READ_DATA_COMPLETE; | 1530 next_state_ = STATE_CACHE_READ_DATA; |
1427 result = ReadFromEntry(read_buf_, read_buf_len_); | |
1428 } | 1531 } |
1429 if (result >= 0 || result == ERR_IO_PENDING) { | 1532 result = OK; |
1430 // Keep looping. | |
1431 return result; | |
1432 } else { | |
1433 // Don't keep looping when we return. | |
1434 next_state_ = STATE_NONE; | |
1435 } | |
1436 } else if (mode_ != NONE && partial_.get()) { | 1533 } else if (mode_ != NONE && partial_.get()) { |
1437 // We are about to return the headers for a byte-range request to the | 1534 // We are about to return the headers for a byte-range request to the |
1438 // user, so let's fix them. | 1535 // user, so let's fix them. |
1439 partial_->FixResponseHeaders(response_.headers); | 1536 partial_->FixResponseHeaders(response_.headers); |
1440 } | 1537 } |
1441 } | 1538 } |
1442 } else if (IsCertificateError(result)) { | 1539 } else if (IsCertificateError(result)) { |
1443 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); | 1540 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); |
1444 // If we get a certificate error, then there is a certificate in ssl_info, | 1541 // If we get a certificate error, then there is a certificate in ssl_info, |
1445 // so GetResponseInfo() should never returns NULL here. | 1542 // so GetResponseInfo() should never returns NULL here. |
1446 DCHECK(response); | 1543 DCHECK(response); |
1447 response_.ssl_info = response->ssl_info; | 1544 response_.ssl_info = response->ssl_info; |
1448 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | 1545 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
1449 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); | 1546 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); |
1450 DCHECK(response); | 1547 DCHECK(response); |
1451 response_.cert_request_info = response->cert_request_info; | 1548 response_.cert_request_info = response->cert_request_info; |
1452 } | 1549 } |
1453 return result; | 1550 return result; |
1454 } | 1551 } |
1455 | 1552 |
1456 void HttpCache::Transaction::OnIOComplete(int result) { | 1553 void HttpCache::Transaction::OnIOComplete(int result) { |
1457 DoLoop(result); | 1554 DoLoop(result); |
1458 } | 1555 } |
1459 | 1556 |
1460 } // namespace net | 1557 } // namespace net |
OLD | NEW |