Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(28)

Side by Side Diff: net/http/http_cache_transaction.cc

Issue 464028: Http cache: Second pass to move the HttpCache::Transaction... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/http/http_cache_transaction.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « net/http/http_cache_transaction.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698