| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |