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 |