Home | History | Annotate | Download | only in http
      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 
     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.
     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:
     74   MockDiskEntry()
     75       : test_mode_(0), doomed_(false), sparse_(false), fail_requests_(false),
     76         busy_(false), delayed_(false) {
     77   }
     78 
     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 
     85   bool is_doomed() const { return doomed_; }
     86 
     87   virtual void Doom() {
     88     doomed_ = true;
     89   }
     90 
     91   virtual void Close() {
     92     Release();
     93   }
     94 
     95   virtual std::string GetKey() const {
     96     if (fail_requests_)
     97       return std::string();
     98     return key_;
     99   }
    100 
    101   virtual Time GetLastUsed() const {
    102     return Time::FromInternalValue(0);
    103   }
    104 
    105   virtual Time GetLastModified() const {
    106     return Time::FromInternalValue(0);
    107   }
    108 
    109   virtual int32 GetDataSize(int index) const {
    110     DCHECK(index >= 0 && index < kNumCacheEntryDataIndices);
    111     return static_cast<int32>(data_[index].size());
    112   }
    113 
    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 
    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 
    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 
    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 
    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 
    261   virtual bool CouldBeSparse() const {
    262     return sparse_;
    263   }
    264 
    265   virtual void CancelSparseIO() { cancel_ = true; }
    266 
    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.
    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.
    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 
    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.
    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   }
    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.
    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:
    371   MockDiskCache()
    372       : open_count_(0), create_count_(0), fail_requests_(false),
    373         soft_failures_(false) {
    374   }
    375 
    376   ~MockDiskCache() {
    377     ReleaseAll();
    378   }
    379 
    380   virtual int32 GetEntryCount() const {
    381     return static_cast<int32>(entries_.size());
    382   }
    383 
    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 
    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 
    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 
    464   virtual int DoomAllEntries(net::CompletionCallback* callback) {
    465     return net::ERR_NOT_IMPLEMENTED;
    466   }
    467 
    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 
    474   virtual int DoomEntriesSince(const base::Time initial_time,
    475                                net::CompletionCallback* callback) {
    476     return net::ERR_NOT_IMPLEMENTED;
    477   }
    478 
    479   virtual int OpenNextEntry(void** iter, disk_cache::Entry** next_entry,
    480                             net::CompletionCallback* callback) {
    481     return net::ERR_NOT_IMPLEMENTED;
    482   }
    483 
    484   virtual void EndEnumeration(void** iter) {}
    485 
    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
    491   int open_count() const { return open_count_; }
    492 
    493   // returns number of times a cache entry was successfully created
    494   int create_count() const { return create_count_; }
    495 
    496   // Fail any subsequent CreateEntry and OpenEntry.
    497   void set_fail_requests() { fail_requests_ = true; }
    498 
    499   // Return entries that fail some of their requests.
    500   void set_soft_failures(bool value) { soft_failures_ = value; }
    501 
    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:
    514     CallbackRunner(net::CompletionCallback* callback, int result)
    515         : callback_(callback), result_(result) {}
    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 
    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:
    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:
    550   MockHttpCache()
    551       : http_cache_(new MockNetworkLayer(), NULL, new MockBackendFactory()) {
    552   }
    553 
    554   explicit MockHttpCache(net::HttpCache::BackendFactory* disk_cache_factory)
    555       : http_cache_(new MockNetworkLayer(), NULL, disk_cache_factory) {
    556   }
    557 
    558   net::HttpCache* http_cache() { return &http_cache_; }
    559 
    560   MockNetworkLayer* network_layer() {
    561     return static_cast<MockNetworkLayer*>(http_cache_.network_layer());
    562   }
    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.
    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.
    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.
    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.
    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 {
    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:
    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:
    647   MockBlockingBackendFactory()
    648       : backend_(NULL), callback_(NULL), block_(true), fail_(false) {}
    649 
    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.
    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 
    677   disk_cache::Backend** backend() { return backend_; }
    678   void set_fail(bool fail) { fail_ = fail; }
    679 
    680   net::CompletionCallback* callback() { return callback_; }
    681 
    682  private:
    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:
    693   explicit DeleteCacheCompletionCallback(MockHttpCache* cache)
    694       : cache_(cache) {}
    695 
    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 
    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 
    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 
    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 
    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 
    761 void RunTransactionTest(net::HttpCache* cache,
    762                         const MockTransaction& trans_info) {
    763   RunTransactionTestWithLog(cache, trans_info, net::BoundNetLog());
    764 }
    765 
    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 
    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:
    785   FastTransactionServer() {
    786     no_store = false;
    787   }
    788   ~FastTransactionServer() {}
    789 
    790   void set_no_store(bool value) { no_store = value; }
    791 
    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:
    825   RangeTransactionServer() {
    826     not_modified_ = false;
    827     modified_ = false;
    828     bad_200_ = false;
    829   }
    830   ~RangeTransactionServer() {
    831     not_modified_ = false;
    832     modified_ = false;
    833     bad_200_ = false;
    834   }
    835 
    836   // Returns only 416 or 304 when set.
    837   void set_not_modified(bool value) { not_modified_ = value; }
    838 
    839   // Returns 206 when revalidating a range (instead of 304).
    840   void set_modified(bool value) { modified_ = value; }
    841 
    842   // Returns 200 instead of 206 (a malformed response overall).
    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.
    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|.
    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.
    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|.
   1012   void AssignTo(MockTransaction* trans) const {
   1013     trans->status = status;
   1014     trans->response_headers = headers;
   1015     trans->data = body;
   1016   }
   1017 
   1018   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 {
   1028   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 
   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 
   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 
   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 
   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 
   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 
   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.
   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.
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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.
   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.
   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 
   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.
   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
   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.
   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 
   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.
   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.
   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.
   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 
   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).
   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.
   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.
   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.
   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.
   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 
   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 
   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 
   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 
   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 
   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 
   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.
   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.
   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.
   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.
   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).
   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).
   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).
   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.
   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.
   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.
   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.
   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.
   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 
   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 
   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 
   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 
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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).
   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).
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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 
   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 
   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 
   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 
   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 
   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 
   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.
   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.
   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.
   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.
   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.
   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.
   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.
   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