OLD | NEW |
1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "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> |
11 #endif | 11 #endif |
12 | 12 |
13 #include "base/histogram.h" | 13 #include "base/histogram.h" |
14 #include "base/ref_counted.h" | 14 #include "base/ref_counted.h" |
15 #include "base/string_util.h" | 15 #include "base/string_util.h" |
16 #include "base/time.h" | 16 #include "base/time.h" |
17 #include "net/base/io_buffer.h" | 17 #include "net/base/io_buffer.h" |
18 #include "net/base/load_flags.h" | 18 #include "net/base/load_flags.h" |
19 #include "net/base/load_log.h" | |
20 #include "net/base/net_errors.h" | 19 #include "net/base/net_errors.h" |
| 20 #include "net/base/net_log.h" |
21 #include "net/base/ssl_cert_request_info.h" | 21 #include "net/base/ssl_cert_request_info.h" |
22 #include "net/disk_cache/disk_cache.h" | 22 #include "net/disk_cache/disk_cache.h" |
23 #include "net/http/http_request_info.h" | 23 #include "net/http/http_request_info.h" |
24 #include "net/http/http_response_headers.h" | 24 #include "net/http/http_response_headers.h" |
25 #include "net/http/http_transaction.h" | 25 #include "net/http/http_transaction.h" |
26 #include "net/http/http_util.h" | 26 #include "net/http/http_util.h" |
27 #include "net/http/partial_data.h" | 27 #include "net/http/partial_data.h" |
28 | 28 |
29 using base::Time; | 29 using base::Time; |
30 | 30 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 cache_callback_->Cancel(); | 158 cache_callback_->Cancel(); |
159 write_headers_callback_->Cancel(); | 159 write_headers_callback_->Cancel(); |
160 | 160 |
161 // We could still have a cache read or write in progress, so we just null the | 161 // We could still have a cache read or write in progress, so we just null the |
162 // cache_ pointer to signal that we are dead. See DoCacheReadCompleted. | 162 // cache_ pointer to signal that we are dead. See DoCacheReadCompleted. |
163 cache_.reset(); | 163 cache_.reset(); |
164 } | 164 } |
165 | 165 |
166 int HttpCache::Transaction::Start(const HttpRequestInfo* request, | 166 int HttpCache::Transaction::Start(const HttpRequestInfo* request, |
167 CompletionCallback* callback, | 167 CompletionCallback* callback, |
168 LoadLog* load_log) { | 168 const BoundNetLog& net_log) { |
169 DCHECK(request); | 169 DCHECK(request); |
170 DCHECK(callback); | 170 DCHECK(callback); |
171 | 171 |
172 // Ensure that we only have one asynchronous call at a time. | 172 // Ensure that we only have one asynchronous call at a time. |
173 DCHECK(!callback_); | 173 DCHECK(!callback_); |
174 DCHECK(!reading_); | 174 DCHECK(!reading_); |
175 DCHECK(!network_trans_.get()); | 175 DCHECK(!network_trans_.get()); |
176 DCHECK(!entry_); | 176 DCHECK(!entry_); |
177 | 177 |
178 if (!cache_) | 178 if (!cache_) |
179 return ERR_UNEXPECTED; | 179 return ERR_UNEXPECTED; |
180 | 180 |
181 SetRequest(load_log, request); | 181 SetRequest(net_log, request); |
182 | 182 |
183 int rv; | 183 int rv; |
184 | 184 |
185 if (!ShouldPassThrough()) { | 185 if (!ShouldPassThrough()) { |
186 cache_key_ = cache_->GenerateCacheKey(request); | 186 cache_key_ = cache_->GenerateCacheKey(request); |
187 | 187 |
188 // Requested cache access mode. | 188 // Requested cache access mode. |
189 if (effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { | 189 if (effective_load_flags_ & LOAD_ONLY_FROM_CACHE) { |
190 mode_ = READ; | 190 mode_ = READ; |
191 } else if (effective_load_flags_ & LOAD_BYPASS_CACHE) { | 191 } else if (effective_load_flags_ & LOAD_BYPASS_CACHE) { |
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
573 int HttpCache::Transaction::DoSendRequest() { | 573 int HttpCache::Transaction::DoSendRequest() { |
574 DCHECK(mode_ & WRITE || mode_ == NONE); | 574 DCHECK(mode_ & WRITE || mode_ == NONE); |
575 DCHECK(!network_trans_.get()); | 575 DCHECK(!network_trans_.get()); |
576 | 576 |
577 // Create a network transaction. | 577 // Create a network transaction. |
578 int rv = cache_->network_layer_->CreateTransaction(&network_trans_); | 578 int rv = cache_->network_layer_->CreateTransaction(&network_trans_); |
579 if (rv != OK) | 579 if (rv != OK) |
580 return rv; | 580 return rv; |
581 | 581 |
582 next_state_ = STATE_SEND_REQUEST_COMPLETE; | 582 next_state_ = STATE_SEND_REQUEST_COMPLETE; |
583 rv = network_trans_->Start(request_, &io_callback_, load_log_); | 583 rv = network_trans_->Start(request_, &io_callback_, net_log_); |
584 return rv; | 584 return rv; |
585 } | 585 } |
586 | 586 |
587 int HttpCache::Transaction::DoSendRequestComplete(int result) { | 587 int HttpCache::Transaction::DoSendRequestComplete(int result) { |
588 if (!cache_) | 588 if (!cache_) |
589 return ERR_UNEXPECTED; | 589 return ERR_UNEXPECTED; |
590 | 590 |
591 if (result == OK) { | 591 if (result == OK) { |
592 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST; | 592 next_state_ = STATE_SUCCESSFUL_SEND_REQUEST; |
593 return OK; | 593 return OK; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 } | 679 } |
680 | 680 |
681 next_state_ = STATE_OPEN_ENTRY; | 681 next_state_ = STATE_OPEN_ENTRY; |
682 return OK; | 682 return OK; |
683 } | 683 } |
684 | 684 |
685 int HttpCache::Transaction::DoOpenEntry() { | 685 int HttpCache::Transaction::DoOpenEntry() { |
686 DCHECK(!new_entry_); | 686 DCHECK(!new_entry_); |
687 next_state_ = STATE_OPEN_ENTRY_COMPLETE; | 687 next_state_ = STATE_OPEN_ENTRY_COMPLETE; |
688 cache_pending_ = true; | 688 cache_pending_ = true; |
689 LoadLog::BeginEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_OPEN_ENTRY); | 689 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY); |
690 return cache_->OpenEntry(cache_key_, &new_entry_, this); | 690 return cache_->OpenEntry(cache_key_, &new_entry_, this); |
691 } | 691 } |
692 | 692 |
693 int HttpCache::Transaction::DoOpenEntryComplete(int result) { | 693 int HttpCache::Transaction::DoOpenEntryComplete(int result) { |
694 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is | 694 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is |
695 // OK, otherwise the cache will end up with an active entry without any | 695 // OK, otherwise the cache will end up with an active entry without any |
696 // transaction attached. | 696 // transaction attached. |
697 LoadLog::EndEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_OPEN_ENTRY); | 697 net_log_.EndEvent(NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY); |
698 cache_pending_ = false; | 698 cache_pending_ = false; |
699 if (result == OK) { | 699 if (result == OK) { |
700 next_state_ = STATE_ADD_TO_ENTRY; | 700 next_state_ = STATE_ADD_TO_ENTRY; |
701 return OK; | 701 return OK; |
702 } | 702 } |
703 | 703 |
704 if (result == ERR_CACHE_RACE) { | 704 if (result == ERR_CACHE_RACE) { |
705 next_state_ = STATE_INIT_ENTRY; | 705 next_state_ = STATE_INIT_ENTRY; |
706 return OK; | 706 return OK; |
707 } | 707 } |
(...skipping 14 matching lines...) Expand all Loading... |
722 | 722 |
723 // The entry does not exist, and we are not permitted to create a new entry, | 723 // The entry does not exist, and we are not permitted to create a new entry, |
724 // so we must fail. | 724 // so we must fail. |
725 return ERR_CACHE_MISS; | 725 return ERR_CACHE_MISS; |
726 } | 726 } |
727 | 727 |
728 int HttpCache::Transaction::DoCreateEntry() { | 728 int HttpCache::Transaction::DoCreateEntry() { |
729 DCHECK(!new_entry_); | 729 DCHECK(!new_entry_); |
730 next_state_ = STATE_CREATE_ENTRY_COMPLETE; | 730 next_state_ = STATE_CREATE_ENTRY_COMPLETE; |
731 cache_pending_ = true; | 731 cache_pending_ = true; |
732 LoadLog::BeginEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_CREATE_ENTRY); | 732 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY); |
733 return cache_->CreateEntry(cache_key_, &new_entry_, this); | 733 return cache_->CreateEntry(cache_key_, &new_entry_, this); |
734 } | 734 } |
735 | 735 |
736 int HttpCache::Transaction::DoCreateEntryComplete(int result) { | 736 int HttpCache::Transaction::DoCreateEntryComplete(int result) { |
737 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is | 737 // It is important that we go to STATE_ADD_TO_ENTRY whenever the result is |
738 // OK, otherwise the cache will end up with an active entry without any | 738 // OK, otherwise the cache will end up with an active entry without any |
739 // transaction attached. | 739 // transaction attached. |
740 LoadLog::EndEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_CREATE_ENTRY); | 740 net_log_.EndEvent(NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY); |
741 cache_pending_ = false; | 741 cache_pending_ = false; |
742 next_state_ = STATE_ADD_TO_ENTRY; | 742 next_state_ = STATE_ADD_TO_ENTRY; |
743 | 743 |
744 if (result == ERR_CACHE_RACE) { | 744 if (result == ERR_CACHE_RACE) { |
745 next_state_ = STATE_INIT_ENTRY; | 745 next_state_ = STATE_INIT_ENTRY; |
746 return OK; | 746 return OK; |
747 } | 747 } |
748 | 748 |
749 if (result != OK) { | 749 if (result != OK) { |
750 // We have a race here: Maybe we failed to open the entry and decided to | 750 // We have a race here: Maybe we failed to open the entry and decided to |
751 // create one, but by the time we called create, another transaction already | 751 // create one, but by the time we called create, another transaction already |
752 // created the entry. If we want to eliminate this issue, we need an atomic | 752 // created the entry. If we want to eliminate this issue, we need an atomic |
753 // OpenOrCreate() method exposed by the disk cache. | 753 // OpenOrCreate() method exposed by the disk cache. |
754 DLOG(WARNING) << "Unable to create cache entry"; | 754 DLOG(WARNING) << "Unable to create cache entry"; |
755 mode_ = NONE; | 755 mode_ = NONE; |
756 if (partial_.get()) | 756 if (partial_.get()) |
757 partial_->RestoreHeaders(&custom_request_->extra_headers); | 757 partial_->RestoreHeaders(&custom_request_->extra_headers); |
758 next_state_ = STATE_SEND_REQUEST; | 758 next_state_ = STATE_SEND_REQUEST; |
759 } | 759 } |
760 return OK; | 760 return OK; |
761 } | 761 } |
762 | 762 |
763 int HttpCache::Transaction::DoDoomEntry() { | 763 int HttpCache::Transaction::DoDoomEntry() { |
764 next_state_ = STATE_DOOM_ENTRY_COMPLETE; | 764 next_state_ = STATE_DOOM_ENTRY_COMPLETE; |
765 cache_pending_ = true; | 765 cache_pending_ = true; |
766 LoadLog::BeginEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_DOOM_ENTRY); | 766 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY); |
767 return cache_->DoomEntry(cache_key_, this); | 767 return cache_->DoomEntry(cache_key_, this); |
768 } | 768 } |
769 | 769 |
770 int HttpCache::Transaction::DoDoomEntryComplete(int result) { | 770 int HttpCache::Transaction::DoDoomEntryComplete(int result) { |
771 LoadLog::EndEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_DOOM_ENTRY); | 771 net_log_.EndEvent(NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY); |
772 next_state_ = STATE_CREATE_ENTRY; | 772 next_state_ = STATE_CREATE_ENTRY; |
773 cache_pending_ = false; | 773 cache_pending_ = false; |
774 if (result == ERR_CACHE_RACE) | 774 if (result == ERR_CACHE_RACE) |
775 next_state_ = STATE_INIT_ENTRY; | 775 next_state_ = STATE_INIT_ENTRY; |
776 | 776 |
777 return OK; | 777 return OK; |
778 } | 778 } |
779 | 779 |
780 int HttpCache::Transaction::DoAddToEntry() { | 780 int HttpCache::Transaction::DoAddToEntry() { |
781 DCHECK(new_entry_); | 781 DCHECK(new_entry_); |
782 cache_pending_ = true; | 782 cache_pending_ = true; |
783 next_state_ = STATE_ADD_TO_ENTRY_COMPLETE; | 783 next_state_ = STATE_ADD_TO_ENTRY_COMPLETE; |
784 LoadLog::BeginEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_WAITING); | 784 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_WAITING); |
785 return cache_->AddTransactionToEntry(new_entry_, this); | 785 return cache_->AddTransactionToEntry(new_entry_, this); |
786 } | 786 } |
787 | 787 |
788 int HttpCache::Transaction::DoAddToEntryComplete(int result) { | 788 int HttpCache::Transaction::DoAddToEntryComplete(int result) { |
789 LoadLog::EndEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_WAITING); | 789 net_log_.EndEvent(NetLog::TYPE_HTTP_CACHE_WAITING); |
790 DCHECK(new_entry_); | 790 DCHECK(new_entry_); |
791 cache_pending_ = false; | 791 cache_pending_ = false; |
792 | 792 |
793 if (result == ERR_CACHE_RACE) { | 793 if (result == ERR_CACHE_RACE) { |
794 new_entry_ = NULL; | 794 new_entry_ = NULL; |
795 next_state_ = STATE_INIT_ENTRY; | 795 next_state_ = STATE_INIT_ENTRY; |
796 return OK; | 796 return OK; |
797 } | 797 } |
798 | 798 |
799 if (result != OK) { | 799 if (result != OK) { |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
959 return OK; | 959 return OK; |
960 } | 960 } |
961 | 961 |
962 int HttpCache::Transaction::DoCacheReadResponse() { | 962 int HttpCache::Transaction::DoCacheReadResponse() { |
963 DCHECK(entry_); | 963 DCHECK(entry_); |
964 next_state_ = STATE_CACHE_READ_RESPONSE_COMPLETE; | 964 next_state_ = STATE_CACHE_READ_RESPONSE_COMPLETE; |
965 | 965 |
966 io_buf_len_ = entry_->disk_entry->GetDataSize(kResponseInfoIndex); | 966 io_buf_len_ = entry_->disk_entry->GetDataSize(kResponseInfoIndex); |
967 read_buf_ = new IOBuffer(io_buf_len_); | 967 read_buf_ = new IOBuffer(io_buf_len_); |
968 | 968 |
969 LoadLog::BeginEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_READ_INFO); | 969 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_INFO); |
970 cache_callback_->AddRef(); // Balanced in DoCacheReadResponseComplete. | 970 cache_callback_->AddRef(); // Balanced in DoCacheReadResponseComplete. |
971 return entry_->disk_entry->ReadData(kResponseInfoIndex, 0, read_buf_, | 971 return entry_->disk_entry->ReadData(kResponseInfoIndex, 0, read_buf_, |
972 io_buf_len_, cache_callback_); | 972 io_buf_len_, cache_callback_); |
973 } | 973 } |
974 | 974 |
975 int HttpCache::Transaction::DoCacheReadResponseComplete(int result) { | 975 int HttpCache::Transaction::DoCacheReadResponseComplete(int result) { |
976 cache_callback_->Release(); // Balance the AddRef from DoCacheReadResponse. | 976 cache_callback_->Release(); // Balance the AddRef from DoCacheReadResponse. |
977 LoadLog::EndEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_READ_INFO); | 977 net_log_.EndEvent(NetLog::TYPE_HTTP_CACHE_READ_INFO); |
978 if (result != io_buf_len_ || | 978 if (result != io_buf_len_ || |
979 !HttpCache::ParseResponseInfo(read_buf_->data(), io_buf_len_, | 979 !HttpCache::ParseResponseInfo(read_buf_->data(), io_buf_len_, |
980 &response_, &truncated_)) { | 980 &response_, &truncated_)) { |
981 DLOG(ERROR) << "ReadData failed: " << result; | 981 DLOG(ERROR) << "ReadData failed: " << result; |
982 return ERR_CACHE_READ_FAILURE; | 982 return ERR_CACHE_READ_FAILURE; |
983 } | 983 } |
984 | 984 |
985 // We now have access to the cache entry. | 985 // We now have access to the cache entry. |
986 // | 986 // |
987 // o if we are a reader for the transaction, then we can start reading the | 987 // o if we are a reader for the transaction, then we can start reading the |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1037 } | 1037 } |
1038 | 1038 |
1039 int HttpCache::Transaction::DoCacheReadMetadata() { | 1039 int HttpCache::Transaction::DoCacheReadMetadata() { |
1040 DCHECK(entry_); | 1040 DCHECK(entry_); |
1041 DCHECK(!response_.metadata); | 1041 DCHECK(!response_.metadata); |
1042 next_state_ = STATE_CACHE_READ_METADATA_COMPLETE; | 1042 next_state_ = STATE_CACHE_READ_METADATA_COMPLETE; |
1043 | 1043 |
1044 response_.metadata = | 1044 response_.metadata = |
1045 new IOBufferWithSize(entry_->disk_entry->GetDataSize(kMetadataIndex)); | 1045 new IOBufferWithSize(entry_->disk_entry->GetDataSize(kMetadataIndex)); |
1046 | 1046 |
1047 LoadLog::BeginEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_READ_INFO); | 1047 net_log_.BeginEvent(NetLog::TYPE_HTTP_CACHE_READ_INFO); |
1048 cache_callback_->AddRef(); // Balanced in DoCacheReadMetadataComplete. | 1048 cache_callback_->AddRef(); // Balanced in DoCacheReadMetadataComplete. |
1049 return entry_->disk_entry->ReadData(kMetadataIndex, 0, response_.metadata, | 1049 return entry_->disk_entry->ReadData(kMetadataIndex, 0, response_.metadata, |
1050 response_.metadata->size(), | 1050 response_.metadata->size(), |
1051 cache_callback_); | 1051 cache_callback_); |
1052 } | 1052 } |
1053 | 1053 |
1054 int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) { | 1054 int HttpCache::Transaction::DoCacheReadMetadataComplete(int result) { |
1055 cache_callback_->Release(); // Balance the AddRef from DoCacheReadMetadata. | 1055 cache_callback_->Release(); // Balance the AddRef from DoCacheReadMetadata. |
1056 LoadLog::EndEvent(load_log_, LoadLog::TYPE_HTTP_CACHE_READ_INFO); | 1056 net_log_.EndEvent(NetLog::TYPE_HTTP_CACHE_READ_INFO); |
1057 if (result != response_.metadata->size()) { | 1057 if (result != response_.metadata->size()) { |
1058 DLOG(ERROR) << "ReadData failed: " << result; | 1058 DLOG(ERROR) << "ReadData failed: " << result; |
1059 return ERR_CACHE_READ_FAILURE; | 1059 return ERR_CACHE_READ_FAILURE; |
1060 } | 1060 } |
1061 | 1061 |
1062 return OK; | 1062 return OK; |
1063 } | 1063 } |
1064 | 1064 |
1065 int HttpCache::Transaction::DoCacheQueryData() { | 1065 int HttpCache::Transaction::DoCacheQueryData() { |
1066 next_state_ = STATE_CACHE_QUERY_DATA_COMPLETE; | 1066 next_state_ = STATE_CACHE_QUERY_DATA_COMPLETE; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1135 } | 1135 } |
1136 | 1136 |
1137 if (result == 0) // End of file. | 1137 if (result == 0) // End of file. |
1138 DoneWritingToEntry(true); | 1138 DoneWritingToEntry(true); |
1139 | 1139 |
1140 return result; | 1140 return result; |
1141 } | 1141 } |
1142 | 1142 |
1143 //----------------------------------------------------------------------------- | 1143 //----------------------------------------------------------------------------- |
1144 | 1144 |
1145 void HttpCache::Transaction::SetRequest(LoadLog* load_log, | 1145 void HttpCache::Transaction::SetRequest(const BoundNetLog& net_log, |
1146 const HttpRequestInfo* request) { | 1146 const HttpRequestInfo* request) { |
1147 load_log_ = load_log; | 1147 net_log_ = net_log; |
1148 request_ = request; | 1148 request_ = request; |
1149 effective_load_flags_ = request_->load_flags; | 1149 effective_load_flags_ = request_->load_flags; |
1150 | 1150 |
1151 switch (cache_->mode()) { | 1151 switch (cache_->mode()) { |
1152 case NORMAL: | 1152 case NORMAL: |
1153 break; | 1153 break; |
1154 case RECORD: | 1154 case RECORD: |
1155 // When in record mode, we want to NEVER load from the cache. | 1155 // When in record mode, we want to NEVER load from the cache. |
1156 // The reason for this is beacuse we save the Set-Cookie headers | 1156 // The reason for this is beacuse we save the Set-Cookie headers |
1157 // (intentionally). If we read from the cache, we replay them | 1157 // (intentionally). If we read from the cache, we replay them |
(...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1816 // |value| goes from 0 to 63. Actually, the max value should be 47 (0x2f) | 1816 // |value| goes from 0 to 63. Actually, the max value should be 47 (0x2f) |
1817 // but we'll see. | 1817 // but we'll see. |
1818 UMA_HISTOGRAM_ENUMERATION("HttpCache.ResponseHeaders", value, 65); | 1818 UMA_HISTOGRAM_ENUMERATION("HttpCache.ResponseHeaders", value, 65); |
1819 } | 1819 } |
1820 | 1820 |
1821 void HttpCache::Transaction::OnIOComplete(int result) { | 1821 void HttpCache::Transaction::OnIOComplete(int result) { |
1822 DoLoop(result); | 1822 DoLoop(result); |
1823 } | 1823 } |
1824 | 1824 |
1825 } // namespace net | 1825 } // namespace net |
OLD | NEW |