| 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 10 matching lines...) Expand all Loading... |
| 21 #include "net/base/load_flags.h" | 21 #include "net/base/load_flags.h" |
| 22 #include "net/base/net_errors.h" | 22 #include "net/base/net_errors.h" |
| 23 #include "net/disk_cache/disk_cache.h" | 23 #include "net/disk_cache/disk_cache.h" |
| 24 #include "net/http/http_network_layer.h" | 24 #include "net/http/http_network_layer.h" |
| 25 #include "net/http/http_network_session.h" | 25 #include "net/http/http_network_session.h" |
| 26 #include "net/http/http_request_info.h" | 26 #include "net/http/http_request_info.h" |
| 27 #include "net/http/http_response_headers.h" | 27 #include "net/http/http_response_headers.h" |
| 28 #include "net/http/http_response_info.h" | 28 #include "net/http/http_response_info.h" |
| 29 #include "net/http/http_transaction.h" | 29 #include "net/http/http_transaction.h" |
| 30 #include "net/http/http_util.h" | 30 #include "net/http/http_util.h" |
| 31 #include "net/http/partial_data.h" |
| 31 | 32 |
| 32 using base::Time; | 33 using base::Time; |
| 33 | 34 |
| 35 // Uncomment this to enable experimental byte-range support. |
| 36 // #define ENABLE_RANGE_SUPPORT |
| 37 |
| 34 namespace net { | 38 namespace net { |
| 35 | 39 |
| 36 // disk cache entry data indices. | 40 // disk cache entry data indices. |
| 37 enum { | 41 enum { |
| 38 kResponseInfoIndex, | 42 kResponseInfoIndex, |
| 39 kResponseContentIndex | 43 kResponseContentIndex |
| 40 }; | 44 }; |
| 41 | 45 |
| 42 // These values can be bit-wise combined to form the flags field of the | 46 // These values can be bit-wise combined to form the flags field of the |
| 43 // serialized HttpResponseInfo. | 47 // serialized HttpResponseInfo. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 69 //----------------------------------------------------------------------------- | 73 //----------------------------------------------------------------------------- |
| 70 | 74 |
| 71 struct HeaderNameAndValue { | 75 struct HeaderNameAndValue { |
| 72 const char* name; | 76 const char* name; |
| 73 const char* value; | 77 const char* value; |
| 74 }; | 78 }; |
| 75 | 79 |
| 76 // If the request includes one of these request headers, then avoid caching | 80 // If the request includes one of these request headers, then avoid caching |
| 77 // to avoid getting confused. | 81 // to avoid getting confused. |
| 78 static const HeaderNameAndValue kPassThroughHeaders[] = { | 82 static const HeaderNameAndValue kPassThroughHeaders[] = { |
| 79 { "range", NULL }, // causes unexpected 206s | |
| 80 { "if-modified-since", NULL }, // causes unexpected 304s | 83 { "if-modified-since", NULL }, // causes unexpected 304s |
| 81 { "if-none-match", NULL }, // causes unexpected 304s | 84 { "if-none-match", NULL }, // causes unexpected 304s |
| 82 { "if-unmodified-since", NULL }, // causes unexpected 412s | 85 { "if-unmodified-since", NULL }, // causes unexpected 412s |
| 83 { "if-match", NULL }, // causes unexpected 412s | 86 { "if-match", NULL }, // causes unexpected 412s |
| 84 { NULL, NULL } | 87 { NULL, NULL } |
| 85 }; | 88 }; |
| 86 | 89 |
| 87 // If the request includes one of these request headers, then avoid reusing | 90 // If the request includes one of these request headers, then avoid reusing |
| 88 // our cached copy if any. | 91 // our cached copy if any. |
| 89 static const HeaderNameAndValue kForceFetchHeaders[] = { | 92 static const HeaderNameAndValue kForceFetchHeaders[] = { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 112 while (v.GetNext()) { | 115 while (v.GetNext()) { |
| 113 if (LowerCaseEqualsASCII(v.value_begin(), v.value_end(), search->value)) | 116 if (LowerCaseEqualsASCII(v.value_begin(), v.value_end(), search->value)) |
| 114 return true; | 117 return true; |
| 115 } | 118 } |
| 116 } | 119 } |
| 117 return false; | 120 return false; |
| 118 } | 121 } |
| 119 | 122 |
| 120 //----------------------------------------------------------------------------- | 123 //----------------------------------------------------------------------------- |
| 121 | 124 |
| 122 //----------------------------------------------------------------------------- | |
| 123 | |
| 124 HttpCache::ActiveEntry::ActiveEntry(disk_cache::Entry* e) | 125 HttpCache::ActiveEntry::ActiveEntry(disk_cache::Entry* e) |
| 125 : disk_entry(e), | 126 : disk_entry(e), |
| 126 writer(NULL), | 127 writer(NULL), |
| 127 will_process_pending_queue(false), | 128 will_process_pending_queue(false), |
| 128 doomed(false) { | 129 doomed(false) { |
| 129 } | 130 } |
| 130 | 131 |
| 131 HttpCache::ActiveEntry::~ActiveEntry() { | 132 HttpCache::ActiveEntry::~ActiveEntry() { |
| 132 if (disk_entry) | 133 if (disk_entry) |
| 133 disk_entry->Close(); | 134 disk_entry->Close(); |
| 134 } | 135 } |
| 135 | 136 |
| 136 //----------------------------------------------------------------------------- | 137 //----------------------------------------------------------------------------- |
| 137 | 138 |
| 138 class HttpCache::Transaction | 139 class HttpCache::Transaction |
| 139 : public HttpTransaction, public RevocableStore::Revocable { | 140 : public HttpTransaction, public RevocableStore::Revocable { |
| 140 public: | 141 public: |
| 141 explicit Transaction(HttpCache* cache) | 142 explicit Transaction(HttpCache* cache) |
| 142 : RevocableStore::Revocable(&cache->transactions_), | 143 : RevocableStore::Revocable(&cache->transactions_), |
| 143 request_(NULL), | 144 request_(NULL), |
| 144 cache_(cache), | 145 cache_(cache), |
| 145 entry_(NULL), | 146 entry_(NULL), |
| 146 network_trans_(NULL), | 147 network_trans_(NULL), |
| 147 callback_(NULL), | 148 callback_(NULL), |
| 148 mode_(NONE), | 149 mode_(NONE), |
| 150 reading_(false), |
| 149 read_offset_(0), | 151 read_offset_(0), |
| 150 effective_load_flags_(0), | 152 effective_load_flags_(0), |
| 151 final_upload_progress_(0), | 153 final_upload_progress_(0), |
| 152 ALLOW_THIS_IN_INITIALIZER_LIST( | 154 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 153 network_info_callback_(this, &Transaction::OnNetworkInfoAvailable)), | 155 network_info_callback_(this, &Transaction::OnNetworkInfoAvailable)), |
| 154 ALLOW_THIS_IN_INITIALIZER_LIST( | 156 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 155 network_read_callback_(this, &Transaction::OnNetworkReadCompleted)), | 157 network_read_callback_(this, &Transaction::OnNetworkReadCompleted)), |
| 156 ALLOW_THIS_IN_INITIALIZER_LIST( | 158 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 157 cache_read_callback_(new CancelableCompletionCallback<Transaction>( | 159 cache_read_callback_(new CancelableCompletionCallback<Transaction>( |
| 158 this, &Transaction::OnCacheReadCompleted))) { | 160 this, &Transaction::OnCacheReadCompleted))) { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 | 226 |
| 225 // Returns true if we should force an end-to-end fetch. | 227 // Returns true if we should force an end-to-end fetch. |
| 226 bool ShouldBypassCache(); | 228 bool ShouldBypassCache(); |
| 227 | 229 |
| 228 // Called to begin reading from the cache. Returns network error code. | 230 // Called to begin reading from the cache. Returns network error code. |
| 229 int BeginCacheRead(); | 231 int BeginCacheRead(); |
| 230 | 232 |
| 231 // Called to begin validating the cache entry. Returns network error code. | 233 // Called to begin validating the cache entry. Returns network error code. |
| 232 int BeginCacheValidation(); | 234 int BeginCacheValidation(); |
| 233 | 235 |
| 236 // Called to begin validating an entry that stores partial content. Returns |
| 237 // a network error code. |
| 238 int BeginPartialCacheValidation(); |
| 239 |
| 240 // Performs the cache validation for the next chunk of data stored by the |
| 241 // cache. If this chunk is not currently stored, starts the network request |
| 242 // to fetch it. Returns a network error code. |
| 243 int ContinuePartialCacheValidation(); |
| 244 |
| 234 // Called to begin a network transaction. Returns network error code. | 245 // Called to begin a network transaction. Returns network error code. |
| 235 int BeginNetworkRequest(); | 246 int BeginNetworkRequest(); |
| 236 | 247 |
| 237 // Called to restart a network transaction after an error. Returns network | 248 // Called to restart a network transaction after an error. Returns network |
| 238 // error code. | 249 // error code. |
| 239 int RestartNetworkRequest(); | 250 int RestartNetworkRequest(); |
| 240 | 251 |
| 241 // Called to restart a network transaction with authentication credentials. | 252 // Called to restart a network transaction with authentication credentials. |
| 242 // Returns network error code. | 253 // Returns network error code. |
| 243 int RestartNetworkRequestWithAuth(const std::wstring& username, | 254 int RestartNetworkRequestWithAuth(const std::wstring& username, |
| 244 const std::wstring& password); | 255 const std::wstring& password); |
| 245 | 256 |
| 246 // Called to determine if we need to validate the cache entry before using it. | 257 // Called to determine if we need to validate the cache entry before using it. |
| 247 bool RequiresValidation(); | 258 bool RequiresValidation(); |
| 248 | 259 |
| 249 // Called to make the request conditional (to ask the server if the cached | 260 // Called to make the request conditional (to ask the server if the cached |
| 250 // copy is valid). Returns true if able to make the request conditional. | 261 // copy is valid). Returns true if able to make the request conditional. |
| 251 bool ConditionalizeRequest(); | 262 bool ConditionalizeRequest(); |
| 252 | 263 |
| 264 // Reads data from the network. |
| 265 int ReadFromNetwork(IOBuffer* data, int data_len); |
| 266 |
| 267 // Reads data from the cache entry. |
| 268 int ReadFromEntry(IOBuffer* data, int data_len); |
| 269 |
| 253 // Called to populate response_ from the cache entry. | 270 // Called to populate response_ from the cache entry. |
| 254 int ReadResponseInfoFromEntry(); | 271 int ReadResponseInfoFromEntry(); |
| 255 | 272 |
| 256 // Called to write data to the cache entry. If the write fails, then the | 273 // Called to write data to the cache entry. If the write fails, then the |
| 257 // cache entry is destroyed. Future calls to this function will just do | 274 // cache entry is destroyed. Future calls to this function will just do |
| 258 // nothing without side-effect. | 275 // nothing without side-effect. |
| 259 void WriteToEntry(int index, int offset, IOBuffer* data, int data_len); | 276 void WriteToEntry(int index, int offset, IOBuffer* data, int data_len); |
| 260 | 277 |
| 261 // Called to write response_ to the cache entry. | 278 // Called to write response_ to the cache entry. |
| 262 void WriteResponseInfoToEntry(); | 279 void WriteResponseInfoToEntry(); |
| 263 | 280 |
| 264 // Called to truncate response content in the entry. | 281 // Called to truncate response content in the entry. |
| 265 void TruncateResponseData(); | 282 void TruncateResponseData(); |
| 266 | 283 |
| 267 // Called to append response data to the cache entry. | 284 // Called to append response data to the cache entry. |
| 268 void AppendResponseDataToEntry(IOBuffer* data, int data_len); | 285 void AppendResponseDataToEntry(IOBuffer* data, int data_len); |
| 269 | 286 |
| 270 // Called when we are done writing to the cache entry. | 287 // Called when we are done writing to the cache entry. |
| 271 void DoneWritingToEntry(bool success); | 288 void DoneWritingToEntry(bool success); |
| 272 | 289 |
| 290 // Performs the needed work after receiving data from the network. |
| 291 int DoNetworkReadCompleted(int result); |
| 292 |
| 293 // Performs the needed work after receiving data from the network, when |
| 294 // working with range requests. |
| 295 int DoPartialNetworkReadCompleted(int result); |
| 296 |
| 297 // Performs the needed work after receiving data from the cache. |
| 298 int DoCacheReadCompleted(int result); |
| 299 |
| 300 // Performs the needed work after receiving data from the cache, when |
| 301 // working with range requests. |
| 302 int DoPartialCacheReadCompleted(int result); |
| 303 |
| 273 // Called to signal completion of the network transaction's Start method: | 304 // Called to signal completion of the network transaction's Start method: |
| 274 void OnNetworkInfoAvailable(int result); | 305 void OnNetworkInfoAvailable(int result); |
| 275 | 306 |
| 276 // Called to signal completion of the network transaction's Read method: | 307 // Called to signal completion of the network transaction's Read method: |
| 277 void OnNetworkReadCompleted(int result); | 308 void OnNetworkReadCompleted(int result); |
| 278 | 309 |
| 279 // Called to signal completion of the cache's ReadData method: | 310 // Called to signal completion of the cache's ReadData method: |
| 280 void OnCacheReadCompleted(int result); | 311 void OnCacheReadCompleted(int result); |
| 281 | 312 |
| 282 const HttpRequestInfo* request_; | 313 const HttpRequestInfo* request_; |
| 283 scoped_ptr<HttpRequestInfo> custom_request_; | 314 scoped_ptr<HttpRequestInfo> custom_request_; |
| 284 HttpCache* cache_; | 315 HttpCache* cache_; |
| 285 HttpCache::ActiveEntry* entry_; | 316 HttpCache::ActiveEntry* entry_; |
| 286 scoped_ptr<HttpTransaction> network_trans_; | 317 scoped_ptr<HttpTransaction> network_trans_; |
| 287 CompletionCallback* callback_; // consumer's callback | 318 CompletionCallback* callback_; // Consumer's callback. |
| 288 HttpResponseInfo response_; | 319 HttpResponseInfo response_; |
| 289 HttpResponseInfo auth_response_; | 320 HttpResponseInfo auth_response_; |
| 290 std::string cache_key_; | 321 std::string cache_key_; |
| 291 Mode mode_; | 322 Mode mode_; |
| 323 bool reading_; // We are already reading. |
| 292 scoped_refptr<IOBuffer> read_buf_; | 324 scoped_refptr<IOBuffer> read_buf_; |
| 325 int read_buf_len_; |
| 293 int read_offset_; | 326 int read_offset_; |
| 294 int effective_load_flags_; | 327 int effective_load_flags_; |
| 328 scoped_ptr<PartialData> partial_; // We are dealing with range requests. |
| 295 uint64 final_upload_progress_; | 329 uint64 final_upload_progress_; |
| 296 CompletionCallbackImpl<Transaction> network_info_callback_; | 330 CompletionCallbackImpl<Transaction> network_info_callback_; |
| 297 CompletionCallbackImpl<Transaction> network_read_callback_; | 331 CompletionCallbackImpl<Transaction> network_read_callback_; |
| 298 scoped_refptr<CancelableCompletionCallback<Transaction> > | 332 scoped_refptr<CancelableCompletionCallback<Transaction> > |
| 299 cache_read_callback_; | 333 cache_read_callback_; |
| 300 }; | 334 }; |
| 301 | 335 |
| 302 HttpCache::Transaction::~Transaction() { | 336 HttpCache::Transaction::~Transaction() { |
| 303 if (!revoked()) { | 337 if (!revoked()) { |
| 304 if (entry_) { | 338 if (entry_) { |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 // previous response in the cache then we should leave it intact. | 460 // previous response in the cache then we should leave it intact. |
| 427 if (auth_response_.headers && mode_ != NONE) { | 461 if (auth_response_.headers && mode_ != NONE) { |
| 428 DCHECK(mode_ & WRITE); | 462 DCHECK(mode_ & WRITE); |
| 429 DoneWritingToEntry(mode_ == READ_WRITE); | 463 DoneWritingToEntry(mode_ == READ_WRITE); |
| 430 mode_ = NONE; | 464 mode_ = NONE; |
| 431 } | 465 } |
| 432 | 466 |
| 433 int rv; | 467 int rv; |
| 434 | 468 |
| 435 switch (mode_) { | 469 switch (mode_) { |
| 470 case READ_WRITE: |
| 471 DCHECK(partial_.get()); |
| 472 reading_ = true; |
| 473 if (!network_trans_.get()) { |
| 474 // We are just reading from the cache, but we may be writing later. |
| 475 rv = ReadFromEntry(buf, buf_len); |
| 476 break; |
| 477 } |
| 436 case NONE: | 478 case NONE: |
| 437 case WRITE: | 479 case WRITE: |
| 438 DCHECK(network_trans_.get()); | 480 DCHECK(network_trans_.get()); |
| 439 rv = network_trans_->Read(buf, buf_len, &network_read_callback_); | 481 rv = ReadFromNetwork(buf, buf_len); |
| 440 read_buf_ = buf; | |
| 441 if (rv >= 0) | |
| 442 OnNetworkReadCompleted(rv); | |
| 443 break; | 482 break; |
| 444 case READ: | 483 case READ: |
| 445 DCHECK(entry_); | 484 rv = ReadFromEntry(buf, buf_len); |
| 446 cache_read_callback_->AddRef(); // Balanced in OnCacheReadCompleted. | |
| 447 rv = entry_->disk_entry->ReadData(kResponseContentIndex, read_offset_, | |
| 448 buf, buf_len, cache_read_callback_); | |
| 449 read_buf_ = buf; | |
| 450 if (rv >= 0) { | |
| 451 OnCacheReadCompleted(rv); | |
| 452 } else if (rv != ERR_IO_PENDING) { | |
| 453 cache_read_callback_->Release(); | |
| 454 } | |
| 455 break; | 485 break; |
| 456 default: | 486 default: |
| 457 NOTREACHED(); | 487 NOTREACHED(); |
| 458 rv = ERR_FAILED; | 488 rv = ERR_FAILED; |
| 459 } | 489 } |
| 460 | 490 |
| 461 if (rv == ERR_IO_PENDING) | 491 if (rv == ERR_IO_PENDING) { |
| 492 DCHECK(!callback_); |
| 462 callback_ = callback; | 493 callback_ = callback; |
| 494 } |
| 463 return rv; | 495 return rv; |
| 464 } | 496 } |
| 465 | 497 |
| 466 const HttpResponseInfo* HttpCache::Transaction::GetResponseInfo() const { | 498 const HttpResponseInfo* HttpCache::Transaction::GetResponseInfo() const { |
| 467 // Null headers means we encountered an error or haven't a response yet | 499 // Null headers means we encountered an error or haven't a response yet |
| 468 if (auth_response_.headers) | 500 if (auth_response_.headers) |
| 469 return &auth_response_; | 501 return &auth_response_; |
| 470 return (response_.headers || response_.ssl_info.cert) ? &response_ : NULL; | 502 return (response_.headers || response_.ssl_info.cert) ? &response_ : NULL; |
| 471 } | 503 } |
| 472 | 504 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 537 // to be validated and then issue a network request if needed or just read | 569 // to be validated and then issue a network request if needed or just read |
| 538 // from the cache if the cache entry is already valid. | 570 // from the cache if the cache entry is already valid. |
| 539 // | 571 // |
| 540 int rv; | 572 int rv; |
| 541 entry_ = entry; | 573 entry_ = entry; |
| 542 switch (mode_) { | 574 switch (mode_) { |
| 543 case READ: | 575 case READ: |
| 544 rv = BeginCacheRead(); | 576 rv = BeginCacheRead(); |
| 545 break; | 577 break; |
| 546 case WRITE: | 578 case WRITE: |
| 579 if (partial_.get()) |
| 580 partial_->RestoreHeaders(&custom_request_->extra_headers); |
| 547 rv = BeginNetworkRequest(); | 581 rv = BeginNetworkRequest(); |
| 548 break; | 582 break; |
| 549 case READ_WRITE: | 583 case READ_WRITE: |
| 550 rv = BeginCacheValidation(); | 584 rv = BeginPartialCacheValidation(); |
| 551 break; | 585 break; |
| 552 default: | 586 default: |
| 553 NOTREACHED(); | 587 NOTREACHED(); |
| 554 rv = ERR_FAILED; | 588 rv = ERR_FAILED; |
| 555 } | 589 } |
| 556 return rv; | 590 return rv; |
| 557 } | 591 } |
| 558 | 592 |
| 559 void HttpCache::Transaction::DoCallback(int rv) { | 593 void HttpCache::Transaction::DoCallback(int rv) { |
| 560 DCHECK(rv != ERR_IO_PENDING); | 594 DCHECK(rv != ERR_IO_PENDING); |
| 561 DCHECK(callback_); | 595 DCHECK(callback_); |
| 562 | 596 |
| 563 // since Run may result in Read being called, clear callback_ up front. | 597 // since Run may result in Read being called, clear callback_ up front. |
| 564 CompletionCallback* c = callback_; | 598 CompletionCallback* c = callback_; |
| 565 callback_ = NULL; | 599 callback_ = NULL; |
| 566 c->Run(rv); | 600 c->Run(rv); |
| 567 } | 601 } |
| 568 | 602 |
| 569 int HttpCache::Transaction::HandleResult(int rv) { | 603 int HttpCache::Transaction::HandleResult(int rv) { |
| 570 DCHECK(rv != ERR_IO_PENDING); | 604 DCHECK(rv != ERR_IO_PENDING); |
| 571 if (callback_) | 605 if (callback_) |
| 572 DoCallback(rv); | 606 DoCallback(rv); |
| 573 return rv; | 607 return rv; |
| 574 } | 608 } |
| 575 | 609 |
| 576 void HttpCache::Transaction::SetRequest(const HttpRequestInfo* request) { | 610 void HttpCache::Transaction::SetRequest(const HttpRequestInfo* request) { |
| 577 request_ = request; | 611 request_ = request; |
| 578 effective_load_flags_ = request_->load_flags; | 612 effective_load_flags_ = request_->load_flags; |
| 579 | 613 |
| 580 switch(cache_->mode()) { | 614 switch (cache_->mode()) { |
| 581 case NORMAL: | 615 case NORMAL: |
| 582 break; | 616 break; |
| 583 case RECORD: | 617 case RECORD: |
| 584 // When in record mode, we want to NEVER load from the cache. | 618 // When in record mode, we want to NEVER load from the cache. |
| 585 // The reason for this is beacuse we save the Set-Cookie headers | 619 // The reason for this is beacuse we save the Set-Cookie headers |
| 586 // (intentionally). If we read from the cache, we replay them | 620 // (intentionally). If we read from the cache, we replay them |
| 587 // prematurely. | 621 // prematurely. |
| 588 effective_load_flags_ |= LOAD_BYPASS_CACHE; | 622 effective_load_flags_ |= LOAD_BYPASS_CACHE; |
| 589 case PLAYBACK: | 623 case PLAYBACK: |
| 590 // When in playback mode, we want to load exclusively from the cache. | 624 // When in playback mode, we want to load exclusively from the cache. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 606 // | 640 // |
| 607 static const struct { | 641 static const struct { |
| 608 const HeaderNameAndValue* search; | 642 const HeaderNameAndValue* search; |
| 609 int load_flag; | 643 int load_flag; |
| 610 } kSpecialHeaders[] = { | 644 } kSpecialHeaders[] = { |
| 611 { kPassThroughHeaders, LOAD_DISABLE_CACHE }, | 645 { kPassThroughHeaders, LOAD_DISABLE_CACHE }, |
| 612 { kForceFetchHeaders, LOAD_BYPASS_CACHE }, | 646 { kForceFetchHeaders, LOAD_BYPASS_CACHE }, |
| 613 { kForceValidateHeaders, LOAD_VALIDATE_CACHE }, | 647 { kForceValidateHeaders, LOAD_VALIDATE_CACHE }, |
| 614 }; | 648 }; |
| 615 | 649 |
| 650 std::string new_extra_headers; |
| 651 bool range_found = false; |
| 652 |
| 616 // scan request headers to see if we have any that would impact our load flags | 653 // scan request headers to see if we have any that would impact our load flags |
| 617 HttpUtil::HeadersIterator it(request_->extra_headers.begin(), | 654 HttpUtil::HeadersIterator it(request_->extra_headers.begin(), |
| 618 request_->extra_headers.end(), | 655 request_->extra_headers.end(), |
| 619 "\r\n"); | 656 "\r\n"); |
| 620 while (it.GetNext()) { | 657 while (it.GetNext()) { |
| 658 if (!LowerCaseEqualsASCII(it.name(), "range")) { |
| 659 new_extra_headers.append(it.name_begin(), it.values_end()); |
| 660 new_extra_headers.append("\r\n"); |
| 661 } else { |
| 662 #ifdef ENABLE_RANGE_SUPPORT |
| 663 range_found = true; |
| 664 #else |
| 665 effective_load_flags_ |= LOAD_DISABLE_CACHE; |
| 666 continue; |
| 667 #endif |
| 668 } |
| 621 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kSpecialHeaders); ++i) { | 669 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kSpecialHeaders); ++i) { |
| 622 if (HeaderMatches(it, kSpecialHeaders[i].search)) { | 670 if (HeaderMatches(it, kSpecialHeaders[i].search)) { |
| 623 effective_load_flags_ |= kSpecialHeaders[i].load_flag; | 671 effective_load_flags_ |= kSpecialHeaders[i].load_flag; |
| 624 break; | 672 break; |
| 625 } | 673 } |
| 626 } | 674 } |
| 627 } | 675 } |
| 676 |
| 677 if (range_found && !(effective_load_flags_ & LOAD_DISABLE_CACHE)) { |
| 678 partial_.reset(new PartialData); |
| 679 if (partial_->Init(request_->extra_headers, new_extra_headers)) { |
| 680 // We will be modifying the actual range requested to the server, so |
| 681 // let's remove the header here. |
| 682 custom_request_.reset(new HttpRequestInfo(*request_)); |
| 683 request_ = custom_request_.get(); |
| 684 custom_request_->extra_headers = new_extra_headers; |
| 685 } else { |
| 686 // The range is invalid or we cannot handle it properly. |
| 687 effective_load_flags_ |= LOAD_DISABLE_CACHE; |
| 688 } |
| 689 } |
| 628 } | 690 } |
| 629 | 691 |
| 630 bool HttpCache::Transaction::ShouldPassThrough() { | 692 bool HttpCache::Transaction::ShouldPassThrough() { |
| 631 // We may have a null disk_cache if there is an error we cannot recover from, | 693 // We may have a null disk_cache if there is an error we cannot recover from, |
| 632 // like not enough disk space, or sharing violations. | 694 // like not enough disk space, or sharing violations. |
| 633 if (!cache_->disk_cache()) | 695 if (!cache_->disk_cache()) |
| 634 return true; | 696 return true; |
| 635 | 697 |
| 636 // When using the record/playback modes, we always use the cache | 698 // When using the record/playback modes, we always use the cache |
| 637 // and we never pass through. | 699 // and we never pass through. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 648 request_->upload_data && request_->upload_data->identifier()) | 710 request_->upload_data && request_->upload_data->identifier()) |
| 649 return false; | 711 return false; |
| 650 | 712 |
| 651 // TODO(darin): add support for caching HEAD responses | 713 // TODO(darin): add support for caching HEAD responses |
| 652 return true; | 714 return true; |
| 653 } | 715 } |
| 654 | 716 |
| 655 int HttpCache::Transaction::BeginCacheRead() { | 717 int HttpCache::Transaction::BeginCacheRead() { |
| 656 DCHECK(mode_ == READ); | 718 DCHECK(mode_ == READ); |
| 657 | 719 |
| 658 // read response headers | 720 // Read response headers. |
| 721 // TODO(rvargas): Handle partial content (206). |
| 659 return HandleResult(ReadResponseInfoFromEntry()); | 722 return HandleResult(ReadResponseInfoFromEntry()); |
| 660 } | 723 } |
| 661 | 724 |
| 662 int HttpCache::Transaction::BeginCacheValidation() { | 725 int HttpCache::Transaction::BeginCacheValidation() { |
| 663 DCHECK(mode_ == READ_WRITE); | 726 DCHECK(mode_ == READ_WRITE); |
| 664 | 727 |
| 665 int rv = ReadResponseInfoFromEntry(); | 728 if ((effective_load_flags_ & LOAD_PREFERRING_CACHE || |
| 666 if (rv != OK) { | 729 !RequiresValidation()) && !partial_.get()) { |
| 667 DCHECK(rv != ERR_IO_PENDING); | |
| 668 } else if (effective_load_flags_ & LOAD_PREFERRING_CACHE || | |
| 669 !RequiresValidation()) { | |
| 670 cache_->ConvertWriterToReader(entry_); | 730 cache_->ConvertWriterToReader(entry_); |
| 671 mode_ = READ; | 731 mode_ = READ; |
| 672 } else { | 732 } else { |
| 673 // Make the network request conditional, to see if we may reuse our cached | 733 // Make the network request conditional, to see if we may reuse our cached |
| 674 // response. If we cannot do so, then we just resort to a normal fetch. | 734 // response. If we cannot do so, then we just resort to a normal fetch. |
| 675 // Our mode remains READ_WRITE for a conditional request. We'll switch to | 735 // Our mode remains READ_WRITE for a conditional request. We'll switch to |
| 676 // either READ or WRITE mode once we hear back from the server. | 736 // either READ or WRITE mode once we hear back from the server. |
| 677 if (!ConditionalizeRequest()) | 737 if (!ConditionalizeRequest()) |
| 678 mode_ = WRITE; | 738 mode_ = WRITE; |
| 679 return BeginNetworkRequest(); | 739 return BeginNetworkRequest(); |
| 680 } | 740 } |
| 681 return HandleResult(rv); | 741 return HandleResult(OK); |
| 742 } |
| 743 |
| 744 int HttpCache::Transaction::BeginPartialCacheValidation() { |
| 745 DCHECK(mode_ == READ_WRITE); |
| 746 |
| 747 int rv = ReadResponseInfoFromEntry(); |
| 748 if (rv != OK) { |
| 749 DCHECK(rv != ERR_IO_PENDING); |
| 750 return HandleResult(rv); |
| 751 } |
| 752 |
| 753 if (response_.headers->response_code() != 206) |
| 754 return BeginCacheValidation(); |
| 755 |
| 756 if (!partial_.get()) { |
| 757 // The request is not for a range, but we have stored just ranges. |
| 758 // TODO(rvargas): Add support for this case. |
| 759 NOTREACHED(); |
| 760 } |
| 761 |
| 762 return ContinuePartialCacheValidation(); |
| 763 } |
| 764 |
| 765 int HttpCache::Transaction::ContinuePartialCacheValidation() { |
| 766 DCHECK(mode_ == READ_WRITE); |
| 767 |
| 768 int rv = partial_->PrepareCacheValidation(entry_->disk_entry, |
| 769 &custom_request_->extra_headers); |
| 770 |
| 771 if (!rv) { |
| 772 // Don't invoke the callback before telling the cache we're done. |
| 773 return rv; |
| 774 } |
| 775 |
| 776 if (rv < 0) { |
| 777 DCHECK(rv != ERR_IO_PENDING); |
| 778 return HandleResult(rv); |
| 779 } |
| 780 |
| 781 return BeginCacheValidation(); |
| 682 } | 782 } |
| 683 | 783 |
| 684 int HttpCache::Transaction::BeginNetworkRequest() { | 784 int HttpCache::Transaction::BeginNetworkRequest() { |
| 685 DCHECK(mode_ & WRITE || mode_ == NONE); | 785 DCHECK(mode_ & WRITE || mode_ == NONE); |
| 686 DCHECK(!network_trans_.get()); | 786 DCHECK(!network_trans_.get()); |
| 687 | 787 |
| 688 network_trans_.reset(cache_->network_layer_->CreateTransaction()); | 788 network_trans_.reset(cache_->network_layer_->CreateTransaction()); |
| 689 if (!network_trans_.get()) | 789 if (!network_trans_.get()) |
| 690 return net::ERR_CACHE_CANNOT_CREATE_NETWORK_TRANSACTION; | 790 return net::ERR_CACHE_CANNOT_CREATE_NETWORK_TRANSACTION; |
| 691 | 791 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 737 if (response_.vary_data.is_valid() && | 837 if (response_.vary_data.is_valid() && |
| 738 !response_.vary_data.MatchesRequest(*request_, *response_.headers)) | 838 !response_.vary_data.MatchesRequest(*request_, *response_.headers)) |
| 739 return true; | 839 return true; |
| 740 | 840 |
| 741 return false; | 841 return false; |
| 742 } | 842 } |
| 743 | 843 |
| 744 bool HttpCache::Transaction::ConditionalizeRequest() { | 844 bool HttpCache::Transaction::ConditionalizeRequest() { |
| 745 DCHECK(response_.headers); | 845 DCHECK(response_.headers); |
| 746 | 846 |
| 747 // This only makes sense for cached 200 responses. | 847 // This only makes sense for cached 200 or 206 responses. |
| 748 if (response_.headers->response_code() != 200) | 848 if (response_.headers->response_code() != 200 && |
| 849 response_.headers->response_code() != 206) |
| 749 return false; | 850 return false; |
| 750 | 851 |
| 751 // Just use the first available ETag and/or Last-Modified header value. | 852 // Just use the first available ETag and/or Last-Modified header value. |
| 752 // TODO(darin): Or should we use the last? | 853 // TODO(darin): Or should we use the last? |
| 753 | 854 |
| 754 std::string etag_value; | 855 std::string etag_value; |
| 755 response_.headers->EnumerateHeader(NULL, "etag", &etag_value); | 856 response_.headers->EnumerateHeader(NULL, "etag", &etag_value); |
| 756 | 857 |
| 757 std::string last_modified_value; | 858 std::string last_modified_value; |
| 758 response_.headers->EnumerateHeader(NULL, "last-modified", | 859 response_.headers->EnumerateHeader(NULL, "last-modified", |
| 759 &last_modified_value); | 860 &last_modified_value); |
| 760 | 861 |
| 761 if (etag_value.empty() && last_modified_value.empty()) | 862 if (etag_value.empty() && last_modified_value.empty()) |
| 762 return false; | 863 return false; |
| 763 | 864 |
| 764 // Need to customize the request, so this forces us to allocate :( | 865 if (!partial_.get()) { |
| 765 custom_request_.reset(new HttpRequestInfo(*request_)); | 866 // Need to customize the request, so this forces us to allocate :( |
| 766 request_ = custom_request_.get(); | 867 custom_request_.reset(new HttpRequestInfo(*request_)); |
| 868 request_ = custom_request_.get(); |
| 869 } |
| 870 DCHECK(custom_request_.get()); |
| 767 | 871 |
| 768 if (!etag_value.empty()) { | 872 if (!etag_value.empty()) { |
| 769 custom_request_->extra_headers.append("If-None-Match: "); | 873 if (partial_.get() && !partial_->IsCurrentRangeCached()) { |
| 874 // We don't want to switch to WRITE mode if we don't have this block of a |
| 875 // byte-range request because we may have other parts cached. |
| 876 custom_request_->extra_headers.append("If-Range: "); |
| 877 } else { |
| 878 custom_request_->extra_headers.append("If-None-Match: "); |
| 879 } |
| 770 custom_request_->extra_headers.append(etag_value); | 880 custom_request_->extra_headers.append(etag_value); |
| 771 custom_request_->extra_headers.append("\r\n"); | 881 custom_request_->extra_headers.append("\r\n"); |
| 882 if (partial_.get() && !partial_->IsCurrentRangeCached()) |
| 883 return true; |
| 772 } | 884 } |
| 773 | 885 |
| 774 if (!last_modified_value.empty()) { | 886 if (!last_modified_value.empty()) { |
| 775 custom_request_->extra_headers.append("If-Modified-Since: "); | 887 if (partial_.get() && !partial_->IsCurrentRangeCached()) { |
| 888 custom_request_->extra_headers.append("If-Range: "); |
| 889 } else { |
| 890 custom_request_->extra_headers.append("If-Modified-Since: "); |
| 891 } |
| 776 custom_request_->extra_headers.append(last_modified_value); | 892 custom_request_->extra_headers.append(last_modified_value); |
| 777 custom_request_->extra_headers.append("\r\n"); | 893 custom_request_->extra_headers.append("\r\n"); |
| 778 } | 894 } |
| 779 | 895 |
| 780 return true; | 896 return true; |
| 781 } | 897 } |
| 782 | 898 |
| 899 int HttpCache::Transaction::ReadFromNetwork(IOBuffer* data, int data_len) { |
| 900 int rv = network_trans_->Read(data, data_len, &network_read_callback_); |
| 901 read_buf_ = data; |
| 902 read_buf_len_ = data_len; |
| 903 if (rv >= 0) |
| 904 rv = DoNetworkReadCompleted(rv); |
| 905 return rv; |
| 906 } |
| 907 |
| 908 int HttpCache::Transaction::ReadFromEntry(IOBuffer* data, int data_len) { |
| 909 DCHECK(entry_); |
| 910 int rv; |
| 911 cache_read_callback_->AddRef(); // Balanced in DoCacheReadCompleted. |
| 912 if (partial_.get()) { |
| 913 rv = partial_->CacheRead(entry_->disk_entry, data, data_len, |
| 914 cache_read_callback_); |
| 915 } else { |
| 916 rv = entry_->disk_entry->ReadData(kResponseContentIndex, read_offset_, |
| 917 data, data_len, cache_read_callback_); |
| 918 } |
| 919 read_buf_ = data; |
| 920 read_buf_len_ = data_len; |
| 921 if (rv >= 0) { |
| 922 rv = DoCacheReadCompleted(rv); |
| 923 } else if (rv != ERR_IO_PENDING) { |
| 924 cache_read_callback_->Release(); |
| 925 } |
| 926 return rv; |
| 927 } |
| 928 |
| 783 int HttpCache::Transaction::ReadResponseInfoFromEntry() { | 929 int HttpCache::Transaction::ReadResponseInfoFromEntry() { |
| 784 DCHECK(entry_); | 930 DCHECK(entry_); |
| 785 | 931 |
| 786 if (!HttpCache::ReadResponseInfo(entry_->disk_entry, &response_)) | 932 if (!HttpCache::ReadResponseInfo(entry_->disk_entry, &response_)) |
| 787 return ERR_CACHE_READ_FAILURE; | 933 return ERR_CACHE_READ_FAILURE; |
| 788 return OK; | 934 return OK; |
| 789 } | 935 } |
| 790 | 936 |
| 791 void HttpCache::Transaction::WriteToEntry(int index, int offset, | 937 void HttpCache::Transaction::WriteToEntry(int index, int offset, |
| 792 IOBuffer* data, int data_len) { | 938 IOBuffer* data, int data_len) { |
| 793 if (!entry_) | 939 if (!entry_) |
| 794 return; | 940 return; |
| 795 | 941 |
| 796 int rv = entry_->disk_entry->WriteData(index, offset, data, data_len, NULL, | 942 int rv = 0; |
| 797 true); | 943 if (!partial_.get() || !data_len) { |
| 944 rv = entry_->disk_entry->WriteData(index, offset, data, data_len, NULL, |
| 945 true); |
| 946 } else { |
| 947 rv = partial_->CacheWrite(entry_->disk_entry, data, data_len, NULL); |
| 948 } |
| 798 if (rv != data_len) { | 949 if (rv != data_len) { |
| 799 DLOG(ERROR) << "failed to write response data to cache"; | 950 DLOG(ERROR) << "failed to write response data to cache"; |
| 800 DoneWritingToEntry(false); | 951 DoneWritingToEntry(false); |
| 801 } | 952 } |
| 802 } | 953 } |
| 803 | 954 |
| 804 void HttpCache::Transaction::WriteResponseInfoToEntry() { | 955 void HttpCache::Transaction::WriteResponseInfoToEntry() { |
| 805 if (!entry_) | 956 if (!entry_) |
| 806 return; | 957 return; |
| 807 | 958 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 827 | 978 |
| 828 if (!HttpCache::WriteResponseInfo(entry_->disk_entry, &response_, | 979 if (!HttpCache::WriteResponseInfo(entry_->disk_entry, &response_, |
| 829 skip_transient_headers)) { | 980 skip_transient_headers)) { |
| 830 DLOG(ERROR) << "failed to write response info to cache"; | 981 DLOG(ERROR) << "failed to write response info to cache"; |
| 831 DoneWritingToEntry(false); | 982 DoneWritingToEntry(false); |
| 832 } | 983 } |
| 833 } | 984 } |
| 834 | 985 |
| 835 void HttpCache::Transaction::AppendResponseDataToEntry(IOBuffer* data, | 986 void HttpCache::Transaction::AppendResponseDataToEntry(IOBuffer* data, |
| 836 int data_len) { | 987 int data_len) { |
| 837 if (!entry_) | 988 if (!entry_ || !data_len) |
| 838 return; | 989 return; |
| 839 | 990 |
| 840 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); | 991 int current_size = entry_->disk_entry->GetDataSize(kResponseContentIndex); |
| 841 WriteToEntry(kResponseContentIndex, current_size, data, data_len); | 992 WriteToEntry(kResponseContentIndex, current_size, data, data_len); |
| 842 } | 993 } |
| 843 | 994 |
| 844 void HttpCache::Transaction::TruncateResponseData() { | 995 void HttpCache::Transaction::TruncateResponseData() { |
| 845 if (!entry_) | 996 if (!entry_) |
| 846 return; | 997 return; |
| 847 | 998 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 869 HandleResult(ERR_UNEXPECTED); | 1020 HandleResult(ERR_UNEXPECTED); |
| 870 return; | 1021 return; |
| 871 } | 1022 } |
| 872 | 1023 |
| 873 if (result == OK) { | 1024 if (result == OK) { |
| 874 const HttpResponseInfo* new_response = network_trans_->GetResponseInfo(); | 1025 const HttpResponseInfo* new_response = network_trans_->GetResponseInfo(); |
| 875 if (new_response->headers->response_code() == 401 || | 1026 if (new_response->headers->response_code() == 401 || |
| 876 new_response->headers->response_code() == 407) { | 1027 new_response->headers->response_code() == 407) { |
| 877 auth_response_ = *new_response; | 1028 auth_response_ = *new_response; |
| 878 } else { | 1029 } else { |
| 1030 #ifdef ENABLE_RANGE_SUPPORT |
| 1031 bool partial_content = new_response->headers->response_code() == 206; |
| 1032 #else |
| 1033 bool partial_content = false; |
| 1034 #endif |
| 1035 // TODO(rvargas): Validate partial_content vs partial_ and mode_ |
| 1036 if (partial_content) { |
| 1037 DCHECK(partial_.get()); |
| 1038 } |
| 879 // Are we expecting a response to a conditional query? | 1039 // Are we expecting a response to a conditional query? |
| 880 if (mode_ == READ_WRITE) { | 1040 if (mode_ == READ_WRITE) { |
| 881 if (new_response->headers->response_code() == 304) { | 1041 if (new_response->headers->response_code() == 304 || partial_content) { |
| 882 // Update cached response based on headers in new_response | 1042 // Update cached response based on headers in new_response. |
| 883 // TODO(wtc): should we update cached certificate | 1043 // TODO(wtc): should we update cached certificate |
| 884 // (response_.ssl_info), too? | 1044 // (response_.ssl_info), too? |
| 885 response_.headers->Update(*new_response->headers); | 1045 response_.headers->Update(*new_response->headers); |
| 886 if (response_.headers->HasHeaderValue("cache-control", "no-store")) { | 1046 if (response_.headers->HasHeaderValue("cache-control", "no-store")) { |
| 887 cache_->DoomEntry(cache_key_); | 1047 cache_->DoomEntry(cache_key_); |
| 888 } else { | 1048 } else { |
| 889 WriteResponseInfoToEntry(); | 1049 WriteResponseInfoToEntry(); |
| 890 } | 1050 } |
| 891 | 1051 |
| 892 if (entry_) { | 1052 if (entry_ && !partial_content) { |
| 893 cache_->ConvertWriterToReader(entry_); | 1053 if (!partial_.get() || partial_->IsLastRange()) |
| 1054 cache_->ConvertWriterToReader(entry_); |
| 894 // We no longer need the network transaction, so destroy it. | 1055 // We no longer need the network transaction, so destroy it. |
| 895 final_upload_progress_ = network_trans_->GetUploadProgress(); | 1056 final_upload_progress_ = network_trans_->GetUploadProgress(); |
| 896 network_trans_.reset(); | 1057 network_trans_.reset(); |
| 897 mode_ = READ; | 1058 if (!partial_.get() || partial_->IsLastRange()) |
| 1059 mode_ = READ; |
| 898 } | 1060 } |
| 899 } else { | 1061 } else { |
| 900 mode_ = WRITE; | 1062 mode_ = WRITE; |
| 901 } | 1063 } |
| 902 } | 1064 } |
| 903 | 1065 |
| 904 if (!(mode_ & READ)) { | 1066 if (!(mode_ & READ)) { |
| 905 response_ = *new_response; | 1067 response_ = *new_response; |
| 906 WriteResponseInfoToEntry(); | 1068 WriteResponseInfoToEntry(); |
| 907 | 1069 |
| 908 // Truncate response data | 1070 // Truncate response data. |
| 909 TruncateResponseData(); | 1071 TruncateResponseData(); |
| 910 | 1072 |
| 911 // If this response is a redirect, then we can stop writing now. (We | 1073 // If this response is a redirect, then we can stop writing now. (We |
| 912 // don't need to cache the response body of a redirect.) | 1074 // don't need to cache the response body of a redirect.) |
| 913 if (response_.headers->IsRedirect(NULL)) | 1075 if (response_.headers->IsRedirect(NULL)) |
| 914 DoneWritingToEntry(true); | 1076 DoneWritingToEntry(true); |
| 915 } | 1077 } |
| 1078 if (reading_) { |
| 1079 DCHECK(partial_.get()); |
| 1080 if (network_trans_.get()) { |
| 1081 result = ReadFromNetwork(read_buf_, read_buf_len_); |
| 1082 } else { |
| 1083 result = ReadFromEntry(read_buf_, read_buf_len_); |
| 1084 } |
| 1085 if (result >= 0 || result == net::ERR_IO_PENDING) |
| 1086 return; |
| 1087 } |
| 916 } | 1088 } |
| 917 } else if (IsCertificateError(result)) { | 1089 } else if (IsCertificateError(result)) { |
| 918 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); | 1090 const HttpResponseInfo* response = network_trans_->GetResponseInfo(); |
| 919 // If we get a certificate error, then there is a certificate in ssl_info, | 1091 // If we get a certificate error, then there is a certificate in ssl_info, |
| 920 // so GetResponseInfo() should never returns NULL here. | 1092 // so GetResponseInfo() should never returns NULL here. |
| 921 DCHECK(response); | 1093 DCHECK(response); |
| 922 response_.ssl_info = response->ssl_info; | 1094 response_.ssl_info = response->ssl_info; |
| 923 } | 1095 } |
| 924 HandleResult(result); | 1096 HandleResult(result); |
| 925 } | 1097 } |
| 926 | 1098 |
| 927 void HttpCache::Transaction::OnNetworkReadCompleted(int result) { | 1099 void HttpCache::Transaction::OnNetworkReadCompleted(int result) { |
| 1100 DoNetworkReadCompleted(result); |
| 1101 } |
| 1102 |
| 1103 int HttpCache::Transaction::DoNetworkReadCompleted(int result) { |
| 928 DCHECK(mode_ & WRITE || mode_ == NONE); | 1104 DCHECK(mode_ & WRITE || mode_ == NONE); |
| 929 | 1105 |
| 930 if (revoked()) { | 1106 if (revoked()) |
| 931 HandleResult(ERR_UNEXPECTED); | 1107 return HandleResult(ERR_UNEXPECTED); |
| 932 return; | |
| 933 } | |
| 934 | 1108 |
| 935 if (result > 0) { | 1109 AppendResponseDataToEntry(read_buf_, result); |
| 936 AppendResponseDataToEntry(read_buf_, result); | 1110 |
| 937 } else if (result == 0) { // end of file | 1111 if (partial_.get()) |
| 1112 return DoPartialNetworkReadCompleted(result); |
| 1113 |
| 1114 if (result == 0) // End of file. |
| 1115 DoneWritingToEntry(true); |
| 1116 |
| 1117 return HandleResult(result); |
| 1118 } |
| 1119 |
| 1120 int HttpCache::Transaction::DoPartialNetworkReadCompleted(int result) { |
| 1121 partial_->OnNetworkReadCompleted(result); |
| 1122 |
| 1123 if (result == 0) { // End of file. |
| 1124 if (mode_ == READ_WRITE) { |
| 1125 // We need to move on to the next range. |
| 1126 network_trans_.reset(); |
| 1127 result = ContinuePartialCacheValidation(); |
| 1128 if (result != OK) |
| 1129 // Any error was already handled. |
| 1130 return result; |
| 1131 } |
| 938 DoneWritingToEntry(true); | 1132 DoneWritingToEntry(true); |
| 939 } | 1133 } |
| 940 HandleResult(result); | 1134 return HandleResult(result); |
| 941 } | 1135 } |
| 942 | 1136 |
| 943 void HttpCache::Transaction::OnCacheReadCompleted(int result) { | 1137 void HttpCache::Transaction::OnCacheReadCompleted(int result) { |
| 1138 DoCacheReadCompleted(result); |
| 1139 } |
| 1140 |
| 1141 int HttpCache::Transaction::DoCacheReadCompleted(int result) { |
| 944 DCHECK(cache_); | 1142 DCHECK(cache_); |
| 945 cache_read_callback_->Release(); // Balance the AddRef() from Start(). | 1143 cache_read_callback_->Release(); // Balance the AddRef() from Start(). |
| 946 | 1144 |
| 947 if (revoked()) { | 1145 if (revoked()) |
| 948 HandleResult(ERR_UNEXPECTED); | 1146 return HandleResult(ERR_UNEXPECTED); |
| 949 return; | 1147 |
| 950 } | 1148 if (partial_.get()) |
| 1149 return DoPartialCacheReadCompleted(result); |
| 951 | 1150 |
| 952 if (result > 0) { | 1151 if (result > 0) { |
| 953 read_offset_ += result; | 1152 read_offset_ += result; |
| 954 } else if (result == 0) { // end of file | 1153 } else if (result == 0) { // End of file. |
| 955 cache_->DoneReadingFromEntry(entry_, this); | 1154 cache_->DoneReadingFromEntry(entry_, this); |
| 956 entry_ = NULL; | 1155 entry_ = NULL; |
| 957 } | 1156 } |
| 958 HandleResult(result); | 1157 return HandleResult(result); |
| 1158 } |
| 1159 |
| 1160 int HttpCache::Transaction::DoPartialCacheReadCompleted(int result) { |
| 1161 partial_->OnCacheReadCompleted(result); |
| 1162 |
| 1163 if (result == 0) { // End of file. |
| 1164 if (partial_.get() && mode_ == READ_WRITE) { |
| 1165 // We need to move on to the next range. |
| 1166 result = ContinuePartialCacheValidation(); |
| 1167 if (result != OK) |
| 1168 // Any error was already handled. |
| 1169 return result; |
| 1170 cache_->ConvertWriterToReader(entry_); |
| 1171 } |
| 1172 cache_->DoneReadingFromEntry(entry_, this); |
| 1173 entry_ = NULL; |
| 1174 } |
| 1175 return HandleResult(result); |
| 959 } | 1176 } |
| 960 | 1177 |
| 961 //----------------------------------------------------------------------------- | 1178 //----------------------------------------------------------------------------- |
| 962 | 1179 |
| 963 HttpCache::HttpCache(ProxyService* proxy_service, | 1180 HttpCache::HttpCache(ProxyService* proxy_service, |
| 964 const std::wstring& cache_dir, | 1181 const std::wstring& cache_dir, |
| 965 int cache_size) | 1182 int cache_size) |
| 966 : disk_cache_dir_(cache_dir), | 1183 : disk_cache_dir_(cache_dir), |
| 967 mode_(NORMAL), | 1184 mode_(NORMAL), |
| 968 type_(DISK_CACHE), | 1185 type_(DISK_CACHE), |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1137 pickle.WriteInt64(response_info->response_time.ToInternalValue()); | 1354 pickle.WriteInt64(response_info->response_time.ToInternalValue()); |
| 1138 | 1355 |
| 1139 net::HttpResponseHeaders::PersistOptions persist_options = | 1356 net::HttpResponseHeaders::PersistOptions persist_options = |
| 1140 net::HttpResponseHeaders::PERSIST_RAW; | 1357 net::HttpResponseHeaders::PERSIST_RAW; |
| 1141 | 1358 |
| 1142 if (skip_transient_headers) { | 1359 if (skip_transient_headers) { |
| 1143 persist_options = | 1360 persist_options = |
| 1144 net::HttpResponseHeaders::PERSIST_SANS_COOKIES | | 1361 net::HttpResponseHeaders::PERSIST_SANS_COOKIES | |
| 1145 net::HttpResponseHeaders::PERSIST_SANS_CHALLENGES | | 1362 net::HttpResponseHeaders::PERSIST_SANS_CHALLENGES | |
| 1146 net::HttpResponseHeaders::PERSIST_SANS_HOP_BY_HOP | | 1363 net::HttpResponseHeaders::PERSIST_SANS_HOP_BY_HOP | |
| 1147 net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE; | 1364 net::HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE | |
| 1365 net::HttpResponseHeaders::PERSIST_SANS_RANGES; |
| 1148 } | 1366 } |
| 1149 | 1367 |
| 1150 response_info->headers->Persist(&pickle, persist_options); | 1368 response_info->headers->Persist(&pickle, persist_options); |
| 1151 | 1369 |
| 1152 if (response_info->ssl_info.cert) { | 1370 if (response_info->ssl_info.cert) { |
| 1153 response_info->ssl_info.cert->Persist(&pickle); | 1371 response_info->ssl_info.cert->Persist(&pickle); |
| 1154 pickle.WriteInt(response_info->ssl_info.cert_status); | 1372 pickle.WriteInt(response_info->ssl_info.cert_status); |
| 1155 } | 1373 } |
| 1156 if (response_info->ssl_info.security_bits != -1) | 1374 if (response_info->ssl_info.security_bits != -1) |
| 1157 pickle.WriteInt(response_info->ssl_info.security_bits); | 1375 pickle.WriteInt(response_info->ssl_info.security_bits); |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1475 static_cast<net::HttpNetworkLayer*>(network_layer_.get()); | 1693 static_cast<net::HttpNetworkLayer*>(network_layer_.get()); |
| 1476 HttpNetworkSession* session = network->GetSession(); | 1694 HttpNetworkSession* session = network->GetSession(); |
| 1477 if (session) { | 1695 if (session) { |
| 1478 session->connection_pool()->CloseIdleSockets(); | 1696 session->connection_pool()->CloseIdleSockets(); |
| 1479 } | 1697 } |
| 1480 } | 1698 } |
| 1481 | 1699 |
| 1482 //----------------------------------------------------------------------------- | 1700 //----------------------------------------------------------------------------- |
| 1483 | 1701 |
| 1484 } // namespace net | 1702 } // namespace net |
| OLD | NEW |