| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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.h" | 5 #include "net/http/http_cache.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 | 10 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 while (v.GetNext()) { | 111 while (v.GetNext()) { |
| 112 if (LowerCaseEqualsASCII(v.value_begin(), v.value_end(), search->value)) | 112 if (LowerCaseEqualsASCII(v.value_begin(), v.value_end(), search->value)) |
| 113 return true; | 113 return true; |
| 114 } | 114 } |
| 115 } | 115 } |
| 116 return false; | 116 return false; |
| 117 } | 117 } |
| 118 | 118 |
| 119 //----------------------------------------------------------------------------- | 119 //----------------------------------------------------------------------------- |
| 120 | 120 |
| 121 std::string HttpCache::GenerateCacheKey(const HttpRequestInfo* request) { | |
| 122 std::string url = request->url.spec(); | |
| 123 if (request->url.has_ref()) | |
| 124 url.erase(url.find_last_of('#')); | |
| 125 | |
| 126 if (mode_ == NORMAL) { | |
| 127 return url; | |
| 128 } | |
| 129 | |
| 130 // In playback and record mode, we cache everything. | |
| 131 | |
| 132 // Lazily initialize. | |
| 133 if (playback_cache_map_ == NULL) | |
| 134 playback_cache_map_.reset(new PlaybackCacheMap()); | |
| 135 | |
| 136 // Each time we request an item from the cache, we tag it with a | |
| 137 // generation number. During playback, multiple fetches for the same | |
| 138 // item will use the same generation number and pull the proper | |
| 139 // instance of an URL from the cache. | |
| 140 int generation = 0; | |
| 141 DCHECK(playback_cache_map_ != NULL); | |
| 142 if (playback_cache_map_->find(url) != playback_cache_map_->end()) | |
| 143 generation = (*playback_cache_map_)[url]; | |
| 144 (*playback_cache_map_)[url] = generation + 1; | |
| 145 | |
| 146 // The key into the cache is GENERATION # + METHOD + URL. | |
| 147 std::string result = IntToString(generation); | |
| 148 result.append(request->method); | |
| 149 result.append(url); | |
| 150 return result; | |
| 151 } | |
| 152 | |
| 153 //----------------------------------------------------------------------------- | 121 //----------------------------------------------------------------------------- |
| 154 | 122 |
| 155 HttpCache::ActiveEntry::ActiveEntry(disk_cache::Entry* e) | 123 HttpCache::ActiveEntry::ActiveEntry(disk_cache::Entry* e) |
| 156 : disk_entry(e), | 124 : disk_entry(e), |
| 157 writer(NULL), | 125 writer(NULL), |
| 158 will_process_pending_queue(false), | 126 will_process_pending_queue(false), |
| 159 doomed(false) { | 127 doomed(false) { |
| 160 } | 128 } |
| 161 | 129 |
| 162 HttpCache::ActiveEntry::~ActiveEntry() { | 130 HttpCache::ActiveEntry::~ActiveEntry() { |
| (...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 return true; | 628 return true; |
| 661 | 629 |
| 662 // When using the record/playback modes, we always use the cache | 630 // When using the record/playback modes, we always use the cache |
| 663 // and we never pass through. | 631 // and we never pass through. |
| 664 if (cache_->mode() == RECORD || cache_->mode() == PLAYBACK) | 632 if (cache_->mode() == RECORD || cache_->mode() == PLAYBACK) |
| 665 return false; | 633 return false; |
| 666 | 634 |
| 667 if (effective_load_flags_ & LOAD_DISABLE_CACHE) | 635 if (effective_load_flags_ & LOAD_DISABLE_CACHE) |
| 668 return true; | 636 return true; |
| 669 | 637 |
| 670 // TODO(darin): add support for caching HEAD and POST responses | 638 if (request_->method == "GET") |
| 671 if (request_->method != "GET") | 639 return false; |
| 672 return true; | |
| 673 | 640 |
| 674 return false; | 641 if (request_->method == "POST" && |
| 642 request_->upload_data && request_->upload_data->identifier()) |
| 643 return false; |
| 644 |
| 645 // TODO(darin): add support for caching HEAD responses |
| 646 return true; |
| 675 } | 647 } |
| 676 | 648 |
| 677 int HttpCache::Transaction::BeginCacheRead() { | 649 int HttpCache::Transaction::BeginCacheRead() { |
| 678 DCHECK(mode_ == READ); | 650 DCHECK(mode_ == READ); |
| 679 | 651 |
| 680 // read response headers | 652 // read response headers |
| 681 return HandleResult(ReadResponseInfoFromEntry()); | 653 return HandleResult(ReadResponseInfoFromEntry()); |
| 682 } | 654 } |
| 683 | 655 |
| 684 int HttpCache::Transaction::BeginCacheValidation() { | 656 int HttpCache::Transaction::BeginCacheValidation() { |
| (...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1200 response_info->vary_data.Persist(&pickle); | 1172 response_info->vary_data.Persist(&pickle); |
| 1201 | 1173 |
| 1202 scoped_refptr<WrappedIOBuffer> data = new WrappedIOBuffer( | 1174 scoped_refptr<WrappedIOBuffer> data = new WrappedIOBuffer( |
| 1203 reinterpret_cast<const char*>(pickle.data())); | 1175 reinterpret_cast<const char*>(pickle.data())); |
| 1204 int len = static_cast<int>(pickle.size()); | 1176 int len = static_cast<int>(pickle.size()); |
| 1205 | 1177 |
| 1206 return disk_entry->WriteData(kResponseInfoIndex, 0, data, len, NULL, | 1178 return disk_entry->WriteData(kResponseInfoIndex, 0, data, len, NULL, |
| 1207 true) == len; | 1179 true) == len; |
| 1208 } | 1180 } |
| 1209 | 1181 |
| 1182 // Generate a key that can be used inside the cache. |
| 1183 std::string HttpCache::GenerateCacheKey(const HttpRequestInfo* request) { |
| 1184 std::string url = request->url.spec(); |
| 1185 if (request->url.has_ref()) |
| 1186 url.erase(url.find_last_of('#')); |
| 1187 |
| 1188 if (mode_ == NORMAL) { |
| 1189 // No valid URL can begin with numerals, so we should not have to worry |
| 1190 // about collisions with normal URLs. |
| 1191 if (request->upload_data && request->upload_data->identifier()) |
| 1192 url.insert(0, StringPrintf("%lld/", request->upload_data->identifier())); |
| 1193 return url; |
| 1194 } |
| 1195 |
| 1196 // In playback and record mode, we cache everything. |
| 1197 |
| 1198 // Lazily initialize. |
| 1199 if (playback_cache_map_ == NULL) |
| 1200 playback_cache_map_.reset(new PlaybackCacheMap()); |
| 1201 |
| 1202 // Each time we request an item from the cache, we tag it with a |
| 1203 // generation number. During playback, multiple fetches for the same |
| 1204 // item will use the same generation number and pull the proper |
| 1205 // instance of an URL from the cache. |
| 1206 int generation = 0; |
| 1207 DCHECK(playback_cache_map_ != NULL); |
| 1208 if (playback_cache_map_->find(url) != playback_cache_map_->end()) |
| 1209 generation = (*playback_cache_map_)[url]; |
| 1210 (*playback_cache_map_)[url] = generation + 1; |
| 1211 |
| 1212 // The key into the cache is GENERATION # + METHOD + URL. |
| 1213 std::string result = IntToString(generation); |
| 1214 result.append(request->method); |
| 1215 result.append(url); |
| 1216 return result; |
| 1217 } |
| 1218 |
| 1210 void HttpCache::DoomEntry(const std::string& key) { | 1219 void HttpCache::DoomEntry(const std::string& key) { |
| 1211 // Need to abandon the ActiveEntry, but any transaction attached to the entry | 1220 // Need to abandon the ActiveEntry, but any transaction attached to the entry |
| 1212 // should not be impacted. Dooming an entry only means that it will no | 1221 // should not be impacted. Dooming an entry only means that it will no |
| 1213 // longer be returned by FindActiveEntry (and it will also be destroyed once | 1222 // longer be returned by FindActiveEntry (and it will also be destroyed once |
| 1214 // all consumers are finished with the entry). | 1223 // all consumers are finished with the entry). |
| 1215 ActiveEntriesMap::iterator it = active_entries_.find(key); | 1224 ActiveEntriesMap::iterator it = active_entries_.find(key); |
| 1216 if (it == active_entries_.end()) { | 1225 if (it == active_entries_.end()) { |
| 1217 disk_cache_->DoomEntry(key); | 1226 disk_cache_->DoomEntry(key); |
| 1218 } else { | 1227 } else { |
| 1219 ActiveEntry* entry = it->second; | 1228 ActiveEntry* entry = it->second; |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1468 return; // have to wait | 1477 return; // have to wait |
| 1469 | 1478 |
| 1470 entry->pending_queue.erase(entry->pending_queue.begin()); | 1479 entry->pending_queue.erase(entry->pending_queue.begin()); |
| 1471 | 1480 |
| 1472 AddTransactionToEntry(entry, next); | 1481 AddTransactionToEntry(entry, next); |
| 1473 } | 1482 } |
| 1474 | 1483 |
| 1475 //----------------------------------------------------------------------------- | 1484 //----------------------------------------------------------------------------- |
| 1476 | 1485 |
| 1477 } // namespace net | 1486 } // namespace net |
| OLD | NEW |