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

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

Issue 500009: Http cache: Add a few more states to the transaction SM.... (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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 87
88 HttpUtil::ValuesIterator v(h.values_begin(), h.values_end(), ','); 88 HttpUtil::ValuesIterator v(h.values_begin(), h.values_end(), ',');
89 while (v.GetNext()) { 89 while (v.GetNext()) {
90 if (LowerCaseEqualsASCII(v.value_begin(), v.value_end(), search->value)) 90 if (LowerCaseEqualsASCII(v.value_begin(), v.value_end(), search->value))
91 return true; 91 return true;
92 } 92 }
93 } 93 }
94 return false; 94 return false;
95 } 95 }
96 96
97 // Indicates DoCacheWriteResponse to mark the entry as incomplete.
98 static const int kTruncatedEntry = 1;
eroman 2009/12/17 05:21:42 This can be deleted now yes?
rvargas (doing something else) 2009/12/17 18:30:12 Removed. Thanks!.
99
97 //----------------------------------------------------------------------------- 100 //-----------------------------------------------------------------------------
98 101
99 HttpCache::Transaction::Transaction(HttpCache* cache, bool enable_range_support) 102 HttpCache::Transaction::Transaction(HttpCache* cache, bool enable_range_support)
100 : next_state_(STATE_NONE), 103 : next_state_(STATE_NONE),
101 request_(NULL), 104 request_(NULL),
102 cache_(cache->AsWeakPtr()), 105 cache_(cache->AsWeakPtr()),
103 entry_(NULL), 106 entry_(NULL),
104 new_entry_(NULL), 107 new_entry_(NULL),
105 network_trans_(NULL), 108 network_trans_(NULL),
106 callback_(NULL), 109 callback_(NULL),
110 new_response_(NULL),
107 mode_(NONE), 111 mode_(NONE),
112 target_state_(STATE_NONE),
108 reading_(false), 113 reading_(false),
109 invalid_range_(false), 114 invalid_range_(false),
110 enable_range_support_(enable_range_support), 115 enable_range_support_(enable_range_support),
111 truncated_(false), 116 truncated_(false),
117 server_responded_206_(false),
112 read_offset_(0), 118 read_offset_(0),
113 effective_load_flags_(0), 119 effective_load_flags_(0),
114 final_upload_progress_(0), 120 final_upload_progress_(0),
115 ALLOW_THIS_IN_INITIALIZER_LIST( 121 ALLOW_THIS_IN_INITIALIZER_LIST(
116 network_callback_(this, &Transaction::OnIOComplete)), 122 network_callback_(this, &Transaction::OnIOComplete)),
117 ALLOW_THIS_IN_INITIALIZER_LIST( 123 ALLOW_THIS_IN_INITIALIZER_LIST(
118 cache_callback_(new CancelableCompletionCallback<Transaction>( 124 cache_callback_(new CancelableCompletionCallback<Transaction>(
119 this, &Transaction::OnIOComplete))) { 125 this, &Transaction::OnIOComplete))) {
120 COMPILE_ASSERT(HttpCache::Transaction::kNumValidationHeaders == 126 COMPILE_ASSERT(HttpCache::Transaction::kNumValidationHeaders ==
121 ARRAYSIZE_UNSAFE(kValidationHeaders), 127 ARRAYSIZE_UNSAFE(kValidationHeaders),
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 next_state_ = STATE_ENTRY_AVAILABLE; 475 next_state_ = STATE_ENTRY_AVAILABLE;
470 if (new_entry_) { 476 if (new_entry_) {
471 // We are inside AddTransactionToEntry() so avoid reentering DoLoop(). 477 // We are inside AddTransactionToEntry() so avoid reentering DoLoop().
472 DCHECK_EQ(new_entry_, entry); 478 DCHECK_EQ(new_entry_, entry);
473 return OK; 479 return OK;
474 } 480 }
475 return DoLoop(OK); 481 return DoLoop(OK);
476 } 482 }
477 483
478 int HttpCache::Transaction::DoEntryAvailable() { 484 int HttpCache::Transaction::DoEntryAvailable() {
485 DCHECK(!new_entry_);
486 if (mode_ == WRITE) {
487 if (partial_.get())
488 partial_->RestoreHeaders(&custom_request_->extra_headers);
489 next_state_ = STATE_SEND_REQUEST;
490 } else {
491 // We have to read the headers from the cached entry.
492 DCHECK(mode_ & READ_META);
493 next_state_ = STATE_CACHE_READ_RESPONSE;
494 }
495 return OK;
496 }
497
498 int HttpCache::Transaction::DoCacheReadResponseComplete() {
479 // We now have access to the cache entry. 499 // We now have access to the cache entry.
480 // 500 //
481 // o if we are the writer for the transaction, then we can start the network
482 // transaction.
483 //
484 // o if we are a reader for the transaction, then we can start reading the 501 // o if we are a reader for the transaction, then we can start reading the
485 // cache entry. 502 // cache entry.
486 // 503 //
487 // o if we can read or write, then we should check if the cache entry needs 504 // o if we can read or write, then we should check if the cache entry needs
488 // to be validated and then issue a network request if needed or just read 505 // to be validated and then issue a network request if needed or just read
489 // from the cache if the cache entry is already valid. 506 // from the cache if the cache entry is already valid.
490 // 507 //
491 // o if we are set to UPDATE, then we are handling an externally 508 // o if we are set to UPDATE, then we are handling an externally
492 // conditionalized request (if-modified-since / if-none-match). We read 509 // conditionalized request (if-modified-since / if-none-match). We check
493 // the cache entry, and check if the request headers define a validation 510 // if the request headers define a validation request.
494 // request.
495 // 511 //
496 DCHECK(!new_entry_); 512 int rv = OK;
497 int rv;
498 switch (mode_) { 513 switch (mode_) {
499 case READ: 514 case READ:
500 rv = BeginCacheRead(); 515 rv = BeginCacheRead();
501 break; 516 break;
502 case WRITE:
503 if (partial_.get())
504 partial_->RestoreHeaders(&custom_request_->extra_headers);
505 next_state_ = STATE_SEND_REQUEST;
506 rv = OK;
507 break;
508 case READ_WRITE: 517 case READ_WRITE:
509 rv = BeginPartialCacheValidation(); 518 rv = BeginPartialCacheValidation();
510 break; 519 break;
511 case UPDATE: 520 case UPDATE:
512 rv = BeginExternallyConditionalizedRequest(); 521 rv = BeginExternallyConditionalizedRequest();
513 break; 522 break;
523 case WRITE:
514 default: 524 default:
515 NOTREACHED(); 525 NOTREACHED();
516 rv = ERR_FAILED; 526 rv = ERR_FAILED;
517 } 527 }
518 return rv; 528 return rv;
519 } 529 }
520 530
521 bool HttpCache::Transaction::AddTruncatedFlag() { 531 bool HttpCache::Transaction::AddTruncatedFlag() {
522 DCHECK(mode_ & WRITE); 532 DCHECK(mode_ & WRITE);
523 533
524 // Don't set the flag for sparse entries. 534 // Don't set the flag for sparse entries.
525 if (partial_.get() && !truncated_) 535 if (partial_.get() && !truncated_)
526 return true; 536 return true;
527 537
528 // Double check that there is something worth keeping. 538 // Double check that there is something worth keeping.
529 if (!entry_->disk_entry->GetDataSize(kResponseContentIndex)) 539 if (!entry_->disk_entry->GetDataSize(kResponseContentIndex))
530 return false; 540 return false;
531 541
542 // We have a serious problem here: We are inside the object destructor and
543 // we need to write to the cache. We could even have a pending operation in
544 // progress already so it's not that we can just issue another operation and
545 // cancel it immediately. So, for now, just verify that the operation
546 // completes synchronously.
532 truncated_ = true; 547 truncated_ = true;
533 WriteResponseInfoToEntry(true); 548 target_state_ = STATE_NONE;
549 next_state_ = STATE_CACHE_WRITE_TRUNCATED_RESPONSE;
550 int rv = DoLoop(OK);
551 DCHECK_EQ(OK, rv);
534 return true; 552 return true;
535 } 553 }
536 554
537 void HttpCache::Transaction::DoCallback(int rv) { 555 void HttpCache::Transaction::DoCallback(int rv) {
538 DCHECK(rv != ERR_IO_PENDING); 556 DCHECK(rv != ERR_IO_PENDING);
539 DCHECK(callback_); 557 DCHECK(callback_);
540 558
541 // since Run may result in Read being called, clear callback_ up front. 559 // Since Run may result in Read being called, clear callback_ up front.
542 CompletionCallback* c = callback_; 560 CompletionCallback* c = callback_;
543 callback_ = NULL; 561 callback_ = NULL;
544 c->Run(rv); 562 c->Run(rv);
545 } 563 }
546 564
547 int HttpCache::Transaction::HandleResult(int rv) { 565 int HttpCache::Transaction::HandleResult(int rv) {
548 DCHECK(rv != ERR_IO_PENDING); 566 DCHECK(rv != ERR_IO_PENDING);
549 if (callback_) 567 if (callback_)
550 DoCallback(rv); 568 DoCallback(rv);
551 return rv; 569 return rv;
552 } 570 }
553 571
554 int HttpCache::Transaction::DoLoop(int result) { 572 int HttpCache::Transaction::DoLoop(int result) {
555 DCHECK(next_state_ != STATE_NONE); 573 DCHECK(next_state_ != STATE_NONE);
556 574
557 int rv = result; 575 int rv = result;
558 do { 576 do {
559 State state = next_state_; 577 State state = next_state_;
560 next_state_ = STATE_NONE; 578 next_state_ = STATE_NONE;
561 switch (state) { 579 switch (state) {
562 case STATE_SEND_REQUEST: 580 case STATE_SEND_REQUEST:
563 DCHECK_EQ(OK, rv); 581 DCHECK_EQ(OK, rv);
564 rv = DoSendRequest(); 582 rv = DoSendRequest();
565 break; 583 break;
566 case STATE_SEND_REQUEST_COMPLETE: 584 case STATE_SEND_REQUEST_COMPLETE:
567 rv = DoSendRequestComplete(rv); 585 rv = DoSendRequestComplete(rv);
568 break; 586 break;
587 case STATE_SUCCESSFUL_SEND_REQUEST:
588 DCHECK_EQ(OK, rv);
589 rv = DoSuccessfulSendRequest();
590 break;
569 case STATE_NETWORK_READ: 591 case STATE_NETWORK_READ:
570 DCHECK_EQ(OK, rv); 592 DCHECK_EQ(OK, rv);
571 rv = DoNetworkRead(); 593 rv = DoNetworkRead();
572 break; 594 break;
573 case STATE_NETWORK_READ_COMPLETE: 595 case STATE_NETWORK_READ_COMPLETE:
574 rv = DoNetworkReadComplete(rv); 596 rv = DoNetworkReadComplete(rv);
575 break; 597 break;
576 case STATE_INIT_ENTRY: 598 case STATE_INIT_ENTRY:
577 DCHECK_EQ(OK, rv); 599 DCHECK_EQ(OK, rv);
578 rv = DoInitEntry(); 600 rv = DoInitEntry();
(...skipping 27 matching lines...) Expand all
606 rv = DoAddToEntry(); 628 rv = DoAddToEntry();
607 break; 629 break;
608 case STATE_ENTRY_AVAILABLE: 630 case STATE_ENTRY_AVAILABLE:
609 DCHECK_EQ(OK, rv); 631 DCHECK_EQ(OK, rv);
610 rv = DoEntryAvailable(); 632 rv = DoEntryAvailable();
611 break; 633 break;
612 case STATE_PARTIAL_CACHE_VALIDATION: 634 case STATE_PARTIAL_CACHE_VALIDATION:
613 DCHECK_EQ(OK, rv); 635 DCHECK_EQ(OK, rv);
614 rv = DoPartialCacheValidation(); 636 rv = DoPartialCacheValidation();
615 break; 637 break;
638 case STATE_UPDATE_CACHED_RESPONSE:
639 DCHECK_EQ(OK, rv);
640 rv = DoUpdateCachedResponse();
641 break;
642 case STATE_UPDATE_CACHED_RESPONSE_COMPLETE:
643 rv = DoUpdateCachedResponseComplete(rv);
644 break;
645 case STATE_OVERWRITE_CACHED_RESPONSE:
646 DCHECK_EQ(OK, rv);
647 rv = DoOverwriteCachedResponse();
648 break;
649 case STATE_TRUNCATE_CACHED_DATA:
650 DCHECK_EQ(OK, rv);
651 rv = DoTruncateCachedData();
652 break;
653 case STATE_TRUNCATE_CACHED_DATA_COMPLETE:
654 rv = DoTruncateCachedDataComplete(rv);
655 break;
656 case STATE_PARTIAL_HEADERS_RECEIVED:
657 DCHECK_EQ(OK, rv);
658 rv = DoPartialHeadersReceived();
659 break;
660 case STATE_CACHE_READ_RESPONSE:
661 DCHECK_EQ(OK, rv);
662 rv = DoCacheReadResponse();
663 break;
664 case STATE_CACHE_READ_RESPONSE_COMPLETE:
665 DCHECK_EQ(OK, rv);
666 rv = DoCacheReadResponseComplete();
667 break;
668 case STATE_CACHE_WRITE_RESPONSE:
669 DCHECK_EQ(OK, rv);
670 rv = DoCacheWriteResponse();
671 break;
672 case STATE_CACHE_WRITE_TRUNCATED_RESPONSE:
673 DCHECK_EQ(OK, rv);
674 rv = DoCacheWriteTruncatedResponse();
675 break;
676 case STATE_CACHE_WRITE_RESPONSE_COMPLETE:
677 rv = DoCacheWriteResponseComplete(rv);
678 break;
616 case STATE_CACHE_QUERY_DATA: 679 case STATE_CACHE_QUERY_DATA:
617 DCHECK_EQ(OK, rv); 680 DCHECK_EQ(OK, rv);
618 rv = DoCacheQueryData(); 681 rv = DoCacheQueryData();
619 break; 682 break;
620 case STATE_CACHE_QUERY_DATA_COMPLETE: 683 case STATE_CACHE_QUERY_DATA_COMPLETE:
621 rv = DoCacheQueryDataComplete(rv); 684 rv = DoCacheQueryDataComplete(rv);
622 break; 685 break;
623 case STATE_CACHE_READ_DATA: 686 case STATE_CACHE_READ_DATA:
624 DCHECK_EQ(OK, rv); 687 DCHECK_EQ(OK, rv);
625 rv = DoCacheReadData(); 688 rv = DoCacheReadData();
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 845
783 if (request_->method == "POST" && 846 if (request_->method == "POST" &&
784 request_->upload_data && request_->upload_data->identifier()) 847 request_->upload_data && request_->upload_data->identifier())
785 return false; 848 return false;
786 849
787 // TODO(darin): add support for caching HEAD responses 850 // TODO(darin): add support for caching HEAD responses
788 return true; 851 return true;
789 } 852 }
790 853
791 int HttpCache::Transaction::BeginCacheRead() { 854 int HttpCache::Transaction::BeginCacheRead() {
792 DCHECK(mode_ == READ);
793
794 // Read response headers.
795 int rv = ReadResponseInfoFromEntry();
796 if (rv != OK)
797 return rv;
798
799 // We don't support any combination of LOAD_ONLY_FROM_CACHE and byte ranges. 855 // We don't support any combination of LOAD_ONLY_FROM_CACHE and byte ranges.
800 if (response_.headers->response_code() == 206 || partial_.get()) { 856 if (response_.headers->response_code() == 206 || partial_.get()) {
801 NOTREACHED(); 857 NOTREACHED();
802 return ERR_CACHE_MISS; 858 return ERR_CACHE_MISS;
803 } 859 }
804 860
805 // We don't have the whole resource. 861 // We don't have the whole resource.
806 if (truncated_) 862 if (truncated_)
807 return ERR_CACHE_MISS; 863 return ERR_CACHE_MISS;
808 864
809 return rv; 865 return OK;
810 } 866 }
811 867
812 int HttpCache::Transaction::BeginCacheValidation() { 868 int HttpCache::Transaction::BeginCacheValidation() {
813 DCHECK(mode_ == READ_WRITE); 869 DCHECK(mode_ == READ_WRITE);
814 870
815 if ((effective_load_flags_ & LOAD_PREFERRING_CACHE || 871 if ((effective_load_flags_ & LOAD_PREFERRING_CACHE ||
816 !RequiresValidation()) && !partial_.get()) { 872 !RequiresValidation()) && !partial_.get()) {
817 cache_->ConvertWriterToReader(entry_); 873 cache_->ConvertWriterToReader(entry_);
818 mode_ = READ; 874 mode_ = READ;
819 } else { 875 } else {
820 // Make the network request conditional, to see if we may reuse our cached 876 // Make the network request conditional, to see if we may reuse our cached
821 // response. If we cannot do so, then we just resort to a normal fetch. 877 // response. If we cannot do so, then we just resort to a normal fetch.
822 // Our mode remains READ_WRITE for a conditional request. We'll switch to 878 // Our mode remains READ_WRITE for a conditional request. We'll switch to
823 // either READ or WRITE mode once we hear back from the server. 879 // either READ or WRITE mode once we hear back from the server.
824 if (!ConditionalizeRequest()) 880 if (!ConditionalizeRequest())
825 mode_ = WRITE; 881 mode_ = WRITE;
826 next_state_ = STATE_SEND_REQUEST; 882 next_state_ = STATE_SEND_REQUEST;
827 } 883 }
828 return OK; 884 return OK;
829 } 885 }
830 886
831 int HttpCache::Transaction::BeginPartialCacheValidation() { 887 int HttpCache::Transaction::BeginPartialCacheValidation() {
832 DCHECK(mode_ == READ_WRITE); 888 DCHECK(mode_ == READ_WRITE);
833 889
834 int rv = ReadResponseInfoFromEntry();
835 if (rv != OK) {
836 DCHECK(rv != ERR_IO_PENDING);
837 return rv;
838 }
839
840 if (response_.headers->response_code() != 206 && !partial_.get() && 890 if (response_.headers->response_code() != 206 && !partial_.get() &&
841 !truncated_) 891 !truncated_)
842 return BeginCacheValidation(); 892 return BeginCacheValidation();
843 893
844 if (!enable_range_support_) 894 if (!enable_range_support_)
845 return BeginCacheValidation(); 895 return BeginCacheValidation();
846 896
847 bool byte_range_requested = partial_.get() != NULL; 897 bool byte_range_requested = partial_.get() != NULL;
848 if (byte_range_requested) { 898 if (byte_range_requested) {
849 next_state_ = STATE_CACHE_QUERY_DATA; 899 next_state_ = STATE_CACHE_QUERY_DATA;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 return OK; 980 return OK;
931 } 981 }
932 982
933 return BeginCacheValidation(); 983 return BeginCacheValidation();
934 } 984 }
935 985
936 int HttpCache::Transaction::BeginExternallyConditionalizedRequest() { 986 int HttpCache::Transaction::BeginExternallyConditionalizedRequest() {
937 DCHECK_EQ(UPDATE, mode_); 987 DCHECK_EQ(UPDATE, mode_);
938 DCHECK(external_validation_.initialized); 988 DCHECK(external_validation_.initialized);
939 989
940 // Read the cached response.
941 int rv = ReadResponseInfoFromEntry();
942 if (rv != OK) {
943 DCHECK(rv != ERR_IO_PENDING);
944 return rv;
945 }
946
947 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kValidationHeaders); i++) { 990 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kValidationHeaders); i++) {
948 if (external_validation_.values[i].empty()) 991 if (external_validation_.values[i].empty())
949 continue; 992 continue;
950 // Retrieve either the cached response's "etag" or "last-modified" header. 993 // Retrieve either the cached response's "etag" or "last-modified" header.
951 std::string validator; 994 std::string validator;
952 response_.headers->EnumerateHeader( 995 response_.headers->EnumerateHeader(
953 NULL, 996 NULL,
954 kValidationHeaders[i].related_response_header_name, 997 kValidationHeaders[i].related_response_header_name,
955 &validator); 998 &validator);
956 999
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1245 if (partial_.get()) { 1288 if (partial_.get()) {
1246 return partial_->CacheRead(entry_->disk_entry, read_buf_, read_buf_len_, 1289 return partial_->CacheRead(entry_->disk_entry, read_buf_, read_buf_len_,
1247 cache_callback_); 1290 cache_callback_);
1248 } 1291 }
1249 1292
1250 return entry_->disk_entry->ReadData(kResponseContentIndex, read_offset_, 1293 return entry_->disk_entry->ReadData(kResponseContentIndex, read_offset_,
1251 read_buf_, read_buf_len_, 1294 read_buf_, read_buf_len_,
1252 cache_callback_); 1295 cache_callback_);
1253 } 1296 }
1254 1297
1255 int HttpCache::Transaction::ReadResponseInfoFromEntry() { 1298 int HttpCache::Transaction::DoCacheReadResponse() {
1256 DCHECK(entry_); 1299 DCHECK(entry_);
1300 next_state_ = STATE_CACHE_READ_RESPONSE_COMPLETE;
1257 1301
1258 LoadLog::BeginEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_READ_INFO); 1302 LoadLog::BeginEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_READ_INFO);
1259 bool read_ok = 1303 bool read_ok =
1260 HttpCache::ReadResponseInfo(entry_->disk_entry, &response_, &truncated_); 1304 HttpCache::ReadResponseInfo(entry_->disk_entry, &response_, &truncated_);
1261 LoadLog::EndEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_READ_INFO); 1305 LoadLog::EndEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_READ_INFO);
1262 1306
1263 return read_ok ? OK : ERR_CACHE_READ_FAILURE; 1307 return read_ok ? OK : ERR_CACHE_READ_FAILURE;
1264 } 1308 }
1265 1309
1266 int HttpCache::Transaction::WriteToEntry(int index, int offset, 1310 int HttpCache::Transaction::WriteToEntry(int index, int offset,
(...skipping 14 matching lines...) Expand all
1281 DLOG(ERROR) << "failed to write response data to cache"; 1325 DLOG(ERROR) << "failed to write response data to cache";
1282 DoneWritingToEntry(false); 1326 DoneWritingToEntry(false);
1283 1327
1284 // We want to ignore errors writing to disk and just keep reading from 1328 // We want to ignore errors writing to disk and just keep reading from
1285 // the network. 1329 // the network.
1286 rv = data_len; 1330 rv = data_len;
1287 } 1331 }
1288 return rv; 1332 return rv;
1289 } 1333 }
1290 1334
1291 void HttpCache::Transaction::WriteResponseInfoToEntry(bool truncated) { 1335 int HttpCache::Transaction::DoCacheWriteResponse() {
1336 return WriteResponseInfoToEntry(false);
1337 }
1338
1339 int HttpCache::Transaction::DoCacheWriteTruncatedResponse() {
1340 return WriteResponseInfoToEntry(true);
1341 }
1342
1343 int HttpCache::Transaction::WriteResponseInfoToEntry(bool truncated) {
1344 next_state_ = STATE_CACHE_WRITE_RESPONSE_COMPLETE;
1292 if (!entry_) 1345 if (!entry_)
1293 return; 1346 return OK;
1294 1347
1295 // Do not cache no-store content (unless we are record mode). Do not cache 1348 // Do not cache no-store content (unless we are record mode). Do not cache
1296 // content with cert errors either. This is to prevent not reporting net 1349 // content with cert errors either. This is to prevent not reporting net
1297 // errors when loading a resource from the cache. When we load a page over 1350 // errors when loading a resource from the cache. When we load a page over
1298 // HTTPS with a cert error we show an SSL blocking page. If the user clicks 1351 // HTTPS with a cert error we show an SSL blocking page. If the user clicks
1299 // proceed we reload the resource ignoring the errors. The loaded resource 1352 // proceed we reload the resource ignoring the errors. The loaded resource
1300 // is then cached. If that resource is subsequently loaded from the cache, 1353 // is then cached. If that resource is subsequently loaded from the cache,
1301 // no net error is reported (even though the cert status contains the actual 1354 // no net error is reported (even though the cert status contains the actual
1302 // errors) and no SSL blocking page is shown. An alternative would be to 1355 // errors) and no SSL blocking page is shown. An alternative would be to
1303 // reverse-map the cert status to a net error and replay the net error. 1356 // reverse-map the cert status to a net error and replay the net error.
1304 if ((cache_->mode() != RECORD && 1357 if ((cache_->mode() != RECORD &&
1305 response_.headers->HasHeaderValue("cache-control", "no-store")) || 1358 response_.headers->HasHeaderValue("cache-control", "no-store")) ||
1306 net::IsCertStatusError(response_.ssl_info.cert_status)) { 1359 net::IsCertStatusError(response_.ssl_info.cert_status)) {
1307 DoneWritingToEntry(false); 1360 DoneWritingToEntry(false);
1308 return; 1361 return OK;
1309 } 1362 }
1310 1363
1311 // When writing headers, we normally only write the non-transient 1364 // When writing headers, we normally only write the non-transient
1312 // headers; when in record mode, record everything. 1365 // headers; when in record mode, record everything.
1313 bool skip_transient_headers = (cache_->mode() != RECORD); 1366 bool skip_transient_headers = (cache_->mode() != RECORD);
1314 1367
1315 if (truncated) { 1368 if (truncated) {
1316 DCHECK_EQ(200, response_.headers->response_code()); 1369 DCHECK_EQ(200, response_.headers->response_code());
1317 } 1370 }
1318 1371
1319 if (!HttpCache::WriteResponseInfo(entry_->disk_entry, &response_, 1372 if (!HttpCache::WriteResponseInfo(entry_->disk_entry, &response_,
1320 skip_transient_headers, truncated)) { 1373 skip_transient_headers, truncated)) {
1321 DLOG(ERROR) << "failed to write response info to cache"; 1374 DLOG(ERROR) << "failed to write response info to cache";
1322 DoneWritingToEntry(false); 1375 DoneWritingToEntry(false);
1323 } 1376 }
1377 return OK;
1378 }
1379
1380 int HttpCache::Transaction::DoCacheWriteResponseComplete(int result) {
1381 next_state_ = target_state_;
1382 target_state_ = STATE_NONE;
1383 return OK;
1324 } 1384 }
1325 1385
1326 int HttpCache::Transaction::AppendResponseDataToEntry( 1386 int HttpCache::Transaction::AppendResponseDataToEntry(
1327 IOBuffer* data, int data_len, CompletionCallback* callback) { 1387 IOBuffer* data, int data_len, CompletionCallback* callback) {
1328 if (!entry_ || !data_len) 1388 if (!entry_ || !data_len)
1329 return data_len; 1389 return data_len;
1330 1390
1331 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); 1391 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex);
1332 return WriteToEntry(kResponseContentIndex, current_size, data, data_len, 1392 return WriteToEntry(kResponseContentIndex, current_size, data, data_len,
1333 callback); 1393 callback);
1334 } 1394 }
1335 1395
1336 void HttpCache::Transaction::TruncateResponseData() { 1396 int HttpCache::Transaction::DoTruncateCachedData() {
1397 next_state_ = STATE_TRUNCATE_CACHED_DATA_COMPLETE;
1337 if (!entry_) 1398 if (!entry_)
1338 return; 1399 return OK;
1339 1400
1340 // Truncate the stream. 1401 // Truncate the stream.
1341 int rv = WriteToEntry(kResponseContentIndex, 0, NULL, 0, NULL); 1402 int rv = WriteToEntry(kResponseContentIndex, 0, NULL, 0, NULL);
1342 DCHECK(rv != ERR_IO_PENDING); 1403 DCHECK(rv != ERR_IO_PENDING);
1404 return OK;
1343 } 1405 }
1344 1406
1345 void HttpCache::Transaction::DoneWritingToEntry(bool success) { 1407 void HttpCache::Transaction::DoneWritingToEntry(bool success) {
1346 if (!entry_) 1408 if (!entry_)
1347 return; 1409 return;
1348 1410
1349 if (cache_->mode() == RECORD) 1411 if (cache_->mode() == RECORD)
1350 DLOG(INFO) << "Recorded: " << request_->method << request_->url 1412 DLOG(INFO) << "Recorded: " << request_->method << request_->url
1351 << " status: " << response_.headers->response_code(); 1413 << " status: " << response_.headers->response_code();
1352 1414
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1430 1492
1431 if (partial_.get()) 1493 if (partial_.get())
1432 return DoPartialNetworkReadCompleted(result); 1494 return DoPartialNetworkReadCompleted(result);
1433 1495
1434 if (result == 0) // End of file. 1496 if (result == 0) // End of file.
1435 DoneWritingToEntry(true); 1497 DoneWritingToEntry(true);
1436 1498
1437 return result; 1499 return result;
1438 } 1500 }
1439 1501
1502 // We received the response headers and there is no error.
1503 int HttpCache::Transaction::DoSuccessfulSendRequest() {
1504 DCHECK(!new_response_);
1505 const HttpResponseInfo* new_response = network_trans_->GetResponseInfo();
1506 if (new_response->headers->response_code() == 401 ||
1507 new_response->headers->response_code() == 407) {
1508 auth_response_ = *new_response;
1509 return OK;
1510 }
1511
1512 if (!ValidatePartialResponse(new_response->headers, &server_responded_206_) &&
1513 !auth_response_.headers) {
1514 // Something went wrong with this request and we have to restart it.
1515 // If we have an authentication response, we are exposed to weird things
1516 // hapenning if the user cancels the authentication before we receive
1517 // the new response.
1518 response_ = HttpResponseInfo();
1519 network_trans_.reset();
1520 next_state_ = STATE_SEND_REQUEST;
1521 return OK;
1522 }
1523 if (server_responded_206_ && mode_ == READ_WRITE && !truncated_ &&
1524 response_.headers->response_code() == 200) {
1525 // We have stored the full entry, but it changed and the server is
1526 // sending a range. We have to delete the old entry.
1527 DoneWritingToEntry(false);
1528 }
1529
1530 new_response_ = new_response;
1531 // Are we expecting a response to a conditional query?
1532 if (mode_ == READ_WRITE || mode_ == UPDATE) {
1533 if (new_response->headers->response_code() == 304 ||
1534 server_responded_206_) {
1535 next_state_ = STATE_UPDATE_CACHED_RESPONSE;
1536 return OK;
1537 }
1538 mode_ = WRITE;
1539 }
1540
1541 next_state_ = STATE_OVERWRITE_CACHED_RESPONSE;
1542 return OK;
1543 }
1544
1545 // We received 304 or 206 and we want to update the cached response headers.
1546 int HttpCache::Transaction::DoUpdateCachedResponse() {
1547 next_state_ = STATE_UPDATE_CACHED_RESPONSE_COMPLETE;
1548 int rv = OK;
1549 // Update cached response based on headers in new_response.
1550 // TODO(wtc): should we update cached certificate (response_.ssl_info), too?
1551 response_.headers->Update(*new_response_->headers);
1552 response_.response_time = new_response_->response_time;
1553 response_.request_time = new_response_->request_time;
1554
1555 if (response_.headers->HasHeaderValue("cache-control", "no-store")) {
1556 cache_->DoomEntry(cache_key_);
1557 } else {
1558 // If we are already reading, we already updated the headers for this
1559 // request; doing it again will change Content-Length.
1560 if (!reading_) {
1561 target_state_ = STATE_UPDATE_CACHED_RESPONSE_COMPLETE;
1562 next_state_ = STATE_CACHE_WRITE_RESPONSE;
1563 rv = OK;
1564 }
1565 }
1566 return rv;
1567 }
1568
1569 int HttpCache::Transaction::DoUpdateCachedResponseComplete(int result) {
1570 if (mode_ == UPDATE) {
1571 DCHECK(!server_responded_206_);
1572 // We got a "not modified" response and already updated the corresponding
1573 // cache entry above.
1574 //
1575 // By closing the cached entry now, we make sure that the 304 rather than
1576 // the cached 200 response, is what will be returned to the user.
1577 DoneWritingToEntry(true);
1578 } else if (entry_ && !server_responded_206_) {
1579 DCHECK_EQ(READ_WRITE, mode_);
1580 if (!partial_.get() || partial_->IsLastRange()) {
1581 cache_->ConvertWriterToReader(entry_);
1582 mode_ = READ;
1583 }
1584 // We no longer need the network transaction, so destroy it.
1585 final_upload_progress_ = network_trans_->GetUploadProgress();
1586 network_trans_.reset();
1587 }
1588 next_state_ = STATE_OVERWRITE_CACHED_RESPONSE;
1589 return OK;
1590 }
1591
1592 int HttpCache::Transaction::DoOverwriteCachedResponse() {
1593 if (mode_ & READ) {
1594 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED;
1595 return OK;
1596 }
1597
1598 // We change the value of Content-Length for partial content.
1599 if (server_responded_206_ && partial_.get())
1600 partial_->FixContentLength(new_response_->headers);
1601
1602 response_ = *new_response_;
1603 target_state_ = STATE_TRUNCATE_CACHED_DATA;
1604 next_state_ = truncated_ ? STATE_CACHE_WRITE_TRUNCATED_RESPONSE :
1605 STATE_CACHE_WRITE_RESPONSE;
1606 return OK;
1607 }
1608
1609 int HttpCache::Transaction::DoTruncateCachedDataComplete(int result) {
1610 // If this response is a redirect, then we can stop writing now. (We don't
1611 // need to cache the response body of a redirect.)
1612 if (response_.headers->IsRedirect(NULL))
1613 DoneWritingToEntry(true);
1614 next_state_ = STATE_PARTIAL_HEADERS_RECEIVED;
1615 return OK;
1616 }
1617
1618 int HttpCache::Transaction::DoPartialHeadersReceived() {
1619 new_response_ = NULL;
1620 if (!partial_.get())
1621 return OK;
1622
1623 if (reading_) {
1624 if (network_trans_.get()) {
1625 next_state_ = STATE_NETWORK_READ;
1626 } else {
1627 next_state_ = STATE_CACHE_READ_DATA;
1628 }
1629 } else if (mode_ != NONE) {
1630 // We are about to return the headers for a byte-range request to the user,
1631 // so let's fix them.
1632 partial_->FixResponseHeaders(response_.headers);
1633 }
1634 return OK;
1635 }
1636
1440 int HttpCache::Transaction::DoSendRequestComplete(int result) { 1637 int HttpCache::Transaction::DoSendRequestComplete(int result) {
1441 if (!cache_) 1638 if (!cache_)
1442 return ERR_UNEXPECTED; 1639 return ERR_UNEXPECTED;
1443 1640
1444 if (result == OK) { 1641 if (result == OK) {
1445 const HttpResponseInfo* new_response = network_trans_->GetResponseInfo(); 1642 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST;
1446 if (new_response->headers->response_code() == 401 || 1643 return OK;
1447 new_response->headers->response_code() == 407) { 1644 }
1448 auth_response_ = *new_response;
1449 } else {
1450 bool partial_content;
1451 if (!ValidatePartialResponse(new_response->headers, &partial_content) &&
1452 !auth_response_.headers) {
1453 // Something went wrong with this request and we have to restart it.
1454 // If we have an authentication response, we are exposed to weird things
1455 // hapenning if the user cancels the authentication before we receive
1456 // the new response.
1457 response_ = HttpResponseInfo();
1458 network_trans_.reset();
1459 next_state_ = STATE_SEND_REQUEST;
1460 return OK;
1461 }
1462 if (partial_content && mode_ == READ_WRITE && !truncated_ &&
1463 response_.headers->response_code() == 200) {
1464 // We have stored the full entry, but it changed and the server is
1465 // sending a range. We have to delete the old entry.
1466 DoneWritingToEntry(false);
1467 }
1468 1645
1469 // Are we expecting a response to a conditional query? 1646 if (IsCertificateError(result)) {
1470 if (mode_ == READ_WRITE || mode_ == UPDATE) {
1471 if (new_response->headers->response_code() == 304 || partial_content) {
1472 // Update cached response based on headers in new_response.
1473 // TODO(wtc): should we update cached certificate
1474 // (response_.ssl_info), too?
1475 response_.headers->Update(*new_response->headers);
1476 response_.response_time = new_response->response_time;
1477 response_.request_time = new_response->request_time;
1478
1479 if (response_.headers->HasHeaderValue("cache-control", "no-store")) {
1480 cache_->DoomEntry(cache_key_);
1481 } else {
1482 // If we are already reading, we already updated the headers for
1483 // this request; doing it again will change Content-Length.
1484 if (!reading_)
1485 WriteResponseInfoToEntry(false);
1486 }
1487
1488 if (mode_ == UPDATE) {
1489 DCHECK(!partial_content);
1490 // We got a "not modified" response and already updated the
1491 // corresponding cache entry above.
1492 //
1493 // By closing the cached entry now, we make sure that the
1494 // 304 rather than the cached 200 response, is what will be
1495 // returned to the user.
1496 DoneWritingToEntry(true);
1497 } else if (entry_ && !partial_content) {
1498 DCHECK_EQ(READ_WRITE, mode_);
1499 if (!partial_.get() || partial_->IsLastRange()) {
1500 cache_->ConvertWriterToReader(entry_);
1501 mode_ = READ;
1502 }
1503 // We no longer need the network transaction, so destroy it.
1504 final_upload_progress_ = network_trans_->GetUploadProgress();
1505 network_trans_.reset();
1506 }
1507 } else {
1508 mode_ = WRITE;
1509 }
1510 }
1511
1512 if (!(mode_ & READ)) {
1513 // We change the value of Content-Length for partial content.
1514 if (partial_content && partial_.get())
1515 partial_->FixContentLength(new_response->headers);
1516
1517 response_ = *new_response;
1518 WriteResponseInfoToEntry(truncated_);
1519
1520 // Truncate response data.
1521 TruncateResponseData();
1522
1523 // If this response is a redirect, then we can stop writing now. (We
1524 // don't need to cache the response body of a redirect.)
1525 if (response_.headers->IsRedirect(NULL))
1526 DoneWritingToEntry(true);
1527 }
1528 if (reading_ && partial_.get()) {
1529 if (network_trans_.get()) {
1530 next_state_ = STATE_NETWORK_READ;
1531 } else {
1532 next_state_ = STATE_CACHE_READ_DATA;
1533 }
1534 result = OK;
1535 } else if (mode_ != NONE && partial_.get()) {
1536 // We are about to return the headers for a byte-range request to the
1537 // user, so let's fix them.
1538 partial_->FixResponseHeaders(response_.headers);
1539 }
1540 }
1541 } else if (IsCertificateError(result)) {
1542 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); 1647 const HttpResponseInfo* response = network_trans_->GetResponseInfo();
1543 // If we get a certificate error, then there is a certificate in ssl_info, 1648 // If we get a certificate error, then there is a certificate in ssl_info,
1544 // so GetResponseInfo() should never returns NULL here. 1649 // so GetResponseInfo() should never returns NULL here.
1545 DCHECK(response); 1650 DCHECK(response);
1546 response_.ssl_info = response->ssl_info; 1651 response_.ssl_info = response->ssl_info;
1547 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { 1652 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
1548 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); 1653 const HttpResponseInfo* response = network_trans_->GetResponseInfo();
1549 DCHECK(response); 1654 DCHECK(response);
1550 response_.cert_request_info = response->cert_request_info; 1655 response_.cert_request_info = response->cert_request_info;
1551 } 1656 }
1552 return result; 1657 return result;
1553 } 1658 }
1554 1659
1555 void HttpCache::Transaction::OnIOComplete(int result) { 1660 void HttpCache::Transaction::OnIOComplete(int result) {
1556 DoLoop(result); 1661 DoLoop(result);
1557 } 1662 }
1558 1663
1559 } // namespace net 1664 } // 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