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

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

Issue 118345: Http Cache: First pass of byte-range requests support.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | net/http/http_cache_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | net/http/http_cache_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698