• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/http/http_cache.h"
6 
7 #include "base/hash_tables.h"
8 #include "base/memory/scoped_vector.h"
9 #include "base/message_loop.h"
10 #include "base/string_util.h"
11 #include "base/stringprintf.h"
12 #include "net/base/cache_type.h"
13 #include "net/base/cert_status_flags.h"
14 #include "net/base/host_port_pair.h"
15 #include "net/base/load_flags.h"
16 #include "net/base/net_errors.h"
17 #include "net/base/net_log_unittest.h"
18 #include "net/base/ssl_cert_request_info.h"
19 #include "net/disk_cache/disk_cache.h"
20 #include "net/http/http_byte_range.h"
21 #include "net/http/http_request_headers.h"
22 #include "net/http/http_request_info.h"
23 #include "net/http/http_response_headers.h"
24 #include "net/http/http_response_info.h"
25 #include "net/http/http_transaction.h"
26 #include "net/http/http_transaction_unittest.h"
27 #include "net/http/http_util.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29 
30 using base::Time;
31 
32 namespace {
33 
GetTestModeForEntry(const std::string & key)34 int GetTestModeForEntry(const std::string& key) {
35   // 'key' is prefixed with an identifier if it corresponds to a cached POST.
36   // Skip past that to locate the actual URL.
37   //
38   // TODO(darin): It breaks the abstraction a bit that we assume 'key' is an
39   // URL corresponding to a registered MockTransaction.  It would be good to
40   // have another way to access the test_mode.
41   GURL url;
42   if (isdigit(key[0])) {
43     size_t slash = key.find('/');
44     DCHECK(slash != std::string::npos);
45     url = GURL(key.substr(slash + 1));
46   } else {
47     url = GURL(key);
48   }
49   const MockTransaction* t = FindMockTransaction(url);
50   DCHECK(t);
51   return t->test_mode;
52 }
53 
54 // We can override the test mode for a given operation by setting this global
55 // variable. Just remember to reset it after the test!.
56 int g_test_mode = 0;
57 
58 // Returns the test mode after considering the global override.
GetEffectiveTestMode(int test_mode)59 int GetEffectiveTestMode(int test_mode) {
60   if (!g_test_mode)
61     return test_mode;
62 
63   return g_test_mode;
64 }
65 
66 //-----------------------------------------------------------------------------
67 // mock disk cache (a very basic memory cache implementation)
68 
69 static const int kNumCacheEntryDataIndices = 3;
70 
71 class MockDiskEntry : public disk_cache::Entry,
72                       public base::RefCounted<MockDiskEntry> {
73  public:
MockDiskEntry()74   MockDiskEntry()
75       : test_mode_(0), doomed_(false), sparse_(false), fail_requests_(false),
76         busy_(false), delayed_(false) {
77   }
78 
MockDiskEntry(const std::string & key)79   explicit MockDiskEntry(const std::string& key)
80       : key_(key), doomed_(false), sparse_(false), fail_requests_(false),
81         busy_(false), delayed_(false) {
82     test_mode_ = GetTestModeForEntry(key);
83   }
84 
is_doomed() const85   bool is_doomed() const { return doomed_; }
86 
Doom()87   virtual void Doom() {
88     doomed_ = true;
89   }
90 
Close()91   virtual void Close() {
92     Release();
93   }
94 
GetKey() const95   virtual std::string GetKey() const {
96     if (fail_requests_)
97       return std::string();
98     return key_;
99   }
100 
GetLastUsed() const101   virtual Time GetLastUsed() const {
102     return Time::FromInternalValue(0);
103   }
104 
GetLastModified() const105   virtual Time GetLastModified() const {
106     return Time::FromInternalValue(0);
107   }
108 
GetDataSize(int index) const109   virtual int32 GetDataSize(int index) const {
110     DCHECK(index >= 0 && index < kNumCacheEntryDataIndices);
111     return static_cast<int32>(data_[index].size());
112   }
113 
ReadData(int index,int offset,net::IOBuffer * buf,int buf_len,net::CompletionCallback * callback)114   virtual int ReadData(int index, int offset, net::IOBuffer* buf, int buf_len,
115                        net::CompletionCallback* callback) {
116     DCHECK(index >= 0 && index < kNumCacheEntryDataIndices);
117     DCHECK(callback);
118 
119     if (fail_requests_)
120       return net::ERR_CACHE_READ_FAILURE;
121 
122     if (offset < 0 || offset > static_cast<int>(data_[index].size()))
123       return net::ERR_FAILED;
124     if (static_cast<size_t>(offset) == data_[index].size())
125       return 0;
126 
127     int num = std::min(buf_len, static_cast<int>(data_[index].size()) - offset);
128     memcpy(buf->data(), &data_[index][offset], num);
129 
130     if (GetEffectiveTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_READ)
131       return num;
132 
133     CallbackLater(callback, num);
134     return net::ERR_IO_PENDING;
135   }
136 
WriteData(int index,int offset,net::IOBuffer * buf,int buf_len,net::CompletionCallback * callback,bool truncate)137   virtual int WriteData(int index, int offset, net::IOBuffer* buf, int buf_len,
138                         net::CompletionCallback* callback, bool truncate) {
139     DCHECK(index >= 0 && index < kNumCacheEntryDataIndices);
140     DCHECK(callback);
141     DCHECK(truncate);
142 
143     if (fail_requests_) {
144       CallbackLater(callback, net::ERR_CACHE_READ_FAILURE);
145       return net::ERR_IO_PENDING;
146     }
147 
148     if (offset < 0 || offset > static_cast<int>(data_[index].size()))
149       return net::ERR_FAILED;
150 
151     data_[index].resize(offset + buf_len);
152     if (buf_len)
153       memcpy(&data_[index][offset], buf->data(), buf_len);
154 
155     if (GetEffectiveTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_WRITE)
156       return buf_len;
157 
158     CallbackLater(callback, buf_len);
159     return net::ERR_IO_PENDING;
160   }
161 
ReadSparseData(int64 offset,net::IOBuffer * buf,int buf_len,net::CompletionCallback * callback)162   virtual int ReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len,
163                              net::CompletionCallback* callback) {
164     DCHECK(callback);
165     if (!sparse_ || busy_)
166       return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
167     if (offset < 0)
168       return net::ERR_FAILED;
169 
170     if (fail_requests_)
171       return net::ERR_CACHE_READ_FAILURE;
172 
173     DCHECK(offset < kint32max);
174     int real_offset = static_cast<int>(offset);
175     if (!buf_len)
176       return 0;
177 
178     int num = std::min(static_cast<int>(data_[1].size()) - real_offset,
179                        buf_len);
180     memcpy(buf->data(), &data_[1][real_offset], num);
181 
182     if (GetEffectiveTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_READ)
183       return num;
184 
185     CallbackLater(callback, num);
186     busy_ = true;
187     delayed_ = false;
188     return net::ERR_IO_PENDING;
189   }
190 
WriteSparseData(int64 offset,net::IOBuffer * buf,int buf_len,net::CompletionCallback * callback)191   virtual int WriteSparseData(int64 offset, net::IOBuffer* buf, int buf_len,
192                               net::CompletionCallback* callback) {
193     DCHECK(callback);
194     if (busy_)
195       return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
196     if (!sparse_) {
197       if (data_[1].size())
198         return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
199       sparse_ = true;
200     }
201     if (offset < 0)
202       return net::ERR_FAILED;
203     if (!buf_len)
204       return 0;
205 
206     if (fail_requests_)
207       return net::ERR_CACHE_READ_FAILURE;
208 
209     DCHECK(offset < kint32max);
210     int real_offset = static_cast<int>(offset);
211 
212     if (static_cast<int>(data_[1].size()) < real_offset + buf_len)
213       data_[1].resize(real_offset + buf_len);
214 
215     memcpy(&data_[1][real_offset], buf->data(), buf_len);
216     if (GetEffectiveTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_WRITE)
217       return buf_len;
218 
219     CallbackLater(callback, buf_len);
220     return net::ERR_IO_PENDING;
221   }
222 
GetAvailableRange(int64 offset,int len,int64 * start,net::CompletionCallback * callback)223   virtual int GetAvailableRange(int64 offset, int len, int64* start,
224                                 net::CompletionCallback* callback) {
225     DCHECK(callback);
226     if (!sparse_ || busy_)
227       return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
228     if (offset < 0)
229       return net::ERR_FAILED;
230 
231     if (fail_requests_)
232       return net::ERR_CACHE_READ_FAILURE;
233 
234     *start = offset;
235     DCHECK(offset < kint32max);
236     int real_offset = static_cast<int>(offset);
237     if (static_cast<int>(data_[1].size()) < real_offset)
238       return 0;
239 
240     int num = std::min(static_cast<int>(data_[1].size()) - real_offset, len);
241     int count = 0;
242     for (; num > 0; num--, real_offset++) {
243       if (!count) {
244         if (data_[1][real_offset]) {
245           count++;
246           *start = real_offset;
247         }
248       } else {
249         if (!data_[1][real_offset])
250           break;
251         count++;
252       }
253     }
254     if (GetEffectiveTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_WRITE)
255       return count;
256 
257     CallbackLater(callback, count);
258     return net::ERR_IO_PENDING;
259   }
260 
CouldBeSparse() const261   virtual bool CouldBeSparse() const {
262     return sparse_;
263   }
264 
CancelSparseIO()265   virtual void CancelSparseIO() { cancel_ = true; }
266 
ReadyForSparseIO(net::CompletionCallback * completion_callback)267   virtual int ReadyForSparseIO(net::CompletionCallback* completion_callback) {
268     if (!cancel_)
269       return net::OK;
270 
271     cancel_ = false;
272     DCHECK(completion_callback);
273     if (GetEffectiveTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_READ)
274       return net::OK;
275 
276     // The pending operation is already in the message loop (and hopefuly
277     // already in the second pass).  Just notify the caller that it finished.
278     CallbackLater(completion_callback, 0);
279     return net::ERR_IO_PENDING;
280   }
281 
282   // Fail most subsequent requests.
set_fail_requests()283   void set_fail_requests() { fail_requests_ = true; }
284 
285   // If |value| is true, don't deliver any completion callbacks until called
286   // again with |value| set to false.  Caution: remember to enable callbacks
287   // again or all subsequent tests will fail.
IgnoreCallbacks(bool value)288   static void IgnoreCallbacks(bool value) {
289     if (ignore_callbacks_ == value)
290       return;
291     ignore_callbacks_ = value;
292     if (!value)
293       StoreAndDeliverCallbacks(false, NULL, NULL, 0);
294   }
295 
296  private:
297   friend class base::RefCounted<MockDiskEntry>;
298 
299   struct CallbackInfo {
300     scoped_refptr<MockDiskEntry> entry;
301     net::CompletionCallback* callback;
302     int result;
303   };
304 
~MockDiskEntry()305   ~MockDiskEntry() {}
306 
307   // Unlike the callbacks for MockHttpTransaction, we want this one to run even
308   // if the consumer called Close on the MockDiskEntry.  We achieve that by
309   // leveraging the fact that this class is reference counted.
CallbackLater(net::CompletionCallback * callback,int result)310   void CallbackLater(net::CompletionCallback* callback, int result) {
311     if (ignore_callbacks_)
312       return StoreAndDeliverCallbacks(true, this, callback, result);
313     MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
314         this, &MockDiskEntry::RunCallback, callback, result));
315   }
RunCallback(net::CompletionCallback * callback,int result)316   void RunCallback(net::CompletionCallback* callback, int result) {
317     if (busy_) {
318       // This is kind of hacky, but controlling the behavior of just this entry
319       // from a test is sort of complicated.  What we really want to do is
320       // delay the delivery of a sparse IO operation a little more so that the
321       // request start operation (async) will finish without seeing the end of
322       // this operation (already posted to the message loop)... and without
323       // just delaying for n mS (which may cause trouble with slow bots).  So
324       // we re-post this operation (all async sparse IO operations will take two
325       // trips trhough the message loop instead of one).
326       if (!delayed_) {
327         delayed_ = true;
328         return CallbackLater(callback, result);
329       }
330     }
331     busy_ = false;
332     callback->Run(result);
333   }
334 
335   // When |store| is true, stores the callback to be delivered later; otherwise
336   // delivers any callback previously stored.
StoreAndDeliverCallbacks(bool store,MockDiskEntry * entry,net::CompletionCallback * callback,int result)337   static void StoreAndDeliverCallbacks(bool store, MockDiskEntry* entry,
338                                        net::CompletionCallback* callback,
339                                        int result) {
340     static std::vector<CallbackInfo> callback_list;
341     if (store) {
342       CallbackInfo c = {entry, callback, result};
343       callback_list.push_back(c);
344     } else {
345       for (size_t i = 0; i < callback_list.size(); i++) {
346         CallbackInfo& c = callback_list[i];
347         c.entry->CallbackLater(c.callback, c.result);
348       }
349       callback_list.clear();
350     }
351   }
352 
353   std::string key_;
354   std::vector<char> data_[kNumCacheEntryDataIndices];
355   int test_mode_;
356   bool doomed_;
357   bool sparse_;
358   bool fail_requests_;
359   bool busy_;
360   bool delayed_;
361   static bool cancel_;
362   static bool ignore_callbacks_;
363 };
364 
365 // Statics.
366 bool MockDiskEntry::cancel_ = false;
367 bool MockDiskEntry::ignore_callbacks_ = false;
368 
369 class MockDiskCache : public disk_cache::Backend {
370  public:
MockDiskCache()371   MockDiskCache()
372       : open_count_(0), create_count_(0), fail_requests_(false),
373         soft_failures_(false) {
374   }
375 
~MockDiskCache()376   ~MockDiskCache() {
377     ReleaseAll();
378   }
379 
GetEntryCount() const380   virtual int32 GetEntryCount() const {
381     return static_cast<int32>(entries_.size());
382   }
383 
OpenEntry(const std::string & key,disk_cache::Entry ** entry,net::CompletionCallback * callback)384   virtual int OpenEntry(const std::string& key, disk_cache::Entry** entry,
385                         net::CompletionCallback* callback) {
386     DCHECK(callback);
387     if (fail_requests_)
388       return net::ERR_CACHE_OPEN_FAILURE;
389 
390     EntryMap::iterator it = entries_.find(key);
391     if (it == entries_.end())
392       return net::ERR_CACHE_OPEN_FAILURE;
393 
394     if (it->second->is_doomed()) {
395       it->second->Release();
396       entries_.erase(it);
397       return net::ERR_CACHE_OPEN_FAILURE;
398     }
399 
400     open_count_++;
401 
402     it->second->AddRef();
403     *entry = it->second;
404 
405     if (soft_failures_)
406       it->second->set_fail_requests();
407 
408     if (GetTestModeForEntry(key) & TEST_MODE_SYNC_CACHE_START)
409       return net::OK;
410 
411     CallbackLater(callback, net::OK);
412     return net::ERR_IO_PENDING;
413   }
414 
CreateEntry(const std::string & key,disk_cache::Entry ** entry,net::CompletionCallback * callback)415   virtual int CreateEntry(const std::string& key, disk_cache::Entry** entry,
416                           net::CompletionCallback* callback) {
417     DCHECK(callback);
418     if (fail_requests_)
419       return net::ERR_CACHE_CREATE_FAILURE;
420 
421     EntryMap::iterator it = entries_.find(key);
422     if (it != entries_.end()) {
423       DCHECK(it->second->is_doomed());
424       it->second->Release();
425       entries_.erase(it);
426     }
427 
428     create_count_++;
429 
430     MockDiskEntry* new_entry = new MockDiskEntry(key);
431 
432     new_entry->AddRef();
433     entries_[key] = new_entry;
434 
435     new_entry->AddRef();
436     *entry = new_entry;
437 
438     if (soft_failures_)
439       new_entry->set_fail_requests();
440 
441     if (GetTestModeForEntry(key) & TEST_MODE_SYNC_CACHE_START)
442       return net::OK;
443 
444     CallbackLater(callback, net::OK);
445     return net::ERR_IO_PENDING;
446   }
447 
DoomEntry(const std::string & key,net::CompletionCallback * callback)448   virtual int DoomEntry(const std::string& key,
449                         net::CompletionCallback* callback) {
450     DCHECK(callback);
451     EntryMap::iterator it = entries_.find(key);
452     if (it != entries_.end()) {
453       it->second->Release();
454       entries_.erase(it);
455     }
456 
457     if (GetTestModeForEntry(key) & TEST_MODE_SYNC_CACHE_START)
458       return net::OK;
459 
460     CallbackLater(callback, net::OK);
461     return net::ERR_IO_PENDING;
462   }
463 
DoomAllEntries(net::CompletionCallback * callback)464   virtual int DoomAllEntries(net::CompletionCallback* callback) {
465     return net::ERR_NOT_IMPLEMENTED;
466   }
467 
DoomEntriesBetween(const base::Time initial_time,const base::Time end_time,net::CompletionCallback * callback)468   virtual int DoomEntriesBetween(const base::Time initial_time,
469                                  const base::Time end_time,
470                                  net::CompletionCallback* callback) {
471     return net::ERR_NOT_IMPLEMENTED;
472   }
473 
DoomEntriesSince(const base::Time initial_time,net::CompletionCallback * callback)474   virtual int DoomEntriesSince(const base::Time initial_time,
475                                net::CompletionCallback* callback) {
476     return net::ERR_NOT_IMPLEMENTED;
477   }
478 
OpenNextEntry(void ** iter,disk_cache::Entry ** next_entry,net::CompletionCallback * callback)479   virtual int OpenNextEntry(void** iter, disk_cache::Entry** next_entry,
480                             net::CompletionCallback* callback) {
481     return net::ERR_NOT_IMPLEMENTED;
482   }
483 
EndEnumeration(void ** iter)484   virtual void EndEnumeration(void** iter) {}
485 
GetStats(std::vector<std::pair<std::string,std::string>> * stats)486   virtual void GetStats(
487       std::vector<std::pair<std::string, std::string> >* stats) {
488   }
489 
490   // returns number of times a cache entry was successfully opened
open_count() const491   int open_count() const { return open_count_; }
492 
493   // returns number of times a cache entry was successfully created
create_count() const494   int create_count() const { return create_count_; }
495 
496   // Fail any subsequent CreateEntry and OpenEntry.
set_fail_requests()497   void set_fail_requests() { fail_requests_ = true; }
498 
499   // Return entries that fail some of their requests.
set_soft_failures(bool value)500   void set_soft_failures(bool value) { soft_failures_ = value; }
501 
ReleaseAll()502   void ReleaseAll() {
503     EntryMap::iterator it = entries_.begin();
504     for (; it != entries_.end(); ++it)
505       it->second->Release();
506     entries_.clear();
507   }
508 
509  private:
510   typedef base::hash_map<std::string, MockDiskEntry*> EntryMap;
511 
512   class CallbackRunner : public Task {
513    public:
CallbackRunner(net::CompletionCallback * callback,int result)514     CallbackRunner(net::CompletionCallback* callback, int result)
515         : callback_(callback), result_(result) {}
Run()516     virtual void Run() {
517       callback_->Run(result_);
518     }
519 
520    private:
521     net::CompletionCallback* callback_;
522     int result_;
523     DISALLOW_COPY_AND_ASSIGN(CallbackRunner);
524   };
525 
CallbackLater(net::CompletionCallback * callback,int result)526   void CallbackLater(net::CompletionCallback* callback, int result) {
527     MessageLoop::current()->PostTask(FROM_HERE,
528                                      new CallbackRunner(callback, result));
529   }
530 
531   EntryMap entries_;
532   int open_count_;
533   int create_count_;
534   bool fail_requests_;
535   bool soft_failures_;
536 };
537 
538 class MockBackendFactory : public net::HttpCache::BackendFactory {
539  public:
CreateBackend(net::NetLog *,disk_cache::Backend ** backend,net::CompletionCallback * callback)540   virtual int CreateBackend(net::NetLog*  /* net_log */,
541                             disk_cache::Backend** backend,
542                             net::CompletionCallback* callback) {
543     *backend = new MockDiskCache();
544     return net::OK;
545   }
546 };
547 
548 class MockHttpCache {
549  public:
MockHttpCache()550   MockHttpCache()
551       : http_cache_(new MockNetworkLayer(), NULL, new MockBackendFactory()) {
552   }
553 
MockHttpCache(net::HttpCache::BackendFactory * disk_cache_factory)554   explicit MockHttpCache(net::HttpCache::BackendFactory* disk_cache_factory)
555       : http_cache_(new MockNetworkLayer(), NULL, disk_cache_factory) {
556   }
557 
http_cache()558   net::HttpCache* http_cache() { return &http_cache_; }
559 
network_layer()560   MockNetworkLayer* network_layer() {
561     return static_cast<MockNetworkLayer*>(http_cache_.network_layer());
562   }
disk_cache()563   MockDiskCache* disk_cache() {
564     TestCompletionCallback cb;
565     disk_cache::Backend* backend;
566     int rv = http_cache_.GetBackend(&backend, &cb);
567     rv = cb.GetResult(rv);
568     return (rv == net::OK) ? static_cast<MockDiskCache*>(backend) : NULL;
569   }
570 
571   // Helper function for reading response info from the disk cache.
ReadResponseInfo(disk_cache::Entry * disk_entry,net::HttpResponseInfo * response_info,bool * response_truncated)572   static bool ReadResponseInfo(disk_cache::Entry* disk_entry,
573                                net::HttpResponseInfo* response_info,
574                                bool* response_truncated) {
575     int size = disk_entry->GetDataSize(0);
576 
577     TestCompletionCallback cb;
578     scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(size));
579     int rv = disk_entry->ReadData(0, 0, buffer, size, &cb);
580     rv = cb.GetResult(rv);
581     EXPECT_EQ(size, rv);
582 
583     return net::HttpCache::ParseResponseInfo(buffer->data(), size,
584                                              response_info,
585                                              response_truncated);
586   }
587 
588   // Helper function for writing response info into the disk cache.
WriteResponseInfo(disk_cache::Entry * disk_entry,const net::HttpResponseInfo * response_info,bool skip_transient_headers,bool response_truncated)589   static bool WriteResponseInfo(disk_cache::Entry* disk_entry,
590                                 const net::HttpResponseInfo* response_info,
591                                 bool skip_transient_headers,
592                                 bool response_truncated) {
593     Pickle pickle;
594     response_info->Persist(
595         &pickle, skip_transient_headers, response_truncated);
596 
597     TestCompletionCallback cb;
598     scoped_refptr<net::WrappedIOBuffer> data(new net::WrappedIOBuffer(
599         reinterpret_cast<const char*>(pickle.data())));
600     int len = static_cast<int>(pickle.size());
601 
602     int rv =  disk_entry->WriteData(0, 0, data, len, &cb, true);
603     rv = cb.GetResult(rv);
604     return (rv == len);
605   }
606 
607   // Helper function to synchronously open a backend entry.
OpenBackendEntry(const std::string & key,disk_cache::Entry ** entry)608   bool OpenBackendEntry(const std::string& key, disk_cache::Entry** entry) {
609     TestCompletionCallback cb;
610     int rv = disk_cache()->OpenEntry(key, entry, &cb);
611     return (cb.GetResult(rv) == net::OK);
612   }
613 
614   // Helper function to synchronously create a backend entry.
CreateBackendEntry(const std::string & key,disk_cache::Entry ** entry,net::NetLog *)615   bool CreateBackendEntry(const std::string& key, disk_cache::Entry** entry,
616                           net::NetLog*  /* net_log */) {
617     TestCompletionCallback cb;
618     int rv = disk_cache()->CreateEntry(key, entry, &cb);
619     return (cb.GetResult(rv) == net::OK);
620   }
621 
622  private:
623   net::HttpCache http_cache_;
624 };
625 
626 // This version of the disk cache doesn't invoke CreateEntry callbacks.
627 class MockDiskCacheNoCB : public MockDiskCache {
CreateEntry(const std::string & key,disk_cache::Entry ** entry,net::CompletionCallback * callback)628   virtual int CreateEntry(const std::string& key, disk_cache::Entry** entry,
629                           net::CompletionCallback* callback) {
630     return net::ERR_IO_PENDING;
631   }
632 };
633 
634 class MockBackendNoCbFactory : public net::HttpCache::BackendFactory {
635  public:
CreateBackend(net::NetLog *,disk_cache::Backend ** backend,net::CompletionCallback * callback)636   virtual int CreateBackend(net::NetLog*  /* net_log */,
637                             disk_cache::Backend** backend,
638                             net::CompletionCallback* callback) {
639     *backend = new MockDiskCacheNoCB();
640     return net::OK;
641   }
642 };
643 
644 // This backend factory allows us to control the backend instantiation.
645 class MockBlockingBackendFactory : public net::HttpCache::BackendFactory {
646  public:
MockBlockingBackendFactory()647   MockBlockingBackendFactory()
648       : backend_(NULL), callback_(NULL), block_(true), fail_(false) {}
649 
CreateBackend(net::NetLog *,disk_cache::Backend ** backend,net::CompletionCallback * callback)650   virtual int CreateBackend(net::NetLog*  /* net_log */,
651                             disk_cache::Backend** backend,
652                             net::CompletionCallback* callback) {
653     if (!block_) {
654       if (!fail_)
655         *backend = new MockDiskCache();
656       return Result();
657     }
658 
659     backend_ =  backend;
660     callback_ = callback;
661     return net::ERR_IO_PENDING;
662   }
663 
664   // Completes the backend creation. Any blocked call will be notified via the
665   // provided callback.
FinishCreation()666   void FinishCreation() {
667     block_ = false;
668     if (callback_) {
669       if (!fail_)
670         *backend_ = new MockDiskCache();
671       net::CompletionCallback* cb = callback_;
672       callback_ = NULL;
673       cb->Run(Result());  // This object can be deleted here.
674     }
675   }
676 
backend()677   disk_cache::Backend** backend() { return backend_; }
set_fail(bool fail)678   void set_fail(bool fail) { fail_ = fail; }
679 
callback()680   net::CompletionCallback* callback() { return callback_; }
681 
682  private:
Result()683   int Result() { return fail_ ? net::ERR_FAILED : net::OK; }
684 
685   disk_cache::Backend** backend_;
686   net::CompletionCallback* callback_;
687   bool block_;
688   bool fail_;
689 };
690 
691 class DeleteCacheCompletionCallback : public TestCompletionCallback {
692  public:
DeleteCacheCompletionCallback(MockHttpCache * cache)693   explicit DeleteCacheCompletionCallback(MockHttpCache* cache)
694       : cache_(cache) {}
695 
RunWithParams(const Tuple1<int> & params)696   virtual void RunWithParams(const Tuple1<int>& params) {
697     delete cache_;
698     TestCompletionCallback::RunWithParams(params);
699   }
700 
701  private:
702   MockHttpCache* cache_;
703 };
704 
705 //-----------------------------------------------------------------------------
706 // helpers
707 
ReadAndVerifyTransaction(net::HttpTransaction * trans,const MockTransaction & trans_info)708 void ReadAndVerifyTransaction(net::HttpTransaction* trans,
709                               const MockTransaction& trans_info) {
710   std::string content;
711   int rv = ReadTransaction(trans, &content);
712 
713   EXPECT_EQ(net::OK, rv);
714   std::string expected(trans_info.data);
715   EXPECT_EQ(expected, content);
716 }
717 
RunTransactionTestWithRequestAndLog(net::HttpCache * cache,const MockTransaction & trans_info,const MockHttpRequest & request,net::HttpResponseInfo * response_info,const net::BoundNetLog & net_log)718 void RunTransactionTestWithRequestAndLog(net::HttpCache* cache,
719                                          const MockTransaction& trans_info,
720                                          const MockHttpRequest& request,
721                                          net::HttpResponseInfo* response_info,
722                                          const net::BoundNetLog& net_log) {
723   TestCompletionCallback callback;
724 
725   // write to the cache
726 
727   scoped_ptr<net::HttpTransaction> trans;
728   int rv = cache->CreateTransaction(&trans);
729   EXPECT_EQ(net::OK, rv);
730   ASSERT_TRUE(trans.get());
731 
732   rv = trans->Start(&request, &callback, net_log);
733   if (rv == net::ERR_IO_PENDING)
734     rv = callback.WaitForResult();
735   ASSERT_EQ(net::OK, rv);
736 
737   const net::HttpResponseInfo* response = trans->GetResponseInfo();
738   ASSERT_TRUE(response);
739 
740   if (response_info)
741     *response_info = *response;
742 
743   ReadAndVerifyTransaction(trans.get(), trans_info);
744 }
745 
RunTransactionTestWithRequest(net::HttpCache * cache,const MockTransaction & trans_info,const MockHttpRequest & request,net::HttpResponseInfo * response_info)746 void RunTransactionTestWithRequest(net::HttpCache* cache,
747                                    const MockTransaction& trans_info,
748                                    const MockHttpRequest& request,
749                                    net::HttpResponseInfo* response_info) {
750   RunTransactionTestWithRequestAndLog(cache, trans_info, request,
751                                       response_info, net::BoundNetLog());
752 }
753 
RunTransactionTestWithLog(net::HttpCache * cache,const MockTransaction & trans_info,const net::BoundNetLog & log)754 void RunTransactionTestWithLog(net::HttpCache* cache,
755                                const MockTransaction& trans_info,
756                                const net::BoundNetLog& log) {
757   RunTransactionTestWithRequestAndLog(
758       cache, trans_info, MockHttpRequest(trans_info), NULL, log);
759 }
760 
RunTransactionTest(net::HttpCache * cache,const MockTransaction & trans_info)761 void RunTransactionTest(net::HttpCache* cache,
762                         const MockTransaction& trans_info) {
763   RunTransactionTestWithLog(cache, trans_info, net::BoundNetLog());
764 }
765 
RunTransactionTestWithResponseInfo(net::HttpCache * cache,const MockTransaction & trans_info,net::HttpResponseInfo * response)766 void RunTransactionTestWithResponseInfo(net::HttpCache* cache,
767                                         const MockTransaction& trans_info,
768                                         net::HttpResponseInfo* response) {
769   RunTransactionTestWithRequest(
770       cache, trans_info, MockHttpRequest(trans_info), response);
771 }
772 
RunTransactionTestWithResponse(net::HttpCache * cache,const MockTransaction & trans_info,std::string * response_headers)773 void RunTransactionTestWithResponse(net::HttpCache* cache,
774                                     const MockTransaction& trans_info,
775                                     std::string* response_headers) {
776   net::HttpResponseInfo response;
777   RunTransactionTestWithResponseInfo(cache, trans_info, &response);
778   response.headers->GetNormalizedHeaders(response_headers);
779 }
780 
781 // This class provides a handler for kFastNoStoreGET_Transaction so that the
782 // no-store header can be included on demand.
783 class FastTransactionServer {
784  public:
FastTransactionServer()785   FastTransactionServer() {
786     no_store = false;
787   }
~FastTransactionServer()788   ~FastTransactionServer() {}
789 
set_no_store(bool value)790   void set_no_store(bool value) { no_store = value; }
791 
FastNoStoreHandler(const net::HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)792   static void FastNoStoreHandler(const net::HttpRequestInfo* request,
793                                  std::string* response_status,
794                                  std::string* response_headers,
795                                  std::string* response_data) {
796     if (no_store)
797       *response_headers = "Cache-Control: no-store\n";
798   }
799 
800  private:
801   static bool no_store;
802   DISALLOW_COPY_AND_ASSIGN(FastTransactionServer);
803 };
804 bool FastTransactionServer::no_store;
805 
806 const MockTransaction kFastNoStoreGET_Transaction = {
807   "http://www.google.com/nostore",
808   "GET",
809   base::Time(),
810   "",
811   net::LOAD_VALIDATE_CACHE,
812   "HTTP/1.1 200 OK",
813   "Cache-Control: max-age=10000\n",
814   base::Time(),
815   "<html><body>Google Blah Blah</body></html>",
816   TEST_MODE_SYNC_NET_START,
817   &FastTransactionServer::FastNoStoreHandler,
818   0
819 };
820 
821 // This class provides a handler for kRangeGET_TransactionOK so that the range
822 // request can be served on demand.
823 class RangeTransactionServer {
824  public:
RangeTransactionServer()825   RangeTransactionServer() {
826     not_modified_ = false;
827     modified_ = false;
828     bad_200_ = false;
829   }
~RangeTransactionServer()830   ~RangeTransactionServer() {
831     not_modified_ = false;
832     modified_ = false;
833     bad_200_ = false;
834   }
835 
836   // Returns only 416 or 304 when set.
set_not_modified(bool value)837   void set_not_modified(bool value) { not_modified_ = value; }
838 
839   // Returns 206 when revalidating a range (instead of 304).
set_modified(bool value)840   void set_modified(bool value) { modified_ = value; }
841 
842   // Returns 200 instead of 206 (a malformed response overall).
set_bad_200(bool value)843   void set_bad_200(bool value) { bad_200_ = value; }
844 
845   static void RangeHandler(const net::HttpRequestInfo* request,
846                            std::string* response_status,
847                            std::string* response_headers,
848                            std::string* response_data);
849 
850  private:
851   static bool not_modified_;
852   static bool modified_;
853   static bool bad_200_;
854   DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer);
855 };
856 bool RangeTransactionServer::not_modified_ = false;
857 bool RangeTransactionServer::modified_ = false;
858 bool RangeTransactionServer::bad_200_ = false;
859 
860 // A dummy extra header that must be preserved on a given request.
861 #define EXTRA_HEADER "Extra: header"
862 static const char kExtraHeaderKey[] = "Extra";
863 
864 // Static.
RangeHandler(const net::HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)865 void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request,
866                                           std::string* response_status,
867                                           std::string* response_headers,
868                                           std::string* response_data) {
869   if (request->extra_headers.IsEmpty()) {
870     response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
871     response_data->clear();
872     return;
873   }
874 
875   // We want to make sure we don't delete extra headers.
876   EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
877 
878   if (not_modified_) {
879     response_status->assign("HTTP/1.1 304 Not Modified");
880     response_data->clear();
881     return;
882   }
883 
884   std::vector<net::HttpByteRange> ranges;
885   std::string range_header;
886   if (!request->extra_headers.GetHeader(
887           net::HttpRequestHeaders::kRange, &range_header) ||
888       !net::HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ ||
889       ranges.size() != 1) {
890     // This is not a byte range request. We return 200.
891     response_status->assign("HTTP/1.1 200 OK");
892     response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
893     response_data->assign("Not a range");
894     return;
895   }
896 
897   // We can handle this range request.
898   net::HttpByteRange byte_range = ranges[0];
899   if (byte_range.first_byte_position() > 79) {
900     response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
901     response_data->clear();
902     return;
903   }
904 
905   EXPECT_TRUE(byte_range.ComputeBounds(80));
906   int start = static_cast<int>(byte_range.first_byte_position());
907   int end = static_cast<int>(byte_range.last_byte_position());
908 
909   EXPECT_LT(end, 80);
910 
911   std::string content_range = base::StringPrintf(
912       "Content-Range: bytes %d-%d/80\n", start, end);
913   response_headers->append(content_range);
914 
915   if (!request->extra_headers.HasHeader("If-None-Match") || modified_) {
916     std::string data;
917     if (end == start) {
918       EXPECT_EQ(0, end % 10);
919       data = "r";
920     } else {
921       EXPECT_EQ(9, (end - start) % 10);
922       for (int block_start = start; block_start < end; block_start += 10) {
923         base::StringAppendF(&data, "rg: %02d-%02d ",
924                             block_start, block_start + 9);
925       }
926     }
927     *response_data = data;
928 
929     if (end - start != 9) {
930       // We also have to fix content-length.
931       int len = end - start + 1;
932       std::string content_length = base::StringPrintf("Content-Length: %d\n",
933                                                       len);
934       response_headers->replace(response_headers->find("Content-Length:"),
935                                 content_length.size(), content_length);
936     }
937   } else {
938     response_status->assign("HTTP/1.1 304 Not Modified");
939     response_data->clear();
940   }
941 }
942 
943 const MockTransaction kRangeGET_TransactionOK = {
944   "http://www.google.com/range",
945   "GET",
946   base::Time(),
947   "Range: bytes = 40-49\r\n"
948   EXTRA_HEADER,
949   net::LOAD_NORMAL,
950   "HTTP/1.1 206 Partial Content",
951   "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
952   "ETag: \"foo\"\n"
953   "Accept-Ranges: bytes\n"
954   "Content-Length: 10\n",
955   base::Time(),
956   "rg: 40-49 ",
957   TEST_MODE_NORMAL,
958   &RangeTransactionServer::RangeHandler,
959   0
960 };
961 
962 // Verifies the response headers (|response|) match a partial content
963 // response for the range starting at |start| and ending at |end|.
Verify206Response(std::string response,int start,int end)964 void Verify206Response(std::string response, int start, int end) {
965   std::string raw_headers(net::HttpUtil::AssembleRawHeaders(response.data(),
966                                                             response.size()));
967   scoped_refptr<net::HttpResponseHeaders> headers(
968       new net::HttpResponseHeaders(raw_headers));
969 
970   ASSERT_EQ(206, headers->response_code());
971 
972   int64 range_start, range_end, object_size;
973   ASSERT_TRUE(
974       headers->GetContentRange(&range_start, &range_end, &object_size));
975   int64 content_length = headers->GetContentLength();
976 
977   int length = end - start + 1;
978   ASSERT_EQ(length, content_length);
979   ASSERT_EQ(start, range_start);
980   ASSERT_EQ(end, range_end);
981 }
982 
983 // Creates a truncated entry that can be resumed using byte ranges.
CreateTruncatedEntry(std::string raw_headers,MockHttpCache * cache)984 void CreateTruncatedEntry(std::string raw_headers, MockHttpCache* cache) {
985   // Create a disk cache entry that stores an incomplete resource.
986   disk_cache::Entry* entry;
987   ASSERT_TRUE(cache->CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
988                                         NULL));
989 
990   raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
991                                                   raw_headers.size());
992 
993   net::HttpResponseInfo response;
994   response.response_time = base::Time::Now();
995   response.request_time = base::Time::Now();
996   response.headers = new net::HttpResponseHeaders(raw_headers);
997   // Set the last argument for this to be an incomplete request.
998   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
999 
1000   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100));
1001   int len = static_cast<int>(base::strlcpy(buf->data(),
1002                                            "rg: 00-09 rg: 10-19 ", 100));
1003   TestCompletionCallback cb;
1004   int rv = entry->WriteData(1, 0, buf, len, &cb, true);
1005   EXPECT_EQ(len, cb.GetResult(rv));
1006   entry->Close();
1007 }
1008 
1009 // Helper to represent a network HTTP response.
1010 struct Response {
1011   // Set this response into |trans|.
AssignTo__anond9c04f320111::Response1012   void AssignTo(MockTransaction* trans) const {
1013     trans->status = status;
1014     trans->response_headers = headers;
1015     trans->data = body;
1016   }
1017 
status_and_headers__anond9c04f320111::Response1018   std::string status_and_headers() const {
1019     return std::string(status) + "\n" + std::string(headers);
1020   }
1021 
1022   const char* status;
1023   const char* headers;
1024   const char* body;
1025 };
1026 
1027 struct Context {
Context__anond9c04f320111::Context1028   Context() : result(net::ERR_IO_PENDING) {}
1029 
1030   int result;
1031   TestCompletionCallback callback;
1032   scoped_ptr<net::HttpTransaction> trans;
1033 };
1034 
1035 }  // namespace
1036 
1037 
1038 //-----------------------------------------------------------------------------
1039 // tests
1040 
TEST(HttpCache,CreateThenDestroy)1041 TEST(HttpCache, CreateThenDestroy) {
1042   MockHttpCache cache;
1043 
1044   scoped_ptr<net::HttpTransaction> trans;
1045   int rv = cache.http_cache()->CreateTransaction(&trans);
1046   EXPECT_EQ(net::OK, rv);
1047   ASSERT_TRUE(trans.get());
1048 }
1049 
TEST(HttpCache,GetBackend)1050 TEST(HttpCache, GetBackend) {
1051   MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(0));
1052 
1053   disk_cache::Backend* backend;
1054   TestCompletionCallback cb;
1055   // This will lazily initialize the backend.
1056   int rv = cache.http_cache()->GetBackend(&backend, &cb);
1057   EXPECT_EQ(net::OK, cb.GetResult(rv));
1058 }
1059 
TEST(HttpCache,SimpleGET)1060 TEST(HttpCache, SimpleGET) {
1061   MockHttpCache cache;
1062 
1063   // write to the cache
1064   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1065 
1066   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1067   EXPECT_EQ(0, cache.disk_cache()->open_count());
1068   EXPECT_EQ(1, cache.disk_cache()->create_count());
1069 }
1070 
TEST(HttpCache,SimpleGETNoDiskCache)1071 TEST(HttpCache, SimpleGETNoDiskCache) {
1072   MockHttpCache cache;
1073 
1074   cache.disk_cache()->set_fail_requests();
1075 
1076   net::CapturingBoundNetLog log(net::CapturingNetLog::kUnbounded);
1077   log.SetLogLevel(net::NetLog::LOG_BASIC);
1078 
1079   // Read from the network, and don't use the cache.
1080   RunTransactionTestWithLog(cache.http_cache(), kSimpleGET_Transaction,
1081                             log.bound());
1082 
1083   // Check that the NetLog was filled as expected.
1084   // (We attempted to both Open and Create entries, but both failed).
1085   net::CapturingNetLog::EntryList entries;
1086   log.GetEntries(&entries);
1087 
1088   EXPECT_EQ(6u, entries.size());
1089   EXPECT_TRUE(net::LogContainsBeginEvent(
1090       entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1091   EXPECT_TRUE(net::LogContainsEndEvent(
1092       entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1093   EXPECT_TRUE(net::LogContainsBeginEvent(
1094       entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
1095   EXPECT_TRUE(net::LogContainsEndEvent(
1096       entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
1097   EXPECT_TRUE(net::LogContainsBeginEvent(
1098       entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1099   EXPECT_TRUE(net::LogContainsEndEvent(
1100       entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1101 
1102   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1103   EXPECT_EQ(0, cache.disk_cache()->open_count());
1104   EXPECT_EQ(0, cache.disk_cache()->create_count());
1105 }
1106 
TEST(HttpCache,SimpleGETNoDiskCache2)1107 TEST(HttpCache, SimpleGETNoDiskCache2) {
1108   // This will initialize a cache object with NULL backend.
1109   MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1110   factory->set_fail(true);
1111   factory->FinishCreation();  // We'll complete synchronously.
1112   MockHttpCache cache(factory);
1113 
1114   // Read from the network, and don't use the cache.
1115   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1116 
1117   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1118   EXPECT_FALSE(cache.http_cache()->GetCurrentBackend());
1119 }
1120 
TEST(HttpCache,SimpleGETWithDiskFailures)1121 TEST(HttpCache, SimpleGETWithDiskFailures) {
1122   MockHttpCache cache;
1123 
1124   cache.disk_cache()->set_soft_failures(true);
1125 
1126   // Read from the network, and fail to write to the cache.
1127   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1128 
1129   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1130   EXPECT_EQ(0, cache.disk_cache()->open_count());
1131   EXPECT_EQ(1, cache.disk_cache()->create_count());
1132 
1133   // This one should see an empty cache again.
1134   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1135 
1136   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1137   EXPECT_EQ(0, cache.disk_cache()->open_count());
1138   EXPECT_EQ(2, cache.disk_cache()->create_count());
1139 }
1140 
1141 // Tests that disk failures after the transaction has started don't cause the
1142 // request to fail.
TEST(HttpCache,SimpleGETWithDiskFailures2)1143 TEST(HttpCache, SimpleGETWithDiskFailures2) {
1144   MockHttpCache cache;
1145 
1146   MockHttpRequest request(kSimpleGET_Transaction);
1147 
1148   scoped_ptr<Context> c(new Context());
1149   int rv = cache.http_cache()->CreateTransaction(&c->trans);
1150   EXPECT_EQ(net::OK, rv);
1151 
1152   rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
1153   EXPECT_EQ(net::ERR_IO_PENDING, rv);
1154   rv = c->callback.WaitForResult();
1155 
1156   // Start failing request now.
1157   cache.disk_cache()->set_soft_failures(true);
1158 
1159   // We have to open the entry again to propagate the failure flag.
1160   disk_cache::Entry* en;
1161   ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en));
1162   en->Close();
1163 
1164   ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1165   c.reset();
1166 
1167   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1168   EXPECT_EQ(1, cache.disk_cache()->open_count());
1169   EXPECT_EQ(1, cache.disk_cache()->create_count());
1170 
1171   // This one should see an empty cache again.
1172   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1173 
1174   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1175   EXPECT_EQ(1, cache.disk_cache()->open_count());
1176   EXPECT_EQ(2, cache.disk_cache()->create_count());
1177 }
1178 
1179 // Tests that we don't crash after failures to read from the cache.
TEST(HttpCache,SimpleGETWithDiskFailures3)1180 TEST(HttpCache, SimpleGETWithDiskFailures3) {
1181   MockHttpCache cache;
1182 
1183   // Read from the network, and write to the cache.
1184   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1185 
1186   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1187   EXPECT_EQ(0, cache.disk_cache()->open_count());
1188   EXPECT_EQ(1, cache.disk_cache()->create_count());
1189 
1190   cache.disk_cache()->set_soft_failures(true);
1191 
1192   // Now fail to read from the cache.
1193   scoped_ptr<Context> c(new Context());
1194   int rv = cache.http_cache()->CreateTransaction(&c->trans);
1195   EXPECT_EQ(net::OK, rv);
1196 
1197   MockHttpRequest request(kSimpleGET_Transaction);
1198   rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
1199   EXPECT_EQ(net::ERR_CACHE_READ_FAILURE, c->callback.GetResult(rv));
1200 }
1201 
TEST(HttpCache,SimpleGET_LoadOnlyFromCache_Hit)1202 TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit) {
1203   MockHttpCache cache;
1204 
1205   net::CapturingBoundNetLog log(net::CapturingNetLog::kUnbounded);
1206 
1207   // This prevents a number of write events from being logged.
1208   log.SetLogLevel(net::NetLog::LOG_BASIC);
1209 
1210   // write to the cache
1211   RunTransactionTestWithLog(cache.http_cache(), kSimpleGET_Transaction,
1212                             log.bound());
1213 
1214   // Check that the NetLog was filled as expected.
1215   net::CapturingNetLog::EntryList entries;
1216   log.GetEntries(&entries);
1217 
1218   EXPECT_EQ(8u, entries.size());
1219   EXPECT_TRUE(net::LogContainsBeginEvent(
1220       entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1221   EXPECT_TRUE(net::LogContainsEndEvent(
1222       entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1223   EXPECT_TRUE(net::LogContainsBeginEvent(
1224       entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
1225   EXPECT_TRUE(net::LogContainsEndEvent(
1226       entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
1227   EXPECT_TRUE(net::LogContainsBeginEvent(
1228       entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1229   EXPECT_TRUE(net::LogContainsEndEvent(
1230       entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1231   EXPECT_TRUE(net::LogContainsBeginEvent(
1232       entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1233   EXPECT_TRUE(net::LogContainsEndEvent(
1234       entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1235 
1236   // force this transaction to read from the cache
1237   MockTransaction transaction(kSimpleGET_Transaction);
1238   transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
1239 
1240   log.Clear();
1241 
1242   RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound());
1243 
1244   // Check that the NetLog was filled as expected.
1245   log.GetEntries(&entries);
1246 
1247   EXPECT_EQ(8u, entries.size());
1248   EXPECT_TRUE(net::LogContainsBeginEvent(
1249       entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1250   EXPECT_TRUE(net::LogContainsEndEvent(
1251       entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1252   EXPECT_TRUE(net::LogContainsBeginEvent(
1253       entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
1254   EXPECT_TRUE(net::LogContainsEndEvent(
1255       entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
1256   EXPECT_TRUE(net::LogContainsBeginEvent(
1257       entries, 4, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1258   EXPECT_TRUE(net::LogContainsEndEvent(
1259       entries, 5, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1260   EXPECT_TRUE(net::LogContainsBeginEvent(
1261       entries, 6, net::NetLog::TYPE_HTTP_CACHE_READ_INFO));
1262   EXPECT_TRUE(net::LogContainsEndEvent(
1263       entries, 7, net::NetLog::TYPE_HTTP_CACHE_READ_INFO));
1264 
1265   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1266   EXPECT_EQ(1, cache.disk_cache()->open_count());
1267   EXPECT_EQ(1, cache.disk_cache()->create_count());
1268 }
1269 
TEST(HttpCache,SimpleGET_LoadOnlyFromCache_Miss)1270 TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Miss) {
1271   MockHttpCache cache;
1272 
1273   // force this transaction to read from the cache
1274   MockTransaction transaction(kSimpleGET_Transaction);
1275   transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
1276 
1277   MockHttpRequest request(transaction);
1278   TestCompletionCallback callback;
1279 
1280   scoped_ptr<net::HttpTransaction> trans;
1281   int rv = cache.http_cache()->CreateTransaction(&trans);
1282   EXPECT_EQ(net::OK, rv);
1283   ASSERT_TRUE(trans.get());
1284 
1285   rv = trans->Start(&request, &callback, net::BoundNetLog());
1286   if (rv == net::ERR_IO_PENDING)
1287     rv = callback.WaitForResult();
1288   ASSERT_EQ(net::ERR_CACHE_MISS, rv);
1289 
1290   trans.reset();
1291 
1292   EXPECT_EQ(0, cache.network_layer()->transaction_count());
1293   EXPECT_EQ(0, cache.disk_cache()->open_count());
1294   EXPECT_EQ(0, cache.disk_cache()->create_count());
1295 }
1296 
TEST(HttpCache,SimpleGET_LoadPreferringCache_Hit)1297 TEST(HttpCache, SimpleGET_LoadPreferringCache_Hit) {
1298   MockHttpCache cache;
1299 
1300   // write to the cache
1301   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1302 
1303   // force this transaction to read from the cache if valid
1304   MockTransaction transaction(kSimpleGET_Transaction);
1305   transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
1306 
1307   RunTransactionTest(cache.http_cache(), transaction);
1308 
1309   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1310   EXPECT_EQ(1, cache.disk_cache()->open_count());
1311   EXPECT_EQ(1, cache.disk_cache()->create_count());
1312 }
1313 
TEST(HttpCache,SimpleGET_LoadPreferringCache_Miss)1314 TEST(HttpCache, SimpleGET_LoadPreferringCache_Miss) {
1315   MockHttpCache cache;
1316 
1317   // force this transaction to read from the cache if valid
1318   MockTransaction transaction(kSimpleGET_Transaction);
1319   transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
1320 
1321   RunTransactionTest(cache.http_cache(), transaction);
1322 
1323   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1324   EXPECT_EQ(0, cache.disk_cache()->open_count());
1325   EXPECT_EQ(1, cache.disk_cache()->create_count());
1326 }
1327 
TEST(HttpCache,SimpleGET_LoadBypassCache)1328 TEST(HttpCache, SimpleGET_LoadBypassCache) {
1329   MockHttpCache cache;
1330 
1331   // Write to the cache.
1332   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1333 
1334   // Force this transaction to write to the cache again.
1335   MockTransaction transaction(kSimpleGET_Transaction);
1336   transaction.load_flags |= net::LOAD_BYPASS_CACHE;
1337 
1338   net::CapturingBoundNetLog log(net::CapturingNetLog::kUnbounded);
1339 
1340   // This prevents a number of write events from being logged.
1341   log.SetLogLevel(net::NetLog::LOG_BASIC);
1342 
1343   RunTransactionTestWithLog(cache.http_cache(), transaction, log.bound());
1344 
1345   // Check that the NetLog was filled as expected.
1346   net::CapturingNetLog::EntryList entries;
1347   log.GetEntries(&entries);
1348 
1349   EXPECT_EQ(8u, entries.size());
1350   EXPECT_TRUE(net::LogContainsBeginEvent(
1351       entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1352   EXPECT_TRUE(net::LogContainsEndEvent(
1353       entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1354   EXPECT_TRUE(net::LogContainsBeginEvent(
1355       entries, 2, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1356   EXPECT_TRUE(net::LogContainsEndEvent(
1357       entries, 3, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1358   EXPECT_TRUE(net::LogContainsBeginEvent(
1359       entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1360   EXPECT_TRUE(net::LogContainsEndEvent(
1361       entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1362   EXPECT_TRUE(net::LogContainsBeginEvent(
1363       entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1364   EXPECT_TRUE(net::LogContainsEndEvent(
1365       entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1366 
1367   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1368   EXPECT_EQ(0, cache.disk_cache()->open_count());
1369   EXPECT_EQ(2, cache.disk_cache()->create_count());
1370 }
1371 
TEST(HttpCache,SimpleGET_LoadBypassCache_Implicit)1372 TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit) {
1373   MockHttpCache cache;
1374 
1375   // write to the cache
1376   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1377 
1378   // force this transaction to write to the cache again
1379   MockTransaction transaction(kSimpleGET_Transaction);
1380   transaction.request_headers = "pragma: no-cache";
1381 
1382   RunTransactionTest(cache.http_cache(), transaction);
1383 
1384   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1385   EXPECT_EQ(0, cache.disk_cache()->open_count());
1386   EXPECT_EQ(2, cache.disk_cache()->create_count());
1387 }
1388 
TEST(HttpCache,SimpleGET_LoadBypassCache_Implicit2)1389 TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit2) {
1390   MockHttpCache cache;
1391 
1392   // write to the cache
1393   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1394 
1395   // force this transaction to write to the cache again
1396   MockTransaction transaction(kSimpleGET_Transaction);
1397   transaction.request_headers = "cache-control: no-cache";
1398 
1399   RunTransactionTest(cache.http_cache(), transaction);
1400 
1401   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1402   EXPECT_EQ(0, cache.disk_cache()->open_count());
1403   EXPECT_EQ(2, cache.disk_cache()->create_count());
1404 }
1405 
TEST(HttpCache,SimpleGET_LoadValidateCache)1406 TEST(HttpCache, SimpleGET_LoadValidateCache) {
1407   MockHttpCache cache;
1408 
1409   // write to the cache
1410   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1411 
1412   // read from the cache
1413   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1414 
1415   // force this transaction to validate the cache
1416   MockTransaction transaction(kSimpleGET_Transaction);
1417   transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
1418 
1419   RunTransactionTest(cache.http_cache(), transaction);
1420 
1421   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1422   EXPECT_EQ(1, cache.disk_cache()->open_count());
1423   EXPECT_EQ(1, cache.disk_cache()->create_count());
1424 }
1425 
TEST(HttpCache,SimpleGET_LoadValidateCache_Implicit)1426 TEST(HttpCache, SimpleGET_LoadValidateCache_Implicit) {
1427   MockHttpCache cache;
1428 
1429   // write to the cache
1430   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1431 
1432   // read from the cache
1433   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1434 
1435   // force this transaction to validate the cache
1436   MockTransaction transaction(kSimpleGET_Transaction);
1437   transaction.request_headers = "cache-control: max-age=0";
1438 
1439   RunTransactionTest(cache.http_cache(), transaction);
1440 
1441   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1442   EXPECT_EQ(1, cache.disk_cache()->open_count());
1443   EXPECT_EQ(1, cache.disk_cache()->create_count());
1444 }
1445 
PreserveRequestHeaders_Handler(const net::HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)1446 static void PreserveRequestHeaders_Handler(
1447     const net::HttpRequestInfo* request,
1448     std::string* response_status,
1449     std::string* response_headers,
1450     std::string* response_data) {
1451   EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
1452 }
1453 
1454 // Tests that we don't remove extra headers for simple requests.
TEST(HttpCache,SimpleGET_PreserveRequestHeaders)1455 TEST(HttpCache, SimpleGET_PreserveRequestHeaders) {
1456   MockHttpCache cache;
1457 
1458   MockTransaction transaction(kSimpleGET_Transaction);
1459   transaction.handler = PreserveRequestHeaders_Handler;
1460   transaction.request_headers = EXTRA_HEADER;
1461   transaction.response_headers = "Cache-Control: max-age=0\n";
1462   AddMockTransaction(&transaction);
1463 
1464   // Write, then revalidate the entry.
1465   RunTransactionTest(cache.http_cache(), transaction);
1466   RunTransactionTest(cache.http_cache(), transaction);
1467 
1468   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1469   EXPECT_EQ(1, cache.disk_cache()->open_count());
1470   EXPECT_EQ(1, cache.disk_cache()->create_count());
1471   RemoveMockTransaction(&transaction);
1472 }
1473 
1474 // Tests that we don't remove extra headers for conditionalized requests.
TEST(HttpCache,ConditionalizedGET_PreserveRequestHeaders)1475 TEST(HttpCache, ConditionalizedGET_PreserveRequestHeaders) {
1476   MockHttpCache cache;
1477 
1478   // Write to the cache.
1479   RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
1480 
1481   MockTransaction transaction(kETagGET_Transaction);
1482   transaction.handler = PreserveRequestHeaders_Handler;
1483   transaction.request_headers = "If-None-Match: \"foopy\"\r\n"
1484                                 EXTRA_HEADER;
1485   AddMockTransaction(&transaction);
1486 
1487   RunTransactionTest(cache.http_cache(), transaction);
1488 
1489   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1490   EXPECT_EQ(1, cache.disk_cache()->open_count());
1491   EXPECT_EQ(1, cache.disk_cache()->create_count());
1492   RemoveMockTransaction(&transaction);
1493 }
1494 
TEST(HttpCache,SimpleGET_ManyReaders)1495 TEST(HttpCache, SimpleGET_ManyReaders) {
1496   MockHttpCache cache;
1497 
1498   MockHttpRequest request(kSimpleGET_Transaction);
1499 
1500   std::vector<Context*> context_list;
1501   const int kNumTransactions = 5;
1502 
1503   for (int i = 0; i < kNumTransactions; ++i) {
1504     context_list.push_back(new Context());
1505     Context* c = context_list[i];
1506 
1507     c->result = cache.http_cache()->CreateTransaction(&c->trans);
1508     EXPECT_EQ(net::OK, c->result);
1509     EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
1510 
1511     c->result = c->trans->Start(&request, &c->callback, net::BoundNetLog());
1512   }
1513 
1514   // All requests are waiting for the active entry.
1515   for (int i = 0; i < kNumTransactions; ++i) {
1516     Context* c = context_list[i];
1517     EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState());
1518   }
1519 
1520   // Allow all requests to move from the Create queue to the active entry.
1521   MessageLoop::current()->RunAllPending();
1522 
1523   // The first request should be a writer at this point, and the subsequent
1524   // requests should be pending.
1525 
1526   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1527   EXPECT_EQ(0, cache.disk_cache()->open_count());
1528   EXPECT_EQ(1, cache.disk_cache()->create_count());
1529 
1530   // All requests depend on the writer, and the writer is between Start and
1531   // Read, i.e. idle.
1532   for (int i = 0; i < kNumTransactions; ++i) {
1533     Context* c = context_list[i];
1534     EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
1535   }
1536 
1537   for (int i = 0; i < kNumTransactions; ++i) {
1538     Context* c = context_list[i];
1539     if (c->result == net::ERR_IO_PENDING)
1540       c->result = c->callback.WaitForResult();
1541     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1542   }
1543 
1544   // We should not have had to re-open the disk entry
1545 
1546   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1547   EXPECT_EQ(0, cache.disk_cache()->open_count());
1548   EXPECT_EQ(1, cache.disk_cache()->create_count());
1549 
1550   for (int i = 0; i < kNumTransactions; ++i) {
1551     Context* c = context_list[i];
1552     delete c;
1553   }
1554 }
1555 
1556 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1557 // If cancelling a request is racing with another request for the same resource
1558 // finishing, we have to make sure that we remove both transactions from the
1559 // entry.
TEST(HttpCache,SimpleGET_RacingReaders)1560 TEST(HttpCache, SimpleGET_RacingReaders) {
1561   MockHttpCache cache;
1562 
1563   MockHttpRequest request(kSimpleGET_Transaction);
1564   MockHttpRequest reader_request(kSimpleGET_Transaction);
1565   reader_request.load_flags = net::LOAD_ONLY_FROM_CACHE;
1566 
1567   std::vector<Context*> context_list;
1568   const int kNumTransactions = 5;
1569 
1570   for (int i = 0; i < kNumTransactions; ++i) {
1571     context_list.push_back(new Context());
1572     Context* c = context_list[i];
1573 
1574     c->result = cache.http_cache()->CreateTransaction(&c->trans);
1575     EXPECT_EQ(net::OK, c->result);
1576 
1577     MockHttpRequest* this_request = &request;
1578     if (i == 1 || i == 2)
1579       this_request = &reader_request;
1580 
1581     c->result = c->trans->Start(this_request, &c->callback, net::BoundNetLog());
1582   }
1583 
1584   // Allow all requests to move from the Create queue to the active entry.
1585   MessageLoop::current()->RunAllPending();
1586 
1587   // The first request should be a writer at this point, and the subsequent
1588   // requests should be pending.
1589 
1590   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1591   EXPECT_EQ(0, cache.disk_cache()->open_count());
1592   EXPECT_EQ(1, cache.disk_cache()->create_count());
1593 
1594   Context* c = context_list[0];
1595   ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1596   c->result = c->callback.WaitForResult();
1597   ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1598 
1599   // Now we have 2 active readers and two queued transactions.
1600 
1601   EXPECT_EQ(net::LOAD_STATE_IDLE,
1602             context_list[2]->trans->GetLoadState());
1603   EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE,
1604             context_list[3]->trans->GetLoadState());
1605 
1606   c = context_list[1];
1607   ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1608   c->result = c->callback.WaitForResult();
1609   if (c->result == net::OK)
1610     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1611 
1612   // At this point we have one reader, two pending transactions and a task on
1613   // the queue to move to the next transaction. Now we cancel the request that
1614   // is the current reader, and expect the queued task to be able to start the
1615   // next request.
1616 
1617   c = context_list[2];
1618   c->trans.reset();
1619 
1620   for (int i = 3; i < kNumTransactions; ++i) {
1621     Context* c = context_list[i];
1622     if (c->result == net::ERR_IO_PENDING)
1623       c->result = c->callback.WaitForResult();
1624     if (c->result == net::OK)
1625       ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1626   }
1627 
1628   // We should not have had to re-open the disk entry.
1629 
1630   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1631   EXPECT_EQ(0, cache.disk_cache()->open_count());
1632   EXPECT_EQ(1, cache.disk_cache()->create_count());
1633 
1634   for (int i = 0; i < kNumTransactions; ++i) {
1635     Context* c = context_list[i];
1636     delete c;
1637   }
1638 }
1639 
1640 // Tests that we can doom an entry with pending transactions and delete one of
1641 // the pending transactions before the first one completes.
1642 // See http://code.google.com/p/chromium/issues/detail?id=25588
TEST(HttpCache,SimpleGET_DoomWithPending)1643 TEST(HttpCache, SimpleGET_DoomWithPending) {
1644   // We need simultaneous doomed / not_doomed entries so let's use a real cache.
1645   MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
1646 
1647   MockHttpRequest request(kSimpleGET_Transaction);
1648   MockHttpRequest writer_request(kSimpleGET_Transaction);
1649   writer_request.load_flags = net::LOAD_BYPASS_CACHE;
1650 
1651   ScopedVector<Context> context_list;
1652   const int kNumTransactions = 4;
1653 
1654   for (int i = 0; i < kNumTransactions; ++i) {
1655     context_list.push_back(new Context());
1656     Context* c = context_list[i];
1657 
1658     c->result = cache.http_cache()->CreateTransaction(&c->trans);
1659     EXPECT_EQ(net::OK, c->result);
1660 
1661     MockHttpRequest* this_request = &request;
1662     if (i == 3)
1663       this_request = &writer_request;
1664 
1665     c->result = c->trans->Start(this_request, &c->callback, net::BoundNetLog());
1666   }
1667 
1668   // The first request should be a writer at this point, and the two subsequent
1669   // requests should be pending. The last request doomed the first entry.
1670 
1671   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1672 
1673   // Cancel the first queued transaction.
1674   delete context_list[1];
1675   context_list.get()[1] = NULL;
1676 
1677   for (int i = 0; i < kNumTransactions; ++i) {
1678     if (i == 1)
1679       continue;
1680     Context* c = context_list[i];
1681     ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1682     c->result = c->callback.WaitForResult();
1683     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1684   }
1685 }
1686 
1687 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1688 // We may attempt to delete an entry synchronously with the act of adding a new
1689 // transaction to said entry.
TEST(HttpCache,FastNoStoreGET_DoneWithPending)1690 TEST(HttpCache, FastNoStoreGET_DoneWithPending) {
1691   MockHttpCache cache;
1692 
1693   // The headers will be served right from the call to Start() the request.
1694   MockHttpRequest request(kFastNoStoreGET_Transaction);
1695   FastTransactionServer request_handler;
1696   AddMockTransaction(&kFastNoStoreGET_Transaction);
1697 
1698   std::vector<Context*> context_list;
1699   const int kNumTransactions = 3;
1700 
1701   for (int i = 0; i < kNumTransactions; ++i) {
1702     context_list.push_back(new Context());
1703     Context* c = context_list[i];
1704 
1705     c->result = cache.http_cache()->CreateTransaction(&c->trans);
1706     EXPECT_EQ(net::OK, c->result);
1707 
1708     c->result = c->trans->Start(&request, &c->callback, net::BoundNetLog());
1709   }
1710 
1711   // Allow all requests to move from the Create queue to the active entry.
1712   MessageLoop::current()->RunAllPending();
1713 
1714   // The first request should be a writer at this point, and the subsequent
1715   // requests should be pending.
1716 
1717   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1718   EXPECT_EQ(0, cache.disk_cache()->open_count());
1719   EXPECT_EQ(1, cache.disk_cache()->create_count());
1720 
1721   // Now, make sure that the second request asks for the entry not to be stored.
1722   request_handler.set_no_store(true);
1723 
1724   for (int i = 0; i < kNumTransactions; ++i) {
1725     Context* c = context_list[i];
1726     if (c->result == net::ERR_IO_PENDING)
1727       c->result = c->callback.WaitForResult();
1728     ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction);
1729     delete c;
1730   }
1731 
1732   EXPECT_EQ(3, cache.network_layer()->transaction_count());
1733   EXPECT_EQ(0, cache.disk_cache()->open_count());
1734   EXPECT_EQ(2, cache.disk_cache()->create_count());
1735 
1736   RemoveMockTransaction(&kFastNoStoreGET_Transaction);
1737 }
1738 
TEST(HttpCache,SimpleGET_ManyWriters_CancelFirst)1739 TEST(HttpCache, SimpleGET_ManyWriters_CancelFirst) {
1740   MockHttpCache cache;
1741 
1742   MockHttpRequest request(kSimpleGET_Transaction);
1743 
1744   std::vector<Context*> context_list;
1745   const int kNumTransactions = 2;
1746 
1747   for (int i = 0; i < kNumTransactions; ++i) {
1748     context_list.push_back(new Context());
1749     Context* c = context_list[i];
1750 
1751     c->result = cache.http_cache()->CreateTransaction(&c->trans);
1752     EXPECT_EQ(net::OK, c->result);
1753 
1754     c->result = c->trans->Start(&request, &c->callback, net::BoundNetLog());
1755   }
1756 
1757   // Allow all requests to move from the Create queue to the active entry.
1758   MessageLoop::current()->RunAllPending();
1759 
1760   // The first request should be a writer at this point, and the subsequent
1761   // requests should be pending.
1762 
1763   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1764   EXPECT_EQ(0, cache.disk_cache()->open_count());
1765   EXPECT_EQ(1, cache.disk_cache()->create_count());
1766 
1767   for (int i = 0; i < kNumTransactions; ++i) {
1768     Context* c = context_list[i];
1769     if (c->result == net::ERR_IO_PENDING)
1770       c->result = c->callback.WaitForResult();
1771     // Destroy only the first transaction.
1772     if (i == 0) {
1773       delete c;
1774       context_list[i] = NULL;
1775     }
1776   }
1777 
1778   // Complete the rest of the transactions.
1779   for (int i = 1; i < kNumTransactions; ++i) {
1780     Context* c = context_list[i];
1781     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1782   }
1783 
1784   // We should have had to re-open the disk entry.
1785 
1786   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1787   EXPECT_EQ(0, cache.disk_cache()->open_count());
1788   EXPECT_EQ(2, cache.disk_cache()->create_count());
1789 
1790   for (int i = 1; i < kNumTransactions; ++i) {
1791     Context* c = context_list[i];
1792     delete c;
1793   }
1794 }
1795 
1796 // Tests that we can cancel requests that are queued waiting to open the disk
1797 // cache entry.
TEST(HttpCache,SimpleGET_ManyWriters_CancelCreate)1798 TEST(HttpCache, SimpleGET_ManyWriters_CancelCreate) {
1799   MockHttpCache cache;
1800 
1801   MockHttpRequest request(kSimpleGET_Transaction);
1802 
1803   std::vector<Context*> context_list;
1804   const int kNumTransactions = 5;
1805 
1806   for (int i = 0; i < kNumTransactions; i++) {
1807     context_list.push_back(new Context());
1808     Context* c = context_list[i];
1809 
1810     c->result = cache.http_cache()->CreateTransaction(&c->trans);
1811     EXPECT_EQ(net::OK, c->result);
1812 
1813     c->result = c->trans->Start(&request, &c->callback, net::BoundNetLog());
1814   }
1815 
1816   // The first request should be creating the disk cache entry and the others
1817   // should be pending.
1818 
1819   EXPECT_EQ(0, cache.network_layer()->transaction_count());
1820   EXPECT_EQ(0, cache.disk_cache()->open_count());
1821   EXPECT_EQ(1, cache.disk_cache()->create_count());
1822 
1823   // Cancel a request from the pending queue.
1824   delete context_list[3];
1825   context_list[3] = NULL;
1826 
1827   // Cancel the request that is creating the entry. This will force the pending
1828   // operations to restart.
1829   delete context_list[0];
1830   context_list[0] = NULL;
1831 
1832   // Complete the rest of the transactions.
1833   for (int i = 1; i < kNumTransactions; i++) {
1834     Context* c = context_list[i];
1835     if (c) {
1836       c->result = c->callback.GetResult(c->result);
1837       ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1838     }
1839   }
1840 
1841   // We should have had to re-create the disk entry.
1842 
1843   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1844   EXPECT_EQ(0, cache.disk_cache()->open_count());
1845   EXPECT_EQ(2, cache.disk_cache()->create_count());
1846 
1847   for (int i = 1; i < kNumTransactions; ++i) {
1848     delete context_list[i];
1849   }
1850 }
1851 
1852 // Tests that we can cancel a single request to open a disk cache entry.
TEST(HttpCache,SimpleGET_CancelCreate)1853 TEST(HttpCache, SimpleGET_CancelCreate) {
1854   MockHttpCache cache;
1855 
1856   MockHttpRequest request(kSimpleGET_Transaction);
1857 
1858   Context* c = new Context();
1859 
1860   c->result = cache.http_cache()->CreateTransaction(&c->trans);
1861   EXPECT_EQ(net::OK, c->result);
1862 
1863   c->result = c->trans->Start(&request, &c->callback, net::BoundNetLog());
1864   EXPECT_EQ(net::ERR_IO_PENDING, c->result);
1865 
1866   // Release the reference that the mock disk cache keeps for this entry, so
1867   // that we test that the http cache handles the cancelation correctly.
1868   cache.disk_cache()->ReleaseAll();
1869   delete c;
1870 
1871   MessageLoop::current()->RunAllPending();
1872   EXPECT_EQ(1, cache.disk_cache()->create_count());
1873 }
1874 
1875 // Tests that we delete/create entries even if multiple requests are queued.
TEST(HttpCache,SimpleGET_ManyWriters_BypassCache)1876 TEST(HttpCache, SimpleGET_ManyWriters_BypassCache) {
1877   MockHttpCache cache;
1878 
1879   MockHttpRequest request(kSimpleGET_Transaction);
1880   request.load_flags = net::LOAD_BYPASS_CACHE;
1881 
1882   std::vector<Context*> context_list;
1883   const int kNumTransactions = 5;
1884 
1885   for (int i = 0; i < kNumTransactions; i++) {
1886     context_list.push_back(new Context());
1887     Context* c = context_list[i];
1888 
1889     c->result = cache.http_cache()->CreateTransaction(&c->trans);
1890     EXPECT_EQ(net::OK, c->result);
1891 
1892     c->result = c->trans->Start(&request, &c->callback, net::BoundNetLog());
1893   }
1894 
1895   // The first request should be deleting the disk cache entry and the others
1896   // should be pending.
1897 
1898   EXPECT_EQ(0, cache.network_layer()->transaction_count());
1899   EXPECT_EQ(0, cache.disk_cache()->open_count());
1900   EXPECT_EQ(0, cache.disk_cache()->create_count());
1901 
1902   // Complete the transactions.
1903   for (int i = 0; i < kNumTransactions; i++) {
1904     Context* c = context_list[i];
1905     c->result = c->callback.GetResult(c->result);
1906     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1907   }
1908 
1909   // We should have had to re-create the disk entry multiple times.
1910 
1911   EXPECT_EQ(5, cache.network_layer()->transaction_count());
1912   EXPECT_EQ(0, cache.disk_cache()->open_count());
1913   EXPECT_EQ(5, cache.disk_cache()->create_count());
1914 
1915   for (int i = 0; i < kNumTransactions; ++i) {
1916     delete context_list[i];
1917   }
1918 }
1919 
TEST(HttpCache,SimpleGET_AbandonedCacheRead)1920 TEST(HttpCache, SimpleGET_AbandonedCacheRead) {
1921   MockHttpCache cache;
1922 
1923   // write to the cache
1924   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1925 
1926   MockHttpRequest request(kSimpleGET_Transaction);
1927   TestCompletionCallback callback;
1928 
1929   scoped_ptr<net::HttpTransaction> trans;
1930   int rv = cache.http_cache()->CreateTransaction(&trans);
1931   EXPECT_EQ(net::OK, rv);
1932   rv = trans->Start(&request, &callback, net::BoundNetLog());
1933   if (rv == net::ERR_IO_PENDING)
1934     rv = callback.WaitForResult();
1935   ASSERT_EQ(net::OK, rv);
1936 
1937   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
1938   rv = trans->Read(buf, 256, &callback);
1939   EXPECT_EQ(net::ERR_IO_PENDING, rv);
1940 
1941   // Test that destroying the transaction while it is reading from the cache
1942   // works properly.
1943   trans.reset();
1944 
1945   // Make sure we pump any pending events, which should include a call to
1946   // HttpCache::Transaction::OnCacheReadCompleted.
1947   MessageLoop::current()->RunAllPending();
1948 }
1949 
1950 // Tests that we can delete the HttpCache and deal with queued transactions
1951 // ("waiting for the backend" as opposed to Active or Doomed entries).
TEST(HttpCache,SimpleGET_ManyWriters_DeleteCache)1952 TEST(HttpCache, SimpleGET_ManyWriters_DeleteCache) {
1953   scoped_ptr<MockHttpCache> cache(new MockHttpCache(
1954                                       new MockBackendNoCbFactory()));
1955 
1956   MockHttpRequest request(kSimpleGET_Transaction);
1957 
1958   std::vector<Context*> context_list;
1959   const int kNumTransactions = 5;
1960 
1961   for (int i = 0; i < kNumTransactions; i++) {
1962     context_list.push_back(new Context());
1963     Context* c = context_list[i];
1964 
1965     c->result = cache->http_cache()->CreateTransaction(&c->trans);
1966     EXPECT_EQ(net::OK, c->result);
1967 
1968     c->result = c->trans->Start(&request, &c->callback, net::BoundNetLog());
1969   }
1970 
1971   // The first request should be creating the disk cache entry and the others
1972   // should be pending.
1973 
1974   EXPECT_EQ(0, cache->network_layer()->transaction_count());
1975   EXPECT_EQ(0, cache->disk_cache()->open_count());
1976   EXPECT_EQ(0, cache->disk_cache()->create_count());
1977 
1978   cache.reset();
1979 
1980   // There is not much to do with the transactions at this point... they are
1981   // waiting for a callback that will not fire.
1982   for (int i = 0; i < kNumTransactions; ++i) {
1983     delete context_list[i];
1984   }
1985 }
1986 
1987 // Tests that we queue requests when initializing the backend.
TEST(HttpCache,SimpleGET_WaitForBackend)1988 TEST(HttpCache, SimpleGET_WaitForBackend) {
1989   MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1990   MockHttpCache cache(factory);
1991 
1992   MockHttpRequest request0(kSimpleGET_Transaction);
1993   MockHttpRequest request1(kTypicalGET_Transaction);
1994   MockHttpRequest request2(kETagGET_Transaction);
1995 
1996   std::vector<Context*> context_list;
1997   const int kNumTransactions = 3;
1998 
1999   for (int i = 0; i < kNumTransactions; i++) {
2000     context_list.push_back(new Context());
2001     Context* c = context_list[i];
2002 
2003     c->result = cache.http_cache()->CreateTransaction(&c->trans);
2004     EXPECT_EQ(net::OK, c->result);
2005   }
2006 
2007   context_list[0]->result = context_list[0]->trans->Start(
2008       &request0, &context_list[0]->callback, net::BoundNetLog());
2009   context_list[1]->result = context_list[1]->trans->Start(
2010       &request1, &context_list[1]->callback, net::BoundNetLog());
2011   context_list[2]->result = context_list[2]->trans->Start(
2012       &request2, &context_list[2]->callback, net::BoundNetLog());
2013 
2014   // Just to make sure that everything is still pending.
2015   MessageLoop::current()->RunAllPending();
2016 
2017   // The first request should be creating the disk cache.
2018   EXPECT_FALSE(context_list[0]->callback.have_result());
2019 
2020   factory->FinishCreation();
2021 
2022   MessageLoop::current()->RunAllPending();
2023   EXPECT_EQ(3, cache.network_layer()->transaction_count());
2024   EXPECT_EQ(3, cache.disk_cache()->create_count());
2025 
2026   for (int i = 0; i < kNumTransactions; ++i) {
2027     EXPECT_TRUE(context_list[i]->callback.have_result());
2028     delete context_list[i];
2029   }
2030 }
2031 
2032 // Tests that we can cancel requests that are queued waiting for the backend
2033 // to be initialized.
TEST(HttpCache,SimpleGET_WaitForBackend_CancelCreate)2034 TEST(HttpCache, SimpleGET_WaitForBackend_CancelCreate) {
2035   MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
2036   MockHttpCache cache(factory);
2037 
2038   MockHttpRequest request0(kSimpleGET_Transaction);
2039   MockHttpRequest request1(kTypicalGET_Transaction);
2040   MockHttpRequest request2(kETagGET_Transaction);
2041 
2042   std::vector<Context*> context_list;
2043   const int kNumTransactions = 3;
2044 
2045   for (int i = 0; i < kNumTransactions; i++) {
2046     context_list.push_back(new Context());
2047     Context* c = context_list[i];
2048 
2049     c->result = cache.http_cache()->CreateTransaction(&c->trans);
2050     EXPECT_EQ(net::OK, c->result);
2051   }
2052 
2053   context_list[0]->result = context_list[0]->trans->Start(
2054       &request0, &context_list[0]->callback, net::BoundNetLog());
2055   context_list[1]->result = context_list[1]->trans->Start(
2056       &request1, &context_list[1]->callback, net::BoundNetLog());
2057   context_list[2]->result = context_list[2]->trans->Start(
2058       &request2, &context_list[2]->callback, net::BoundNetLog());
2059 
2060   // Just to make sure that everything is still pending.
2061   MessageLoop::current()->RunAllPending();
2062 
2063   // The first request should be creating the disk cache.
2064   EXPECT_FALSE(context_list[0]->callback.have_result());
2065 
2066   // Cancel a request from the pending queue.
2067   delete context_list[1];
2068   context_list[1] = NULL;
2069 
2070   // Cancel the request that is creating the entry.
2071   delete context_list[0];
2072   context_list[0] = NULL;
2073 
2074   // Complete the last transaction.
2075   factory->FinishCreation();
2076 
2077   context_list[2]->result =
2078       context_list[2]->callback.GetResult(context_list[2]->result);
2079   ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction);
2080 
2081   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2082   EXPECT_EQ(1, cache.disk_cache()->create_count());
2083 
2084   delete context_list[2];
2085 }
2086 
2087 // Tests that we can delete the cache while creating the backend.
TEST(HttpCache,DeleteCacheWaitingForBackend)2088 TEST(HttpCache, DeleteCacheWaitingForBackend) {
2089   MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
2090   scoped_ptr<MockHttpCache> cache(new MockHttpCache(factory));
2091 
2092   MockHttpRequest request(kSimpleGET_Transaction);
2093 
2094   scoped_ptr<Context> c(new Context());
2095   c->result = cache->http_cache()->CreateTransaction(&c->trans);
2096   EXPECT_EQ(net::OK, c->result);
2097 
2098   c->trans->Start(&request, &c->callback, net::BoundNetLog());
2099 
2100   // Just to make sure that everything is still pending.
2101   MessageLoop::current()->RunAllPending();
2102 
2103   // The request should be creating the disk cache.
2104   EXPECT_FALSE(c->callback.have_result());
2105 
2106   // We cannot call FinishCreation because the factory itself will go away with
2107   // the cache, so grab the callback and attempt to use it.
2108   net::CompletionCallback* callback = factory->callback();
2109   disk_cache::Backend** backend = factory->backend();
2110 
2111   cache.reset();
2112   MessageLoop::current()->RunAllPending();
2113 
2114   *backend = NULL;
2115   callback->Run(net::ERR_ABORTED);
2116 }
2117 
2118 // Tests that we can delete the cache while creating the backend, from within
2119 // one of the callbacks.
TEST(HttpCache,DeleteCacheWaitingForBackend2)2120 TEST(HttpCache, DeleteCacheWaitingForBackend2) {
2121   MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
2122   MockHttpCache* cache = new MockHttpCache(factory);
2123 
2124   DeleteCacheCompletionCallback cb(cache);
2125   disk_cache::Backend* backend;
2126   int rv = cache->http_cache()->GetBackend(&backend, &cb);
2127   EXPECT_EQ(net::ERR_IO_PENDING, rv);
2128 
2129   // Now let's queue a regular transaction
2130   MockHttpRequest request(kSimpleGET_Transaction);
2131 
2132   scoped_ptr<Context> c(new Context());
2133   c->result = cache->http_cache()->CreateTransaction(&c->trans);
2134   EXPECT_EQ(net::OK, c->result);
2135 
2136   c->trans->Start(&request, &c->callback, net::BoundNetLog());
2137 
2138   // And another direct backend request.
2139   TestCompletionCallback cb2;
2140   rv = cache->http_cache()->GetBackend(&backend, &cb2);
2141   EXPECT_EQ(net::ERR_IO_PENDING, rv);
2142 
2143   // Just to make sure that everything is still pending.
2144   MessageLoop::current()->RunAllPending();
2145 
2146   // The request should be queued.
2147   EXPECT_FALSE(c->callback.have_result());
2148 
2149   // Generate the callback.
2150   factory->FinishCreation();
2151   rv = cb.WaitForResult();
2152 
2153   // The cache should be gone by now.
2154   MessageLoop::current()->RunAllPending();
2155   EXPECT_EQ(net::OK, c->callback.GetResult(c->result));
2156   EXPECT_FALSE(cb2.have_result());
2157 }
2158 
TEST(HttpCache,TypicalGET_ConditionalRequest)2159 TEST(HttpCache, TypicalGET_ConditionalRequest) {
2160   MockHttpCache cache;
2161 
2162   // write to the cache
2163   RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
2164 
2165   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2166   EXPECT_EQ(0, cache.disk_cache()->open_count());
2167   EXPECT_EQ(1, cache.disk_cache()->create_count());
2168 
2169   // get the same URL again, but this time we expect it to result
2170   // in a conditional request.
2171   RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
2172 
2173   EXPECT_EQ(2, cache.network_layer()->transaction_count());
2174   EXPECT_EQ(1, cache.disk_cache()->open_count());
2175   EXPECT_EQ(1, cache.disk_cache()->create_count());
2176 }
2177 
ETagGet_ConditionalRequest_Handler(const net::HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)2178 static void ETagGet_ConditionalRequest_Handler(
2179     const net::HttpRequestInfo* request,
2180     std::string* response_status,
2181     std::string* response_headers,
2182     std::string* response_data) {
2183   EXPECT_TRUE(
2184       request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
2185   response_status->assign("HTTP/1.1 304 Not Modified");
2186   response_headers->assign(kETagGET_Transaction.response_headers);
2187   response_data->clear();
2188 }
2189 
TEST(HttpCache,ETagGET_ConditionalRequest_304)2190 TEST(HttpCache, ETagGET_ConditionalRequest_304) {
2191   MockHttpCache cache;
2192 
2193   ScopedMockTransaction transaction(kETagGET_Transaction);
2194 
2195   // write to the cache
2196   RunTransactionTest(cache.http_cache(), transaction);
2197 
2198   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2199   EXPECT_EQ(0, cache.disk_cache()->open_count());
2200   EXPECT_EQ(1, cache.disk_cache()->create_count());
2201 
2202   // get the same URL again, but this time we expect it to result
2203   // in a conditional request.
2204   transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2205   transaction.handler = ETagGet_ConditionalRequest_Handler;
2206   RunTransactionTest(cache.http_cache(), transaction);
2207 
2208   EXPECT_EQ(2, cache.network_layer()->transaction_count());
2209   EXPECT_EQ(1, cache.disk_cache()->open_count());
2210   EXPECT_EQ(1, cache.disk_cache()->create_count());
2211 }
2212 
ETagGet_ConditionalRequest_NoStore_Handler(const net::HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)2213 static void ETagGet_ConditionalRequest_NoStore_Handler(
2214     const net::HttpRequestInfo* request,
2215     std::string* response_status,
2216     std::string* response_headers,
2217     std::string* response_data) {
2218   EXPECT_TRUE(
2219       request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
2220   response_status->assign("HTTP/1.1 304 Not Modified");
2221   response_headers->assign("Cache-Control: no-store\n");
2222   response_data->clear();
2223 }
2224 
TEST(HttpCache,ETagGET_ConditionalRequest_304_NoStore)2225 TEST(HttpCache, ETagGET_ConditionalRequest_304_NoStore) {
2226   MockHttpCache cache;
2227 
2228   ScopedMockTransaction transaction(kETagGET_Transaction);
2229 
2230   // Write to the cache.
2231   RunTransactionTest(cache.http_cache(), transaction);
2232 
2233   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2234   EXPECT_EQ(0, cache.disk_cache()->open_count());
2235   EXPECT_EQ(1, cache.disk_cache()->create_count());
2236 
2237   // Get the same URL again, but this time we expect it to result
2238   // in a conditional request.
2239   transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2240   transaction.handler = ETagGet_ConditionalRequest_NoStore_Handler;
2241   RunTransactionTest(cache.http_cache(), transaction);
2242 
2243   EXPECT_EQ(2, cache.network_layer()->transaction_count());
2244   EXPECT_EQ(1, cache.disk_cache()->open_count());
2245   EXPECT_EQ(1, cache.disk_cache()->create_count());
2246 
2247   ScopedMockTransaction transaction2(kETagGET_Transaction);
2248 
2249   // Write to the cache again. This should create a new entry.
2250   RunTransactionTest(cache.http_cache(), transaction2);
2251 
2252   EXPECT_EQ(3, cache.network_layer()->transaction_count());
2253   EXPECT_EQ(1, cache.disk_cache()->open_count());
2254   EXPECT_EQ(2, cache.disk_cache()->create_count());
2255 }
2256 
TEST(HttpCache,SimplePOST_SkipsCache)2257 TEST(HttpCache, SimplePOST_SkipsCache) {
2258   MockHttpCache cache;
2259 
2260   // Test that we skip the cache for POST requests that do not have an upload
2261   // identifier.
2262 
2263   RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
2264 
2265   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2266   EXPECT_EQ(0, cache.disk_cache()->open_count());
2267   EXPECT_EQ(0, cache.disk_cache()->create_count());
2268 }
2269 
2270 // Helper that does 4 requests using HttpCache:
2271 //
2272 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
2273 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2274 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2275 //     be returned.
2276 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2277 //     returned.
ConditionalizedRequestUpdatesCacheHelper(const Response & net_response_1,const Response & net_response_2,const Response & cached_response_2,const char * extra_request_headers)2278 static void ConditionalizedRequestUpdatesCacheHelper(
2279     const Response& net_response_1,
2280     const Response& net_response_2,
2281     const Response& cached_response_2,
2282     const char* extra_request_headers) {
2283   MockHttpCache cache;
2284 
2285   // The URL we will be requesting.
2286   const char* kUrl = "http://foobar.com/main.css";
2287 
2288   // Junk network response.
2289   static const Response kUnexpectedResponse = {
2290     "HTTP/1.1 500 Unexpected",
2291     "Server: unexpected_header",
2292     "unexpected body"
2293   };
2294 
2295   // We will control the network layer's responses for |kUrl| using
2296   // |mock_network_response|.
2297   MockTransaction mock_network_response = { 0 };
2298   mock_network_response.url = kUrl;
2299   AddMockTransaction(&mock_network_response);
2300 
2301   // Request |kUrl| for the first time. It should hit the network and
2302   // receive |kNetResponse1|, which it saves into the HTTP cache.
2303 
2304   MockTransaction request = { 0 };
2305   request.url = kUrl;
2306   request.method = "GET";
2307   request.request_headers = "";
2308 
2309   net_response_1.AssignTo(&mock_network_response);  // Network mock.
2310   net_response_1.AssignTo(&request);                // Expected result.
2311 
2312   std::string response_headers;
2313   RunTransactionTestWithResponse(
2314       cache.http_cache(), request, &response_headers);
2315 
2316   EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
2317   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2318   EXPECT_EQ(0, cache.disk_cache()->open_count());
2319   EXPECT_EQ(1, cache.disk_cache()->create_count());
2320 
2321   // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
2322   // cache, so we don't hit the network.
2323 
2324   request.load_flags = net::LOAD_ONLY_FROM_CACHE;
2325 
2326   kUnexpectedResponse.AssignTo(&mock_network_response);  // Network mock.
2327   net_response_1.AssignTo(&request);                     // Expected result.
2328 
2329   RunTransactionTestWithResponse(
2330       cache.http_cache(), request, &response_headers);
2331 
2332   EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
2333   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2334   EXPECT_EQ(1, cache.disk_cache()->open_count());
2335   EXPECT_EQ(1, cache.disk_cache()->create_count());
2336 
2337   // Request |kUrl| yet again, but this time give the request an
2338   // "If-Modified-Since" header. This will cause the request to re-hit the
2339   // network. However now the network response is going to be
2340   // different -- this simulates a change made to the CSS file.
2341 
2342   request.request_headers = extra_request_headers;
2343   request.load_flags = net::LOAD_NORMAL;
2344 
2345   net_response_2.AssignTo(&mock_network_response);  // Network mock.
2346   net_response_2.AssignTo(&request);                // Expected result.
2347 
2348   RunTransactionTestWithResponse(
2349       cache.http_cache(), request, &response_headers);
2350 
2351   EXPECT_EQ(net_response_2.status_and_headers(), response_headers);
2352   EXPECT_EQ(2, cache.network_layer()->transaction_count());
2353   EXPECT_EQ(1, cache.disk_cache()->open_count());
2354   EXPECT_EQ(1, cache.disk_cache()->create_count());
2355 
2356   // Finally, request |kUrl| again. This request should be serviced from
2357   // the cache. Moreover, the value in the cache should be |kNetResponse2|
2358   // and NOT |kNetResponse1|. The previous step should have replaced the
2359   // value in the cache with the modified response.
2360 
2361   request.request_headers = "";
2362   request.load_flags = net::LOAD_ONLY_FROM_CACHE;
2363 
2364   kUnexpectedResponse.AssignTo(&mock_network_response);  // Network mock.
2365   cached_response_2.AssignTo(&request);                  // Expected result.
2366 
2367   RunTransactionTestWithResponse(
2368       cache.http_cache(), request, &response_headers);
2369 
2370   EXPECT_EQ(cached_response_2.status_and_headers(), response_headers);
2371   EXPECT_EQ(2, cache.network_layer()->transaction_count());
2372   EXPECT_EQ(2, cache.disk_cache()->open_count());
2373   EXPECT_EQ(1, cache.disk_cache()->create_count());
2374 
2375   RemoveMockTransaction(&mock_network_response);
2376 }
2377 
2378 // Check that when an "if-modified-since" header is attached
2379 // to the request, the result still updates the cached entry.
TEST(HttpCache,ConditionalizedRequestUpdatesCache1)2380 TEST(HttpCache, ConditionalizedRequestUpdatesCache1) {
2381   // First network response for |kUrl|.
2382   static const Response kNetResponse1 = {
2383     "HTTP/1.1 200 OK",
2384     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2385     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2386     "body1"
2387   };
2388 
2389   // Second network response for |kUrl|.
2390   static const Response kNetResponse2 = {
2391     "HTTP/1.1 200 OK",
2392     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2393     "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2394     "body2"
2395   };
2396 
2397   const char* extra_headers =
2398       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n";
2399 
2400   ConditionalizedRequestUpdatesCacheHelper(
2401       kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2402 }
2403 
2404 // Check that when an "if-none-match" header is attached
2405 // to the request, the result updates the cached entry.
TEST(HttpCache,ConditionalizedRequestUpdatesCache2)2406 TEST(HttpCache, ConditionalizedRequestUpdatesCache2) {
2407   // First network response for |kUrl|.
2408   static const Response kNetResponse1 = {
2409     "HTTP/1.1 200 OK",
2410     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2411     "Etag: \"ETAG1\"\n"
2412     "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n",  // Should never expire.
2413     "body1"
2414   };
2415 
2416   // Second network response for |kUrl|.
2417   static const Response kNetResponse2 = {
2418     "HTTP/1.1 200 OK",
2419     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2420     "Etag: \"ETAG2\"\n"
2421     "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n",  // Should never expire.
2422     "body2"
2423   };
2424 
2425   const char* extra_headers = "If-None-Match: \"ETAG1\"\n";
2426 
2427   ConditionalizedRequestUpdatesCacheHelper(
2428       kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2429 }
2430 
2431 // Check that when an "if-modified-since" header is attached
2432 // to a request, the 304 (not modified result) result updates the cached
2433 // headers, and the 304 response is returned rather than the cached response.
TEST(HttpCache,ConditionalizedRequestUpdatesCache3)2434 TEST(HttpCache, ConditionalizedRequestUpdatesCache3) {
2435   // First network response for |kUrl|.
2436   static const Response kNetResponse1 = {
2437     "HTTP/1.1 200 OK",
2438     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2439     "Server: server1\n"
2440     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2441     "body1"
2442   };
2443 
2444   // Second network response for |kUrl|.
2445   static const Response kNetResponse2 = {
2446     "HTTP/1.1 304 Not Modified",
2447     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2448     "Server: server2\n"
2449     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2450     ""
2451   };
2452 
2453   static const Response kCachedResponse2 = {
2454     "HTTP/1.1 200 OK",
2455     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2456     "Server: server2\n"
2457     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2458     "body1"
2459   };
2460 
2461   const char* extra_headers =
2462       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n";
2463 
2464   ConditionalizedRequestUpdatesCacheHelper(
2465       kNetResponse1, kNetResponse2, kCachedResponse2, extra_headers);
2466 }
2467 
2468 // Test that when doing an externally conditionalized if-modified-since
2469 // and there is no corresponding cache entry, a new cache entry is NOT
2470 // created (304 response).
TEST(HttpCache,ConditionalizedRequestUpdatesCache4)2471 TEST(HttpCache, ConditionalizedRequestUpdatesCache4) {
2472   MockHttpCache cache;
2473 
2474   const char* kUrl = "http://foobar.com/main.css";
2475 
2476   static const Response kNetResponse = {
2477     "HTTP/1.1 304 Not Modified",
2478     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2479     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2480     ""
2481   };
2482 
2483   const char* kExtraRequestHeaders =
2484       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT";
2485 
2486   // We will control the network layer's responses for |kUrl| using
2487   // |mock_network_response|.
2488   MockTransaction mock_network_response = { 0 };
2489   mock_network_response.url = kUrl;
2490   AddMockTransaction(&mock_network_response);
2491 
2492   MockTransaction request = { 0 };
2493   request.url = kUrl;
2494   request.method = "GET";
2495   request.request_headers = kExtraRequestHeaders;
2496 
2497   kNetResponse.AssignTo(&mock_network_response);  // Network mock.
2498   kNetResponse.AssignTo(&request);                // Expected result.
2499 
2500   std::string response_headers;
2501   RunTransactionTestWithResponse(
2502       cache.http_cache(), request, &response_headers);
2503 
2504   EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2505   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2506   EXPECT_EQ(0, cache.disk_cache()->open_count());
2507   EXPECT_EQ(0, cache.disk_cache()->create_count());
2508 
2509   RemoveMockTransaction(&mock_network_response);
2510 }
2511 
2512 // Test that when doing an externally conditionalized if-modified-since
2513 // and there is no corresponding cache entry, a new cache entry is NOT
2514 // created (200 response).
TEST(HttpCache,ConditionalizedRequestUpdatesCache5)2515 TEST(HttpCache, ConditionalizedRequestUpdatesCache5) {
2516   MockHttpCache cache;
2517 
2518   const char* kUrl = "http://foobar.com/main.css";
2519 
2520   static const Response kNetResponse = {
2521     "HTTP/1.1 200 OK",
2522     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2523     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2524     "foobar!!!"
2525   };
2526 
2527   const char* kExtraRequestHeaders =
2528       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT";
2529 
2530   // We will control the network layer's responses for |kUrl| using
2531   // |mock_network_response|.
2532   MockTransaction mock_network_response = { 0 };
2533   mock_network_response.url = kUrl;
2534   AddMockTransaction(&mock_network_response);
2535 
2536   MockTransaction request = { 0 };
2537   request.url = kUrl;
2538   request.method = "GET";
2539   request.request_headers = kExtraRequestHeaders;
2540 
2541   kNetResponse.AssignTo(&mock_network_response);  // Network mock.
2542   kNetResponse.AssignTo(&request);                // Expected result.
2543 
2544   std::string response_headers;
2545   RunTransactionTestWithResponse(
2546       cache.http_cache(), request, &response_headers);
2547 
2548   EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2549   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2550   EXPECT_EQ(0, cache.disk_cache()->open_count());
2551   EXPECT_EQ(0, cache.disk_cache()->create_count());
2552 
2553   RemoveMockTransaction(&mock_network_response);
2554 }
2555 
2556 // Test that when doing an externally conditionalized if-modified-since
2557 // if the date does not match the cache entry's last-modified date,
2558 // then we do NOT use the response (304) to update the cache.
2559 // (the if-modified-since date is 2 days AFTER the cache's modification date).
TEST(HttpCache,ConditionalizedRequestUpdatesCache6)2560 TEST(HttpCache, ConditionalizedRequestUpdatesCache6) {
2561   static const Response kNetResponse1 = {
2562     "HTTP/1.1 200 OK",
2563     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2564     "Server: server1\n"
2565     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2566     "body1"
2567   };
2568 
2569   // Second network response for |kUrl|.
2570   static const Response kNetResponse2 = {
2571     "HTTP/1.1 304 Not Modified",
2572     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2573     "Server: server2\n"
2574     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2575     ""
2576   };
2577 
2578   // This is two days in the future from the original response's last-modified
2579   // date!
2580   const char* kExtraRequestHeaders =
2581       "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\n";
2582 
2583   ConditionalizedRequestUpdatesCacheHelper(
2584       kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2585 }
2586 
2587 // Test that when doing an externally conditionalized if-none-match
2588 // if the etag does not match the cache entry's etag, then we do not use the
2589 // response (304) to update the cache.
TEST(HttpCache,ConditionalizedRequestUpdatesCache7)2590 TEST(HttpCache, ConditionalizedRequestUpdatesCache7) {
2591   static const Response kNetResponse1 = {
2592     "HTTP/1.1 200 OK",
2593     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2594     "Etag: \"Foo1\"\n"
2595     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2596     "body1"
2597   };
2598 
2599   // Second network response for |kUrl|.
2600   static const Response kNetResponse2 = {
2601     "HTTP/1.1 304 Not Modified",
2602     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2603     "Etag: \"Foo2\"\n"
2604     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2605     ""
2606   };
2607 
2608   // Different etag from original response.
2609   const char* kExtraRequestHeaders = "If-None-Match: \"Foo2\"\n";
2610 
2611   ConditionalizedRequestUpdatesCacheHelper(
2612       kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2613 }
2614 
2615 // Test that doing an externally conditionalized request with both if-none-match
2616 // and if-modified-since updates the cache.
TEST(HttpCache,ConditionalizedRequestUpdatesCache8)2617 TEST(HttpCache, ConditionalizedRequestUpdatesCache8) {
2618   static const Response kNetResponse1 = {
2619     "HTTP/1.1 200 OK",
2620     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2621     "Etag: \"Foo1\"\n"
2622     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2623     "body1"
2624   };
2625 
2626   // Second network response for |kUrl|.
2627   static const Response kNetResponse2 = {
2628     "HTTP/1.1 200 OK",
2629     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2630     "Etag: \"Foo2\"\n"
2631     "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2632     "body2"
2633   };
2634 
2635   const char* kExtraRequestHeaders =
2636       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2637       "If-None-Match: \"Foo1\"\r\n";
2638 
2639   ConditionalizedRequestUpdatesCacheHelper(
2640       kNetResponse1, kNetResponse2, kNetResponse2, kExtraRequestHeaders);
2641 }
2642 
2643 // Test that doing an externally conditionalized request with both if-none-match
2644 // and if-modified-since does not update the cache with only one match.
TEST(HttpCache,ConditionalizedRequestUpdatesCache9)2645 TEST(HttpCache, ConditionalizedRequestUpdatesCache9) {
2646   static const Response kNetResponse1 = {
2647     "HTTP/1.1 200 OK",
2648     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2649     "Etag: \"Foo1\"\n"
2650     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2651     "body1"
2652   };
2653 
2654   // Second network response for |kUrl|.
2655   static const Response kNetResponse2 = {
2656     "HTTP/1.1 200 OK",
2657     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2658     "Etag: \"Foo2\"\n"
2659     "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2660     "body2"
2661   };
2662 
2663   // The etag doesn't match what we have stored.
2664   const char* kExtraRequestHeaders =
2665       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n"
2666       "If-None-Match: \"Foo2\"\n";
2667 
2668   ConditionalizedRequestUpdatesCacheHelper(
2669       kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2670 }
2671 
2672 // Test that doing an externally conditionalized request with both if-none-match
2673 // and if-modified-since does not update the cache with only one match.
TEST(HttpCache,ConditionalizedRequestUpdatesCache10)2674 TEST(HttpCache, ConditionalizedRequestUpdatesCache10) {
2675   static const Response kNetResponse1 = {
2676     "HTTP/1.1 200 OK",
2677     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2678     "Etag: \"Foo1\"\n"
2679     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2680     "body1"
2681   };
2682 
2683   // Second network response for |kUrl|.
2684   static const Response kNetResponse2 = {
2685     "HTTP/1.1 200 OK",
2686     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2687     "Etag: \"Foo2\"\n"
2688     "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2689     "body2"
2690   };
2691 
2692   // The modification date doesn't match what we have stored.
2693   const char* kExtraRequestHeaders =
2694       "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\n"
2695       "If-None-Match: \"Foo1\"\n";
2696 
2697   ConditionalizedRequestUpdatesCacheHelper(
2698       kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2699 }
2700 
2701 // Test that doing an externally conditionalized request with two conflicting
2702 // headers does not update the cache.
TEST(HttpCache,ConditionalizedRequestUpdatesCache11)2703 TEST(HttpCache, ConditionalizedRequestUpdatesCache11) {
2704   static const Response kNetResponse1 = {
2705     "HTTP/1.1 200 OK",
2706     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2707     "Etag: \"Foo1\"\n"
2708     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2709     "body1"
2710   };
2711 
2712   // Second network response for |kUrl|.
2713   static const Response kNetResponse2 = {
2714     "HTTP/1.1 200 OK",
2715     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2716     "Etag: \"Foo2\"\n"
2717     "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2718     "body2"
2719   };
2720 
2721   // Two dates, the second matches what we have stored.
2722   const char* kExtraRequestHeaders =
2723       "If-Modified-Since: Mon, 04 Feb 2008 22:38:21 GMT\n"
2724       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\n";
2725 
2726   ConditionalizedRequestUpdatesCacheHelper(
2727       kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2728 }
2729 
TEST(HttpCache,UrlContainingHash)2730 TEST(HttpCache, UrlContainingHash) {
2731   MockHttpCache cache;
2732 
2733   // Do a typical GET request -- should write an entry into our cache.
2734   MockTransaction trans(kTypicalGET_Transaction);
2735   RunTransactionTest(cache.http_cache(), trans);
2736 
2737   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2738   EXPECT_EQ(0, cache.disk_cache()->open_count());
2739   EXPECT_EQ(1, cache.disk_cache()->create_count());
2740 
2741   // Request the same URL, but this time with a reference section (hash).
2742   // Since the cache key strips the hash sections, this should be a cache hit.
2743   std::string url_with_hash = std::string(trans.url) + "#multiple#hashes";
2744   trans.url = url_with_hash.c_str();
2745   trans.load_flags = net::LOAD_ONLY_FROM_CACHE;
2746 
2747   RunTransactionTest(cache.http_cache(), trans);
2748 
2749   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2750   EXPECT_EQ(1, cache.disk_cache()->open_count());
2751   EXPECT_EQ(1, cache.disk_cache()->create_count());
2752 }
2753 
TEST(HttpCache,SimplePOST_LoadOnlyFromCache_Miss)2754 TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Miss) {
2755   MockHttpCache cache;
2756 
2757   // Test that we skip the cache for POST requests.  Eventually, we will want
2758   // to cache these, but we'll still have cases where skipping the cache makes
2759   // sense, so we want to make sure that it works properly.
2760 
2761   MockTransaction transaction(kSimplePOST_Transaction);
2762   transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
2763 
2764   MockHttpRequest request(transaction);
2765   TestCompletionCallback callback;
2766 
2767   scoped_ptr<net::HttpTransaction> trans;
2768   int rv = cache.http_cache()->CreateTransaction(&trans);
2769   EXPECT_EQ(net::OK, rv);
2770   ASSERT_TRUE(trans.get());
2771 
2772   rv = trans->Start(&request, &callback, net::BoundNetLog());
2773   if (rv == net::ERR_IO_PENDING)
2774     rv = callback.WaitForResult();
2775   ASSERT_EQ(net::ERR_CACHE_MISS, rv);
2776 
2777   trans.reset();
2778 
2779   EXPECT_EQ(0, cache.network_layer()->transaction_count());
2780   EXPECT_EQ(0, cache.disk_cache()->open_count());
2781   EXPECT_EQ(0, cache.disk_cache()->create_count());
2782 }
2783 
TEST(HttpCache,SimplePOST_LoadOnlyFromCache_Hit)2784 TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Hit) {
2785   MockHttpCache cache;
2786 
2787   // Test that we hit the cache for POST requests.
2788 
2789   MockTransaction transaction(kSimplePOST_Transaction);
2790 
2791   const int64 kUploadId = 1;  // Just a dummy value.
2792 
2793   MockHttpRequest request(transaction);
2794   request.upload_data = new net::UploadData();
2795   request.upload_data->set_identifier(kUploadId);
2796   request.upload_data->AppendBytes("hello", 5);
2797 
2798   // Populate the cache.
2799   RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2800 
2801   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2802   EXPECT_EQ(0, cache.disk_cache()->open_count());
2803   EXPECT_EQ(1, cache.disk_cache()->create_count());
2804 
2805   // Load from cache.
2806   request.load_flags |= net::LOAD_ONLY_FROM_CACHE;
2807   RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2808 
2809   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2810   EXPECT_EQ(1, cache.disk_cache()->open_count());
2811   EXPECT_EQ(1, cache.disk_cache()->create_count());
2812 }
2813 
TEST(HttpCache,RangeGET_SkipsCache)2814 TEST(HttpCache, RangeGET_SkipsCache) {
2815   MockHttpCache cache;
2816 
2817   // Test that we skip the cache for range GET requests.  Eventually, we will
2818   // want to cache these, but we'll still have cases where skipping the cache
2819   // makes sense, so we want to make sure that it works properly.
2820 
2821   RunTransactionTest(cache.http_cache(), kRangeGET_Transaction);
2822 
2823   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2824   EXPECT_EQ(0, cache.disk_cache()->open_count());
2825   EXPECT_EQ(0, cache.disk_cache()->create_count());
2826 
2827   MockTransaction transaction(kSimpleGET_Transaction);
2828   transaction.request_headers = "If-None-Match: foo";
2829   RunTransactionTest(cache.http_cache(), transaction);
2830 
2831   EXPECT_EQ(2, cache.network_layer()->transaction_count());
2832   EXPECT_EQ(0, cache.disk_cache()->open_count());
2833   EXPECT_EQ(0, cache.disk_cache()->create_count());
2834 
2835   transaction.request_headers =
2836       "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT";
2837   RunTransactionTest(cache.http_cache(), transaction);
2838 
2839   EXPECT_EQ(3, cache.network_layer()->transaction_count());
2840   EXPECT_EQ(0, cache.disk_cache()->open_count());
2841   EXPECT_EQ(0, cache.disk_cache()->create_count());
2842 }
2843 
2844 // Test that we skip the cache for range requests that include a validation
2845 // header.
TEST(HttpCache,RangeGET_SkipsCache2)2846 TEST(HttpCache, RangeGET_SkipsCache2) {
2847   MockHttpCache cache;
2848 
2849   MockTransaction transaction(kRangeGET_Transaction);
2850   transaction.request_headers = "If-None-Match: foo\r\n"
2851                                 EXTRA_HEADER
2852                                 "\r\nRange: bytes = 40-49";
2853   RunTransactionTest(cache.http_cache(), transaction);
2854 
2855   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2856   EXPECT_EQ(0, cache.disk_cache()->open_count());
2857   EXPECT_EQ(0, cache.disk_cache()->create_count());
2858 
2859   transaction.request_headers =
2860       "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
2861       EXTRA_HEADER
2862       "\r\nRange: bytes = 40-49";
2863   RunTransactionTest(cache.http_cache(), transaction);
2864 
2865   EXPECT_EQ(2, cache.network_layer()->transaction_count());
2866   EXPECT_EQ(0, cache.disk_cache()->open_count());
2867   EXPECT_EQ(0, cache.disk_cache()->create_count());
2868 
2869   transaction.request_headers = "If-Range: bla\r\n"
2870                                 EXTRA_HEADER
2871                                 "\r\nRange: bytes = 40-49\n";
2872   RunTransactionTest(cache.http_cache(), transaction);
2873 
2874   EXPECT_EQ(3, cache.network_layer()->transaction_count());
2875   EXPECT_EQ(0, cache.disk_cache()->open_count());
2876   EXPECT_EQ(0, cache.disk_cache()->create_count());
2877 }
2878 
2879 // Tests that receiving 206 for a regular request is handled correctly.
TEST(HttpCache,GET_Crazy206)2880 TEST(HttpCache, GET_Crazy206) {
2881   MockHttpCache cache;
2882 
2883   // Write to the cache.
2884   MockTransaction transaction(kRangeGET_TransactionOK);
2885   AddMockTransaction(&transaction);
2886   transaction.request_headers = EXTRA_HEADER;
2887   transaction.handler = NULL;
2888   RunTransactionTest(cache.http_cache(), transaction);
2889 
2890   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2891   EXPECT_EQ(0, cache.disk_cache()->open_count());
2892   EXPECT_EQ(1, cache.disk_cache()->create_count());
2893 
2894   // This should read again from the net.
2895   RunTransactionTest(cache.http_cache(), transaction);
2896 
2897   EXPECT_EQ(2, cache.network_layer()->transaction_count());
2898   EXPECT_EQ(0, cache.disk_cache()->open_count());
2899   EXPECT_EQ(2, cache.disk_cache()->create_count());
2900   RemoveMockTransaction(&transaction);
2901 }
2902 
2903 // Tests that we don't cache partial responses that can't be validated.
TEST(HttpCache,RangeGET_NoStrongValidators)2904 TEST(HttpCache, RangeGET_NoStrongValidators) {
2905   MockHttpCache cache;
2906   std::string headers;
2907 
2908   // Attempt to write to the cache (40-49).
2909   MockTransaction transaction(kRangeGET_TransactionOK);
2910   AddMockTransaction(&transaction);
2911   transaction.response_headers = "Content-Length: 10\n"
2912                                  "ETag: w/\"foo\"\n";
2913   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2914 
2915   Verify206Response(headers, 40, 49);
2916   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2917   EXPECT_EQ(0, cache.disk_cache()->open_count());
2918   EXPECT_EQ(1, cache.disk_cache()->create_count());
2919 
2920   // Now verify that there's no cached data.
2921   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
2922                                  &headers);
2923 
2924   Verify206Response(headers, 40, 49);
2925   EXPECT_EQ(2, cache.network_layer()->transaction_count());
2926   EXPECT_EQ(0, cache.disk_cache()->open_count());
2927   EXPECT_EQ(2, cache.disk_cache()->create_count());
2928 
2929   RemoveMockTransaction(&transaction);
2930 }
2931 
2932 // Tests that we can cache range requests and fetch random blocks from the
2933 // cache and the network.
TEST(HttpCache,RangeGET_OK)2934 TEST(HttpCache, RangeGET_OK) {
2935   MockHttpCache cache;
2936   AddMockTransaction(&kRangeGET_TransactionOK);
2937   std::string headers;
2938 
2939   // Write to the cache (40-49).
2940   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
2941                                  &headers);
2942 
2943   Verify206Response(headers, 40, 49);
2944   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2945   EXPECT_EQ(0, cache.disk_cache()->open_count());
2946   EXPECT_EQ(1, cache.disk_cache()->create_count());
2947 
2948   // Read from the cache (40-49).
2949   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
2950                                  &headers);
2951 
2952   Verify206Response(headers, 40, 49);
2953   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2954   EXPECT_EQ(1, cache.disk_cache()->open_count());
2955   EXPECT_EQ(1, cache.disk_cache()->create_count());
2956 
2957   // Make sure we are done with the previous transaction.
2958   MessageLoop::current()->RunAllPending();
2959 
2960   // Write to the cache (30-39).
2961   MockTransaction transaction(kRangeGET_TransactionOK);
2962   transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
2963   transaction.data = "rg: 30-39 ";
2964   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2965 
2966   Verify206Response(headers, 30, 39);
2967   EXPECT_EQ(2, cache.network_layer()->transaction_count());
2968   EXPECT_EQ(2, cache.disk_cache()->open_count());
2969   EXPECT_EQ(1, cache.disk_cache()->create_count());
2970 
2971   // Make sure we are done with the previous transaction.
2972   MessageLoop::current()->RunAllPending();
2973 
2974   // Write and read from the cache (20-59).
2975   transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
2976   transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
2977   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2978 
2979   Verify206Response(headers, 20, 59);
2980   EXPECT_EQ(4, cache.network_layer()->transaction_count());
2981   EXPECT_EQ(3, cache.disk_cache()->open_count());
2982   EXPECT_EQ(1, cache.disk_cache()->create_count());
2983 
2984   RemoveMockTransaction(&kRangeGET_TransactionOK);
2985 }
2986 
2987 // Tests that we can cache range requests and fetch random blocks from the
2988 // cache and the network, with synchronous responses.
TEST(HttpCache,RangeGET_SyncOK)2989 TEST(HttpCache, RangeGET_SyncOK) {
2990   MockHttpCache cache;
2991 
2992   MockTransaction transaction(kRangeGET_TransactionOK);
2993   transaction.test_mode = TEST_MODE_SYNC_ALL;
2994   AddMockTransaction(&transaction);
2995 
2996   // Write to the cache (40-49).
2997   std::string headers;
2998   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
2999 
3000   Verify206Response(headers, 40, 49);
3001   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3002   EXPECT_EQ(0, cache.disk_cache()->open_count());
3003   EXPECT_EQ(1, cache.disk_cache()->create_count());
3004 
3005   // Read from the cache (40-49).
3006   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3007 
3008   Verify206Response(headers, 40, 49);
3009   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3010   EXPECT_EQ(0, cache.disk_cache()->open_count());
3011   EXPECT_EQ(1, cache.disk_cache()->create_count());
3012 
3013   // Make sure we are done with the previous transaction.
3014   MessageLoop::current()->RunAllPending();
3015 
3016   // Write to the cache (30-39).
3017   transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3018   transaction.data = "rg: 30-39 ";
3019   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3020 
3021   Verify206Response(headers, 30, 39);
3022   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3023   EXPECT_EQ(1, cache.disk_cache()->open_count());
3024   EXPECT_EQ(1, cache.disk_cache()->create_count());
3025 
3026   // Make sure we are done with the previous transaction.
3027   MessageLoop::current()->RunAllPending();
3028 
3029   // Write and read from the cache (20-59).
3030   transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
3031   transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3032   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3033 
3034   Verify206Response(headers, 20, 59);
3035   EXPECT_EQ(4, cache.network_layer()->transaction_count());
3036   EXPECT_EQ(2, cache.disk_cache()->open_count());
3037   EXPECT_EQ(1, cache.disk_cache()->create_count());
3038 
3039   RemoveMockTransaction(&transaction);
3040 }
3041 
3042 // Tests that we don't revalidate an entry unless we are required to do so.
TEST(HttpCache,RangeGET_Revalidate1)3043 TEST(HttpCache, RangeGET_Revalidate1) {
3044   MockHttpCache cache;
3045   std::string headers;
3046 
3047   // Write to the cache (40-49).
3048   MockTransaction transaction(kRangeGET_TransactionOK);
3049   transaction.response_headers =
3050       "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3051       "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n"  // Should never expire.
3052       "ETag: \"foo\"\n"
3053       "Accept-Ranges: bytes\n"
3054       "Content-Length: 10\n";
3055   AddMockTransaction(&transaction);
3056   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3057 
3058   Verify206Response(headers, 40, 49);
3059   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3060   EXPECT_EQ(0, cache.disk_cache()->open_count());
3061   EXPECT_EQ(1, cache.disk_cache()->create_count());
3062 
3063   // Read from the cache (40-49).
3064   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3065   Verify206Response(headers, 40, 49);
3066 
3067   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3068   EXPECT_EQ(1, cache.disk_cache()->open_count());
3069   EXPECT_EQ(1, cache.disk_cache()->create_count());
3070 
3071   // Read again forcing the revalidation.
3072   transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3073   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3074 
3075   Verify206Response(headers, 40, 49);
3076   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3077   EXPECT_EQ(1, cache.disk_cache()->open_count());
3078   EXPECT_EQ(1, cache.disk_cache()->create_count());
3079 
3080   RemoveMockTransaction(&transaction);
3081 }
3082 
3083 // Checks that we revalidate an entry when the headers say so.
TEST(HttpCache,RangeGET_Revalidate2)3084 TEST(HttpCache, RangeGET_Revalidate2) {
3085   MockHttpCache cache;
3086   std::string headers;
3087 
3088   // Write to the cache (40-49).
3089   MockTransaction transaction(kRangeGET_TransactionOK);
3090   transaction.response_headers =
3091       "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3092       "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n"  // Expired.
3093       "ETag: \"foo\"\n"
3094       "Accept-Ranges: bytes\n"
3095       "Content-Length: 10\n";
3096   AddMockTransaction(&transaction);
3097   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3098 
3099   Verify206Response(headers, 40, 49);
3100   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3101   EXPECT_EQ(0, cache.disk_cache()->open_count());
3102   EXPECT_EQ(1, cache.disk_cache()->create_count());
3103 
3104   // Read from the cache (40-49).
3105   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3106   Verify206Response(headers, 40, 49);
3107 
3108   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3109   EXPECT_EQ(1, cache.disk_cache()->open_count());
3110   EXPECT_EQ(1, cache.disk_cache()->create_count());
3111 
3112   RemoveMockTransaction(&transaction);
3113 }
3114 
3115 // Tests that we deal with 304s for range requests.
TEST(HttpCache,RangeGET_304)3116 TEST(HttpCache, RangeGET_304) {
3117   MockHttpCache cache;
3118   AddMockTransaction(&kRangeGET_TransactionOK);
3119   std::string headers;
3120 
3121   // Write to the cache (40-49).
3122   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3123                                  &headers);
3124 
3125   Verify206Response(headers, 40, 49);
3126   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3127   EXPECT_EQ(0, cache.disk_cache()->open_count());
3128   EXPECT_EQ(1, cache.disk_cache()->create_count());
3129 
3130   // Read from the cache (40-49).
3131   RangeTransactionServer handler;
3132   handler.set_not_modified(true);
3133   MockTransaction transaction(kRangeGET_TransactionOK);
3134   transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3135   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3136 
3137   Verify206Response(headers, 40, 49);
3138   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3139   EXPECT_EQ(1, cache.disk_cache()->open_count());
3140   EXPECT_EQ(1, cache.disk_cache()->create_count());
3141 
3142   RemoveMockTransaction(&kRangeGET_TransactionOK);
3143 }
3144 
3145 // Tests that we deal with 206s when revalidating range requests.
TEST(HttpCache,RangeGET_ModifiedResult)3146 TEST(HttpCache, RangeGET_ModifiedResult) {
3147   MockHttpCache cache;
3148   AddMockTransaction(&kRangeGET_TransactionOK);
3149   std::string headers;
3150 
3151   // Write to the cache (40-49).
3152   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3153                                  &headers);
3154 
3155   Verify206Response(headers, 40, 49);
3156   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3157   EXPECT_EQ(0, cache.disk_cache()->open_count());
3158   EXPECT_EQ(1, cache.disk_cache()->create_count());
3159 
3160   // Attempt to read from the cache (40-49).
3161   RangeTransactionServer handler;
3162   handler.set_modified(true);
3163   MockTransaction transaction(kRangeGET_TransactionOK);
3164   transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3165   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3166 
3167   Verify206Response(headers, 40, 49);
3168   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3169   EXPECT_EQ(1, cache.disk_cache()->open_count());
3170   EXPECT_EQ(1, cache.disk_cache()->create_count());
3171 
3172   // And the entry should be gone.
3173   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3174   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3175   EXPECT_EQ(1, cache.disk_cache()->open_count());
3176   EXPECT_EQ(2, cache.disk_cache()->create_count());
3177 
3178   RemoveMockTransaction(&kRangeGET_TransactionOK);
3179 }
3180 
3181 // Tests that we can cache range requests when the start or end is unknown.
3182 // We start with one suffix request, followed by a request from a given point.
TEST(HttpCache,UnknownRangeGET_1)3183 TEST(HttpCache, UnknownRangeGET_1) {
3184   MockHttpCache cache;
3185   AddMockTransaction(&kRangeGET_TransactionOK);
3186   std::string headers;
3187 
3188   // Write to the cache (70-79).
3189   MockTransaction transaction(kRangeGET_TransactionOK);
3190   transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
3191   transaction.data = "rg: 70-79 ";
3192   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3193 
3194   Verify206Response(headers, 70, 79);
3195   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3196   EXPECT_EQ(0, cache.disk_cache()->open_count());
3197   EXPECT_EQ(1, cache.disk_cache()->create_count());
3198 
3199   // Make sure we are done with the previous transaction.
3200   MessageLoop::current()->RunAllPending();
3201 
3202   // Write and read from the cache (60-79).
3203   transaction.request_headers = "Range: bytes = 60-\r\n" EXTRA_HEADER;
3204   transaction.data = "rg: 60-69 rg: 70-79 ";
3205   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3206 
3207   Verify206Response(headers, 60, 79);
3208   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3209   EXPECT_EQ(1, cache.disk_cache()->open_count());
3210   EXPECT_EQ(1, cache.disk_cache()->create_count());
3211 
3212   RemoveMockTransaction(&kRangeGET_TransactionOK);
3213 }
3214 
3215 // Tests that we can cache range requests when the start or end is unknown.
3216 // We start with one request from a given point, followed by a suffix request.
3217 // We'll also verify that synchronous cache responses work as intended.
TEST(HttpCache,UnknownRangeGET_2)3218 TEST(HttpCache, UnknownRangeGET_2) {
3219   MockHttpCache cache;
3220   std::string headers;
3221 
3222   MockTransaction transaction(kRangeGET_TransactionOK);
3223   transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
3224                           TEST_MODE_SYNC_CACHE_READ |
3225                           TEST_MODE_SYNC_CACHE_WRITE;
3226   AddMockTransaction(&transaction);
3227 
3228   // Write to the cache (70-79).
3229   transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
3230   transaction.data = "rg: 70-79 ";
3231   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3232 
3233   Verify206Response(headers, 70, 79);
3234   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3235   EXPECT_EQ(0, cache.disk_cache()->open_count());
3236   EXPECT_EQ(1, cache.disk_cache()->create_count());
3237 
3238   // Make sure we are done with the previous transaction.
3239   MessageLoop::current()->RunAllPending();
3240 
3241   // Write and read from the cache (60-79).
3242   transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
3243   transaction.data = "rg: 60-69 rg: 70-79 ";
3244   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3245 
3246   Verify206Response(headers, 60, 79);
3247   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3248   EXPECT_EQ(1, cache.disk_cache()->open_count());
3249   EXPECT_EQ(1, cache.disk_cache()->create_count());
3250 
3251   RemoveMockTransaction(&transaction);
3252 }
3253 
3254 // Tests that receiving Not Modified when asking for an open range doesn't mess
3255 // up things.
TEST(HttpCache,UnknownRangeGET_304)3256 TEST(HttpCache, UnknownRangeGET_304) {
3257   MockHttpCache cache;
3258   std::string headers;
3259 
3260   MockTransaction transaction(kRangeGET_TransactionOK);
3261   AddMockTransaction(&transaction);
3262 
3263   RangeTransactionServer handler;
3264   handler.set_not_modified(true);
3265 
3266   // Ask for the end of the file, without knowing the length.
3267   transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
3268   transaction.data = "";
3269   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3270 
3271   // We just bypass the cache.
3272   EXPECT_EQ(0U, headers.find("HTTP/1.1 304 Not Modified\n"));
3273   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3274   EXPECT_EQ(0, cache.disk_cache()->open_count());
3275   EXPECT_EQ(1, cache.disk_cache()->create_count());
3276 
3277   RunTransactionTest(cache.http_cache(), transaction);
3278   EXPECT_EQ(2, cache.disk_cache()->create_count());
3279 
3280   RemoveMockTransaction(&transaction);
3281 }
3282 
3283 // Tests that we can handle non-range requests when we have cached a range.
TEST(HttpCache,GET_Previous206)3284 TEST(HttpCache, GET_Previous206) {
3285   MockHttpCache cache;
3286   AddMockTransaction(&kRangeGET_TransactionOK);
3287   std::string headers;
3288 
3289   // Write to the cache (40-49).
3290   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3291                                  &headers);
3292 
3293   Verify206Response(headers, 40, 49);
3294   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3295   EXPECT_EQ(0, cache.disk_cache()->open_count());
3296   EXPECT_EQ(1, cache.disk_cache()->create_count());
3297 
3298   // Write and read from the cache (0-79), when not asked for a range.
3299   MockTransaction transaction(kRangeGET_TransactionOK);
3300   transaction.request_headers = EXTRA_HEADER;
3301   transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
3302                      "rg: 50-59 rg: 60-69 rg: 70-79 ";
3303   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3304 
3305   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
3306   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3307   EXPECT_EQ(1, cache.disk_cache()->open_count());
3308   EXPECT_EQ(1, cache.disk_cache()->create_count());
3309 
3310   RemoveMockTransaction(&kRangeGET_TransactionOK);
3311 }
3312 
3313 // Tests that we can handle non-range requests when we have cached the first
3314 // part of the object and the server replies with 304 (Not Modified).
TEST(HttpCache,GET_Previous206_NotModified)3315 TEST(HttpCache, GET_Previous206_NotModified) {
3316   MockHttpCache cache;
3317 
3318   MockTransaction transaction(kRangeGET_TransactionOK);
3319   AddMockTransaction(&transaction);
3320   std::string headers;
3321 
3322   // Write to the cache (0-9).
3323   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
3324   transaction.data = "rg: 00-09 ";
3325   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3326   Verify206Response(headers, 0, 9);
3327 
3328   // Write to the cache (70-79).
3329   transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
3330   transaction.data = "rg: 70-79 ";
3331   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3332   Verify206Response(headers, 70, 79);
3333 
3334   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3335   EXPECT_EQ(1, cache.disk_cache()->open_count());
3336   EXPECT_EQ(1, cache.disk_cache()->create_count());
3337 
3338   // Read from the cache (0-9), write and read from cache (10 - 79).
3339   transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3340   transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER;
3341   transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
3342                       "rg: 50-59 rg: 60-69 rg: 70-79 ";
3343   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3344 
3345   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
3346   EXPECT_EQ(4, cache.network_layer()->transaction_count());
3347   EXPECT_EQ(2, cache.disk_cache()->open_count());
3348   EXPECT_EQ(1, cache.disk_cache()->create_count());
3349 
3350   RemoveMockTransaction(&transaction);
3351 }
3352 
3353 // Tests that we can handle a regular request to a sparse entry, that results in
3354 // new content provided by the server (206).
TEST(HttpCache,GET_Previous206_NewContent)3355 TEST(HttpCache, GET_Previous206_NewContent) {
3356   MockHttpCache cache;
3357   AddMockTransaction(&kRangeGET_TransactionOK);
3358   std::string headers;
3359 
3360   // Write to the cache (0-9).
3361   MockTransaction transaction(kRangeGET_TransactionOK);
3362   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
3363   transaction.data = "rg: 00-09 ";
3364   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3365 
3366   Verify206Response(headers, 0, 9);
3367   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3368   EXPECT_EQ(0, cache.disk_cache()->open_count());
3369   EXPECT_EQ(1, cache.disk_cache()->create_count());
3370 
3371   // Now we'll issue a request without any range that should result first in a
3372   // 206 (when revalidating), and then in a weird standard answer: the test
3373   // server will not modify the response so we'll get the default range... a
3374   // real server will answer with 200.
3375   MockTransaction transaction2(kRangeGET_TransactionOK);
3376   transaction2.request_headers = EXTRA_HEADER;
3377   transaction2.load_flags |= net::LOAD_VALIDATE_CACHE;
3378   transaction2.data = "Not a range";
3379   RangeTransactionServer handler;
3380   handler.set_modified(true);
3381   RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3382 
3383   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
3384   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3385   EXPECT_EQ(1, cache.disk_cache()->open_count());
3386   EXPECT_EQ(1, cache.disk_cache()->create_count());
3387 
3388   // Verify that the previous request deleted the entry.
3389   RunTransactionTest(cache.http_cache(), transaction);
3390   EXPECT_EQ(2, cache.disk_cache()->create_count());
3391 
3392   RemoveMockTransaction(&transaction);
3393 }
3394 
3395 // Tests that we can handle cached 206 responses that are not sparse.
TEST(HttpCache,GET_Previous206_NotSparse)3396 TEST(HttpCache, GET_Previous206_NotSparse) {
3397   MockHttpCache cache;
3398 
3399   // Create a disk cache entry that stores 206 headers while not being sparse.
3400   disk_cache::Entry* entry;
3401   ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
3402                                        NULL));
3403 
3404   std::string raw_headers(kRangeGET_TransactionOK.status);
3405   raw_headers.append("\n");
3406   raw_headers.append(kRangeGET_TransactionOK.response_headers);
3407   raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
3408                                                   raw_headers.size());
3409 
3410   net::HttpResponseInfo response;
3411   response.headers = new net::HttpResponseHeaders(raw_headers);
3412   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
3413 
3414   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
3415   int len = static_cast<int>(base::strlcpy(buf->data(),
3416                                            kRangeGET_TransactionOK.data, 500));
3417   TestCompletionCallback cb;
3418   int rv = entry->WriteData(1, 0, buf, len, &cb, true);
3419   EXPECT_EQ(len, cb.GetResult(rv));
3420   entry->Close();
3421 
3422   // Now see that we don't use the stored entry.
3423   std::string headers;
3424   RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
3425                                  &headers);
3426 
3427   // We are expecting a 200.
3428   std::string expected_headers(kSimpleGET_Transaction.status);
3429   expected_headers.append("\n");
3430   expected_headers.append(kSimpleGET_Transaction.response_headers);
3431   EXPECT_EQ(expected_headers, headers);
3432   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3433   EXPECT_EQ(1, cache.disk_cache()->open_count());
3434   EXPECT_EQ(2, cache.disk_cache()->create_count());
3435 }
3436 
3437 // Tests that we can handle cached 206 responses that are not sparse. This time
3438 // we issue a range request and expect to receive a range.
TEST(HttpCache,RangeGET_Previous206_NotSparse_2)3439 TEST(HttpCache, RangeGET_Previous206_NotSparse_2) {
3440   MockHttpCache cache;
3441   AddMockTransaction(&kRangeGET_TransactionOK);
3442 
3443   // Create a disk cache entry that stores 206 headers while not being sparse.
3444   disk_cache::Entry* entry;
3445   ASSERT_TRUE(cache.CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
3446                                        NULL));
3447 
3448   std::string raw_headers(kRangeGET_TransactionOK.status);
3449   raw_headers.append("\n");
3450   raw_headers.append(kRangeGET_TransactionOK.response_headers);
3451   raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
3452                                                   raw_headers.size());
3453 
3454   net::HttpResponseInfo response;
3455   response.headers = new net::HttpResponseHeaders(raw_headers);
3456   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
3457 
3458   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
3459   int len = static_cast<int>(base::strlcpy(buf->data(),
3460                                            kRangeGET_TransactionOK.data, 500));
3461   TestCompletionCallback cb;
3462   int rv = entry->WriteData(1, 0, buf, len, &cb, true);
3463   EXPECT_EQ(len, cb.GetResult(rv));
3464   entry->Close();
3465 
3466   // Now see that we don't use the stored entry.
3467   std::string headers;
3468   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3469                                  &headers);
3470 
3471   // We are expecting a 206.
3472   Verify206Response(headers, 40, 49);
3473   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3474   EXPECT_EQ(1, cache.disk_cache()->open_count());
3475   EXPECT_EQ(2, cache.disk_cache()->create_count());
3476 
3477   RemoveMockTransaction(&kRangeGET_TransactionOK);
3478 }
3479 
3480 // Tests that we can handle cached 206 responses that can't be validated.
TEST(HttpCache,GET_Previous206_NotValidation)3481 TEST(HttpCache, GET_Previous206_NotValidation) {
3482   MockHttpCache cache;
3483 
3484   // Create a disk cache entry that stores 206 headers.
3485   disk_cache::Entry* entry;
3486   ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
3487                                        NULL));
3488 
3489   // Make sure that the headers cannot be validated with the server.
3490   std::string raw_headers(kRangeGET_TransactionOK.status);
3491   raw_headers.append("\n");
3492   raw_headers.append("Content-Length: 80\n");
3493   raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
3494                                                   raw_headers.size());
3495 
3496   net::HttpResponseInfo response;
3497   response.headers = new net::HttpResponseHeaders(raw_headers);
3498   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
3499 
3500   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
3501   int len = static_cast<int>(base::strlcpy(buf->data(),
3502                                            kRangeGET_TransactionOK.data, 500));
3503   TestCompletionCallback cb;
3504   int rv = entry->WriteData(1, 0, buf, len, &cb, true);
3505   EXPECT_EQ(len, cb.GetResult(rv));
3506   entry->Close();
3507 
3508   // Now see that we don't use the stored entry.
3509   std::string headers;
3510   RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
3511                                  &headers);
3512 
3513   // We are expecting a 200.
3514   std::string expected_headers(kSimpleGET_Transaction.status);
3515   expected_headers.append("\n");
3516   expected_headers.append(kSimpleGET_Transaction.response_headers);
3517   EXPECT_EQ(expected_headers, headers);
3518   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3519   EXPECT_EQ(1, cache.disk_cache()->open_count());
3520   EXPECT_EQ(2, cache.disk_cache()->create_count());
3521 }
3522 
3523 // Tests that we can handle range requests with cached 200 responses.
TEST(HttpCache,RangeGET_Previous200)3524 TEST(HttpCache, RangeGET_Previous200) {
3525   MockHttpCache cache;
3526 
3527   // Store the whole thing with status 200.
3528   MockTransaction transaction(kTypicalGET_Transaction);
3529   transaction.url = kRangeGET_TransactionOK.url;
3530   transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
3531                      "rg: 50-59 rg: 60-69 rg: 70-79 ";
3532   AddMockTransaction(&transaction);
3533   RunTransactionTest(cache.http_cache(), transaction);
3534   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3535   EXPECT_EQ(0, cache.disk_cache()->open_count());
3536   EXPECT_EQ(1, cache.disk_cache()->create_count());
3537 
3538   RemoveMockTransaction(&transaction);
3539   AddMockTransaction(&kRangeGET_TransactionOK);
3540 
3541   // Now see that we use the stored entry.
3542   std::string headers;
3543   MockTransaction transaction2(kRangeGET_TransactionOK);
3544   RangeTransactionServer handler;
3545   handler.set_not_modified(true);
3546   RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3547 
3548   // We are expecting a 206.
3549   Verify206Response(headers, 40, 49);
3550   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3551   EXPECT_EQ(1, cache.disk_cache()->open_count());
3552   EXPECT_EQ(1, cache.disk_cache()->create_count());
3553 
3554   // The last transaction has finished so make sure the entry is deactivated.
3555   MessageLoop::current()->RunAllPending();
3556 
3557   // Make a request for an invalid range.
3558   MockTransaction transaction3(kRangeGET_TransactionOK);
3559   transaction3.request_headers = "Range: bytes = 80-90\r\n" EXTRA_HEADER;
3560   transaction3.data = "";
3561   transaction3.load_flags = net::LOAD_PREFERRING_CACHE;
3562   RunTransactionTestWithResponse(cache.http_cache(), transaction3, &headers);
3563   EXPECT_EQ(2, cache.disk_cache()->open_count());
3564   EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
3565   EXPECT_NE(std::string::npos, headers.find("Content-Range: bytes 0-0/80"));
3566   EXPECT_NE(std::string::npos, headers.find("Content-Length: 0"));
3567 
3568   // Make sure the entry is deactivated.
3569   MessageLoop::current()->RunAllPending();
3570 
3571   // Even though the request was invalid, we should have the entry.
3572   RunTransactionTest(cache.http_cache(), transaction2);
3573   EXPECT_EQ(3, cache.disk_cache()->open_count());
3574 
3575   // Make sure the entry is deactivated.
3576   MessageLoop::current()->RunAllPending();
3577 
3578   // Now we should receive a range from the server and drop the stored entry.
3579   handler.set_not_modified(false);
3580   transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
3581   RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3582   Verify206Response(headers, 40, 49);
3583   EXPECT_EQ(5, cache.network_layer()->transaction_count());
3584   EXPECT_EQ(4, cache.disk_cache()->open_count());
3585   EXPECT_EQ(1, cache.disk_cache()->create_count());
3586 
3587   RunTransactionTest(cache.http_cache(), transaction2);
3588   EXPECT_EQ(2, cache.disk_cache()->create_count());
3589 
3590   RemoveMockTransaction(&kRangeGET_TransactionOK);
3591 }
3592 
3593 // Tests that we can handle a 200 response when dealing with sparse entries.
TEST(HttpCache,RangeRequestResultsIn200)3594 TEST(HttpCache, RangeRequestResultsIn200) {
3595   MockHttpCache cache;
3596   AddMockTransaction(&kRangeGET_TransactionOK);
3597   std::string headers;
3598 
3599   // Write to the cache (70-79).
3600   MockTransaction transaction(kRangeGET_TransactionOK);
3601   transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
3602   transaction.data = "rg: 70-79 ";
3603   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3604 
3605   Verify206Response(headers, 70, 79);
3606   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3607   EXPECT_EQ(0, cache.disk_cache()->open_count());
3608   EXPECT_EQ(1, cache.disk_cache()->create_count());
3609 
3610   // Now we'll issue a request that results in a plain 200 response, but to
3611   // the to the same URL that we used to store sparse data, and making sure
3612   // that we ask for a range.
3613   RemoveMockTransaction(&kRangeGET_TransactionOK);
3614   MockTransaction transaction2(kSimpleGET_Transaction);
3615   transaction2.url = kRangeGET_TransactionOK.url;
3616   transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
3617   AddMockTransaction(&transaction2);
3618 
3619   RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3620 
3621   std::string expected_headers(kSimpleGET_Transaction.status);
3622   expected_headers.append("\n");
3623   expected_headers.append(kSimpleGET_Transaction.response_headers);
3624   EXPECT_EQ(expected_headers, headers);
3625   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3626   EXPECT_EQ(1, cache.disk_cache()->open_count());
3627   EXPECT_EQ(1, cache.disk_cache()->create_count());
3628 
3629   RemoveMockTransaction(&transaction2);
3630 }
3631 
3632 // Tests that a range request that falls outside of the size that we know about
3633 // only deletes the entry if the resource has indeed changed.
TEST(HttpCache,RangeGET_MoreThanCurrentSize)3634 TEST(HttpCache, RangeGET_MoreThanCurrentSize) {
3635   MockHttpCache cache;
3636   AddMockTransaction(&kRangeGET_TransactionOK);
3637   std::string headers;
3638 
3639   // Write to the cache (40-49).
3640   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3641                                  &headers);
3642 
3643   Verify206Response(headers, 40, 49);
3644   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3645   EXPECT_EQ(0, cache.disk_cache()->open_count());
3646   EXPECT_EQ(1, cache.disk_cache()->create_count());
3647 
3648   // A weird request should not delete this entry. Ask for bytes 120-.
3649   MockTransaction transaction(kRangeGET_TransactionOK);
3650   transaction.request_headers = "Range: bytes = 120-\r\n" EXTRA_HEADER;
3651   transaction.data = "";
3652   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3653 
3654   EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
3655   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3656   EXPECT_EQ(1, cache.disk_cache()->open_count());
3657   EXPECT_EQ(1, cache.disk_cache()->create_count());
3658 
3659   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3660   EXPECT_EQ(2, cache.disk_cache()->open_count());
3661   EXPECT_EQ(1, cache.disk_cache()->create_count());
3662 
3663   RemoveMockTransaction(&kRangeGET_TransactionOK);
3664 }
3665 
3666 // Tests that we don't delete a sparse entry when we cancel a request.
TEST(HttpCache,RangeGET_Cancel)3667 TEST(HttpCache, RangeGET_Cancel) {
3668   MockHttpCache cache;
3669   AddMockTransaction(&kRangeGET_TransactionOK);
3670 
3671   MockHttpRequest request(kRangeGET_TransactionOK);
3672 
3673   Context* c = new Context();
3674   int rv = cache.http_cache()->CreateTransaction(&c->trans);
3675   EXPECT_EQ(net::OK, rv);
3676 
3677   rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
3678   if (rv == net::ERR_IO_PENDING)
3679     rv = c->callback.WaitForResult();
3680 
3681   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3682   EXPECT_EQ(0, cache.disk_cache()->open_count());
3683   EXPECT_EQ(1, cache.disk_cache()->create_count());
3684 
3685   // Make sure that the entry has some data stored.
3686   scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
3687   rv = c->trans->Read(buf, buf->size(), &c->callback);
3688   if (rv == net::ERR_IO_PENDING)
3689     rv = c->callback.WaitForResult();
3690   EXPECT_EQ(buf->size(), rv);
3691 
3692   // Destroy the transaction.
3693   delete c;
3694 
3695   // Verify that the entry has not been deleted.
3696   disk_cache::Entry* entry;
3697   ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
3698   entry->Close();
3699   RemoveMockTransaction(&kRangeGET_TransactionOK);
3700 }
3701 
3702 // Tests that we don't delete a sparse entry when we start a new request after
3703 // cancelling the previous one.
TEST(HttpCache,RangeGET_Cancel2)3704 TEST(HttpCache, RangeGET_Cancel2) {
3705   MockHttpCache cache;
3706   AddMockTransaction(&kRangeGET_TransactionOK);
3707 
3708   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3709   MockHttpRequest request(kRangeGET_TransactionOK);
3710   request.load_flags |= net::LOAD_VALIDATE_CACHE;
3711 
3712   Context* c = new Context();
3713   int rv = cache.http_cache()->CreateTransaction(&c->trans);
3714   EXPECT_EQ(net::OK, rv);
3715 
3716   rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
3717   if (rv == net::ERR_IO_PENDING)
3718     rv = c->callback.WaitForResult();
3719 
3720   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3721   EXPECT_EQ(1, cache.disk_cache()->open_count());
3722   EXPECT_EQ(1, cache.disk_cache()->create_count());
3723 
3724   // Make sure that we revalidate the entry and read from the cache (a single
3725   // read will return while waiting for the network).
3726   scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
3727   rv = c->trans->Read(buf, buf->size(), &c->callback);
3728   EXPECT_EQ(5, c->callback.GetResult(rv));
3729   rv = c->trans->Read(buf, buf->size(), &c->callback);
3730   EXPECT_EQ(net::ERR_IO_PENDING, rv);
3731 
3732   // Destroy the transaction before completing the read.
3733   delete c;
3734 
3735   // We have the read and the delete (OnProcessPendingQueue) waiting on the
3736   // message loop. This means that a new transaction will just reuse the same
3737   // active entry (no open or create).
3738 
3739   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3740 
3741   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3742   EXPECT_EQ(1, cache.disk_cache()->open_count());
3743   EXPECT_EQ(1, cache.disk_cache()->create_count());
3744   RemoveMockTransaction(&kRangeGET_TransactionOK);
3745 }
3746 
3747 // A slight variation of the previous test, this time we cancel two requests in
3748 // a row, making sure that the second is waiting for the entry to be ready.
TEST(HttpCache,RangeGET_Cancel3)3749 TEST(HttpCache, RangeGET_Cancel3) {
3750   MockHttpCache cache;
3751   AddMockTransaction(&kRangeGET_TransactionOK);
3752 
3753   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3754   MockHttpRequest request(kRangeGET_TransactionOK);
3755   request.load_flags |= net::LOAD_VALIDATE_CACHE;
3756 
3757   Context* c = new Context();
3758   int rv = cache.http_cache()->CreateTransaction(&c->trans);
3759   EXPECT_EQ(net::OK, rv);
3760 
3761   rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
3762   EXPECT_EQ(net::ERR_IO_PENDING, rv);
3763   rv = c->callback.WaitForResult();
3764 
3765   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3766   EXPECT_EQ(1, cache.disk_cache()->open_count());
3767   EXPECT_EQ(1, cache.disk_cache()->create_count());
3768 
3769   // Make sure that we revalidate the entry and read from the cache (a single
3770   // read will return while waiting for the network).
3771   scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
3772   rv = c->trans->Read(buf, buf->size(), &c->callback);
3773   EXPECT_EQ(5, c->callback.GetResult(rv));
3774   rv = c->trans->Read(buf, buf->size(), &c->callback);
3775   EXPECT_EQ(net::ERR_IO_PENDING, rv);
3776 
3777   // Destroy the transaction before completing the read.
3778   delete c;
3779 
3780   // We have the read and the delete (OnProcessPendingQueue) waiting on the
3781   // message loop. This means that a new transaction will just reuse the same
3782   // active entry (no open or create).
3783 
3784   c = new Context();
3785   rv = cache.http_cache()->CreateTransaction(&c->trans);
3786   EXPECT_EQ(net::OK, rv);
3787 
3788   rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
3789   EXPECT_EQ(net::ERR_IO_PENDING, rv);
3790 
3791   MockDiskEntry::IgnoreCallbacks(true);
3792   MessageLoop::current()->RunAllPending();
3793   MockDiskEntry::IgnoreCallbacks(false);
3794 
3795   // The new transaction is waiting for the query range callback.
3796   delete c;
3797 
3798   // And we should not crash when the callback is delivered.
3799   MessageLoop::current()->RunAllPending();
3800 
3801   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3802   EXPECT_EQ(1, cache.disk_cache()->open_count());
3803   EXPECT_EQ(1, cache.disk_cache()->create_count());
3804   RemoveMockTransaction(&kRangeGET_TransactionOK);
3805 }
3806 
3807 // Tests that an invalid range response results in no cached entry.
TEST(HttpCache,RangeGET_InvalidResponse1)3808 TEST(HttpCache, RangeGET_InvalidResponse1) {
3809   MockHttpCache cache;
3810   std::string headers;
3811 
3812   MockTransaction transaction(kRangeGET_TransactionOK);
3813   transaction.handler = NULL;
3814   transaction.response_headers = "Content-Range: bytes 40-49/45\n"
3815                                  "Content-Length: 10\n";
3816   AddMockTransaction(&transaction);
3817   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3818 
3819   std::string expected(transaction.status);
3820   expected.append("\n");
3821   expected.append(transaction.response_headers);
3822   EXPECT_EQ(expected, headers);
3823 
3824   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3825   EXPECT_EQ(0, cache.disk_cache()->open_count());
3826   EXPECT_EQ(1, cache.disk_cache()->create_count());
3827 
3828   // Verify that we don't have a cached entry.
3829   disk_cache::Entry* entry;
3830   EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
3831 
3832   RemoveMockTransaction(&kRangeGET_TransactionOK);
3833 }
3834 
3835 // Tests that we reject a range that doesn't match the content-length.
TEST(HttpCache,RangeGET_InvalidResponse2)3836 TEST(HttpCache, RangeGET_InvalidResponse2) {
3837   MockHttpCache cache;
3838   std::string headers;
3839 
3840   MockTransaction transaction(kRangeGET_TransactionOK);
3841   transaction.handler = NULL;
3842   transaction.response_headers = "Content-Range: bytes 40-49/80\n"
3843                                  "Content-Length: 20\n";
3844   AddMockTransaction(&transaction);
3845   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3846 
3847   std::string expected(transaction.status);
3848   expected.append("\n");
3849   expected.append(transaction.response_headers);
3850   EXPECT_EQ(expected, headers);
3851 
3852   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3853   EXPECT_EQ(0, cache.disk_cache()->open_count());
3854   EXPECT_EQ(1, cache.disk_cache()->create_count());
3855 
3856   // Verify that we don't have a cached entry.
3857   disk_cache::Entry* entry;
3858   EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
3859 
3860   RemoveMockTransaction(&kRangeGET_TransactionOK);
3861 }
3862 
3863 // Tests that if a server tells us conflicting information about a resource we
3864 // ignore the response.
TEST(HttpCache,RangeGET_InvalidResponse3)3865 TEST(HttpCache, RangeGET_InvalidResponse3) {
3866   MockHttpCache cache;
3867   std::string headers;
3868 
3869   MockTransaction transaction(kRangeGET_TransactionOK);
3870   transaction.handler = NULL;
3871   transaction.request_headers = "Range: bytes = 50-59\r\n" EXTRA_HEADER;
3872   std::string response_headers(transaction.response_headers);
3873   response_headers.append("Content-Range: bytes 50-59/160\n");
3874   transaction.response_headers = response_headers.c_str();
3875   AddMockTransaction(&transaction);
3876   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3877 
3878   Verify206Response(headers, 50, 59);
3879   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3880   EXPECT_EQ(0, cache.disk_cache()->open_count());
3881   EXPECT_EQ(1, cache.disk_cache()->create_count());
3882 
3883   RemoveMockTransaction(&transaction);
3884   AddMockTransaction(&kRangeGET_TransactionOK);
3885 
3886   // This transaction will report a resource size of 80 bytes, and we think it's
3887   // 160 so we should ignore the response.
3888   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3889                                  &headers);
3890 
3891   Verify206Response(headers, 40, 49);
3892   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3893   EXPECT_EQ(1, cache.disk_cache()->open_count());
3894   EXPECT_EQ(1, cache.disk_cache()->create_count());
3895 
3896   // Verify that we cached the first response but not the second one.
3897   disk_cache::Entry* en;
3898   ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
3899 
3900   int64 cached_start = 0;
3901   TestCompletionCallback cb;
3902   int rv = en->GetAvailableRange(40, 20, &cached_start, &cb);
3903   EXPECT_EQ(10, cb.GetResult(rv));
3904   EXPECT_EQ(50, cached_start);
3905   en->Close();
3906 
3907   RemoveMockTransaction(&kRangeGET_TransactionOK);
3908 }
3909 
3910 // Tests that we handle large range values properly.
TEST(HttpCache,RangeGET_LargeValues)3911 TEST(HttpCache, RangeGET_LargeValues) {
3912   // We need a real sparse cache for this test.
3913   MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
3914   std::string headers;
3915 
3916   MockTransaction transaction(kRangeGET_TransactionOK);
3917   transaction.handler = NULL;
3918   transaction.request_headers = "Range: bytes = 4294967288-4294967297\r\n"
3919                                 EXTRA_HEADER;
3920   transaction.response_headers =
3921       "ETag: \"foo\"\n"
3922       "Content-Range: bytes 4294967288-4294967297/4294967299\n"
3923       "Content-Length: 10\n";
3924   AddMockTransaction(&transaction);
3925   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3926 
3927   std::string expected(transaction.status);
3928   expected.append("\n");
3929   expected.append(transaction.response_headers);
3930   EXPECT_EQ(expected, headers);
3931 
3932   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3933 
3934   // Verify that we have a cached entry.
3935   disk_cache::Entry* en;
3936   ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
3937   en->Close();
3938 
3939   RemoveMockTransaction(&kRangeGET_TransactionOK);
3940 }
3941 
3942 // Tests that we don't crash with a range request if the disk cache was not
3943 // initialized properly.
TEST(HttpCache,RangeGET_NoDiskCache)3944 TEST(HttpCache, RangeGET_NoDiskCache) {
3945   MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
3946   factory->set_fail(true);
3947   factory->FinishCreation();  // We'll complete synchronously.
3948   MockHttpCache cache(factory);
3949 
3950   AddMockTransaction(&kRangeGET_TransactionOK);
3951 
3952   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3953   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3954 
3955   RemoveMockTransaction(&kRangeGET_TransactionOK);
3956 }
3957 
3958 // Tests that we handle byte range requests that skip the cache.
TEST(HttpCache,RangeHEAD)3959 TEST(HttpCache, RangeHEAD) {
3960   MockHttpCache cache;
3961   AddMockTransaction(&kRangeGET_TransactionOK);
3962 
3963   MockTransaction transaction(kRangeGET_TransactionOK);
3964   transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
3965   transaction.method = "HEAD";
3966   transaction.data = "rg: 70-79 ";
3967 
3968   std::string headers;
3969   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3970 
3971   Verify206Response(headers, 70, 79);
3972   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3973   EXPECT_EQ(0, cache.disk_cache()->open_count());
3974   EXPECT_EQ(0, cache.disk_cache()->create_count());
3975 
3976   RemoveMockTransaction(&kRangeGET_TransactionOK);
3977 }
3978 
3979 // Tests that we don't crash when after reading from the cache we issue a
3980 // request for the next range and the server gives us a 200 synchronously.
TEST(HttpCache,RangeGET_FastFlakyServer)3981 TEST(HttpCache, RangeGET_FastFlakyServer) {
3982   MockHttpCache cache;
3983 
3984   MockTransaction transaction(kRangeGET_TransactionOK);
3985   transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER;
3986   transaction.test_mode = TEST_MODE_SYNC_NET_START;
3987   transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3988   AddMockTransaction(&transaction);
3989 
3990   // Write to the cache.
3991   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3992 
3993   // And now read from the cache and the network.
3994   RangeTransactionServer handler;
3995   handler.set_bad_200(true);
3996   transaction.data = "Not a range";
3997   RunTransactionTest(cache.http_cache(), transaction);
3998 
3999   EXPECT_EQ(3, cache.network_layer()->transaction_count());
4000   EXPECT_EQ(1, cache.disk_cache()->open_count());
4001   EXPECT_EQ(1, cache.disk_cache()->create_count());
4002 
4003   RemoveMockTransaction(&transaction);
4004 }
4005 
4006 // Tests that when the server gives us less data than expected, we don't keep
4007 // asking for more data.
TEST(HttpCache,RangeGET_FastFlakyServer2)4008 TEST(HttpCache, RangeGET_FastFlakyServer2) {
4009   MockHttpCache cache;
4010 
4011   // First, check with an empty cache (WRITE mode).
4012   MockTransaction transaction(kRangeGET_TransactionOK);
4013   transaction.request_headers = "Range: bytes = 40-49\r\n" EXTRA_HEADER;
4014   transaction.data = "rg: 40-";  // Less than expected.
4015   transaction.handler = NULL;
4016   std::string headers(transaction.response_headers);
4017   headers.append("Content-Range: bytes 40-49/80\n");
4018   transaction.response_headers = headers.c_str();
4019 
4020   AddMockTransaction(&transaction);
4021 
4022   // Write to the cache.
4023   RunTransactionTest(cache.http_cache(), transaction);
4024 
4025   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4026   EXPECT_EQ(0, cache.disk_cache()->open_count());
4027   EXPECT_EQ(1, cache.disk_cache()->create_count());
4028 
4029   // Now verify that even in READ_WRITE mode, we forward the bad response to
4030   // the caller.
4031   transaction.request_headers = "Range: bytes = 60-69\r\n" EXTRA_HEADER;
4032   transaction.data = "rg: 60-";  // Less than expected.
4033   headers = kRangeGET_TransactionOK.response_headers;
4034   headers.append("Content-Range: bytes 60-69/80\n");
4035   transaction.response_headers = headers.c_str();
4036 
4037   RunTransactionTest(cache.http_cache(), transaction);
4038 
4039   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4040   EXPECT_EQ(1, cache.disk_cache()->open_count());
4041   EXPECT_EQ(1, cache.disk_cache()->create_count());
4042 
4043   RemoveMockTransaction(&transaction);
4044 }
4045 
4046 #ifdef NDEBUG
4047 // This test hits a NOTREACHED so it is a release mode only test.
TEST(HttpCache,RangeGET_OK_LoadOnlyFromCache)4048 TEST(HttpCache, RangeGET_OK_LoadOnlyFromCache) {
4049   MockHttpCache cache;
4050   AddMockTransaction(&kRangeGET_TransactionOK);
4051 
4052   // Write to the cache (40-49).
4053   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4054   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4055   EXPECT_EQ(0, cache.disk_cache()->open_count());
4056   EXPECT_EQ(1, cache.disk_cache()->create_count());
4057 
4058   // Force this transaction to read from the cache.
4059   MockTransaction transaction(kRangeGET_TransactionOK);
4060   transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
4061 
4062   MockHttpRequest request(transaction);
4063   TestCompletionCallback callback;
4064 
4065   scoped_ptr<net::HttpTransaction> trans;
4066   int rv = cache.http_cache()->CreateTransaction(&trans);
4067   EXPECT_EQ(net::OK, rv);
4068   ASSERT_TRUE(trans.get());
4069 
4070   rv = trans->Start(&request, &callback, net::BoundNetLog());
4071   if (rv == net::ERR_IO_PENDING)
4072     rv = callback.WaitForResult();
4073   ASSERT_EQ(net::ERR_CACHE_MISS, rv);
4074 
4075   trans.reset();
4076 
4077   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4078   EXPECT_EQ(1, cache.disk_cache()->open_count());
4079   EXPECT_EQ(1, cache.disk_cache()->create_count());
4080 
4081   RemoveMockTransaction(&kRangeGET_TransactionOK);
4082 }
4083 #endif
4084 
4085 // Tests the handling of the "truncation" flag.
TEST(HttpCache,WriteResponseInfo_Truncated)4086 TEST(HttpCache, WriteResponseInfo_Truncated) {
4087   MockHttpCache cache;
4088   disk_cache::Entry* entry;
4089   ASSERT_TRUE(cache.CreateBackendEntry("http://www.google.com", &entry,
4090                                        NULL));
4091 
4092   std::string headers("HTTP/1.1 200 OK");
4093   headers = net::HttpUtil::AssembleRawHeaders(headers.data(), headers.size());
4094   net::HttpResponseInfo response;
4095   response.headers = new net::HttpResponseHeaders(headers);
4096 
4097   // Set the last argument for this to be an incomplete request.
4098   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
4099   bool truncated = false;
4100   EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4101   EXPECT_TRUE(truncated);
4102 
4103   // And now test the opposite case.
4104   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4105   truncated = true;
4106   EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4107   EXPECT_FALSE(truncated);
4108   entry->Close();
4109 }
4110 
4111 // Tests basic pickling/unpickling of HttpResponseInfo.
TEST(HttpCache,PersistHttpResponseInfo)4112 TEST(HttpCache, PersistHttpResponseInfo) {
4113   // Set some fields (add more if needed.)
4114   net::HttpResponseInfo response1;
4115   response1.was_cached = false;
4116   response1.socket_address = net::HostPortPair("1.2.3.4", 80);
4117   response1.headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK");
4118 
4119   // Pickle.
4120   Pickle pickle;
4121   response1.Persist(&pickle, false, false);
4122 
4123   // Unpickle.
4124   net::HttpResponseInfo response2;
4125   bool response_truncated;
4126   EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated));
4127   EXPECT_FALSE(response_truncated);
4128 
4129   // Verify fields.
4130   EXPECT_TRUE(response2.was_cached);  // InitFromPickle sets this flag.
4131   EXPECT_EQ("1.2.3.4", response2.socket_address.host());
4132   EXPECT_EQ(80, response2.socket_address.port());
4133   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
4134 }
4135 
4136 // Tests that we delete an entry when the request is cancelled before starting
4137 // to read from the network.
TEST(HttpCache,DoomOnDestruction)4138 TEST(HttpCache, DoomOnDestruction) {
4139   MockHttpCache cache;
4140 
4141   MockHttpRequest request(kSimpleGET_Transaction);
4142 
4143   Context* c = new Context();
4144   int rv = cache.http_cache()->CreateTransaction(&c->trans);
4145   EXPECT_EQ(net::OK, rv);
4146 
4147   rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
4148   if (rv == net::ERR_IO_PENDING)
4149     c->result = c->callback.WaitForResult();
4150 
4151   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4152   EXPECT_EQ(0, cache.disk_cache()->open_count());
4153   EXPECT_EQ(1, cache.disk_cache()->create_count());
4154 
4155   // Destroy the transaction. We only have the headers so we should delete this
4156   // entry.
4157   delete c;
4158 
4159   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4160 
4161   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4162   EXPECT_EQ(0, cache.disk_cache()->open_count());
4163   EXPECT_EQ(2, cache.disk_cache()->create_count());
4164 }
4165 
4166 // Tests that we delete an entry when the request is cancelled if the response
4167 // does not have content-length and strong validators.
TEST(HttpCache,DoomOnDestruction2)4168 TEST(HttpCache, DoomOnDestruction2) {
4169   MockHttpCache cache;
4170 
4171   MockHttpRequest request(kSimpleGET_Transaction);
4172 
4173   Context* c = new Context();
4174   int rv = cache.http_cache()->CreateTransaction(&c->trans);
4175   EXPECT_EQ(net::OK, rv);
4176 
4177   rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
4178   if (rv == net::ERR_IO_PENDING)
4179     rv = c->callback.WaitForResult();
4180 
4181   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4182   EXPECT_EQ(0, cache.disk_cache()->open_count());
4183   EXPECT_EQ(1, cache.disk_cache()->create_count());
4184 
4185   // Make sure that the entry has some data stored.
4186   scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
4187   rv = c->trans->Read(buf, buf->size(), &c->callback);
4188   if (rv == net::ERR_IO_PENDING)
4189     rv = c->callback.WaitForResult();
4190   EXPECT_EQ(buf->size(), rv);
4191 
4192   // Destroy the transaction.
4193   delete c;
4194 
4195   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4196 
4197   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4198   EXPECT_EQ(0, cache.disk_cache()->open_count());
4199   EXPECT_EQ(2, cache.disk_cache()->create_count());
4200 }
4201 
4202 // Tests that we delete an entry when the request is cancelled if the response
4203 // has an "Accept-Ranges: none" header.
TEST(HttpCache,DoomOnDestruction3)4204 TEST(HttpCache, DoomOnDestruction3) {
4205   MockHttpCache cache;
4206 
4207   MockTransaction transaction(kSimpleGET_Transaction);
4208   transaction.response_headers =
4209       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
4210       "Content-Length: 22\n"
4211       "Accept-Ranges: none\n"
4212       "Etag: foopy\n";
4213   AddMockTransaction(&transaction);
4214   MockHttpRequest request(transaction);
4215 
4216   Context* c = new Context();
4217   int rv = cache.http_cache()->CreateTransaction(&c->trans);
4218   EXPECT_EQ(net::OK, rv);
4219 
4220   rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
4221   if (rv == net::ERR_IO_PENDING)
4222     rv = c->callback.WaitForResult();
4223 
4224   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4225   EXPECT_EQ(0, cache.disk_cache()->open_count());
4226   EXPECT_EQ(1, cache.disk_cache()->create_count());
4227 
4228   // Make sure that the entry has some data stored.
4229   scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
4230   rv = c->trans->Read(buf, buf->size(), &c->callback);
4231   if (rv == net::ERR_IO_PENDING)
4232     rv = c->callback.WaitForResult();
4233   EXPECT_EQ(buf->size(), rv);
4234 
4235   // Destroy the transaction.
4236   delete c;
4237 
4238   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4239 
4240   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4241   EXPECT_EQ(0, cache.disk_cache()->open_count());
4242   EXPECT_EQ(2, cache.disk_cache()->create_count());
4243 
4244   RemoveMockTransaction(&transaction);
4245 }
4246 
4247 // Tests that we mark an entry as incomplete when the request is cancelled.
TEST(HttpCache,Set_Truncated_Flag)4248 TEST(HttpCache, Set_Truncated_Flag) {
4249   MockHttpCache cache;
4250 
4251   MockTransaction transaction(kSimpleGET_Transaction);
4252   transaction.response_headers =
4253       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
4254       "Content-Length: 22\n"
4255       "Etag: foopy\n";
4256   AddMockTransaction(&transaction);
4257   MockHttpRequest request(transaction);
4258 
4259   scoped_ptr<Context> c(new Context());
4260   int rv = cache.http_cache()->CreateTransaction(&c->trans);
4261   EXPECT_EQ(net::OK, rv);
4262 
4263   rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
4264   if (rv == net::ERR_IO_PENDING)
4265     rv = c->callback.WaitForResult();
4266 
4267   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4268   EXPECT_EQ(0, cache.disk_cache()->open_count());
4269   EXPECT_EQ(1, cache.disk_cache()->create_count());
4270 
4271   // Make sure that the entry has some data stored.
4272   scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
4273   rv = c->trans->Read(buf, buf->size(), &c->callback);
4274   if (rv == net::ERR_IO_PENDING)
4275     rv = c->callback.WaitForResult();
4276   EXPECT_EQ(buf->size(), rv);
4277 
4278   // We want to cancel the request when the transaction is busy.
4279   rv = c->trans->Read(buf, buf->size(), &c->callback);
4280   EXPECT_EQ(net::ERR_IO_PENDING, rv);
4281   EXPECT_FALSE(c->callback.have_result());
4282 
4283   g_test_mode = TEST_MODE_SYNC_ALL;
4284 
4285   // Destroy the transaction.
4286   c->trans.reset();
4287   g_test_mode = 0;
4288 
4289   // Make sure that we don't invoke the callback. We may have an issue if the
4290   // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
4291   // could end up with the transaction being deleted twice if we send any
4292   // notification from the transaction destructor (see http://crbug.com/31723).
4293   EXPECT_FALSE(c->callback.have_result());
4294 
4295   // Verify that the entry is marked as incomplete.
4296   disk_cache::Entry* entry;
4297   ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
4298   net::HttpResponseInfo response;
4299   bool truncated = false;
4300   EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4301   EXPECT_TRUE(truncated);
4302   entry->Close();
4303 
4304   RemoveMockTransaction(&transaction);
4305 }
4306 
4307 // Tests that we can continue with a request that was interrupted.
TEST(HttpCache,GET_IncompleteResource)4308 TEST(HttpCache, GET_IncompleteResource) {
4309   MockHttpCache cache;
4310   AddMockTransaction(&kRangeGET_TransactionOK);
4311 
4312   std::string raw_headers("HTTP/1.1 200 OK\n"
4313                           "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4314                           "ETag: \"foo\"\n"
4315                           "Accept-Ranges: bytes\n"
4316                           "Content-Length: 80\n");
4317   CreateTruncatedEntry(raw_headers, &cache);
4318 
4319   // Now make a regular request.
4320   std::string headers;
4321   MockTransaction transaction(kRangeGET_TransactionOK);
4322   transaction.request_headers = EXTRA_HEADER;
4323   transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4324                      "rg: 50-59 rg: 60-69 rg: 70-79 ";
4325   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4326 
4327   // We update the headers with the ones received while revalidating.
4328   std::string expected_headers(
4329       "HTTP/1.1 200 OK\n"
4330       "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4331       "Accept-Ranges: bytes\n"
4332       "ETag: \"foo\"\n"
4333       "Content-Length: 80\n");
4334 
4335   EXPECT_EQ(expected_headers, headers);
4336   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4337   EXPECT_EQ(1, cache.disk_cache()->open_count());
4338   EXPECT_EQ(1, cache.disk_cache()->create_count());
4339 
4340   // Verify that the disk entry was updated.
4341   disk_cache::Entry* entry;
4342   ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4343   EXPECT_EQ(80, entry->GetDataSize(1));
4344   bool truncated = true;
4345   net::HttpResponseInfo response;
4346   EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4347   EXPECT_FALSE(truncated);
4348   entry->Close();
4349 
4350   RemoveMockTransaction(&kRangeGET_TransactionOK);
4351 }
4352 
4353 // Tests that we delete truncated entries if the server changes its mind midway.
TEST(HttpCache,GET_IncompleteResource2)4354 TEST(HttpCache, GET_IncompleteResource2) {
4355   MockHttpCache cache;
4356   AddMockTransaction(&kRangeGET_TransactionOK);
4357 
4358   // Content-length will be intentionally bad.
4359   std::string raw_headers("HTTP/1.1 200 OK\n"
4360                           "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4361                           "ETag: \"foo\"\n"
4362                           "Accept-Ranges: bytes\n"
4363                           "Content-Length: 50\n");
4364   CreateTruncatedEntry(raw_headers, &cache);
4365 
4366   // Now make a regular request. We expect the code to fail the validation and
4367   // retry the request without using byte ranges.
4368   std::string headers;
4369   MockTransaction transaction(kRangeGET_TransactionOK);
4370   transaction.request_headers = EXTRA_HEADER;
4371   transaction.data = "Not a range";
4372   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4373 
4374   // The server will return 200 instead of a byte range.
4375   std::string expected_headers(
4376       "HTTP/1.1 200 OK\n"
4377       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
4378 
4379   EXPECT_EQ(expected_headers, headers);
4380   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4381   EXPECT_EQ(1, cache.disk_cache()->open_count());
4382   EXPECT_EQ(1, cache.disk_cache()->create_count());
4383 
4384   // Verify that the disk entry was deleted.
4385   disk_cache::Entry* entry;
4386   ASSERT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4387   RemoveMockTransaction(&kRangeGET_TransactionOK);
4388 }
4389 
4390 // Tests that we always validate a truncated request.
TEST(HttpCache,GET_IncompleteResource3)4391 TEST(HttpCache, GET_IncompleteResource3) {
4392   MockHttpCache cache;
4393   AddMockTransaction(&kRangeGET_TransactionOK);
4394 
4395   // This should not require validation for 10 hours.
4396   std::string raw_headers("HTTP/1.1 200 OK\n"
4397                           "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4398                           "ETag: \"foo\"\n"
4399                           "Cache-Control: max-age= 36000\n"
4400                           "Accept-Ranges: bytes\n"
4401                           "Content-Length: 80\n");
4402   CreateTruncatedEntry(raw_headers, &cache);
4403 
4404   // Now make a regular request.
4405   std::string headers;
4406   MockTransaction transaction(kRangeGET_TransactionOK);
4407   transaction.request_headers = EXTRA_HEADER;
4408   transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4409                      "rg: 50-59 rg: 60-69 rg: 70-79 ";
4410 
4411   scoped_ptr<Context> c(new Context);
4412   EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(&c->trans));
4413 
4414   MockHttpRequest request(transaction);
4415   int rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
4416   EXPECT_EQ(net::OK, c->callback.GetResult(rv));
4417 
4418   // We should have checked with the server before finishing Start().
4419   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4420   EXPECT_EQ(1, cache.disk_cache()->open_count());
4421   EXPECT_EQ(1, cache.disk_cache()->create_count());
4422 
4423   RemoveMockTransaction(&kRangeGET_TransactionOK);
4424 }
4425 
4426 // Tests that we cache a 200 response to the validation request.
TEST(HttpCache,GET_IncompleteResource4)4427 TEST(HttpCache, GET_IncompleteResource4) {
4428   MockHttpCache cache;
4429   AddMockTransaction(&kRangeGET_TransactionOK);
4430 
4431   std::string raw_headers("HTTP/1.1 200 OK\n"
4432                           "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4433                           "ETag: \"foo\"\n"
4434                           "Accept-Ranges: bytes\n"
4435                           "Content-Length: 80\n");
4436   CreateTruncatedEntry(raw_headers, &cache);
4437 
4438   // Now make a regular request.
4439   std::string headers;
4440   MockTransaction transaction(kRangeGET_TransactionOK);
4441   transaction.request_headers = EXTRA_HEADER;
4442   transaction.data = "Not a range";
4443   RangeTransactionServer handler;
4444   handler.set_bad_200(true);
4445   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4446 
4447   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4448   EXPECT_EQ(1, cache.disk_cache()->open_count());
4449   EXPECT_EQ(1, cache.disk_cache()->create_count());
4450 
4451   // Verify that the disk entry was updated.
4452   disk_cache::Entry* entry;
4453   ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4454   EXPECT_EQ(11, entry->GetDataSize(1));
4455   bool truncated = true;
4456   net::HttpResponseInfo response;
4457   EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4458   EXPECT_FALSE(truncated);
4459   entry->Close();
4460 
4461   RemoveMockTransaction(&kRangeGET_TransactionOK);
4462 }
4463 
4464 // Tests that when we cancel a request that was interrupted, we mark it again
4465 // as truncated.
TEST(HttpCache,GET_CancelIncompleteResource)4466 TEST(HttpCache, GET_CancelIncompleteResource) {
4467   MockHttpCache cache;
4468   AddMockTransaction(&kRangeGET_TransactionOK);
4469 
4470   std::string raw_headers("HTTP/1.1 200 OK\n"
4471                           "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
4472                           "ETag: \"foo\"\n"
4473                           "Accept-Ranges: bytes\n"
4474                           "Content-Length: 80\n");
4475   CreateTruncatedEntry(raw_headers, &cache);
4476 
4477   // Now make a regular request.
4478   MockTransaction transaction(kRangeGET_TransactionOK);
4479   transaction.request_headers = EXTRA_HEADER;
4480 
4481   MockHttpRequest request(transaction);
4482   Context* c = new Context();
4483   EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(&c->trans));
4484 
4485   int rv = c->trans->Start(&request, &c->callback, net::BoundNetLog());
4486   EXPECT_EQ(net::OK, c->callback.GetResult(rv));
4487 
4488   // Read 20 bytes from the cache, and 10 from the net.
4489   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100));
4490   rv = c->trans->Read(buf, 20, &c->callback);
4491   EXPECT_EQ(20, c->callback.GetResult(rv));
4492   rv = c->trans->Read(buf, 10, &c->callback);
4493   EXPECT_EQ(10, c->callback.GetResult(rv));
4494 
4495   // At this point, we are already reading so canceling the request should leave
4496   // a truncated one.
4497   delete c;
4498 
4499   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4500   EXPECT_EQ(1, cache.disk_cache()->open_count());
4501   EXPECT_EQ(1, cache.disk_cache()->create_count());
4502 
4503   // Verify that the disk entry was updated: now we have 30 bytes.
4504   disk_cache::Entry* entry;
4505   ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4506   EXPECT_EQ(30, entry->GetDataSize(1));
4507   bool truncated = false;
4508   net::HttpResponseInfo response;
4509   EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
4510   EXPECT_TRUE(truncated);
4511   entry->Close();
4512   RemoveMockTransaction(&kRangeGET_TransactionOK);
4513 }
4514 
4515 // Tests that we can handle range requests when we have a truncated entry.
TEST(HttpCache,RangeGET_IncompleteResource)4516 TEST(HttpCache, RangeGET_IncompleteResource) {
4517   MockHttpCache cache;
4518   AddMockTransaction(&kRangeGET_TransactionOK);
4519 
4520   // Content-length will be intentionally bogus.
4521   std::string raw_headers("HTTP/1.1 200 OK\n"
4522                           "Last-Modified: something\n"
4523                           "ETag: \"foo\"\n"
4524                           "Accept-Ranges: bytes\n"
4525                           "Content-Length: 10\n");
4526   CreateTruncatedEntry(raw_headers, &cache);
4527 
4528   // Now make a range request.
4529   std::string headers;
4530   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4531                                  &headers);
4532 
4533   Verify206Response(headers, 40, 49);
4534   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4535   EXPECT_EQ(1, cache.disk_cache()->open_count());
4536   EXPECT_EQ(2, cache.disk_cache()->create_count());
4537 
4538   RemoveMockTransaction(&kRangeGET_TransactionOK);
4539 }
4540 
TEST(HttpCache,SyncRead)4541 TEST(HttpCache, SyncRead) {
4542   MockHttpCache cache;
4543 
4544   // This test ensures that a read that completes synchronously does not cause
4545   // any problems.
4546 
4547   ScopedMockTransaction transaction(kSimpleGET_Transaction);
4548   transaction.test_mode |= (TEST_MODE_SYNC_CACHE_START |
4549                             TEST_MODE_SYNC_CACHE_READ |
4550                             TEST_MODE_SYNC_CACHE_WRITE);
4551 
4552   MockHttpRequest r1(transaction),
4553                   r2(transaction),
4554                   r3(transaction);
4555 
4556   TestTransactionConsumer c1(cache.http_cache()),
4557                           c2(cache.http_cache()),
4558                           c3(cache.http_cache());
4559 
4560   c1.Start(&r1, net::BoundNetLog());
4561 
4562   r2.load_flags |= net::LOAD_ONLY_FROM_CACHE;
4563   c2.Start(&r2, net::BoundNetLog());
4564 
4565   r3.load_flags |= net::LOAD_ONLY_FROM_CACHE;
4566   c3.Start(&r3, net::BoundNetLog());
4567 
4568   MessageLoop::current()->Run();
4569 
4570   EXPECT_TRUE(c1.is_done());
4571   EXPECT_TRUE(c2.is_done());
4572   EXPECT_TRUE(c3.is_done());
4573 
4574   EXPECT_EQ(net::OK, c1.error());
4575   EXPECT_EQ(net::OK, c2.error());
4576   EXPECT_EQ(net::OK, c3.error());
4577 }
4578 
TEST(HttpCache,ValidationResultsIn200)4579 TEST(HttpCache, ValidationResultsIn200) {
4580   MockHttpCache cache;
4581 
4582   // This test ensures that a conditional request, which results in a 200
4583   // instead of a 304, properly truncates the existing response data.
4584 
4585   // write to the cache
4586   RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
4587 
4588   // force this transaction to validate the cache
4589   MockTransaction transaction(kETagGET_Transaction);
4590   transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
4591   RunTransactionTest(cache.http_cache(), transaction);
4592 
4593   // read from the cache
4594   RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
4595 }
4596 
TEST(HttpCache,CachedRedirect)4597 TEST(HttpCache, CachedRedirect) {
4598   MockHttpCache cache;
4599 
4600   ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction);
4601   kTestTransaction.status = "HTTP/1.1 301 Moved Permanently";
4602   kTestTransaction.response_headers = "Location: http://www.bar.com/\n";
4603 
4604   MockHttpRequest request(kTestTransaction);
4605   TestCompletionCallback callback;
4606 
4607   // write to the cache
4608   {
4609     scoped_ptr<net::HttpTransaction> trans;
4610     int rv = cache.http_cache()->CreateTransaction(&trans);
4611     EXPECT_EQ(net::OK, rv);
4612     ASSERT_TRUE(trans.get());
4613 
4614     rv = trans->Start(&request, &callback, net::BoundNetLog());
4615     if (rv == net::ERR_IO_PENDING)
4616       rv = callback.WaitForResult();
4617     ASSERT_EQ(net::OK, rv);
4618 
4619     const net::HttpResponseInfo* info = trans->GetResponseInfo();
4620     ASSERT_TRUE(info);
4621 
4622     EXPECT_EQ(info->headers->response_code(), 301);
4623 
4624     std::string location;
4625     info->headers->EnumerateHeader(NULL, "Location", &location);
4626     EXPECT_EQ(location, "http://www.bar.com/");
4627 
4628     // Destroy transaction when going out of scope. We have not actually
4629     // read the response body -- want to test that it is still getting cached.
4630   }
4631   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4632   EXPECT_EQ(0, cache.disk_cache()->open_count());
4633   EXPECT_EQ(1, cache.disk_cache()->create_count());
4634 
4635   // read from the cache
4636   {
4637     scoped_ptr<net::HttpTransaction> trans;
4638     int rv = cache.http_cache()->CreateTransaction(&trans);
4639     EXPECT_EQ(net::OK, rv);
4640     ASSERT_TRUE(trans.get());
4641 
4642     rv = trans->Start(&request, &callback, net::BoundNetLog());
4643     if (rv == net::ERR_IO_PENDING)
4644       rv = callback.WaitForResult();
4645     ASSERT_EQ(net::OK, rv);
4646 
4647     const net::HttpResponseInfo* info = trans->GetResponseInfo();
4648     ASSERT_TRUE(info);
4649 
4650     EXPECT_EQ(info->headers->response_code(), 301);
4651 
4652     std::string location;
4653     info->headers->EnumerateHeader(NULL, "Location", &location);
4654     EXPECT_EQ(location, "http://www.bar.com/");
4655 
4656     // Destroy transaction when going out of scope. We have not actually
4657     // read the response body -- want to test that it is still getting cached.
4658   }
4659   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4660   EXPECT_EQ(1, cache.disk_cache()->open_count());
4661   EXPECT_EQ(1, cache.disk_cache()->create_count());
4662 }
4663 
TEST(HttpCache,CacheControlNoStore)4664 TEST(HttpCache, CacheControlNoStore) {
4665   MockHttpCache cache;
4666 
4667   ScopedMockTransaction transaction(kSimpleGET_Transaction);
4668   transaction.response_headers = "cache-control: no-store\n";
4669 
4670   // initial load
4671   RunTransactionTest(cache.http_cache(), transaction);
4672 
4673   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4674   EXPECT_EQ(0, cache.disk_cache()->open_count());
4675   EXPECT_EQ(1, cache.disk_cache()->create_count());
4676 
4677   // try loading again; it should result in a network fetch
4678   RunTransactionTest(cache.http_cache(), transaction);
4679 
4680   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4681   EXPECT_EQ(0, cache.disk_cache()->open_count());
4682   EXPECT_EQ(2, cache.disk_cache()->create_count());
4683 
4684   disk_cache::Entry* entry;
4685   EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
4686 }
4687 
TEST(HttpCache,CacheControlNoStore2)4688 TEST(HttpCache, CacheControlNoStore2) {
4689   // this test is similar to the above test, except that the initial response
4690   // is cachable, but when it is validated, no-store is received causing the
4691   // cached document to be deleted.
4692   MockHttpCache cache;
4693 
4694   ScopedMockTransaction transaction(kETagGET_Transaction);
4695 
4696   // initial load
4697   RunTransactionTest(cache.http_cache(), transaction);
4698 
4699   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4700   EXPECT_EQ(0, cache.disk_cache()->open_count());
4701   EXPECT_EQ(1, cache.disk_cache()->create_count());
4702 
4703   // try loading again; it should result in a network fetch
4704   transaction.load_flags = net::LOAD_VALIDATE_CACHE;
4705   transaction.response_headers = "cache-control: no-store\n";
4706   RunTransactionTest(cache.http_cache(), transaction);
4707 
4708   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4709   EXPECT_EQ(1, cache.disk_cache()->open_count());
4710   EXPECT_EQ(1, cache.disk_cache()->create_count());
4711 
4712   disk_cache::Entry* entry;
4713   EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
4714 }
4715 
TEST(HttpCache,CacheControlNoStore3)4716 TEST(HttpCache, CacheControlNoStore3) {
4717   // this test is similar to the above test, except that the response is a 304
4718   // instead of a 200.  this should never happen in practice, but it seems like
4719   // a good thing to verify that we still destroy the cache entry.
4720   MockHttpCache cache;
4721 
4722   ScopedMockTransaction transaction(kETagGET_Transaction);
4723 
4724   // initial load
4725   RunTransactionTest(cache.http_cache(), transaction);
4726 
4727   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4728   EXPECT_EQ(0, cache.disk_cache()->open_count());
4729   EXPECT_EQ(1, cache.disk_cache()->create_count());
4730 
4731   // try loading again; it should result in a network fetch
4732   transaction.load_flags = net::LOAD_VALIDATE_CACHE;
4733   transaction.response_headers = "cache-control: no-store\n";
4734   transaction.status = "HTTP/1.1 304 Not Modified";
4735   RunTransactionTest(cache.http_cache(), transaction);
4736 
4737   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4738   EXPECT_EQ(1, cache.disk_cache()->open_count());
4739   EXPECT_EQ(1, cache.disk_cache()->create_count());
4740 
4741   disk_cache::Entry* entry;
4742   EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
4743 }
4744 
4745 // Ensure that we don't cache requests served over bad HTTPS.
TEST(HttpCache,SimpleGET_SSLError)4746 TEST(HttpCache, SimpleGET_SSLError) {
4747   MockHttpCache cache;
4748 
4749   MockTransaction transaction = kSimpleGET_Transaction;
4750   transaction.cert_status = net::CERT_STATUS_REVOKED;
4751   ScopedMockTransaction scoped_transaction(transaction);
4752 
4753   // write to the cache
4754   RunTransactionTest(cache.http_cache(), transaction);
4755 
4756   // Test that it was not cached.
4757   transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
4758 
4759   MockHttpRequest request(transaction);
4760   TestCompletionCallback callback;
4761 
4762   scoped_ptr<net::HttpTransaction> trans;
4763   int rv = cache.http_cache()->CreateTransaction(&trans);
4764   EXPECT_EQ(net::OK, rv);
4765   ASSERT_TRUE(trans.get());
4766 
4767   rv = trans->Start(&request, &callback, net::BoundNetLog());
4768   if (rv == net::ERR_IO_PENDING)
4769     rv = callback.WaitForResult();
4770   ASSERT_EQ(net::ERR_CACHE_MISS, rv);
4771 }
4772 
4773 // Ensure that we don't crash by if left-behind transactions.
TEST(HttpCache,OutlivedTransactions)4774 TEST(HttpCache, OutlivedTransactions) {
4775   MockHttpCache* cache = new MockHttpCache;
4776 
4777   scoped_ptr<net::HttpTransaction> trans;
4778   int rv = cache->http_cache()->CreateTransaction(&trans);
4779   EXPECT_EQ(net::OK, rv);
4780 
4781   delete cache;
4782   trans.reset();
4783 }
4784 
4785 // Test that the disabled mode works.
TEST(HttpCache,CacheDisabledMode)4786 TEST(HttpCache, CacheDisabledMode) {
4787   MockHttpCache cache;
4788 
4789   // write to the cache
4790   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
4791 
4792   // go into disabled mode
4793   cache.http_cache()->set_mode(net::HttpCache::DISABLE);
4794 
4795   // force this transaction to write to the cache again
4796   MockTransaction transaction(kSimpleGET_Transaction);
4797 
4798   RunTransactionTest(cache.http_cache(), transaction);
4799 
4800   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4801   EXPECT_EQ(0, cache.disk_cache()->open_count());
4802   EXPECT_EQ(1, cache.disk_cache()->create_count());
4803 }
4804 
4805 // Other tests check that the response headers of the cached response
4806 // get updated on 304. Here we specifically check that the
4807 // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
4808 // fields also gets updated.
4809 // http://crbug.com/20594.
TEST(HttpCache,UpdatesRequestResponseTimeOn304)4810 TEST(HttpCache, UpdatesRequestResponseTimeOn304) {
4811   MockHttpCache cache;
4812 
4813   const char* kUrl = "http://foobar";
4814   const char* kData = "body";
4815 
4816   MockTransaction mock_network_response = { 0 };
4817   mock_network_response.url = kUrl;
4818 
4819   AddMockTransaction(&mock_network_response);
4820 
4821   // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
4822 
4823   MockTransaction request = { 0 };
4824   request.url = kUrl;
4825   request.method = "GET";
4826   request.request_headers = "";
4827   request.data = kData;
4828 
4829   static const Response kNetResponse1 = {
4830     "HTTP/1.1 200 OK",
4831     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
4832     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
4833     kData
4834   };
4835 
4836   kNetResponse1.AssignTo(&mock_network_response);
4837 
4838   RunTransactionTest(cache.http_cache(), request);
4839 
4840   // Request |kUrl| again, this time validating the cache and getting
4841   // a 304 back.
4842 
4843   request.load_flags = net::LOAD_VALIDATE_CACHE;
4844 
4845   static const Response kNetResponse2 = {
4846     "HTTP/1.1 304 Not Modified",
4847     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
4848     ""
4849   };
4850 
4851   kNetResponse2.AssignTo(&mock_network_response);
4852 
4853   base::Time request_time = base::Time() + base::TimeDelta::FromHours(1234);
4854   base::Time response_time = base::Time() + base::TimeDelta::FromHours(1235);
4855 
4856   mock_network_response.request_time = request_time;
4857   mock_network_response.response_time = response_time;
4858 
4859   net::HttpResponseInfo response;
4860   RunTransactionTestWithResponseInfo(cache.http_cache(), request, &response);
4861 
4862   // The request and response times should have been updated.
4863   EXPECT_EQ(request_time.ToInternalValue(),
4864             response.request_time.ToInternalValue());
4865   EXPECT_EQ(response_time.ToInternalValue(),
4866             response.response_time.ToInternalValue());
4867 
4868   std::string headers;
4869   response.headers->GetNormalizedHeaders(&headers);
4870 
4871   EXPECT_EQ("HTTP/1.1 200 OK\n"
4872             "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
4873             "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
4874             headers);
4875 
4876   RemoveMockTransaction(&mock_network_response);
4877 }
4878 
4879 // Tests that we can write metadata to an entry.
TEST(HttpCache,WriteMetadata_OK)4880 TEST(HttpCache, WriteMetadata_OK) {
4881   MockHttpCache cache;
4882 
4883   // Write to the cache
4884   net::HttpResponseInfo response;
4885   RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
4886                                      &response);
4887   EXPECT_TRUE(response.metadata.get() == NULL);
4888 
4889   // Trivial call.
4890   cache.http_cache()->WriteMetadata(GURL("foo"), Time::Now(), NULL, 0);
4891 
4892   // Write meta data to the same entry.
4893   scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
4894   memset(buf->data(), 0, buf->size());
4895   base::strlcpy(buf->data(), "Hi there", buf->size());
4896   cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
4897                                     response.response_time, buf, buf->size());
4898 
4899   // Release the buffer before the operation takes place.
4900   buf = NULL;
4901 
4902   // Makes sure we finish pending operations.
4903   MessageLoop::current()->RunAllPending();
4904 
4905   RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
4906                                      &response);
4907   ASSERT_TRUE(response.metadata.get() != NULL);
4908   EXPECT_EQ(50, response.metadata->size());
4909   EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
4910 
4911   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4912   EXPECT_EQ(2, cache.disk_cache()->open_count());
4913   EXPECT_EQ(1, cache.disk_cache()->create_count());
4914 }
4915 
4916 // Tests that we only write metadata to an entry if the time stamp matches.
TEST(HttpCache,WriteMetadata_Fail)4917 TEST(HttpCache, WriteMetadata_Fail) {
4918   MockHttpCache cache;
4919 
4920   // Write to the cache
4921   net::HttpResponseInfo response;
4922   RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
4923                                      &response);
4924   EXPECT_TRUE(response.metadata.get() == NULL);
4925 
4926   // Attempt to write meta data to the same entry.
4927   scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
4928   memset(buf->data(), 0, buf->size());
4929   base::strlcpy(buf->data(), "Hi there", buf->size());
4930   base::Time expected_time = response.response_time -
4931                              base::TimeDelta::FromMilliseconds(20);
4932   cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
4933                                     expected_time, buf, buf->size());
4934 
4935   // Makes sure we finish pending operations.
4936   MessageLoop::current()->RunAllPending();
4937 
4938   RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
4939                                      &response);
4940   EXPECT_TRUE(response.metadata.get() == NULL);
4941 
4942   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4943   EXPECT_EQ(2, cache.disk_cache()->open_count());
4944   EXPECT_EQ(1, cache.disk_cache()->create_count());
4945 }
4946 
4947 // Tests that we can read metadata after validating the entry and with READ mode
4948 // transactions.
TEST(HttpCache,ReadMetadata)4949 TEST(HttpCache, ReadMetadata) {
4950   MockHttpCache cache;
4951 
4952   // Write to the cache
4953   net::HttpResponseInfo response;
4954   RunTransactionTestWithResponseInfo(cache.http_cache(),
4955                                      kTypicalGET_Transaction, &response);
4956   EXPECT_TRUE(response.metadata.get() == NULL);
4957 
4958   // Write meta data to the same entry.
4959   scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
4960   memset(buf->data(), 0, buf->size());
4961   base::strlcpy(buf->data(), "Hi there", buf->size());
4962   cache.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction.url),
4963                                     response.response_time, buf, buf->size());
4964 
4965   // Makes sure we finish pending operations.
4966   MessageLoop::current()->RunAllPending();
4967 
4968   // Start with a READ mode transaction.
4969   MockTransaction trans1(kTypicalGET_Transaction);
4970   trans1.load_flags = net::LOAD_ONLY_FROM_CACHE;
4971 
4972   RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
4973   ASSERT_TRUE(response.metadata.get() != NULL);
4974   EXPECT_EQ(50, response.metadata->size());
4975   EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
4976 
4977   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4978   EXPECT_EQ(2, cache.disk_cache()->open_count());
4979   EXPECT_EQ(1, cache.disk_cache()->create_count());
4980   MessageLoop::current()->RunAllPending();
4981 
4982   // Now make sure that the entry is re-validated with the server.
4983   trans1.load_flags = net::LOAD_VALIDATE_CACHE;
4984   trans1.status = "HTTP/1.1 304 Not Modified";
4985   AddMockTransaction(&trans1);
4986 
4987   response.metadata = NULL;
4988   RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
4989   EXPECT_TRUE(response.metadata.get() != NULL);
4990 
4991   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4992   EXPECT_EQ(3, cache.disk_cache()->open_count());
4993   EXPECT_EQ(1, cache.disk_cache()->create_count());
4994   MessageLoop::current()->RunAllPending();
4995   RemoveMockTransaction(&trans1);
4996 
4997   // Now return 200 when validating the entry so the metadata will be lost.
4998   MockTransaction trans2(kTypicalGET_Transaction);
4999   trans2.load_flags = net::LOAD_VALIDATE_CACHE;
5000   RunTransactionTestWithResponseInfo(cache.http_cache(), trans2, &response);
5001   EXPECT_TRUE(response.metadata.get() == NULL);
5002 
5003   EXPECT_EQ(3, cache.network_layer()->transaction_count());
5004   EXPECT_EQ(4, cache.disk_cache()->open_count());
5005   EXPECT_EQ(1, cache.disk_cache()->create_count());
5006 }
5007