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

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

Issue 197016: Http Cache: Add support for resuming downloading a... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 3 months 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.h ('k') | net/http/http_cache_unittest.cc » ('j') | 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.h" 5 #include "net/http/http_cache.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 // This bit is set if the response info has a security-bits field (security 57 // This bit is set if the response info has a security-bits field (security
58 // strength, in bits, of the SSL connection) at the end. 58 // strength, in bits, of the SSL connection) at the end.
59 RESPONSE_INFO_HAS_SECURITY_BITS = 1 << 9, 59 RESPONSE_INFO_HAS_SECURITY_BITS = 1 << 9,
60 60
61 // This bit is set if the response info has a cert status at the end. 61 // This bit is set if the response info has a cert status at the end.
62 RESPONSE_INFO_HAS_CERT_STATUS = 1 << 10, 62 RESPONSE_INFO_HAS_CERT_STATUS = 1 << 10,
63 63
64 // This bit is set if the response info has vary header data. 64 // This bit is set if the response info has vary header data.
65 RESPONSE_INFO_HAS_VARY_DATA = 1 << 11, 65 RESPONSE_INFO_HAS_VARY_DATA = 1 << 11,
66 66
67 // TODO(darin): Add other bits to indicate alternate request methods and 67 // This bit is set if the request was cancelled before completion.
68 // whether or not we are storing a partial document. For now, we don't 68 RESPONSE_INFO_TRUNCATED = 1 << 12,
69 // support storing those. 69
70 // TODO(darin): Add other bits to indicate alternate request methods.
71 // For now, we don't support storing those.
70 }; 72 };
71 73
72 //----------------------------------------------------------------------------- 74 //-----------------------------------------------------------------------------
73 75
74 struct HeaderNameAndValue { 76 struct HeaderNameAndValue {
75 const char* name; 77 const char* name;
76 const char* value; 78 const char* value;
77 }; 79 };
78 80
79 // If the request includes one of these request headers, then avoid caching 81 // If the request includes one of these request headers, then avoid caching
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 : RevocableStore::Revocable(&cache->transactions_), 174 : RevocableStore::Revocable(&cache->transactions_),
173 request_(NULL), 175 request_(NULL),
174 cache_(cache), 176 cache_(cache),
175 entry_(NULL), 177 entry_(NULL),
176 network_trans_(NULL), 178 network_trans_(NULL),
177 callback_(NULL), 179 callback_(NULL),
178 mode_(NONE), 180 mode_(NONE),
179 reading_(false), 181 reading_(false),
180 invalid_range_(false), 182 invalid_range_(false),
181 enable_range_support_(enable_range_support), 183 enable_range_support_(enable_range_support),
184 truncated_(false),
182 read_offset_(0), 185 read_offset_(0),
183 effective_load_flags_(0), 186 effective_load_flags_(0),
184 final_upload_progress_(0), 187 final_upload_progress_(0),
185 ALLOW_THIS_IN_INITIALIZER_LIST( 188 ALLOW_THIS_IN_INITIALIZER_LIST(
186 network_info_callback_(this, &Transaction::OnNetworkInfoAvailable)), 189 network_info_callback_(this, &Transaction::OnNetworkInfoAvailable)),
187 ALLOW_THIS_IN_INITIALIZER_LIST( 190 ALLOW_THIS_IN_INITIALIZER_LIST(
188 network_read_callback_(this, &Transaction::OnNetworkReadCompleted)), 191 network_read_callback_(this, &Transaction::OnNetworkReadCompleted)),
189 ALLOW_THIS_IN_INITIALIZER_LIST( 192 ALLOW_THIS_IN_INITIALIZER_LIST(
190 cache_read_callback_(new CancelableCompletionCallback<Transaction>( 193 cache_read_callback_(new CancelableCompletionCallback<Transaction>(
191 this, &Transaction::OnCacheReadCompleted))) { 194 this, &Transaction::OnCacheReadCompleted))) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 244
242 const std::string& key() const { return cache_key_; } 245 const std::string& key() const { return cache_key_; }
243 246
244 // Associates this transaction with a cache entry. 247 // Associates this transaction with a cache entry.
245 int AddToEntry(); 248 int AddToEntry();
246 249
247 // Called by the HttpCache when the given disk cache entry becomes accessible 250 // Called by the HttpCache when the given disk cache entry becomes accessible
248 // to the transaction. Returns network error code. 251 // to the transaction. Returns network error code.
249 int EntryAvailable(ActiveEntry* entry); 252 int EntryAvailable(ActiveEntry* entry);
250 253
254 // This transaction is being deleted and we are not done writing to the cache.
255 // We need to indicate that the response data was truncated.
256 void AddTruncatedFlag();
257
251 private: 258 private:
252 // This is a helper function used to trigger a completion callback. It may 259 // This is a helper function used to trigger a completion callback. It may
253 // only be called if callback_ is non-null. 260 // only be called if callback_ is non-null.
254 void DoCallback(int rv); 261 void DoCallback(int rv);
255 262
256 // This will trigger the completion callback if appropriate. 263 // This will trigger the completion callback if appropriate.
257 int HandleResult(int rv); 264 int HandleResult(int rv);
258 265
259 // Sets request_ and fields derived from it. 266 // Sets request_ and fields derived from it.
260 void SetRequest(LoadLog* load_log, const HttpRequestInfo* request); 267 void SetRequest(LoadLog* load_log, const HttpRequestInfo* request);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 int ReadFromEntry(IOBuffer* data, int data_len); 327 int ReadFromEntry(IOBuffer* data, int data_len);
321 328
322 // Called to populate response_ from the cache entry. 329 // Called to populate response_ from the cache entry.
323 int ReadResponseInfoFromEntry(); 330 int ReadResponseInfoFromEntry();
324 331
325 // Called to write data to the cache entry. If the write fails, then the 332 // Called to write data to the cache entry. If the write fails, then the
326 // cache entry is destroyed. Future calls to this function will just do 333 // cache entry is destroyed. Future calls to this function will just do
327 // nothing without side-effect. 334 // nothing without side-effect.
328 void WriteToEntry(int index, int offset, IOBuffer* data, int data_len); 335 void WriteToEntry(int index, int offset, IOBuffer* data, int data_len);
329 336
330 // Called to write response_ to the cache entry. 337 // Called to write response_ to the cache entry. |truncated| indicates if the
331 void WriteResponseInfoToEntry(); 338 // entry should be marked as incomplete.
339 void WriteResponseInfoToEntry(bool truncated);
332 340
333 // Called to append response data to the cache entry. 341 // Called to append response data to the cache entry.
334 void AppendResponseDataToEntry(IOBuffer* data, int data_len); 342 void AppendResponseDataToEntry(IOBuffer* data, int data_len);
335 343
336 // Called to truncate response content in the entry. 344 // Called to truncate response content in the entry.
337 void TruncateResponseData(); 345 void TruncateResponseData();
338 346
339 // Called when we are done writing to the cache entry. 347 // Called when we are done writing to the cache entry.
340 void DoneWritingToEntry(bool success); 348 void DoneWritingToEntry(bool success);
341 349
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 HttpCache::ActiveEntry* entry_; 384 HttpCache::ActiveEntry* entry_;
377 scoped_ptr<HttpTransaction> network_trans_; 385 scoped_ptr<HttpTransaction> network_trans_;
378 CompletionCallback* callback_; // Consumer's callback. 386 CompletionCallback* callback_; // Consumer's callback.
379 HttpResponseInfo response_; 387 HttpResponseInfo response_;
380 HttpResponseInfo auth_response_; 388 HttpResponseInfo auth_response_;
381 std::string cache_key_; 389 std::string cache_key_;
382 Mode mode_; 390 Mode mode_;
383 bool reading_; // We are already reading. 391 bool reading_; // We are already reading.
384 bool invalid_range_; // We may bypass the cache for this request. 392 bool invalid_range_; // We may bypass the cache for this request.
385 bool enable_range_support_; 393 bool enable_range_support_;
394 bool truncated_; // We don't have all the response data.
386 scoped_refptr<IOBuffer> read_buf_; 395 scoped_refptr<IOBuffer> read_buf_;
387 int read_buf_len_; 396 int read_buf_len_;
388 int read_offset_; 397 int read_offset_;
389 int effective_load_flags_; 398 int effective_load_flags_;
390 scoped_ptr<PartialData> partial_; // We are dealing with range requests. 399 scoped_ptr<PartialData> partial_; // We are dealing with range requests.
391 uint64 final_upload_progress_; 400 uint64 final_upload_progress_;
392 CompletionCallbackImpl<Transaction> network_info_callback_; 401 CompletionCallbackImpl<Transaction> network_info_callback_;
393 CompletionCallbackImpl<Transaction> network_read_callback_; 402 CompletionCallbackImpl<Transaction> network_read_callback_;
394 scoped_refptr<CancelableCompletionCallback<Transaction> > 403 scoped_refptr<CancelableCompletionCallback<Transaction> >
395 cache_read_callback_; 404 cache_read_callback_;
396 }; 405 };
397 406
398 HttpCache::Transaction::~Transaction() { 407 HttpCache::Transaction::~Transaction() {
399 if (!revoked()) { 408 if (!revoked()) {
400 if (entry_) { 409 if (entry_) {
401 cache_->DoneWithEntry(entry_, this); 410 bool cancel_request = reading_ && !partial_.get() &&
411 enable_range_support_ &&
412 response_.headers->response_code() == 200;
413
414 cache_->DoneWithEntry(entry_, this, cancel_request);
402 } else { 415 } else {
403 cache_->RemovePendingTransaction(this); 416 cache_->RemovePendingTransaction(this);
404 } 417 }
405 } 418 }
406 419
407 // If there is an outstanding callback, mark it as cancelled so running it 420 // If there is an outstanding callback, mark it as cancelled so running it
408 // does nothing. 421 // does nothing.
409 cache_read_callback_->Cancel(); 422 cache_read_callback_->Cancel();
410 423
411 // We could still have a cache read in progress, so we just null the cache_ 424 // We could still have a cache read in progress, so we just null the cache_
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 564
552 // If we have an intermediate auth response at this point, then it means the 565 // If we have an intermediate auth response at this point, then it means the
553 // user wishes to read the network response (the error page). If there is a 566 // user wishes to read the network response (the error page). If there is a
554 // previous response in the cache then we should leave it intact. 567 // previous response in the cache then we should leave it intact.
555 if (auth_response_.headers && mode_ != NONE) { 568 if (auth_response_.headers && mode_ != NONE) {
556 DCHECK(mode_ & WRITE); 569 DCHECK(mode_ & WRITE);
557 DoneWritingToEntry(mode_ == READ_WRITE); 570 DoneWritingToEntry(mode_ == READ_WRITE);
558 mode_ = NONE; 571 mode_ = NONE;
559 } 572 }
560 573
574 reading_ = true;
561 int rv; 575 int rv;
562 576
563 switch (mode_) { 577 switch (mode_) {
564 case READ_WRITE: 578 case READ_WRITE:
565 DCHECK(partial_.get()); 579 DCHECK(partial_.get());
566 reading_ = true;
567 if (!network_trans_.get()) { 580 if (!network_trans_.get()) {
568 // We are just reading from the cache, but we may be writing later. 581 // We are just reading from the cache, but we may be writing later.
569 rv = ReadFromEntry(buf, buf_len); 582 rv = ReadFromEntry(buf, buf_len);
570 break; 583 break;
571 } 584 }
572 case NONE: 585 case NONE:
573 case WRITE: 586 case WRITE:
574 DCHECK(network_trans_.get()); 587 DCHECK(network_trans_.get());
575 rv = ReadFromNetwork(buf, buf_len); 588 rv = ReadFromNetwork(buf, buf_len);
576 break; 589 break;
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 case UPDATE: 703 case UPDATE:
691 rv = BeginExternallyConditionalizedRequest(); 704 rv = BeginExternallyConditionalizedRequest();
692 break; 705 break;
693 default: 706 default:
694 NOTREACHED(); 707 NOTREACHED();
695 rv = ERR_FAILED; 708 rv = ERR_FAILED;
696 } 709 }
697 return rv; 710 return rv;
698 } 711 }
699 712
713 void HttpCache::Transaction::AddTruncatedFlag() {
714 DCHECK(mode_ & WRITE);
715 truncated_ = true;
716 WriteResponseInfoToEntry(true);
717 }
718
700 void HttpCache::Transaction::DoCallback(int rv) { 719 void HttpCache::Transaction::DoCallback(int rv) {
701 DCHECK(rv != ERR_IO_PENDING); 720 DCHECK(rv != ERR_IO_PENDING);
702 DCHECK(callback_); 721 DCHECK(callback_);
703 722
704 // since Run may result in Read being called, clear callback_ up front. 723 // since Run may result in Read being called, clear callback_ up front.
705 CompletionCallback* c = callback_; 724 CompletionCallback* c = callback_;
706 callback_ = NULL; 725 callback_ = NULL;
707 c->Run(rv); 726 c->Run(rv);
708 } 727 }
709 728
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
870 int rv = ReadResponseInfoFromEntry(); 889 int rv = ReadResponseInfoFromEntry();
871 if (rv != OK) 890 if (rv != OK)
872 return HandleResult(rv); 891 return HandleResult(rv);
873 892
874 // We don't support any combination of LOAD_ONLY_FROM_CACHE and byte ranges. 893 // We don't support any combination of LOAD_ONLY_FROM_CACHE and byte ranges.
875 if (response_.headers->response_code() == 206 || partial_.get()) { 894 if (response_.headers->response_code() == 206 || partial_.get()) {
876 NOTREACHED(); 895 NOTREACHED();
877 return HandleResult(ERR_CACHE_MISS); 896 return HandleResult(ERR_CACHE_MISS);
878 } 897 }
879 898
899 // We don't have the whole resource.
900 if (truncated_)
901 return HandleResult(ERR_CACHE_MISS);
902
880 return HandleResult(rv); 903 return HandleResult(rv);
881 } 904 }
882 905
883 int HttpCache::Transaction::BeginCacheValidation() { 906 int HttpCache::Transaction::BeginCacheValidation() {
884 DCHECK(mode_ == READ_WRITE); 907 DCHECK(mode_ == READ_WRITE);
885 908
886 if ((effective_load_flags_ & LOAD_PREFERRING_CACHE || 909 if ((effective_load_flags_ & LOAD_PREFERRING_CACHE ||
887 !RequiresValidation()) && !partial_.get()) { 910 !RequiresValidation()) && !partial_.get()) {
888 cache_->ConvertWriterToReader(entry_); 911 cache_->ConvertWriterToReader(entry_);
889 mode_ = READ; 912 mode_ = READ;
(...skipping 11 matching lines...) Expand all
901 924
902 int HttpCache::Transaction::BeginPartialCacheValidation() { 925 int HttpCache::Transaction::BeginPartialCacheValidation() {
903 DCHECK(mode_ == READ_WRITE); 926 DCHECK(mode_ == READ_WRITE);
904 927
905 int rv = ReadResponseInfoFromEntry(); 928 int rv = ReadResponseInfoFromEntry();
906 if (rv != OK) { 929 if (rv != OK) {
907 DCHECK(rv != ERR_IO_PENDING); 930 DCHECK(rv != ERR_IO_PENDING);
908 return HandleResult(rv); 931 return HandleResult(rv);
909 } 932 }
910 933
911 if (response_.headers->response_code() != 206 && !partial_.get()) 934 if (response_.headers->response_code() != 206 && !partial_.get() &&
935 !truncated_)
912 return BeginCacheValidation(); 936 return BeginCacheValidation();
913 937
914 if (!enable_range_support_) 938 if (!enable_range_support_)
915 return BeginCacheValidation(); 939 return BeginCacheValidation();
916 940
917 bool byte_range_requested = partial_.get() != NULL; 941 bool byte_range_requested = partial_.get() != NULL;
918 if (!byte_range_requested) { 942 if (!byte_range_requested) {
919 // The request is not for a range, but we have stored just ranges. 943 // The request is not for a range, but we have stored just ranges.
920 partial_.reset(new PartialData()); 944 partial_.reset(new PartialData());
921 if (!custom_request_.get()) { 945 if (!custom_request_.get()) {
922 custom_request_.reset(new HttpRequestInfo(*request_)); 946 custom_request_.reset(new HttpRequestInfo(*request_));
923 request_ = custom_request_.get(); 947 request_ = custom_request_.get();
924 DCHECK(custom_request_->extra_headers.empty()); 948 DCHECK(custom_request_->extra_headers.empty());
925 } 949 }
926 } 950 }
927 951
928 if (!partial_->UpdateFromStoredHeaders(response_.headers, 952 if (!partial_->UpdateFromStoredHeaders(response_.headers, entry_->disk_entry,
929 entry_->disk_entry)) { 953 truncated_)) {
930 // The stored data cannot be used. Get rid of it and restart this request. 954 // The stored data cannot be used. Get rid of it and restart this request.
931 DoomPartialEntry(!byte_range_requested); 955 DoomPartialEntry(!byte_range_requested);
932 mode_ = WRITE; 956 mode_ = WRITE;
933 return AddToEntry(); 957 return AddToEntry();
934 } 958 }
935 959
936 if (!partial_->IsRequestedRangeOK()) { 960 if (!partial_->IsRequestedRangeOK()) {
937 // The stored data is fine, but the request may be invalid. 961 // The stored data is fine, but the request may be invalid.
938 invalid_range_ = true; 962 invalid_range_ = true;
939 } 963 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
980 } 1004 }
981 1005
982 // Retrieve either the cached response's "etag" or "last-modified" header, 1006 // Retrieve either the cached response's "etag" or "last-modified" header,
983 // depending on which is applicable for the caller's request header. 1007 // depending on which is applicable for the caller's request header.
984 std::string validator; 1008 std::string validator;
985 response_.headers->EnumerateHeader( 1009 response_.headers->EnumerateHeader(
986 NULL, 1010 NULL,
987 external_validation_.type_info().related_response_header_name, 1011 external_validation_.type_info().related_response_header_name,
988 &validator); 1012 &validator);
989 1013
990 if (response_.headers->response_code() != 200 || 1014 if (response_.headers->response_code() != 200 || truncated_ ||
991 validator.empty() || 1015 validator.empty() || validator != external_validation_.value) {
992 validator != external_validation_.value) {
993 // The externally conditionalized request is not a validation request 1016 // The externally conditionalized request is not a validation request
994 // for our existing cache entry. Proceed with caching disabled. 1017 // for our existing cache entry. Proceed with caching disabled.
995 DoneWritingToEntry(true); 1018 DoneWritingToEntry(true);
996 } 1019 }
997 1020
998 return BeginNetworkRequest(); 1021 return BeginNetworkRequest();
999 } 1022 }
1000 1023
1001 int HttpCache::Transaction::BeginNetworkRequest() { 1024 int HttpCache::Transaction::BeginNetworkRequest() {
1002 DCHECK(mode_ & WRITE || mode_ == NONE); 1025 DCHECK(mode_ & WRITE || mode_ == NONE);
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
1244 rv = DoCacheReadCompleted(rv); 1267 rv = DoCacheReadCompleted(rv);
1245 } else if (rv != ERR_IO_PENDING) { 1268 } else if (rv != ERR_IO_PENDING) {
1246 cache_read_callback_->Release(); 1269 cache_read_callback_->Release();
1247 } 1270 }
1248 return rv; 1271 return rv;
1249 } 1272 }
1250 1273
1251 int HttpCache::Transaction::ReadResponseInfoFromEntry() { 1274 int HttpCache::Transaction::ReadResponseInfoFromEntry() {
1252 DCHECK(entry_); 1275 DCHECK(entry_);
1253 1276
1254 if (!HttpCache::ReadResponseInfo(entry_->disk_entry, &response_)) 1277 if (!HttpCache::ReadResponseInfo(entry_->disk_entry, &response_, &truncated_))
1255 return ERR_CACHE_READ_FAILURE; 1278 return ERR_CACHE_READ_FAILURE;
1256 return OK; 1279 return OK;
1257 } 1280 }
1258 1281
1259 void HttpCache::Transaction::WriteToEntry(int index, int offset, 1282 void HttpCache::Transaction::WriteToEntry(int index, int offset,
1260 IOBuffer* data, int data_len) { 1283 IOBuffer* data, int data_len) {
1261 if (!entry_) 1284 if (!entry_)
1262 return; 1285 return;
1263 1286
1264 int rv = 0; 1287 int rv = 0;
1265 if (!partial_.get() || !data_len) { 1288 if (!partial_.get() || !data_len) {
1266 rv = entry_->disk_entry->WriteData(index, offset, data, data_len, NULL, 1289 rv = entry_->disk_entry->WriteData(index, offset, data, data_len, NULL,
1267 true); 1290 true);
1268 } else { 1291 } else {
1269 rv = partial_->CacheWrite(entry_->disk_entry, data, data_len, NULL); 1292 rv = partial_->CacheWrite(entry_->disk_entry, data, data_len, NULL);
1270 } 1293 }
1271 if (rv != data_len) { 1294 if (rv != data_len) {
1272 DLOG(ERROR) << "failed to write response data to cache"; 1295 DLOG(ERROR) << "failed to write response data to cache";
1273 DoneWritingToEntry(false); 1296 DoneWritingToEntry(false);
1274 } 1297 }
1275 } 1298 }
1276 1299
1277 void HttpCache::Transaction::WriteResponseInfoToEntry() { 1300 void HttpCache::Transaction::WriteResponseInfoToEntry(bool truncated) {
1278 if (!entry_) 1301 if (!entry_)
1279 return; 1302 return;
1280 1303
1281 // Do not cache no-store content (unless we are record mode). Do not cache 1304 // Do not cache no-store content (unless we are record mode). Do not cache
1282 // content with cert errors either. This is to prevent not reporting net 1305 // content with cert errors either. This is to prevent not reporting net
1283 // errors when loading a resource from the cache. When we load a page over 1306 // errors when loading a resource from the cache. When we load a page over
1284 // HTTPS with a cert error we show an SSL blocking page. If the user clicks 1307 // HTTPS with a cert error we show an SSL blocking page. If the user clicks
1285 // proceed we reload the resource ignoring the errors. The loaded resource 1308 // proceed we reload the resource ignoring the errors. The loaded resource
1286 // is then cached. If that resource is subsequently loaded from the cache, 1309 // is then cached. If that resource is subsequently loaded from the cache,
1287 // no net error is reported (even though the cert status contains the actual 1310 // no net error is reported (even though the cert status contains the actual
1288 // errors) and no SSL blocking page is shown. An alternative would be to 1311 // errors) and no SSL blocking page is shown. An alternative would be to
1289 // reverse-map the cert status to a net error and replay the net error. 1312 // reverse-map the cert status to a net error and replay the net error.
1290 if ((cache_->mode() != RECORD && 1313 if ((cache_->mode() != RECORD &&
1291 response_.headers->HasHeaderValue("cache-control", "no-store")) || 1314 response_.headers->HasHeaderValue("cache-control", "no-store")) ||
1292 net::IsCertStatusError(response_.ssl_info.cert_status)) { 1315 net::IsCertStatusError(response_.ssl_info.cert_status)) {
1293 DoneWritingToEntry(false); 1316 DoneWritingToEntry(false);
1294 return; 1317 return;
1295 } 1318 }
1296 1319
1297 // When writing headers, we normally only write the non-transient 1320 // When writing headers, we normally only write the non-transient
1298 // headers; when in record mode, record everything. 1321 // headers; when in record mode, record everything.
1299 bool skip_transient_headers = (cache_->mode() != RECORD); 1322 bool skip_transient_headers = (cache_->mode() != RECORD);
1300 1323
1324 if (truncated) {
1325 DCHECK_EQ(200, response_.headers->response_code());
1326 }
1327
1301 if (!HttpCache::WriteResponseInfo(entry_->disk_entry, &response_, 1328 if (!HttpCache::WriteResponseInfo(entry_->disk_entry, &response_,
1302 skip_transient_headers)) { 1329 skip_transient_headers, truncated)) {
1303 DLOG(ERROR) << "failed to write response info to cache"; 1330 DLOG(ERROR) << "failed to write response info to cache";
1304 DoneWritingToEntry(false); 1331 DoneWritingToEntry(false);
1305 } 1332 }
1306 } 1333 }
1307 1334
1308 void HttpCache::Transaction::AppendResponseDataToEntry(IOBuffer* data, 1335 void HttpCache::Transaction::AppendResponseDataToEntry(IOBuffer* data,
1309 int data_len) { 1336 int data_len) {
1310 if (!entry_ || !data_len) 1337 if (!entry_ || !data_len)
1311 return; 1338 return;
1312 1339
(...skipping 16 matching lines...) Expand all
1329 if (cache_->mode() == RECORD) 1356 if (cache_->mode() == RECORD)
1330 DLOG(INFO) << "Recorded: " << request_->method << request_->url 1357 DLOG(INFO) << "Recorded: " << request_->method << request_->url
1331 << " status: " << response_.headers->response_code(); 1358 << " status: " << response_.headers->response_code();
1332 1359
1333 cache_->DoneWritingToEntry(entry_, success); 1360 cache_->DoneWritingToEntry(entry_, success);
1334 entry_ = NULL; 1361 entry_ = NULL;
1335 mode_ = NONE; // switch to 'pass through' mode 1362 mode_ = NONE; // switch to 'pass through' mode
1336 } 1363 }
1337 1364
1338 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) { 1365 void HttpCache::Transaction::DoomPartialEntry(bool delete_object) {
1339 cache_->DoneWithEntry(entry_, this); 1366 cache_->DoneWithEntry(entry_, this, false);
1340 cache_->DoomEntry(cache_key_); 1367 cache_->DoomEntry(cache_key_);
1341 entry_ = NULL; 1368 entry_ = NULL;
1342 if (delete_object) 1369 if (delete_object)
1343 partial_.reset(NULL); 1370 partial_.reset(NULL);
1344 } 1371 }
1345 1372
1346 int HttpCache::Transaction::DoNetworkReadCompleted(int result) { 1373 int HttpCache::Transaction::DoNetworkReadCompleted(int result) {
1347 DCHECK(mode_ & WRITE || mode_ == NONE); 1374 DCHECK(mode_ & WRITE || mode_ == NONE);
1348 1375
1349 if (revoked()) 1376 if (revoked())
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1422 return; 1449 return;
1423 } 1450 }
1424 1451
1425 if (result == OK) { 1452 if (result == OK) {
1426 const HttpResponseInfo* new_response = network_trans_->GetResponseInfo(); 1453 const HttpResponseInfo* new_response = network_trans_->GetResponseInfo();
1427 if (new_response->headers->response_code() == 401 || 1454 if (new_response->headers->response_code() == 401 ||
1428 new_response->headers->response_code() == 407) { 1455 new_response->headers->response_code() == 407) {
1429 auth_response_ = *new_response; 1456 auth_response_ = *new_response;
1430 } else { 1457 } else {
1431 bool partial_content = ValidatePartialResponse(new_response->headers); 1458 bool partial_content = ValidatePartialResponse(new_response->headers);
1432 if (partial_content && mode_ == READ_WRITE && 1459 if (partial_content && mode_ == READ_WRITE && !truncated_ &&
1433 response_.headers->response_code() == 200) { 1460 response_.headers->response_code() == 200) {
1434 // We have stored the full entry, but it changed and the server is 1461 // We have stored the full entry, but it changed and the server is
1435 // sending a range. We have to delete the old entry. 1462 // sending a range. We have to delete the old entry.
1436 DoneWritingToEntry(false); 1463 DoneWritingToEntry(false);
1437 } 1464 }
1438 1465
1439 // Are we expecting a response to a conditional query? 1466 // Are we expecting a response to a conditional query?
1440 if (mode_ == READ_WRITE || mode_ == UPDATE) { 1467 if (mode_ == READ_WRITE || mode_ == UPDATE) {
1441 if (new_response->headers->response_code() == 304 || partial_content) { 1468 if (new_response->headers->response_code() == 304 || partial_content) {
1442 // Update cached response based on headers in new_response. 1469 // Update cached response based on headers in new_response.
1443 // TODO(wtc): should we update cached certificate 1470 // TODO(wtc): should we update cached certificate
1444 // (response_.ssl_info), too? 1471 // (response_.ssl_info), too?
1445 response_.headers->Update(*new_response->headers); 1472 response_.headers->Update(*new_response->headers);
1446 response_.response_time = new_response->response_time; 1473 response_.response_time = new_response->response_time;
1447 response_.request_time = new_response->request_time; 1474 response_.request_time = new_response->request_time;
1448 1475
1449 if (response_.headers->HasHeaderValue("cache-control", "no-store")) { 1476 if (response_.headers->HasHeaderValue("cache-control", "no-store")) {
1450 cache_->DoomEntry(cache_key_); 1477 cache_->DoomEntry(cache_key_);
1451 } else { 1478 } else {
1452 // If we are already reading, we already updated the headers for 1479 // If we are already reading, we already updated the headers for
1453 // this request; doing it again will change Content-Length. 1480 // this request; doing it again will change Content-Length.
1454 if (!reading_) 1481 if (!reading_)
1455 WriteResponseInfoToEntry(); 1482 WriteResponseInfoToEntry(false);
1456 } 1483 }
1457 1484
1458 if (mode_ == UPDATE) { 1485 if (mode_ == UPDATE) {
1459 DCHECK(!partial_content); 1486 DCHECK(!partial_content);
1460 // We got a "not modified" response and already updated the 1487 // We got a "not modified" response and already updated the
1461 // corresponding cache entry above. 1488 // corresponding cache entry above.
1462 // 1489 //
1463 // By closing the cached entry now, we make sure that the 1490 // By closing the cached entry now, we make sure that the
1464 // 304 rather than the cached 200 response, is what will be 1491 // 304 rather than the cached 200 response, is what will be
1465 // returned to the user. 1492 // returned to the user.
(...skipping 12 matching lines...) Expand all
1478 mode_ = WRITE; 1505 mode_ = WRITE;
1479 } 1506 }
1480 } 1507 }
1481 1508
1482 if (!(mode_ & READ)) { 1509 if (!(mode_ & READ)) {
1483 // We change the value of Content-Length for partial content. 1510 // We change the value of Content-Length for partial content.
1484 if (partial_content && partial_.get()) 1511 if (partial_content && partial_.get())
1485 partial_->FixContentLength(new_response->headers); 1512 partial_->FixContentLength(new_response->headers);
1486 1513
1487 response_ = *new_response; 1514 response_ = *new_response;
1488 WriteResponseInfoToEntry(); 1515 WriteResponseInfoToEntry(truncated_);
1489 1516
1490 // Truncate response data. 1517 // Truncate response data.
1491 TruncateResponseData(); 1518 TruncateResponseData();
1492 1519
1493 // If this response is a redirect, then we can stop writing now. (We 1520 // If this response is a redirect, then we can stop writing now. (We
1494 // don't need to cache the response body of a redirect.) 1521 // don't need to cache the response body of a redirect.)
1495 if (response_.headers->IsRedirect(NULL)) 1522 if (response_.headers->IsRedirect(NULL))
1496 DoneWritingToEntry(true); 1523 DoneWritingToEntry(true);
1497 } 1524 }
1498 if (reading_) { 1525 if (reading_ && partial_.get()) {
1499 DCHECK(partial_.get());
1500 if (network_trans_.get()) { 1526 if (network_trans_.get()) {
1501 result = ReadFromNetwork(read_buf_, read_buf_len_); 1527 result = ReadFromNetwork(read_buf_, read_buf_len_);
1502 } else { 1528 } else {
1503 result = ReadFromEntry(read_buf_, read_buf_len_); 1529 result = ReadFromEntry(read_buf_, read_buf_len_);
1504 } 1530 }
1505 if (result >= 0 || result == net::ERR_IO_PENDING) 1531 if (result >= 0 || result == net::ERR_IO_PENDING)
1506 return; 1532 return;
1507 } else if (partial_.get()) { 1533 } else if (partial_.get()) {
1508 // 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
1509 // user, so let's fix them. 1535 // user, so let's fix them.
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1629 HttpCache* HttpCache::GetCache() { 1655 HttpCache* HttpCache::GetCache() {
1630 return this; 1656 return this;
1631 } 1657 }
1632 1658
1633 void HttpCache::Suspend(bool suspend) { 1659 void HttpCache::Suspend(bool suspend) {
1634 network_layer_->Suspend(suspend); 1660 network_layer_->Suspend(suspend);
1635 } 1661 }
1636 1662
1637 // static 1663 // static
1638 bool HttpCache::ParseResponseInfo(const char* data, int len, 1664 bool HttpCache::ParseResponseInfo(const char* data, int len,
1639 HttpResponseInfo* response_info) { 1665 HttpResponseInfo* response_info,
1666 bool* response_truncated) {
1640 Pickle pickle(data, len); 1667 Pickle pickle(data, len);
1641 void* iter = NULL; 1668 void* iter = NULL;
1642 1669
1643 // read flags and verify version 1670 // read flags and verify version
1644 int flags; 1671 int flags;
1645 if (!pickle.ReadInt(&iter, &flags)) 1672 if (!pickle.ReadInt(&iter, &flags))
1646 return false; 1673 return false;
1647 int version = flags & RESPONSE_INFO_VERSION_MASK; 1674 int version = flags & RESPONSE_INFO_VERSION_MASK;
1648 if (version != RESPONSE_INFO_VERSION) { 1675 if (version != RESPONSE_INFO_VERSION) {
1649 DLOG(ERROR) << "unexpected response info version: " << version; 1676 DLOG(ERROR) << "unexpected response info version: " << version;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1683 return false; 1710 return false;
1684 response_info->ssl_info.security_bits = security_bits; 1711 response_info->ssl_info.security_bits = security_bits;
1685 } 1712 }
1686 1713
1687 // read vary-data 1714 // read vary-data
1688 if (flags & RESPONSE_INFO_HAS_VARY_DATA) { 1715 if (flags & RESPONSE_INFO_HAS_VARY_DATA) {
1689 if (!response_info->vary_data.InitFromPickle(pickle, &iter)) 1716 if (!response_info->vary_data.InitFromPickle(pickle, &iter))
1690 return false; 1717 return false;
1691 } 1718 }
1692 1719
1720 *response_truncated = (flags & RESPONSE_INFO_TRUNCATED) ? true : false;
1721
1693 return true; 1722 return true;
1694 } 1723 }
1695 1724
1696 // static 1725 // static
1697 bool HttpCache::ReadResponseInfo(disk_cache::Entry* disk_entry, 1726 bool HttpCache::ReadResponseInfo(disk_cache::Entry* disk_entry,
1698 HttpResponseInfo* response_info) { 1727 HttpResponseInfo* response_info,
1728 bool* response_truncated) {
1699 int size = disk_entry->GetDataSize(kResponseInfoIndex); 1729 int size = disk_entry->GetDataSize(kResponseInfoIndex);
1700 1730
1701 scoped_refptr<IOBuffer> buffer = new IOBuffer(size); 1731 scoped_refptr<IOBuffer> buffer = new IOBuffer(size);
1702 int rv = disk_entry->ReadData(kResponseInfoIndex, 0, buffer, size, NULL); 1732 int rv = disk_entry->ReadData(kResponseInfoIndex, 0, buffer, size, NULL);
1703 if (rv != size) { 1733 if (rv != size) {
1704 DLOG(ERROR) << "ReadData failed: " << rv; 1734 DLOG(ERROR) << "ReadData failed: " << rv;
1705 return false; 1735 return false;
1706 } 1736 }
1707 1737
1708 return ParseResponseInfo(buffer->data(), size, response_info); 1738 return ParseResponseInfo(buffer->data(), size, response_info,
1739 response_truncated);
1709 } 1740 }
1710 1741
1711 // static 1742 // static
1712 bool HttpCache::WriteResponseInfo(disk_cache::Entry* disk_entry, 1743 bool HttpCache::WriteResponseInfo(disk_cache::Entry* disk_entry,
1713 const HttpResponseInfo* response_info, 1744 const HttpResponseInfo* response_info,
1714 bool skip_transient_headers) { 1745 bool skip_transient_headers,
1746 bool response_truncated) {
1715 int flags = RESPONSE_INFO_VERSION; 1747 int flags = RESPONSE_INFO_VERSION;
1716 if (response_info->ssl_info.cert) { 1748 if (response_info->ssl_info.cert) {
1717 flags |= RESPONSE_INFO_HAS_CERT; 1749 flags |= RESPONSE_INFO_HAS_CERT;
1718 flags |= RESPONSE_INFO_HAS_CERT_STATUS; 1750 flags |= RESPONSE_INFO_HAS_CERT_STATUS;
1719 } 1751 }
1720 if (response_info->ssl_info.security_bits != -1) 1752 if (response_info->ssl_info.security_bits != -1)
1721 flags |= RESPONSE_INFO_HAS_SECURITY_BITS; 1753 flags |= RESPONSE_INFO_HAS_SECURITY_BITS;
1722 if (response_info->vary_data.is_valid()) 1754 if (response_info->vary_data.is_valid())
1723 flags |= RESPONSE_INFO_HAS_VARY_DATA; 1755 flags |= RESPONSE_INFO_HAS_VARY_DATA;
1756 if (response_truncated)
1757 flags |= RESPONSE_INFO_TRUNCATED;
1724 1758
1725 Pickle pickle; 1759 Pickle pickle;
1726 pickle.WriteInt(flags); 1760 pickle.WriteInt(flags);
1727 pickle.WriteInt64(response_info->request_time.ToInternalValue()); 1761 pickle.WriteInt64(response_info->request_time.ToInternalValue());
1728 pickle.WriteInt64(response_info->response_time.ToInternalValue()); 1762 pickle.WriteInt64(response_info->response_time.ToInternalValue());
1729 1763
1730 net::HttpResponseHeaders::PersistOptions persist_options = 1764 net::HttpResponseHeaders::PersistOptions persist_options =
1731 net::HttpResponseHeaders::PERSIST_RAW; 1765 net::HttpResponseHeaders::PERSIST_RAW;
1732 1766
1733 if (skip_transient_headers) { 1767 if (skip_transient_headers) {
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1935 1969
1936 // We do this before calling EntryAvailable to force any further calls to 1970 // We do this before calling EntryAvailable to force any further calls to
1937 // AddTransactionToEntry to add their transaction to the pending queue, which 1971 // AddTransactionToEntry to add their transaction to the pending queue, which
1938 // ensures FIFO ordering. 1972 // ensures FIFO ordering.
1939 if (!entry->writer && !entry->pending_queue.empty()) 1973 if (!entry->writer && !entry->pending_queue.empty())
1940 ProcessPendingQueue(entry); 1974 ProcessPendingQueue(entry);
1941 1975
1942 return trans->EntryAvailable(entry); 1976 return trans->EntryAvailable(entry);
1943 } 1977 }
1944 1978
1945 void HttpCache::DoneWithEntry(ActiveEntry* entry, Transaction* trans) { 1979 void HttpCache::DoneWithEntry(ActiveEntry* entry, Transaction* trans,
1980 bool cancel) {
1946 // If we already posted a task to move on to the next transaction and this was 1981 // If we already posted a task to move on to the next transaction and this was
1947 // the writer, there is nothing to cancel. 1982 // the writer, there is nothing to cancel.
1948 if (entry->will_process_pending_queue && entry->readers.empty()) 1983 if (entry->will_process_pending_queue && entry->readers.empty())
1949 return; 1984 return;
1950 1985
1951 if (entry->writer) { 1986 if (entry->writer) {
1952 DCHECK(trans == entry->writer); 1987 DCHECK(trans == entry->writer);
1953 1988
1954 // Assume that this is not a successful write. 1989 // Assume there was a failure.
1955 DoneWritingToEntry(entry, false); 1990 bool success = false;
1991 if (cancel) {
1992 DCHECK(entry->disk_entry);
1993 // This is a successful operation in the sense that we want to keep the
1994 // entry.
1995 success = true;
1996 // Double check that there is something worth keeping.
1997 if (!entry->disk_entry->GetDataSize(kResponseContentIndex))
1998 success = false;
1999 trans->AddTruncatedFlag();
2000 }
2001 DoneWritingToEntry(entry, success);
1956 } else { 2002 } else {
1957 DoneReadingFromEntry(entry, trans); 2003 DoneReadingFromEntry(entry, trans);
1958 } 2004 }
1959 } 2005 }
1960 2006
1961 void HttpCache::DoneWritingToEntry(ActiveEntry* entry, bool success) { 2007 void HttpCache::DoneWritingToEntry(ActiveEntry* entry, bool success) {
1962 DCHECK(entry->readers.empty()); 2008 DCHECK(entry->readers.empty());
1963 2009
1964 entry->writer = NULL; 2010 entry->writer = NULL;
1965 2011
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
2063 static_cast<net::HttpNetworkLayer*>(network_layer_.get()); 2109 static_cast<net::HttpNetworkLayer*>(network_layer_.get());
2064 HttpNetworkSession* session = network->GetSession(); 2110 HttpNetworkSession* session = network->GetSession();
2065 if (session) { 2111 if (session) {
2066 session->tcp_socket_pool()->CloseIdleSockets(); 2112 session->tcp_socket_pool()->CloseIdleSockets();
2067 } 2113 }
2068 } 2114 }
2069 2115
2070 //----------------------------------------------------------------------------- 2116 //-----------------------------------------------------------------------------
2071 2117
2072 } // namespace net 2118 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_cache.h ('k') | net/http/http_cache_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698