1// Copyright (c) 2012 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 <algorithm>
8
9#include "base/bind.h"
10#include "base/bind_helpers.h"
11#include "base/memory/scoped_vector.h"
12#include "base/message_loop/message_loop.h"
13#include "base/strings/string_util.h"
14#include "base/strings/stringprintf.h"
15#include "net/base/cache_type.h"
16#include "net/base/host_port_pair.h"
17#include "net/base/load_flags.h"
18#include "net/base/load_timing_info.h"
19#include "net/base/load_timing_info_test_util.h"
20#include "net/base/net_errors.h"
21#include "net/base/net_log_unittest.h"
22#include "net/base/upload_bytes_element_reader.h"
23#include "net/base/upload_data_stream.h"
24#include "net/cert/cert_status_flags.h"
25#include "net/disk_cache/disk_cache.h"
26#include "net/http/http_byte_range.h"
27#include "net/http/http_request_headers.h"
28#include "net/http/http_request_info.h"
29#include "net/http/http_response_headers.h"
30#include "net/http/http_response_info.h"
31#include "net/http/http_transaction.h"
32#include "net/http/http_transaction_test_util.h"
33#include "net/http/http_util.h"
34#include "net/http/mock_http_cache.h"
35#include "net/socket/client_socket_handle.h"
36#include "net/ssl/ssl_cert_request_info.h"
37#include "net/websockets/websocket_handshake_stream_base.h"
38#include "testing/gtest/include/gtest/gtest.h"
39
40using base::Time;
41
42namespace {
43
44// Tests the load timing values of a request that goes through a
45// MockNetworkTransaction.
46void TestLoadTimingNetworkRequest(const net::LoadTimingInfo& load_timing_info) {
47  EXPECT_FALSE(load_timing_info.socket_reused);
48  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
49
50  EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
51  EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
52
53  net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
54                                   net::CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
55  EXPECT_LE(load_timing_info.connect_timing.connect_end,
56            load_timing_info.send_start);
57
58  EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
59
60  // Set by URLRequest / URLRequestHttpJob, at a higher level.
61  EXPECT_TRUE(load_timing_info.request_start_time.is_null());
62  EXPECT_TRUE(load_timing_info.request_start.is_null());
63  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
64}
65
66// Tests the load timing values of a request that receives a cached response.
67void TestLoadTimingCachedResponse(const net::LoadTimingInfo& load_timing_info) {
68  EXPECT_FALSE(load_timing_info.socket_reused);
69  EXPECT_EQ(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
70
71  EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
72  EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
73
74  net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
75
76  // Only the send start / end times should be sent, and they should have the
77  // same value.
78  EXPECT_FALSE(load_timing_info.send_start.is_null());
79  EXPECT_EQ(load_timing_info.send_start, load_timing_info.send_end);
80
81  // Set by URLRequest / URLRequestHttpJob, at a higher level.
82  EXPECT_TRUE(load_timing_info.request_start_time.is_null());
83  EXPECT_TRUE(load_timing_info.request_start.is_null());
84  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
85}
86
87class DeleteCacheCompletionCallback : public net::TestCompletionCallbackBase {
88 public:
89  explicit DeleteCacheCompletionCallback(MockHttpCache* cache)
90      : cache_(cache),
91        callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete,
92                             base::Unretained(this))) {
93  }
94
95  const net::CompletionCallback& callback() const { return callback_; }
96
97 private:
98  void OnComplete(int result) {
99    delete cache_;
100    SetResult(result);
101  }
102
103  MockHttpCache* cache_;
104  net::CompletionCallback callback_;
105
106  DISALLOW_COPY_AND_ASSIGN(DeleteCacheCompletionCallback);
107};
108
109//-----------------------------------------------------------------------------
110// helpers
111
112void ReadAndVerifyTransaction(net::HttpTransaction* trans,
113                              const MockTransaction& trans_info) {
114  std::string content;
115  int rv = ReadTransaction(trans, &content);
116
117  EXPECT_EQ(net::OK, rv);
118  std::string expected(trans_info.data);
119  EXPECT_EQ(expected, content);
120}
121
122void RunTransactionTestBase(net::HttpCache* cache,
123                            const MockTransaction& trans_info,
124                            const MockHttpRequest& request,
125                            net::HttpResponseInfo* response_info,
126                            const net::BoundNetLog& net_log,
127                            net::LoadTimingInfo* load_timing_info,
128                            int64* received_bytes) {
129  net::TestCompletionCallback callback;
130
131  // write to the cache
132
133  scoped_ptr<net::HttpTransaction> trans;
134  int rv = cache->CreateTransaction(net::DEFAULT_PRIORITY, &trans);
135  EXPECT_EQ(net::OK, rv);
136  ASSERT_TRUE(trans.get());
137
138  rv = trans->Start(&request, callback.callback(), net_log);
139  if (rv == net::ERR_IO_PENDING)
140    rv = callback.WaitForResult();
141  ASSERT_EQ(trans_info.return_code, rv);
142
143  if (net::OK != rv)
144    return;
145
146  const net::HttpResponseInfo* response = trans->GetResponseInfo();
147  ASSERT_TRUE(response);
148
149  if (response_info)
150    *response_info = *response;
151
152  if (load_timing_info) {
153    // If a fake network connection is used, need a NetLog to get a fake socket
154    // ID.
155    EXPECT_TRUE(net_log.net_log());
156    *load_timing_info = net::LoadTimingInfo();
157    trans->GetLoadTimingInfo(load_timing_info);
158  }
159
160  ReadAndVerifyTransaction(trans.get(), trans_info);
161
162  if (received_bytes)
163    *received_bytes = trans->GetTotalReceivedBytes();
164}
165
166void RunTransactionTestWithRequest(net::HttpCache* cache,
167                                   const MockTransaction& trans_info,
168                                   const MockHttpRequest& request,
169                                   net::HttpResponseInfo* response_info) {
170  RunTransactionTestBase(cache, trans_info, request, response_info,
171                         net::BoundNetLog(), NULL, NULL);
172}
173
174void RunTransactionTestAndGetTiming(net::HttpCache* cache,
175                                    const MockTransaction& trans_info,
176                                    const net::BoundNetLog& log,
177                                    net::LoadTimingInfo* load_timing_info) {
178  RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
179                         NULL, log, load_timing_info, NULL);
180}
181
182void RunTransactionTest(net::HttpCache* cache,
183                        const MockTransaction& trans_info) {
184  RunTransactionTestAndGetTiming(cache, trans_info, net::BoundNetLog(), NULL);
185}
186
187void RunTransactionTestWithResponseInfo(net::HttpCache* cache,
188                                        const MockTransaction& trans_info,
189                                        net::HttpResponseInfo* response) {
190  RunTransactionTestWithRequest(cache, trans_info, MockHttpRequest(trans_info),
191                                response);
192}
193
194void RunTransactionTestWithResponseInfoAndGetTiming(
195    net::HttpCache* cache,
196    const MockTransaction& trans_info,
197    net::HttpResponseInfo* response,
198    const net::BoundNetLog& log,
199    net::LoadTimingInfo* load_timing_info) {
200  RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
201                         response, log, load_timing_info, NULL);
202}
203
204void RunTransactionTestWithResponse(net::HttpCache* cache,
205                                    const MockTransaction& trans_info,
206                                    std::string* response_headers) {
207  net::HttpResponseInfo response;
208  RunTransactionTestWithResponseInfo(cache, trans_info, &response);
209  response.headers->GetNormalizedHeaders(response_headers);
210}
211
212void RunTransactionTestWithResponseAndGetTiming(
213    net::HttpCache* cache,
214    const MockTransaction& trans_info,
215    std::string* response_headers,
216    const net::BoundNetLog& log,
217    net::LoadTimingInfo* load_timing_info) {
218  net::HttpResponseInfo response;
219  RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
220                         &response, log, load_timing_info, NULL);
221  response.headers->GetNormalizedHeaders(response_headers);
222}
223
224// This class provides a handler for kFastNoStoreGET_Transaction so that the
225// no-store header can be included on demand.
226class FastTransactionServer {
227 public:
228  FastTransactionServer() {
229    no_store = false;
230  }
231  ~FastTransactionServer() {}
232
233  void set_no_store(bool value) { no_store = value; }
234
235  static void FastNoStoreHandler(const net::HttpRequestInfo* request,
236                                 std::string* response_status,
237                                 std::string* response_headers,
238                                 std::string* response_data) {
239    if (no_store)
240      *response_headers = "Cache-Control: no-store\n";
241  }
242
243 private:
244  static bool no_store;
245  DISALLOW_COPY_AND_ASSIGN(FastTransactionServer);
246};
247bool FastTransactionServer::no_store;
248
249const MockTransaction kFastNoStoreGET_Transaction = {
250  "http://www.google.com/nostore",
251  "GET",
252  base::Time(),
253  "",
254  net::LOAD_VALIDATE_CACHE,
255  "HTTP/1.1 200 OK",
256  "Cache-Control: max-age=10000\n",
257  base::Time(),
258  "<html><body>Google Blah Blah</body></html>",
259  TEST_MODE_SYNC_NET_START,
260  &FastTransactionServer::FastNoStoreHandler,
261  0,
262  net::OK
263};
264
265// This class provides a handler for kRangeGET_TransactionOK so that the range
266// request can be served on demand.
267class RangeTransactionServer {
268 public:
269  RangeTransactionServer() {
270    not_modified_ = false;
271    modified_ = false;
272    bad_200_ = false;
273  }
274  ~RangeTransactionServer() {
275    not_modified_ = false;
276    modified_ = false;
277    bad_200_ = false;
278  }
279
280  // Returns only 416 or 304 when set.
281  void set_not_modified(bool value) { not_modified_ = value; }
282
283  // Returns 206 when revalidating a range (instead of 304).
284  void set_modified(bool value) { modified_ = value; }
285
286  // Returns 200 instead of 206 (a malformed response overall).
287  void set_bad_200(bool value) { bad_200_ = value; }
288
289  static void RangeHandler(const net::HttpRequestInfo* request,
290                           std::string* response_status,
291                           std::string* response_headers,
292                           std::string* response_data);
293
294 private:
295  static bool not_modified_;
296  static bool modified_;
297  static bool bad_200_;
298  DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer);
299};
300bool RangeTransactionServer::not_modified_ = false;
301bool RangeTransactionServer::modified_ = false;
302bool RangeTransactionServer::bad_200_ = false;
303
304// A dummy extra header that must be preserved on a given request.
305
306// EXTRA_HEADER_LINE doesn't include a line terminator because it
307// will be passed to AddHeaderFromString() which doesn't accept them.
308#define EXTRA_HEADER_LINE "Extra: header"
309
310// EXTRA_HEADER contains a line terminator, as expected by
311// AddHeadersFromString() (_not_ AddHeaderFromString()).
312#define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
313
314static const char kExtraHeaderKey[] = "Extra";
315
316// Static.
317void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request,
318                                          std::string* response_status,
319                                          std::string* response_headers,
320                                          std::string* response_data) {
321  if (request->extra_headers.IsEmpty()) {
322    response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
323    response_data->clear();
324    return;
325  }
326
327  // We want to make sure we don't delete extra headers.
328  EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
329
330  if (request->extra_headers.HasHeader("X-Require-Mock-Auth") &&
331      !request->extra_headers.HasHeader("Authorization")) {
332    response_status->assign("HTTP/1.1 401 Unauthorized");
333    response_data->assign("WWW-Authenticate: Foo\n");
334    return;
335  }
336
337  if (not_modified_) {
338    response_status->assign("HTTP/1.1 304 Not Modified");
339    response_data->clear();
340    return;
341  }
342
343  std::vector<net::HttpByteRange> ranges;
344  std::string range_header;
345  if (!request->extra_headers.GetHeader(
346          net::HttpRequestHeaders::kRange, &range_header) ||
347      !net::HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ ||
348      ranges.size() != 1) {
349    // This is not a byte range request. We return 200.
350    response_status->assign("HTTP/1.1 200 OK");
351    response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
352    response_data->assign("Not a range");
353    return;
354  }
355
356  // We can handle this range request.
357  net::HttpByteRange byte_range = ranges[0];
358  if (byte_range.first_byte_position() > 79) {
359    response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
360    response_data->clear();
361    return;
362  }
363
364  EXPECT_TRUE(byte_range.ComputeBounds(80));
365  int start = static_cast<int>(byte_range.first_byte_position());
366  int end = static_cast<int>(byte_range.last_byte_position());
367
368  EXPECT_LT(end, 80);
369
370  std::string content_range = base::StringPrintf(
371      "Content-Range: bytes %d-%d/80\n", start, end);
372  response_headers->append(content_range);
373
374  if (!request->extra_headers.HasHeader("If-None-Match") || modified_) {
375    std::string data;
376    if (end == start) {
377      EXPECT_EQ(0, end % 10);
378      data = "r";
379    } else {
380      EXPECT_EQ(9, (end - start) % 10);
381      for (int block_start = start; block_start < end; block_start += 10) {
382        base::StringAppendF(&data, "rg: %02d-%02d ",
383                            block_start, block_start + 9);
384      }
385    }
386    *response_data = data;
387
388    if (end - start != 9) {
389      // We also have to fix content-length.
390      int len = end - start + 1;
391      std::string content_length = base::StringPrintf("Content-Length: %d\n",
392                                                      len);
393      response_headers->replace(response_headers->find("Content-Length:"),
394                                content_length.size(), content_length);
395    }
396  } else {
397    response_status->assign("HTTP/1.1 304 Not Modified");
398    response_data->clear();
399  }
400}
401
402const MockTransaction kRangeGET_TransactionOK = {
403  "http://www.google.com/range",
404  "GET",
405  base::Time(),
406  "Range: bytes = 40-49\r\n"
407  EXTRA_HEADER,
408  net::LOAD_NORMAL,
409  "HTTP/1.1 206 Partial Content",
410  "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
411  "ETag: \"foo\"\n"
412  "Accept-Ranges: bytes\n"
413  "Content-Length: 10\n",
414  base::Time(),
415  "rg: 40-49 ",
416  TEST_MODE_NORMAL,
417  &RangeTransactionServer::RangeHandler,
418  0,
419  net::OK
420};
421
422// Verifies the response headers (|response|) match a partial content
423// response for the range starting at |start| and ending at |end|.
424void Verify206Response(std::string response, int start, int end) {
425  std::string raw_headers(net::HttpUtil::AssembleRawHeaders(response.data(),
426                                                            response.size()));
427  scoped_refptr<net::HttpResponseHeaders> headers(
428      new net::HttpResponseHeaders(raw_headers));
429
430  ASSERT_EQ(206, headers->response_code());
431
432  int64 range_start, range_end, object_size;
433  ASSERT_TRUE(
434      headers->GetContentRange(&range_start, &range_end, &object_size));
435  int64 content_length = headers->GetContentLength();
436
437  int length = end - start + 1;
438  ASSERT_EQ(length, content_length);
439  ASSERT_EQ(start, range_start);
440  ASSERT_EQ(end, range_end);
441}
442
443// Creates a truncated entry that can be resumed using byte ranges.
444void CreateTruncatedEntry(std::string raw_headers, MockHttpCache* cache) {
445  // Create a disk cache entry that stores an incomplete resource.
446  disk_cache::Entry* entry;
447  ASSERT_TRUE(cache->CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
448                                        NULL));
449
450  raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
451                                                  raw_headers.size());
452
453  net::HttpResponseInfo response;
454  response.response_time = base::Time::Now();
455  response.request_time = base::Time::Now();
456  response.headers = new net::HttpResponseHeaders(raw_headers);
457  // Set the last argument for this to be an incomplete request.
458  EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
459
460  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100));
461  int len = static_cast<int>(base::strlcpy(buf->data(),
462                                           "rg: 00-09 rg: 10-19 ", 100));
463  net::TestCompletionCallback cb;
464  int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
465  EXPECT_EQ(len, cb.GetResult(rv));
466  entry->Close();
467}
468
469// Helper to represent a network HTTP response.
470struct Response {
471  // Set this response into |trans|.
472  void AssignTo(MockTransaction* trans) const {
473    trans->status = status;
474    trans->response_headers = headers;
475    trans->data = body;
476  }
477
478  std::string status_and_headers() const {
479    return std::string(status) + "\n" + std::string(headers);
480  }
481
482  const char* status;
483  const char* headers;
484  const char* body;
485};
486
487struct Context {
488  Context() : result(net::ERR_IO_PENDING) {}
489
490  int result;
491  net::TestCompletionCallback callback;
492  scoped_ptr<net::HttpTransaction> trans;
493};
494
495class FakeWebSocketHandshakeStreamCreateHelper
496    : public net::WebSocketHandshakeStreamBase::CreateHelper {
497 public:
498  virtual ~FakeWebSocketHandshakeStreamCreateHelper() {}
499  virtual net::WebSocketHandshakeStreamBase* CreateBasicStream(
500      scoped_ptr<net::ClientSocketHandle> connect, bool using_proxy) OVERRIDE {
501    return NULL;
502  }
503  virtual net::WebSocketHandshakeStreamBase* CreateSpdyStream(
504      const base::WeakPtr<net::SpdySession>& session,
505      bool use_relative_url) OVERRIDE {
506    return NULL;
507  }
508};
509
510// Returns true if |entry| is not one of the log types paid attention to in this
511// test. Note that TYPE_HTTP_CACHE_WRITE_INFO and TYPE_HTTP_CACHE_*_DATA are
512// ignored.
513bool ShouldIgnoreLogEntry(const net::CapturingNetLog::CapturedEntry& entry) {
514  switch (entry.type) {
515    case net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND:
516    case net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY:
517    case net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY:
518    case net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY:
519    case net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY:
520    case net::NetLog::TYPE_HTTP_CACHE_READ_INFO:
521      return false;
522    default:
523      return true;
524  }
525}
526
527// Modifies |entries| to only include log entries created by the cache layer and
528// asserted on in these tests.
529void FilterLogEntries(net::CapturingNetLog::CapturedEntryList* entries) {
530  entries->erase(std::remove_if(entries->begin(), entries->end(),
531                                &ShouldIgnoreLogEntry),
532                 entries->end());
533}
534
535}  // namespace
536
537
538//-----------------------------------------------------------------------------
539// Tests.
540
541TEST(HttpCache, CreateThenDestroy) {
542  MockHttpCache cache;
543
544  scoped_ptr<net::HttpTransaction> trans;
545  EXPECT_EQ(net::OK, cache.CreateTransaction(&trans));
546  ASSERT_TRUE(trans.get());
547}
548
549TEST(HttpCache, GetBackend) {
550  MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(0));
551
552  disk_cache::Backend* backend;
553  net::TestCompletionCallback cb;
554  // This will lazily initialize the backend.
555  int rv = cache.http_cache()->GetBackend(&backend, cb.callback());
556  EXPECT_EQ(net::OK, cb.GetResult(rv));
557}
558
559TEST(HttpCache, SimpleGET) {
560  MockHttpCache cache;
561  net::CapturingBoundNetLog log;
562  net::LoadTimingInfo load_timing_info;
563
564  // Write to the cache.
565  RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
566                                 log.bound(), &load_timing_info);
567
568  EXPECT_EQ(1, cache.network_layer()->transaction_count());
569  EXPECT_EQ(0, cache.disk_cache()->open_count());
570  EXPECT_EQ(1, cache.disk_cache()->create_count());
571  TestLoadTimingNetworkRequest(load_timing_info);
572}
573
574TEST(HttpCache, SimpleGETNoDiskCache) {
575  MockHttpCache cache;
576
577  cache.disk_cache()->set_fail_requests();
578
579  net::CapturingBoundNetLog log;
580  net::LoadTimingInfo load_timing_info;
581
582  // Read from the network, and don't use the cache.
583  RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
584                                 log.bound(), &load_timing_info);
585
586  // Check that the NetLog was filled as expected.
587  // (We attempted to both Open and Create entries, but both failed).
588  net::CapturingNetLog::CapturedEntryList entries;
589  log.GetEntries(&entries);
590  FilterLogEntries(&entries);
591
592  EXPECT_EQ(6u, entries.size());
593  EXPECT_TRUE(net::LogContainsBeginEvent(
594      entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
595  EXPECT_TRUE(net::LogContainsEndEvent(
596      entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
597  EXPECT_TRUE(net::LogContainsBeginEvent(
598      entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
599  EXPECT_TRUE(net::LogContainsEndEvent(
600      entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
601  EXPECT_TRUE(net::LogContainsBeginEvent(
602      entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
603  EXPECT_TRUE(net::LogContainsEndEvent(
604      entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
605
606  EXPECT_EQ(1, cache.network_layer()->transaction_count());
607  EXPECT_EQ(0, cache.disk_cache()->open_count());
608  EXPECT_EQ(0, cache.disk_cache()->create_count());
609  TestLoadTimingNetworkRequest(load_timing_info);
610}
611
612TEST(HttpCache, SimpleGETNoDiskCache2) {
613  // This will initialize a cache object with NULL backend.
614  MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
615  factory->set_fail(true);
616  factory->FinishCreation();  // We'll complete synchronously.
617  MockHttpCache cache(factory);
618
619  // Read from the network, and don't use the cache.
620  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
621
622  EXPECT_EQ(1, cache.network_layer()->transaction_count());
623  EXPECT_FALSE(cache.http_cache()->GetCurrentBackend());
624}
625
626// Tests that IOBuffers are not referenced after IO completes.
627TEST(HttpCache, ReleaseBuffer) {
628  MockHttpCache cache;
629
630  // Write to the cache.
631  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
632
633  MockHttpRequest request(kSimpleGET_Transaction);
634  scoped_ptr<net::HttpTransaction> trans;
635  ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
636
637  const int kBufferSize = 10;
638  scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
639  net::ReleaseBufferCompletionCallback cb(buffer.get());
640
641  int rv = trans->Start(&request, cb.callback(), net::BoundNetLog());
642  EXPECT_EQ(net::OK, cb.GetResult(rv));
643
644  rv = trans->Read(buffer.get(), kBufferSize, cb.callback());
645  EXPECT_EQ(kBufferSize, cb.GetResult(rv));
646}
647
648TEST(HttpCache, SimpleGETWithDiskFailures) {
649  MockHttpCache cache;
650
651  cache.disk_cache()->set_soft_failures(true);
652
653  // Read from the network, and fail to write to the cache.
654  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
655
656  EXPECT_EQ(1, cache.network_layer()->transaction_count());
657  EXPECT_EQ(0, cache.disk_cache()->open_count());
658  EXPECT_EQ(1, cache.disk_cache()->create_count());
659
660  // This one should see an empty cache again.
661  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
662
663  EXPECT_EQ(2, cache.network_layer()->transaction_count());
664  EXPECT_EQ(0, cache.disk_cache()->open_count());
665  EXPECT_EQ(2, cache.disk_cache()->create_count());
666}
667
668// Tests that disk failures after the transaction has started don't cause the
669// request to fail.
670TEST(HttpCache, SimpleGETWithDiskFailures2) {
671  MockHttpCache cache;
672
673  MockHttpRequest request(kSimpleGET_Transaction);
674
675  scoped_ptr<Context> c(new Context());
676  int rv = cache.CreateTransaction(&c->trans);
677  ASSERT_EQ(net::OK, rv);
678
679  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
680  EXPECT_EQ(net::ERR_IO_PENDING, rv);
681  rv = c->callback.WaitForResult();
682
683  // Start failing request now.
684  cache.disk_cache()->set_soft_failures(true);
685
686  // We have to open the entry again to propagate the failure flag.
687  disk_cache::Entry* en;
688  ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en));
689  en->Close();
690
691  ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
692  c.reset();
693
694  EXPECT_EQ(1, cache.network_layer()->transaction_count());
695  EXPECT_EQ(1, cache.disk_cache()->open_count());
696  EXPECT_EQ(1, cache.disk_cache()->create_count());
697
698  // This one should see an empty cache again.
699  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
700
701  EXPECT_EQ(2, cache.network_layer()->transaction_count());
702  EXPECT_EQ(1, cache.disk_cache()->open_count());
703  EXPECT_EQ(2, cache.disk_cache()->create_count());
704}
705
706// Tests that we handle failures to read from the cache.
707TEST(HttpCache, SimpleGETWithDiskFailures3) {
708  MockHttpCache cache;
709
710  // Read from the network, and write to the cache.
711  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
712
713  EXPECT_EQ(1, cache.network_layer()->transaction_count());
714  EXPECT_EQ(0, cache.disk_cache()->open_count());
715  EXPECT_EQ(1, cache.disk_cache()->create_count());
716
717  cache.disk_cache()->set_soft_failures(true);
718
719  // Now fail to read from the cache.
720  scoped_ptr<Context> c(new Context());
721  int rv = cache.CreateTransaction(&c->trans);
722  ASSERT_EQ(net::OK, rv);
723
724  MockHttpRequest request(kSimpleGET_Transaction);
725  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
726  EXPECT_EQ(net::OK, c->callback.GetResult(rv));
727
728  // Now verify that the entry was removed from the cache.
729  cache.disk_cache()->set_soft_failures(false);
730
731  EXPECT_EQ(2, cache.network_layer()->transaction_count());
732  EXPECT_EQ(1, cache.disk_cache()->open_count());
733  EXPECT_EQ(2, cache.disk_cache()->create_count());
734
735  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
736
737  EXPECT_EQ(3, cache.network_layer()->transaction_count());
738  EXPECT_EQ(1, cache.disk_cache()->open_count());
739  EXPECT_EQ(3, cache.disk_cache()->create_count());
740}
741
742TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Hit) {
743  MockHttpCache cache;
744
745  net::CapturingBoundNetLog log;
746  net::LoadTimingInfo load_timing_info;
747
748  // Write to the cache.
749  RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
750                                 log.bound(), &load_timing_info);
751
752  // Check that the NetLog was filled as expected.
753  net::CapturingNetLog::CapturedEntryList entries;
754  log.GetEntries(&entries);
755  FilterLogEntries(&entries);
756
757  EXPECT_EQ(8u, entries.size());
758  EXPECT_TRUE(net::LogContainsBeginEvent(
759      entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
760  EXPECT_TRUE(net::LogContainsEndEvent(
761      entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
762  EXPECT_TRUE(net::LogContainsBeginEvent(
763      entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
764  EXPECT_TRUE(net::LogContainsEndEvent(
765      entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
766  EXPECT_TRUE(net::LogContainsBeginEvent(
767      entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
768  EXPECT_TRUE(net::LogContainsEndEvent(
769      entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
770  EXPECT_TRUE(net::LogContainsBeginEvent(
771      entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
772  EXPECT_TRUE(net::LogContainsEndEvent(
773      entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
774
775  TestLoadTimingNetworkRequest(load_timing_info);
776
777  // Force this transaction to read from the cache.
778  MockTransaction transaction(kSimpleGET_Transaction);
779  transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
780
781  log.Clear();
782
783  RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
784                                 &load_timing_info);
785
786  // Check that the NetLog was filled as expected.
787  log.GetEntries(&entries);
788  FilterLogEntries(&entries);
789
790  EXPECT_EQ(8u, entries.size());
791  EXPECT_TRUE(net::LogContainsBeginEvent(
792      entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
793  EXPECT_TRUE(net::LogContainsEndEvent(
794      entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
795  EXPECT_TRUE(net::LogContainsBeginEvent(
796      entries, 2, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
797  EXPECT_TRUE(net::LogContainsEndEvent(
798      entries, 3, net::NetLog::TYPE_HTTP_CACHE_OPEN_ENTRY));
799  EXPECT_TRUE(net::LogContainsBeginEvent(
800      entries, 4, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
801  EXPECT_TRUE(net::LogContainsEndEvent(
802      entries, 5, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
803  EXPECT_TRUE(net::LogContainsBeginEvent(
804      entries, 6, net::NetLog::TYPE_HTTP_CACHE_READ_INFO));
805  EXPECT_TRUE(net::LogContainsEndEvent(
806      entries, 7, net::NetLog::TYPE_HTTP_CACHE_READ_INFO));
807
808  EXPECT_EQ(1, cache.network_layer()->transaction_count());
809  EXPECT_EQ(1, cache.disk_cache()->open_count());
810  EXPECT_EQ(1, cache.disk_cache()->create_count());
811  TestLoadTimingCachedResponse(load_timing_info);
812}
813
814TEST(HttpCache, SimpleGET_LoadOnlyFromCache_Miss) {
815  MockHttpCache cache;
816
817  // force this transaction to read from the cache
818  MockTransaction transaction(kSimpleGET_Transaction);
819  transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
820
821  MockHttpRequest request(transaction);
822  net::TestCompletionCallback callback;
823
824  scoped_ptr<net::HttpTransaction> trans;
825  ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
826
827  int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
828  if (rv == net::ERR_IO_PENDING)
829    rv = callback.WaitForResult();
830  ASSERT_EQ(net::ERR_CACHE_MISS, rv);
831
832  trans.reset();
833
834  EXPECT_EQ(0, cache.network_layer()->transaction_count());
835  EXPECT_EQ(0, cache.disk_cache()->open_count());
836  EXPECT_EQ(0, cache.disk_cache()->create_count());
837}
838
839TEST(HttpCache, SimpleGET_LoadPreferringCache_Hit) {
840  MockHttpCache cache;
841
842  // write to the cache
843  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
844
845  // force this transaction to read from the cache if valid
846  MockTransaction transaction(kSimpleGET_Transaction);
847  transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
848
849  RunTransactionTest(cache.http_cache(), transaction);
850
851  EXPECT_EQ(1, cache.network_layer()->transaction_count());
852  EXPECT_EQ(1, cache.disk_cache()->open_count());
853  EXPECT_EQ(1, cache.disk_cache()->create_count());
854}
855
856TEST(HttpCache, SimpleGET_LoadPreferringCache_Miss) {
857  MockHttpCache cache;
858
859  // force this transaction to read from the cache if valid
860  MockTransaction transaction(kSimpleGET_Transaction);
861  transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
862
863  RunTransactionTest(cache.http_cache(), transaction);
864
865  EXPECT_EQ(1, cache.network_layer()->transaction_count());
866  EXPECT_EQ(0, cache.disk_cache()->open_count());
867  EXPECT_EQ(1, cache.disk_cache()->create_count());
868}
869
870// Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
871TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMatch) {
872  MockHttpCache cache;
873
874  // Write to the cache.
875  MockTransaction transaction(kSimpleGET_Transaction);
876  transaction.request_headers = "Foo: bar\r\n";
877  transaction.response_headers = "Cache-Control: max-age=10000\n"
878                                 "Vary: Foo\n";
879  AddMockTransaction(&transaction);
880  RunTransactionTest(cache.http_cache(), transaction);
881
882  // Read from the cache.
883  transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
884  RunTransactionTest(cache.http_cache(), transaction);
885
886  EXPECT_EQ(1, cache.network_layer()->transaction_count());
887  EXPECT_EQ(1, cache.disk_cache()->open_count());
888  EXPECT_EQ(1, cache.disk_cache()->create_count());
889  RemoveMockTransaction(&transaction);
890}
891
892// Tests LOAD_PREFERRING_CACHE in the presence of vary headers.
893TEST(HttpCache, SimpleGET_LoadPreferringCache_VaryMismatch) {
894  MockHttpCache cache;
895
896  // Write to the cache.
897  MockTransaction transaction(kSimpleGET_Transaction);
898  transaction.request_headers = "Foo: bar\r\n";
899  transaction.response_headers = "Cache-Control: max-age=10000\n"
900                                 "Vary: Foo\n";
901  AddMockTransaction(&transaction);
902  RunTransactionTest(cache.http_cache(), transaction);
903
904  // Attempt to read from the cache... this is a vary mismatch that must reach
905  // the network again.
906  transaction.load_flags |= net::LOAD_PREFERRING_CACHE;
907  transaction.request_headers = "Foo: none\r\n";
908  net::CapturingBoundNetLog log;
909  net::LoadTimingInfo load_timing_info;
910  RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
911                                 &load_timing_info);
912
913  EXPECT_EQ(2, cache.network_layer()->transaction_count());
914  EXPECT_EQ(1, cache.disk_cache()->open_count());
915  EXPECT_EQ(1, cache.disk_cache()->create_count());
916  TestLoadTimingNetworkRequest(load_timing_info);
917  RemoveMockTransaction(&transaction);
918}
919
920// Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
921// network success
922TEST(HttpCache, SimpleGET_CacheOverride_Network) {
923  MockHttpCache cache;
924
925  // Prime cache.
926  MockTransaction transaction(kSimpleGET_Transaction);
927  transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
928  transaction.response_headers = "Cache-Control: no-cache\n";
929
930  AddMockTransaction(&transaction);
931  RunTransactionTest(cache.http_cache(), transaction);
932  EXPECT_EQ(1, cache.network_layer()->transaction_count());
933  EXPECT_EQ(1, cache.disk_cache()->create_count());
934  RemoveMockTransaction(&transaction);
935
936  // Re-run transaction; make sure the result came from the network,
937  // not the cache.
938  transaction.data = "Changed data.";
939  AddMockTransaction(&transaction);
940  net::HttpResponseInfo response_info;
941  RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
942                                     &response_info);
943
944  EXPECT_EQ(2, cache.network_layer()->transaction_count());
945  EXPECT_FALSE(response_info.server_data_unavailable);
946  EXPECT_TRUE(response_info.network_accessed);
947
948  RemoveMockTransaction(&transaction);
949}
950
951// Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
952// offline failure
953TEST(HttpCache, SimpleGET_CacheOverride_Offline) {
954  MockHttpCache cache;
955
956  // Prime cache.
957  MockTransaction transaction(kSimpleGET_Transaction);
958  transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
959  transaction.response_headers = "Cache-Control: no-cache\n";
960
961  AddMockTransaction(&transaction);
962  RunTransactionTest(cache.http_cache(), transaction);
963  EXPECT_EQ(1, cache.network_layer()->transaction_count());
964  EXPECT_EQ(1, cache.disk_cache()->create_count());
965  RemoveMockTransaction(&transaction);
966
967  // Network failure with offline error; should return cache entry above +
968  // flag signalling stale data.
969  transaction.return_code = net::ERR_NAME_NOT_RESOLVED;
970  AddMockTransaction(&transaction);
971
972  MockHttpRequest request(transaction);
973  net::TestCompletionCallback callback;
974  scoped_ptr<net::HttpTransaction> trans;
975  ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
976  int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
977  EXPECT_EQ(net::OK, callback.GetResult(rv));
978
979  const net::HttpResponseInfo* response_info = trans->GetResponseInfo();
980  ASSERT_TRUE(response_info);
981  EXPECT_TRUE(response_info->server_data_unavailable);
982  EXPECT_TRUE(response_info->was_cached);
983  EXPECT_FALSE(response_info->network_accessed);
984  ReadAndVerifyTransaction(trans.get(), transaction);
985  EXPECT_EQ(2, cache.network_layer()->transaction_count());
986
987  RemoveMockTransaction(&transaction);
988}
989
990// Tests that LOAD_FROM_CACHE_IF_OFFLINE returns proper response on
991// non-offline failure.
992TEST(HttpCache, SimpleGET_CacheOverride_NonOffline) {
993  MockHttpCache cache;
994
995  // Prime cache.
996  MockTransaction transaction(kSimpleGET_Transaction);
997  transaction.load_flags |= net::LOAD_FROM_CACHE_IF_OFFLINE;
998  transaction.response_headers = "Cache-Control: no-cache\n";
999
1000  AddMockTransaction(&transaction);
1001  RunTransactionTest(cache.http_cache(), transaction);
1002  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1003  EXPECT_EQ(1, cache.disk_cache()->create_count());
1004  RemoveMockTransaction(&transaction);
1005
1006  // Network failure with non-offline error; should fail with that error.
1007  transaction.return_code = net::ERR_PROXY_CONNECTION_FAILED;
1008  AddMockTransaction(&transaction);
1009
1010  net::HttpResponseInfo response_info2;
1011  RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1012                                     &response_info2);
1013
1014  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1015  EXPECT_FALSE(response_info2.server_data_unavailable);
1016
1017  RemoveMockTransaction(&transaction);
1018}
1019
1020// Tests that was_cached was set properly on a failure, even if the cached
1021// response wasn't returned.
1022TEST(HttpCache, SimpleGET_CacheSignal_Failure) {
1023  MockHttpCache cache;
1024
1025  // Prime cache.
1026  MockTransaction transaction(kSimpleGET_Transaction);
1027  transaction.response_headers = "Cache-Control: no-cache\n";
1028
1029  AddMockTransaction(&transaction);
1030  RunTransactionTest(cache.http_cache(), transaction);
1031  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1032  EXPECT_EQ(1, cache.disk_cache()->create_count());
1033  RemoveMockTransaction(&transaction);
1034
1035  // Network failure with error; should fail but have was_cached set.
1036  transaction.return_code = net::ERR_FAILED;
1037  AddMockTransaction(&transaction);
1038
1039  MockHttpRequest request(transaction);
1040  net::TestCompletionCallback callback;
1041  scoped_ptr<net::HttpTransaction> trans;
1042  int rv = cache.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY, &trans);
1043  EXPECT_EQ(net::OK, rv);
1044  ASSERT_TRUE(trans.get());
1045  rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
1046  EXPECT_EQ(net::ERR_FAILED, callback.GetResult(rv));
1047
1048  const net::HttpResponseInfo* response_info = trans->GetResponseInfo();
1049  ASSERT_TRUE(response_info);
1050  EXPECT_TRUE(response_info->was_cached);
1051  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1052
1053  RemoveMockTransaction(&transaction);
1054}
1055
1056// Confirm if we have an empty cache, a read is marked as network verified.
1057TEST(HttpCache, SimpleGET_NetworkAccessed_Network) {
1058  MockHttpCache cache;
1059
1060  // write to the cache
1061  net::HttpResponseInfo response_info;
1062  RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
1063                                     &response_info);
1064
1065  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1066  EXPECT_EQ(0, cache.disk_cache()->open_count());
1067  EXPECT_EQ(1, cache.disk_cache()->create_count());
1068  EXPECT_TRUE(response_info.network_accessed);
1069}
1070
1071// Confirm if we have a fresh entry in cache, it isn't marked as
1072// network verified.
1073TEST(HttpCache, SimpleGET_NetworkAccessed_Cache) {
1074  MockHttpCache cache;
1075
1076  // Prime cache.
1077  MockTransaction transaction(kSimpleGET_Transaction);
1078
1079  RunTransactionTest(cache.http_cache(), transaction);
1080  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1081  EXPECT_EQ(1, cache.disk_cache()->create_count());
1082
1083  // Re-run transaction; make sure we don't mark the network as accessed.
1084  net::HttpResponseInfo response_info;
1085  RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1086                                     &response_info);
1087
1088  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1089  EXPECT_FALSE(response_info.server_data_unavailable);
1090  EXPECT_FALSE(response_info.network_accessed);
1091}
1092
1093TEST(HttpCache, SimpleGET_LoadBypassCache) {
1094  MockHttpCache cache;
1095
1096  // Write to the cache.
1097  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1098
1099  // Force this transaction to write to the cache again.
1100  MockTransaction transaction(kSimpleGET_Transaction);
1101  transaction.load_flags |= net::LOAD_BYPASS_CACHE;
1102
1103  net::CapturingBoundNetLog log;
1104  net::LoadTimingInfo load_timing_info;
1105
1106  // Write to the cache.
1107  RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
1108                                 &load_timing_info);
1109
1110  // Check that the NetLog was filled as expected.
1111  net::CapturingNetLog::CapturedEntryList entries;
1112  log.GetEntries(&entries);
1113  FilterLogEntries(&entries);
1114
1115  EXPECT_EQ(8u, entries.size());
1116  EXPECT_TRUE(net::LogContainsBeginEvent(
1117      entries, 0, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1118  EXPECT_TRUE(net::LogContainsEndEvent(
1119      entries, 1, net::NetLog::TYPE_HTTP_CACHE_GET_BACKEND));
1120  EXPECT_TRUE(net::LogContainsBeginEvent(
1121      entries, 2, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1122  EXPECT_TRUE(net::LogContainsEndEvent(
1123      entries, 3, net::NetLog::TYPE_HTTP_CACHE_DOOM_ENTRY));
1124  EXPECT_TRUE(net::LogContainsBeginEvent(
1125      entries, 4, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1126  EXPECT_TRUE(net::LogContainsEndEvent(
1127      entries, 5, net::NetLog::TYPE_HTTP_CACHE_CREATE_ENTRY));
1128  EXPECT_TRUE(net::LogContainsBeginEvent(
1129      entries, 6, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1130  EXPECT_TRUE(net::LogContainsEndEvent(
1131      entries, 7, net::NetLog::TYPE_HTTP_CACHE_ADD_TO_ENTRY));
1132
1133  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1134  EXPECT_EQ(0, cache.disk_cache()->open_count());
1135  EXPECT_EQ(2, cache.disk_cache()->create_count());
1136  TestLoadTimingNetworkRequest(load_timing_info);
1137}
1138
1139TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit) {
1140  MockHttpCache cache;
1141
1142  // write to the cache
1143  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1144
1145  // force this transaction to write to the cache again
1146  MockTransaction transaction(kSimpleGET_Transaction);
1147  transaction.request_headers = "pragma: no-cache\r\n";
1148
1149  RunTransactionTest(cache.http_cache(), transaction);
1150
1151  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1152  EXPECT_EQ(0, cache.disk_cache()->open_count());
1153  EXPECT_EQ(2, cache.disk_cache()->create_count());
1154}
1155
1156TEST(HttpCache, SimpleGET_LoadBypassCache_Implicit2) {
1157  MockHttpCache cache;
1158
1159  // write to the cache
1160  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1161
1162  // force this transaction to write to the cache again
1163  MockTransaction transaction(kSimpleGET_Transaction);
1164  transaction.request_headers = "cache-control: no-cache\r\n";
1165
1166  RunTransactionTest(cache.http_cache(), transaction);
1167
1168  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1169  EXPECT_EQ(0, cache.disk_cache()->open_count());
1170  EXPECT_EQ(2, cache.disk_cache()->create_count());
1171}
1172
1173TEST(HttpCache, SimpleGET_LoadValidateCache) {
1174  MockHttpCache cache;
1175
1176  // Write to the cache.
1177  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1178
1179  // Read from the cache.
1180  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1181
1182  // Force this transaction to validate the cache.
1183  MockTransaction transaction(kSimpleGET_Transaction);
1184  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
1185
1186  net::HttpResponseInfo response_info;
1187  net::CapturingBoundNetLog log;
1188  net::LoadTimingInfo load_timing_info;
1189  RunTransactionTestWithResponseInfoAndGetTiming(
1190      cache.http_cache(), transaction, &response_info, log.bound(),
1191      &load_timing_info);
1192
1193  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1194  EXPECT_EQ(1, cache.disk_cache()->open_count());
1195  EXPECT_EQ(1, cache.disk_cache()->create_count());
1196  EXPECT_TRUE(response_info.network_accessed);
1197  TestLoadTimingNetworkRequest(load_timing_info);
1198}
1199
1200TEST(HttpCache, SimpleGET_LoadValidateCache_Implicit) {
1201  MockHttpCache cache;
1202
1203  // write to the cache
1204  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1205
1206  // read from the cache
1207  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1208
1209  // force this transaction to validate the cache
1210  MockTransaction transaction(kSimpleGET_Transaction);
1211  transaction.request_headers = "cache-control: max-age=0\r\n";
1212
1213  RunTransactionTest(cache.http_cache(), transaction);
1214
1215  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1216  EXPECT_EQ(1, cache.disk_cache()->open_count());
1217  EXPECT_EQ(1, cache.disk_cache()->create_count());
1218}
1219
1220static void PreserveRequestHeaders_Handler(
1221    const net::HttpRequestInfo* request,
1222    std::string* response_status,
1223    std::string* response_headers,
1224    std::string* response_data) {
1225  EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
1226}
1227
1228// Tests that we don't remove extra headers for simple requests.
1229TEST(HttpCache, SimpleGET_PreserveRequestHeaders) {
1230  MockHttpCache cache;
1231
1232  MockTransaction transaction(kSimpleGET_Transaction);
1233  transaction.handler = PreserveRequestHeaders_Handler;
1234  transaction.request_headers = EXTRA_HEADER;
1235  transaction.response_headers = "Cache-Control: max-age=0\n";
1236  AddMockTransaction(&transaction);
1237
1238  // Write, then revalidate the entry.
1239  RunTransactionTest(cache.http_cache(), transaction);
1240  RunTransactionTest(cache.http_cache(), transaction);
1241
1242  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1243  EXPECT_EQ(1, cache.disk_cache()->open_count());
1244  EXPECT_EQ(1, cache.disk_cache()->create_count());
1245  RemoveMockTransaction(&transaction);
1246}
1247
1248// Tests that we don't remove extra headers for conditionalized requests.
1249TEST(HttpCache, ConditionalizedGET_PreserveRequestHeaders) {
1250  MockHttpCache cache;
1251
1252  // Write to the cache.
1253  RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
1254
1255  MockTransaction transaction(kETagGET_Transaction);
1256  transaction.handler = PreserveRequestHeaders_Handler;
1257  transaction.request_headers = "If-None-Match: \"foopy\"\r\n"
1258                                EXTRA_HEADER;
1259  AddMockTransaction(&transaction);
1260
1261  RunTransactionTest(cache.http_cache(), transaction);
1262
1263  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1264  EXPECT_EQ(1, cache.disk_cache()->open_count());
1265  EXPECT_EQ(1, cache.disk_cache()->create_count());
1266  RemoveMockTransaction(&transaction);
1267}
1268
1269TEST(HttpCache, SimpleGET_ManyReaders) {
1270  MockHttpCache cache;
1271
1272  MockHttpRequest request(kSimpleGET_Transaction);
1273
1274  std::vector<Context*> context_list;
1275  const int kNumTransactions = 5;
1276
1277  for (int i = 0; i < kNumTransactions; ++i) {
1278    context_list.push_back(new Context());
1279    Context* c = context_list[i];
1280
1281    c->result = cache.CreateTransaction(&c->trans);
1282    ASSERT_EQ(net::OK, c->result);
1283    EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
1284
1285    c->result = c->trans->Start(
1286        &request, c->callback.callback(), net::BoundNetLog());
1287  }
1288
1289  // All requests are waiting for the active entry.
1290  for (int i = 0; i < kNumTransactions; ++i) {
1291    Context* c = context_list[i];
1292    EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState());
1293  }
1294
1295  // Allow all requests to move from the Create queue to the active entry.
1296  base::MessageLoop::current()->RunUntilIdle();
1297
1298  // The first request should be a writer at this point, and the subsequent
1299  // requests should be pending.
1300
1301  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1302  EXPECT_EQ(0, cache.disk_cache()->open_count());
1303  EXPECT_EQ(1, cache.disk_cache()->create_count());
1304
1305  // All requests depend on the writer, and the writer is between Start and
1306  // Read, i.e. idle.
1307  for (int i = 0; i < kNumTransactions; ++i) {
1308    Context* c = context_list[i];
1309    EXPECT_EQ(net::LOAD_STATE_IDLE, c->trans->GetLoadState());
1310  }
1311
1312  for (int i = 0; i < kNumTransactions; ++i) {
1313    Context* c = context_list[i];
1314    if (c->result == net::ERR_IO_PENDING)
1315      c->result = c->callback.WaitForResult();
1316    ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1317  }
1318
1319  // We should not have had to re-open the disk entry
1320
1321  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1322  EXPECT_EQ(0, cache.disk_cache()->open_count());
1323  EXPECT_EQ(1, cache.disk_cache()->create_count());
1324
1325  for (int i = 0; i < kNumTransactions; ++i) {
1326    Context* c = context_list[i];
1327    delete c;
1328  }
1329}
1330
1331// This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
1332// If cancelling a request is racing with another request for the same resource
1333// finishing, we have to make sure that we remove both transactions from the
1334// entry.
1335TEST(HttpCache, SimpleGET_RacingReaders) {
1336  MockHttpCache cache;
1337
1338  MockHttpRequest request(kSimpleGET_Transaction);
1339  MockHttpRequest reader_request(kSimpleGET_Transaction);
1340  reader_request.load_flags = net::LOAD_ONLY_FROM_CACHE;
1341
1342  std::vector<Context*> context_list;
1343  const int kNumTransactions = 5;
1344
1345  for (int i = 0; i < kNumTransactions; ++i) {
1346    context_list.push_back(new Context());
1347    Context* c = context_list[i];
1348
1349    c->result = cache.CreateTransaction(&c->trans);
1350    ASSERT_EQ(net::OK, c->result);
1351
1352    MockHttpRequest* this_request = &request;
1353    if (i == 1 || i == 2)
1354      this_request = &reader_request;
1355
1356    c->result = c->trans->Start(
1357        this_request, c->callback.callback(), net::BoundNetLog());
1358  }
1359
1360  // Allow all requests to move from the Create queue to the active entry.
1361  base::MessageLoop::current()->RunUntilIdle();
1362
1363  // The first request should be a writer at this point, and the subsequent
1364  // requests should be pending.
1365
1366  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1367  EXPECT_EQ(0, cache.disk_cache()->open_count());
1368  EXPECT_EQ(1, cache.disk_cache()->create_count());
1369
1370  Context* c = context_list[0];
1371  ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1372  c->result = c->callback.WaitForResult();
1373  ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1374
1375  // Now we have 2 active readers and two queued transactions.
1376
1377  EXPECT_EQ(net::LOAD_STATE_IDLE,
1378            context_list[2]->trans->GetLoadState());
1379  EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_CACHE,
1380            context_list[3]->trans->GetLoadState());
1381
1382  c = context_list[1];
1383  ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1384  c->result = c->callback.WaitForResult();
1385  if (c->result == net::OK)
1386    ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1387
1388  // At this point we have one reader, two pending transactions and a task on
1389  // the queue to move to the next transaction. Now we cancel the request that
1390  // is the current reader, and expect the queued task to be able to start the
1391  // next request.
1392
1393  c = context_list[2];
1394  c->trans.reset();
1395
1396  for (int i = 3; i < kNumTransactions; ++i) {
1397    Context* c = context_list[i];
1398    if (c->result == net::ERR_IO_PENDING)
1399      c->result = c->callback.WaitForResult();
1400    if (c->result == net::OK)
1401      ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1402  }
1403
1404  // We should not have had to re-open the disk entry.
1405
1406  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1407  EXPECT_EQ(0, cache.disk_cache()->open_count());
1408  EXPECT_EQ(1, cache.disk_cache()->create_count());
1409
1410  for (int i = 0; i < kNumTransactions; ++i) {
1411    Context* c = context_list[i];
1412    delete c;
1413  }
1414}
1415
1416// Tests that we can doom an entry with pending transactions and delete one of
1417// the pending transactions before the first one completes.
1418// See http://code.google.com/p/chromium/issues/detail?id=25588
1419TEST(HttpCache, SimpleGET_DoomWithPending) {
1420  // We need simultaneous doomed / not_doomed entries so let's use a real cache.
1421  MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
1422
1423  MockHttpRequest request(kSimpleGET_Transaction);
1424  MockHttpRequest writer_request(kSimpleGET_Transaction);
1425  writer_request.load_flags = net::LOAD_BYPASS_CACHE;
1426
1427  ScopedVector<Context> context_list;
1428  const int kNumTransactions = 4;
1429
1430  for (int i = 0; i < kNumTransactions; ++i) {
1431    context_list.push_back(new Context());
1432    Context* c = context_list[i];
1433
1434    c->result = cache.CreateTransaction(&c->trans);
1435    ASSERT_EQ(net::OK, c->result);
1436
1437    MockHttpRequest* this_request = &request;
1438    if (i == 3)
1439      this_request = &writer_request;
1440
1441    c->result = c->trans->Start(
1442        this_request, c->callback.callback(), net::BoundNetLog());
1443  }
1444
1445  // The first request should be a writer at this point, and the two subsequent
1446  // requests should be pending. The last request doomed the first entry.
1447
1448  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1449
1450  // Cancel the first queued transaction.
1451  delete context_list[1];
1452  context_list.get()[1] = NULL;
1453
1454  for (int i = 0; i < kNumTransactions; ++i) {
1455    if (i == 1)
1456      continue;
1457    Context* c = context_list[i];
1458    ASSERT_EQ(net::ERR_IO_PENDING, c->result);
1459    c->result = c->callback.WaitForResult();
1460    ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1461  }
1462}
1463
1464// This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
1465// We may attempt to delete an entry synchronously with the act of adding a new
1466// transaction to said entry.
1467TEST(HttpCache, FastNoStoreGET_DoneWithPending) {
1468  MockHttpCache cache;
1469
1470  // The headers will be served right from the call to Start() the request.
1471  MockHttpRequest request(kFastNoStoreGET_Transaction);
1472  FastTransactionServer request_handler;
1473  AddMockTransaction(&kFastNoStoreGET_Transaction);
1474
1475  std::vector<Context*> context_list;
1476  const int kNumTransactions = 3;
1477
1478  for (int i = 0; i < kNumTransactions; ++i) {
1479    context_list.push_back(new Context());
1480    Context* c = context_list[i];
1481
1482    c->result = cache.CreateTransaction(&c->trans);
1483    ASSERT_EQ(net::OK, c->result);
1484
1485    c->result = c->trans->Start(
1486        &request, c->callback.callback(), net::BoundNetLog());
1487  }
1488
1489  // Allow all requests to move from the Create queue to the active entry.
1490  base::MessageLoop::current()->RunUntilIdle();
1491
1492  // The first request should be a writer at this point, and the subsequent
1493  // requests should be pending.
1494
1495  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1496  EXPECT_EQ(0, cache.disk_cache()->open_count());
1497  EXPECT_EQ(1, cache.disk_cache()->create_count());
1498
1499  // Now, make sure that the second request asks for the entry not to be stored.
1500  request_handler.set_no_store(true);
1501
1502  for (int i = 0; i < kNumTransactions; ++i) {
1503    Context* c = context_list[i];
1504    if (c->result == net::ERR_IO_PENDING)
1505      c->result = c->callback.WaitForResult();
1506    ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction);
1507    delete c;
1508  }
1509
1510  EXPECT_EQ(3, cache.network_layer()->transaction_count());
1511  EXPECT_EQ(0, cache.disk_cache()->open_count());
1512  EXPECT_EQ(2, cache.disk_cache()->create_count());
1513
1514  RemoveMockTransaction(&kFastNoStoreGET_Transaction);
1515}
1516
1517TEST(HttpCache, SimpleGET_ManyWriters_CancelFirst) {
1518  MockHttpCache cache;
1519
1520  MockHttpRequest request(kSimpleGET_Transaction);
1521
1522  std::vector<Context*> context_list;
1523  const int kNumTransactions = 2;
1524
1525  for (int i = 0; i < kNumTransactions; ++i) {
1526    context_list.push_back(new Context());
1527    Context* c = context_list[i];
1528
1529    c->result = cache.CreateTransaction(&c->trans);
1530    ASSERT_EQ(net::OK, c->result);
1531
1532    c->result = c->trans->Start(
1533        &request, c->callback.callback(), net::BoundNetLog());
1534  }
1535
1536  // Allow all requests to move from the Create queue to the active entry.
1537  base::MessageLoop::current()->RunUntilIdle();
1538
1539  // The first request should be a writer at this point, and the subsequent
1540  // requests should be pending.
1541
1542  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1543  EXPECT_EQ(0, cache.disk_cache()->open_count());
1544  EXPECT_EQ(1, cache.disk_cache()->create_count());
1545
1546  for (int i = 0; i < kNumTransactions; ++i) {
1547    Context* c = context_list[i];
1548    if (c->result == net::ERR_IO_PENDING)
1549      c->result = c->callback.WaitForResult();
1550    // Destroy only the first transaction.
1551    if (i == 0) {
1552      delete c;
1553      context_list[i] = NULL;
1554    }
1555  }
1556
1557  // Complete the rest of the transactions.
1558  for (int i = 1; i < kNumTransactions; ++i) {
1559    Context* c = context_list[i];
1560    ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1561  }
1562
1563  // We should have had to re-open the disk entry.
1564
1565  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1566  EXPECT_EQ(0, cache.disk_cache()->open_count());
1567  EXPECT_EQ(2, cache.disk_cache()->create_count());
1568
1569  for (int i = 1; i < kNumTransactions; ++i) {
1570    Context* c = context_list[i];
1571    delete c;
1572  }
1573}
1574
1575// Tests that we can cancel requests that are queued waiting to open the disk
1576// cache entry.
1577TEST(HttpCache, SimpleGET_ManyWriters_CancelCreate) {
1578  MockHttpCache cache;
1579
1580  MockHttpRequest request(kSimpleGET_Transaction);
1581
1582  std::vector<Context*> context_list;
1583  const int kNumTransactions = 5;
1584
1585  for (int i = 0; i < kNumTransactions; i++) {
1586    context_list.push_back(new Context());
1587    Context* c = context_list[i];
1588
1589    c->result = cache.CreateTransaction(&c->trans);
1590    ASSERT_EQ(net::OK, c->result);
1591
1592    c->result = c->trans->Start(
1593        &request, c->callback.callback(), net::BoundNetLog());
1594  }
1595
1596  // The first request should be creating the disk cache entry and the others
1597  // should be pending.
1598
1599  EXPECT_EQ(0, cache.network_layer()->transaction_count());
1600  EXPECT_EQ(0, cache.disk_cache()->open_count());
1601  EXPECT_EQ(1, cache.disk_cache()->create_count());
1602
1603  // Cancel a request from the pending queue.
1604  delete context_list[3];
1605  context_list[3] = NULL;
1606
1607  // Cancel the request that is creating the entry. This will force the pending
1608  // operations to restart.
1609  delete context_list[0];
1610  context_list[0] = NULL;
1611
1612  // Complete the rest of the transactions.
1613  for (int i = 1; i < kNumTransactions; i++) {
1614    Context* c = context_list[i];
1615    if (c) {
1616      c->result = c->callback.GetResult(c->result);
1617      ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1618    }
1619  }
1620
1621  // We should have had to re-create the disk entry.
1622
1623  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1624  EXPECT_EQ(0, cache.disk_cache()->open_count());
1625  EXPECT_EQ(2, cache.disk_cache()->create_count());
1626
1627  for (int i = 1; i < kNumTransactions; ++i) {
1628    delete context_list[i];
1629  }
1630}
1631
1632// Tests that we can cancel a single request to open a disk cache entry.
1633TEST(HttpCache, SimpleGET_CancelCreate) {
1634  MockHttpCache cache;
1635
1636  MockHttpRequest request(kSimpleGET_Transaction);
1637
1638  Context* c = new Context();
1639
1640  c->result = cache.CreateTransaction(&c->trans);
1641  ASSERT_EQ(net::OK, c->result);
1642
1643  c->result = c->trans->Start(
1644      &request, c->callback.callback(), net::BoundNetLog());
1645  EXPECT_EQ(net::ERR_IO_PENDING, c->result);
1646
1647  // Release the reference that the mock disk cache keeps for this entry, so
1648  // that we test that the http cache handles the cancellation correctly.
1649  cache.disk_cache()->ReleaseAll();
1650  delete c;
1651
1652  base::MessageLoop::current()->RunUntilIdle();
1653  EXPECT_EQ(1, cache.disk_cache()->create_count());
1654}
1655
1656// Tests that we delete/create entries even if multiple requests are queued.
1657TEST(HttpCache, SimpleGET_ManyWriters_BypassCache) {
1658  MockHttpCache cache;
1659
1660  MockHttpRequest request(kSimpleGET_Transaction);
1661  request.load_flags = net::LOAD_BYPASS_CACHE;
1662
1663  std::vector<Context*> context_list;
1664  const int kNumTransactions = 5;
1665
1666  for (int i = 0; i < kNumTransactions; i++) {
1667    context_list.push_back(new Context());
1668    Context* c = context_list[i];
1669
1670    c->result = cache.CreateTransaction(&c->trans);
1671    ASSERT_EQ(net::OK, c->result);
1672
1673    c->result = c->trans->Start(
1674        &request, c->callback.callback(), net::BoundNetLog());
1675  }
1676
1677  // The first request should be deleting the disk cache entry and the others
1678  // should be pending.
1679
1680  EXPECT_EQ(0, cache.network_layer()->transaction_count());
1681  EXPECT_EQ(0, cache.disk_cache()->open_count());
1682  EXPECT_EQ(0, cache.disk_cache()->create_count());
1683
1684  // Complete the transactions.
1685  for (int i = 0; i < kNumTransactions; i++) {
1686    Context* c = context_list[i];
1687    c->result = c->callback.GetResult(c->result);
1688    ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1689  }
1690
1691  // We should have had to re-create the disk entry multiple times.
1692
1693  EXPECT_EQ(5, cache.network_layer()->transaction_count());
1694  EXPECT_EQ(0, cache.disk_cache()->open_count());
1695  EXPECT_EQ(5, cache.disk_cache()->create_count());
1696
1697  for (int i = 0; i < kNumTransactions; ++i) {
1698    delete context_list[i];
1699  }
1700}
1701
1702// Tests that a (simulated) timeout allows transactions waiting on the cache
1703// lock to continue.
1704TEST(HttpCache, SimpleGET_WriterTimeout) {
1705  MockHttpCache cache;
1706  cache.BypassCacheLock();
1707
1708  MockHttpRequest request(kSimpleGET_Transaction);
1709  Context c1, c2;
1710  ASSERT_EQ(net::OK, cache.CreateTransaction(&c1.trans));
1711  ASSERT_EQ(net::ERR_IO_PENDING,
1712            c1.trans->Start(&request, c1.callback.callback(),
1713                            net::BoundNetLog()));
1714  ASSERT_EQ(net::OK, cache.CreateTransaction(&c2.trans));
1715  ASSERT_EQ(net::ERR_IO_PENDING,
1716            c2.trans->Start(&request, c2.callback.callback(),
1717                            net::BoundNetLog()));
1718
1719  // The second request is queued after the first one.
1720
1721  c2.callback.WaitForResult();
1722  ReadAndVerifyTransaction(c2.trans.get(), kSimpleGET_Transaction);
1723
1724  // Complete the first transaction.
1725  c1.callback.WaitForResult();
1726  ReadAndVerifyTransaction(c1.trans.get(), kSimpleGET_Transaction);
1727}
1728
1729TEST(HttpCache, SimpleGET_AbandonedCacheRead) {
1730  MockHttpCache cache;
1731
1732  // write to the cache
1733  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1734
1735  MockHttpRequest request(kSimpleGET_Transaction);
1736  net::TestCompletionCallback callback;
1737
1738  scoped_ptr<net::HttpTransaction> trans;
1739  ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
1740  int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
1741  if (rv == net::ERR_IO_PENDING)
1742    rv = callback.WaitForResult();
1743  ASSERT_EQ(net::OK, rv);
1744
1745  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
1746  rv = trans->Read(buf.get(), 256, callback.callback());
1747  EXPECT_EQ(net::ERR_IO_PENDING, rv);
1748
1749  // Test that destroying the transaction while it is reading from the cache
1750  // works properly.
1751  trans.reset();
1752
1753  // Make sure we pump any pending events, which should include a call to
1754  // HttpCache::Transaction::OnCacheReadCompleted.
1755  base::MessageLoop::current()->RunUntilIdle();
1756}
1757
1758// Tests that we can delete the HttpCache and deal with queued transactions
1759// ("waiting for the backend" as opposed to Active or Doomed entries).
1760TEST(HttpCache, SimpleGET_ManyWriters_DeleteCache) {
1761  scoped_ptr<MockHttpCache> cache(new MockHttpCache(
1762                                      new MockBackendNoCbFactory()));
1763
1764  MockHttpRequest request(kSimpleGET_Transaction);
1765
1766  std::vector<Context*> context_list;
1767  const int kNumTransactions = 5;
1768
1769  for (int i = 0; i < kNumTransactions; i++) {
1770    context_list.push_back(new Context());
1771    Context* c = context_list[i];
1772
1773    c->result = cache->CreateTransaction(&c->trans);
1774    ASSERT_EQ(net::OK, c->result);
1775
1776    c->result = c->trans->Start(
1777        &request, c->callback.callback(), net::BoundNetLog());
1778  }
1779
1780  // The first request should be creating the disk cache entry and the others
1781  // should be pending.
1782
1783  EXPECT_EQ(0, cache->network_layer()->transaction_count());
1784  EXPECT_EQ(0, cache->disk_cache()->open_count());
1785  EXPECT_EQ(0, cache->disk_cache()->create_count());
1786
1787  cache.reset();
1788
1789  // There is not much to do with the transactions at this point... they are
1790  // waiting for a callback that will not fire.
1791  for (int i = 0; i < kNumTransactions; ++i) {
1792    delete context_list[i];
1793  }
1794}
1795
1796// Tests that we queue requests when initializing the backend.
1797TEST(HttpCache, SimpleGET_WaitForBackend) {
1798  MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1799  MockHttpCache cache(factory);
1800
1801  MockHttpRequest request0(kSimpleGET_Transaction);
1802  MockHttpRequest request1(kTypicalGET_Transaction);
1803  MockHttpRequest request2(kETagGET_Transaction);
1804
1805  std::vector<Context*> context_list;
1806  const int kNumTransactions = 3;
1807
1808  for (int i = 0; i < kNumTransactions; i++) {
1809    context_list.push_back(new Context());
1810    Context* c = context_list[i];
1811
1812    c->result = cache.CreateTransaction(&c->trans);
1813    ASSERT_EQ(net::OK, c->result);
1814  }
1815
1816  context_list[0]->result = context_list[0]->trans->Start(
1817      &request0, context_list[0]->callback.callback(), net::BoundNetLog());
1818  context_list[1]->result = context_list[1]->trans->Start(
1819      &request1, context_list[1]->callback.callback(), net::BoundNetLog());
1820  context_list[2]->result = context_list[2]->trans->Start(
1821      &request2, context_list[2]->callback.callback(), net::BoundNetLog());
1822
1823  // Just to make sure that everything is still pending.
1824  base::MessageLoop::current()->RunUntilIdle();
1825
1826  // The first request should be creating the disk cache.
1827  EXPECT_FALSE(context_list[0]->callback.have_result());
1828
1829  factory->FinishCreation();
1830
1831  base::MessageLoop::current()->RunUntilIdle();
1832  EXPECT_EQ(3, cache.network_layer()->transaction_count());
1833  EXPECT_EQ(3, cache.disk_cache()->create_count());
1834
1835  for (int i = 0; i < kNumTransactions; ++i) {
1836    EXPECT_TRUE(context_list[i]->callback.have_result());
1837    delete context_list[i];
1838  }
1839}
1840
1841// Tests that we can cancel requests that are queued waiting for the backend
1842// to be initialized.
1843TEST(HttpCache, SimpleGET_WaitForBackend_CancelCreate) {
1844  MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1845  MockHttpCache cache(factory);
1846
1847  MockHttpRequest request0(kSimpleGET_Transaction);
1848  MockHttpRequest request1(kTypicalGET_Transaction);
1849  MockHttpRequest request2(kETagGET_Transaction);
1850
1851  std::vector<Context*> context_list;
1852  const int kNumTransactions = 3;
1853
1854  for (int i = 0; i < kNumTransactions; i++) {
1855    context_list.push_back(new Context());
1856    Context* c = context_list[i];
1857
1858    c->result = cache.CreateTransaction(&c->trans);
1859    ASSERT_EQ(net::OK, c->result);
1860  }
1861
1862  context_list[0]->result = context_list[0]->trans->Start(
1863      &request0, context_list[0]->callback.callback(), net::BoundNetLog());
1864  context_list[1]->result = context_list[1]->trans->Start(
1865      &request1, context_list[1]->callback.callback(), net::BoundNetLog());
1866  context_list[2]->result = context_list[2]->trans->Start(
1867      &request2, context_list[2]->callback.callback(), net::BoundNetLog());
1868
1869  // Just to make sure that everything is still pending.
1870  base::MessageLoop::current()->RunUntilIdle();
1871
1872  // The first request should be creating the disk cache.
1873  EXPECT_FALSE(context_list[0]->callback.have_result());
1874
1875  // Cancel a request from the pending queue.
1876  delete context_list[1];
1877  context_list[1] = NULL;
1878
1879  // Cancel the request that is creating the entry.
1880  delete context_list[0];
1881  context_list[0] = NULL;
1882
1883  // Complete the last transaction.
1884  factory->FinishCreation();
1885
1886  context_list[2]->result =
1887      context_list[2]->callback.GetResult(context_list[2]->result);
1888  ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction);
1889
1890  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1891  EXPECT_EQ(1, cache.disk_cache()->create_count());
1892
1893  delete context_list[2];
1894}
1895
1896// Tests that we can delete the cache while creating the backend.
1897TEST(HttpCache, DeleteCacheWaitingForBackend) {
1898  MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1899  scoped_ptr<MockHttpCache> cache(new MockHttpCache(factory));
1900
1901  MockHttpRequest request(kSimpleGET_Transaction);
1902
1903  scoped_ptr<Context> c(new Context());
1904  c->result = cache->CreateTransaction(&c->trans);
1905  ASSERT_EQ(net::OK, c->result);
1906
1907  c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
1908
1909  // Just to make sure that everything is still pending.
1910  base::MessageLoop::current()->RunUntilIdle();
1911
1912  // The request should be creating the disk cache.
1913  EXPECT_FALSE(c->callback.have_result());
1914
1915  // We cannot call FinishCreation because the factory itself will go away with
1916  // the cache, so grab the callback and attempt to use it.
1917  net::CompletionCallback callback = factory->callback();
1918  scoped_ptr<disk_cache::Backend>* backend = factory->backend();
1919
1920  cache.reset();
1921  base::MessageLoop::current()->RunUntilIdle();
1922
1923  backend->reset();
1924  callback.Run(net::ERR_ABORTED);
1925}
1926
1927// Tests that we can delete the cache while creating the backend, from within
1928// one of the callbacks.
1929TEST(HttpCache, DeleteCacheWaitingForBackend2) {
1930  MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
1931  MockHttpCache* cache = new MockHttpCache(factory);
1932
1933  DeleteCacheCompletionCallback cb(cache);
1934  disk_cache::Backend* backend;
1935  int rv = cache->http_cache()->GetBackend(&backend, cb.callback());
1936  EXPECT_EQ(net::ERR_IO_PENDING, rv);
1937
1938  // Now let's queue a regular transaction
1939  MockHttpRequest request(kSimpleGET_Transaction);
1940
1941  scoped_ptr<Context> c(new Context());
1942  c->result = cache->CreateTransaction(&c->trans);
1943  ASSERT_EQ(net::OK, c->result);
1944
1945  c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
1946
1947  // And another direct backend request.
1948  net::TestCompletionCallback cb2;
1949  rv = cache->http_cache()->GetBackend(&backend, cb2.callback());
1950  EXPECT_EQ(net::ERR_IO_PENDING, rv);
1951
1952  // Just to make sure that everything is still pending.
1953  base::MessageLoop::current()->RunUntilIdle();
1954
1955  // The request should be queued.
1956  EXPECT_FALSE(c->callback.have_result());
1957
1958  // Generate the callback.
1959  factory->FinishCreation();
1960  rv = cb.WaitForResult();
1961
1962  // The cache should be gone by now.
1963  base::MessageLoop::current()->RunUntilIdle();
1964  EXPECT_EQ(net::OK, c->callback.GetResult(c->result));
1965  EXPECT_FALSE(cb2.have_result());
1966}
1967
1968TEST(HttpCache, TypicalGET_ConditionalRequest) {
1969  MockHttpCache cache;
1970
1971  // write to the cache
1972  RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
1973
1974  EXPECT_EQ(1, cache.network_layer()->transaction_count());
1975  EXPECT_EQ(0, cache.disk_cache()->open_count());
1976  EXPECT_EQ(1, cache.disk_cache()->create_count());
1977
1978  // Get the same URL again, but this time we expect it to result
1979  // in a conditional request.
1980  net::CapturingBoundNetLog log;
1981  net::LoadTimingInfo load_timing_info;
1982  RunTransactionTestAndGetTiming(cache.http_cache(), kTypicalGET_Transaction,
1983                                 log.bound(), &load_timing_info);
1984
1985  EXPECT_EQ(2, cache.network_layer()->transaction_count());
1986  EXPECT_EQ(1, cache.disk_cache()->open_count());
1987  EXPECT_EQ(1, cache.disk_cache()->create_count());
1988  TestLoadTimingNetworkRequest(load_timing_info);
1989}
1990
1991static void ETagGet_ConditionalRequest_Handler(
1992    const net::HttpRequestInfo* request,
1993    std::string* response_status,
1994    std::string* response_headers,
1995    std::string* response_data) {
1996  EXPECT_TRUE(
1997      request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
1998  response_status->assign("HTTP/1.1 304 Not Modified");
1999  response_headers->assign(kETagGET_Transaction.response_headers);
2000  response_data->clear();
2001}
2002
2003TEST(HttpCache, ETagGET_ConditionalRequest_304) {
2004  MockHttpCache cache;
2005
2006  ScopedMockTransaction transaction(kETagGET_Transaction);
2007
2008  // write to the cache
2009  RunTransactionTest(cache.http_cache(), transaction);
2010
2011  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2012  EXPECT_EQ(0, cache.disk_cache()->open_count());
2013  EXPECT_EQ(1, cache.disk_cache()->create_count());
2014
2015  // Get the same URL again, but this time we expect it to result
2016  // in a conditional request.
2017  transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2018  transaction.handler = ETagGet_ConditionalRequest_Handler;
2019  net::CapturingBoundNetLog log;
2020  net::LoadTimingInfo load_timing_info;
2021  RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2022                                 &load_timing_info);
2023
2024  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2025  EXPECT_EQ(1, cache.disk_cache()->open_count());
2026  EXPECT_EQ(1, cache.disk_cache()->create_count());
2027  TestLoadTimingNetworkRequest(load_timing_info);
2028}
2029
2030class RevalidationServer {
2031 public:
2032  RevalidationServer() {
2033    s_etag_used_ = false;
2034    s_last_modified_used_ = false;
2035  }
2036
2037  bool EtagUsed() { return s_etag_used_; }
2038  bool LastModifiedUsed() { return s_last_modified_used_; }
2039
2040  static void Handler(const net::HttpRequestInfo* request,
2041                      std::string* response_status,
2042                      std::string* response_headers,
2043                      std::string* response_data);
2044
2045 private:
2046  static bool s_etag_used_;
2047  static bool s_last_modified_used_;
2048};
2049bool RevalidationServer::s_etag_used_ = false;
2050bool RevalidationServer::s_last_modified_used_ = false;
2051
2052void RevalidationServer::Handler(const net::HttpRequestInfo* request,
2053                                 std::string* response_status,
2054                                 std::string* response_headers,
2055                                 std::string* response_data) {
2056  if (request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch))
2057      s_etag_used_ = true;
2058
2059  if (request->extra_headers.HasHeader(
2060          net::HttpRequestHeaders::kIfModifiedSince)) {
2061      s_last_modified_used_ = true;
2062  }
2063
2064  if (s_etag_used_ || s_last_modified_used_) {
2065    response_status->assign("HTTP/1.1 304 Not Modified");
2066    response_headers->assign(kTypicalGET_Transaction.response_headers);
2067    response_data->clear();
2068  } else {
2069    response_status->assign(kTypicalGET_Transaction.status);
2070    response_headers->assign(kTypicalGET_Transaction.response_headers);
2071    response_data->assign(kTypicalGET_Transaction.data);
2072  }
2073}
2074
2075// Tests revalidation after a vary match.
2076TEST(HttpCache, SimpleGET_LoadValidateCache_VaryMatch) {
2077  MockHttpCache cache;
2078
2079  // Write to the cache.
2080  MockTransaction transaction(kTypicalGET_Transaction);
2081  transaction.request_headers = "Foo: bar\r\n";
2082  transaction.response_headers =
2083      "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2084      "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2085      "Etag: \"foopy\"\n"
2086      "Cache-Control: max-age=0\n"
2087      "Vary: Foo\n";
2088  AddMockTransaction(&transaction);
2089  RunTransactionTest(cache.http_cache(), transaction);
2090
2091  // Read from the cache.
2092  RevalidationServer server;
2093  transaction.handler = server.Handler;
2094  net::CapturingBoundNetLog log;
2095  net::LoadTimingInfo load_timing_info;
2096  RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2097                                 &load_timing_info);
2098
2099  EXPECT_TRUE(server.EtagUsed());
2100  EXPECT_TRUE(server.LastModifiedUsed());
2101  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2102  EXPECT_EQ(1, cache.disk_cache()->open_count());
2103  EXPECT_EQ(1, cache.disk_cache()->create_count());
2104  TestLoadTimingNetworkRequest(load_timing_info);
2105  RemoveMockTransaction(&transaction);
2106}
2107
2108// Tests revalidation after a vary mismatch if etag is present.
2109TEST(HttpCache, SimpleGET_LoadValidateCache_VaryMismatch) {
2110  MockHttpCache cache;
2111
2112  // Write to the cache.
2113  MockTransaction transaction(kTypicalGET_Transaction);
2114  transaction.request_headers = "Foo: bar\r\n";
2115  transaction.response_headers =
2116      "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2117      "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2118      "Etag: \"foopy\"\n"
2119      "Cache-Control: max-age=0\n"
2120      "Vary: Foo\n";
2121  AddMockTransaction(&transaction);
2122  RunTransactionTest(cache.http_cache(), transaction);
2123
2124  // Read from the cache and revalidate the entry.
2125  RevalidationServer server;
2126  transaction.handler = server.Handler;
2127  transaction.request_headers = "Foo: none\r\n";
2128  net::CapturingBoundNetLog log;
2129  net::LoadTimingInfo load_timing_info;
2130  RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2131                                 &load_timing_info);
2132
2133  EXPECT_TRUE(server.EtagUsed());
2134  EXPECT_FALSE(server.LastModifiedUsed());
2135  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2136  EXPECT_EQ(1, cache.disk_cache()->open_count());
2137  EXPECT_EQ(1, cache.disk_cache()->create_count());
2138  TestLoadTimingNetworkRequest(load_timing_info);
2139  RemoveMockTransaction(&transaction);
2140}
2141
2142// Tests lack of revalidation after a vary mismatch and no etag.
2143TEST(HttpCache, SimpleGET_LoadDontValidateCache_VaryMismatch) {
2144  MockHttpCache cache;
2145
2146  // Write to the cache.
2147  MockTransaction transaction(kTypicalGET_Transaction);
2148  transaction.request_headers = "Foo: bar\r\n";
2149  transaction.response_headers =
2150      "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
2151      "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2152      "Cache-Control: max-age=0\n"
2153      "Vary: Foo\n";
2154  AddMockTransaction(&transaction);
2155  RunTransactionTest(cache.http_cache(), transaction);
2156
2157  // Read from the cache and don't revalidate the entry.
2158  RevalidationServer server;
2159  transaction.handler = server.Handler;
2160  transaction.request_headers = "Foo: none\r\n";
2161  net::CapturingBoundNetLog log;
2162  net::LoadTimingInfo load_timing_info;
2163  RunTransactionTestAndGetTiming(cache.http_cache(), transaction, log.bound(),
2164                                 &load_timing_info);
2165
2166  EXPECT_FALSE(server.EtagUsed());
2167  EXPECT_FALSE(server.LastModifiedUsed());
2168  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2169  EXPECT_EQ(1, cache.disk_cache()->open_count());
2170  EXPECT_EQ(1, cache.disk_cache()->create_count());
2171  TestLoadTimingNetworkRequest(load_timing_info);
2172  RemoveMockTransaction(&transaction);
2173}
2174
2175static void ETagGet_UnconditionalRequest_Handler(
2176    const net::HttpRequestInfo* request,
2177    std::string* response_status,
2178    std::string* response_headers,
2179    std::string* response_data) {
2180  EXPECT_FALSE(
2181      request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
2182}
2183
2184TEST(HttpCache, ETagGET_Http10) {
2185  MockHttpCache cache;
2186
2187  ScopedMockTransaction transaction(kETagGET_Transaction);
2188  transaction.status = "HTTP/1.0 200 OK";
2189
2190  // Write to the cache.
2191  RunTransactionTest(cache.http_cache(), transaction);
2192
2193  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2194  EXPECT_EQ(0, cache.disk_cache()->open_count());
2195  EXPECT_EQ(1, cache.disk_cache()->create_count());
2196
2197  // Get the same URL again, without generating a conditional request.
2198  transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2199  transaction.handler = ETagGet_UnconditionalRequest_Handler;
2200  RunTransactionTest(cache.http_cache(), transaction);
2201
2202  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2203  EXPECT_EQ(1, cache.disk_cache()->open_count());
2204  EXPECT_EQ(1, cache.disk_cache()->create_count());
2205}
2206
2207TEST(HttpCache, ETagGET_Http10_Range) {
2208  MockHttpCache cache;
2209
2210  ScopedMockTransaction transaction(kETagGET_Transaction);
2211  transaction.status = "HTTP/1.0 200 OK";
2212
2213  // Write to the cache.
2214  RunTransactionTest(cache.http_cache(), transaction);
2215
2216  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2217  EXPECT_EQ(0, cache.disk_cache()->open_count());
2218  EXPECT_EQ(1, cache.disk_cache()->create_count());
2219
2220  // Get the same URL again, but use a byte range request.
2221  transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2222  transaction.handler = ETagGet_UnconditionalRequest_Handler;
2223  transaction.request_headers = "Range: bytes = 5-\r\n";
2224  RunTransactionTest(cache.http_cache(), transaction);
2225
2226  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2227  EXPECT_EQ(1, cache.disk_cache()->open_count());
2228  EXPECT_EQ(2, cache.disk_cache()->create_count());
2229}
2230
2231static void ETagGet_ConditionalRequest_NoStore_Handler(
2232    const net::HttpRequestInfo* request,
2233    std::string* response_status,
2234    std::string* response_headers,
2235    std::string* response_data) {
2236  EXPECT_TRUE(
2237      request->extra_headers.HasHeader(net::HttpRequestHeaders::kIfNoneMatch));
2238  response_status->assign("HTTP/1.1 304 Not Modified");
2239  response_headers->assign("Cache-Control: no-store\n");
2240  response_data->clear();
2241}
2242
2243TEST(HttpCache, ETagGET_ConditionalRequest_304_NoStore) {
2244  MockHttpCache cache;
2245
2246  ScopedMockTransaction transaction(kETagGET_Transaction);
2247
2248  // Write to the cache.
2249  RunTransactionTest(cache.http_cache(), transaction);
2250
2251  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2252  EXPECT_EQ(0, cache.disk_cache()->open_count());
2253  EXPECT_EQ(1, cache.disk_cache()->create_count());
2254
2255  // Get the same URL again, but this time we expect it to result
2256  // in a conditional request.
2257  transaction.load_flags = net::LOAD_VALIDATE_CACHE;
2258  transaction.handler = ETagGet_ConditionalRequest_NoStore_Handler;
2259  RunTransactionTest(cache.http_cache(), transaction);
2260
2261  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2262  EXPECT_EQ(1, cache.disk_cache()->open_count());
2263  EXPECT_EQ(1, cache.disk_cache()->create_count());
2264
2265  ScopedMockTransaction transaction2(kETagGET_Transaction);
2266
2267  // Write to the cache again. This should create a new entry.
2268  RunTransactionTest(cache.http_cache(), transaction2);
2269
2270  EXPECT_EQ(3, cache.network_layer()->transaction_count());
2271  EXPECT_EQ(1, cache.disk_cache()->open_count());
2272  EXPECT_EQ(2, cache.disk_cache()->create_count());
2273}
2274
2275// Helper that does 4 requests using HttpCache:
2276//
2277// (1) loads |kUrl| -- expects |net_response_1| to be returned.
2278// (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
2279// (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
2280//     be returned.
2281// (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
2282//     returned.
2283static void ConditionalizedRequestUpdatesCacheHelper(
2284    const Response& net_response_1,
2285    const Response& net_response_2,
2286    const Response& cached_response_2,
2287    const char* extra_request_headers) {
2288  MockHttpCache cache;
2289
2290  // The URL we will be requesting.
2291  const char* kUrl = "http://foobar.com/main.css";
2292
2293  // Junk network response.
2294  static const Response kUnexpectedResponse = {
2295    "HTTP/1.1 500 Unexpected",
2296    "Server: unexpected_header",
2297    "unexpected body"
2298  };
2299
2300  // We will control the network layer's responses for |kUrl| using
2301  // |mock_network_response|.
2302  MockTransaction mock_network_response = { 0 };
2303  mock_network_response.url = kUrl;
2304  AddMockTransaction(&mock_network_response);
2305
2306  // Request |kUrl| for the first time. It should hit the network and
2307  // receive |kNetResponse1|, which it saves into the HTTP cache.
2308
2309  MockTransaction request = { 0 };
2310  request.url = kUrl;
2311  request.method = "GET";
2312  request.request_headers = "";
2313
2314  net_response_1.AssignTo(&mock_network_response);  // Network mock.
2315  net_response_1.AssignTo(&request);                // Expected result.
2316
2317  std::string response_headers;
2318  RunTransactionTestWithResponse(
2319      cache.http_cache(), request, &response_headers);
2320
2321  EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
2322  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2323  EXPECT_EQ(0, cache.disk_cache()->open_count());
2324  EXPECT_EQ(1, cache.disk_cache()->create_count());
2325
2326  // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
2327  // cache, so we don't hit the network.
2328
2329  request.load_flags = net::LOAD_ONLY_FROM_CACHE;
2330
2331  kUnexpectedResponse.AssignTo(&mock_network_response);  // Network mock.
2332  net_response_1.AssignTo(&request);                     // Expected result.
2333
2334  RunTransactionTestWithResponse(
2335      cache.http_cache(), request, &response_headers);
2336
2337  EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
2338  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2339  EXPECT_EQ(1, cache.disk_cache()->open_count());
2340  EXPECT_EQ(1, cache.disk_cache()->create_count());
2341
2342  // Request |kUrl| yet again, but this time give the request an
2343  // "If-Modified-Since" header. This will cause the request to re-hit the
2344  // network. However now the network response is going to be
2345  // different -- this simulates a change made to the CSS file.
2346
2347  request.request_headers = extra_request_headers;
2348  request.load_flags = net::LOAD_NORMAL;
2349
2350  net_response_2.AssignTo(&mock_network_response);  // Network mock.
2351  net_response_2.AssignTo(&request);                // Expected result.
2352
2353  RunTransactionTestWithResponse(
2354      cache.http_cache(), request, &response_headers);
2355
2356  EXPECT_EQ(net_response_2.status_and_headers(), response_headers);
2357  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2358  EXPECT_EQ(1, cache.disk_cache()->open_count());
2359  EXPECT_EQ(1, cache.disk_cache()->create_count());
2360
2361  // Finally, request |kUrl| again. This request should be serviced from
2362  // the cache. Moreover, the value in the cache should be |kNetResponse2|
2363  // and NOT |kNetResponse1|. The previous step should have replaced the
2364  // value in the cache with the modified response.
2365
2366  request.request_headers = "";
2367  request.load_flags = net::LOAD_ONLY_FROM_CACHE;
2368
2369  kUnexpectedResponse.AssignTo(&mock_network_response);  // Network mock.
2370  cached_response_2.AssignTo(&request);                  // Expected result.
2371
2372  RunTransactionTestWithResponse(
2373      cache.http_cache(), request, &response_headers);
2374
2375  EXPECT_EQ(cached_response_2.status_and_headers(), response_headers);
2376  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2377  EXPECT_EQ(2, cache.disk_cache()->open_count());
2378  EXPECT_EQ(1, cache.disk_cache()->create_count());
2379
2380  RemoveMockTransaction(&mock_network_response);
2381}
2382
2383// Check that when an "if-modified-since" header is attached
2384// to the request, the result still updates the cached entry.
2385TEST(HttpCache, ConditionalizedRequestUpdatesCache1) {
2386  // First network response for |kUrl|.
2387  static const Response kNetResponse1 = {
2388    "HTTP/1.1 200 OK",
2389    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2390    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2391    "body1"
2392  };
2393
2394  // Second network response for |kUrl|.
2395  static const Response kNetResponse2 = {
2396    "HTTP/1.1 200 OK",
2397    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2398    "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2399    "body2"
2400  };
2401
2402  const char* extra_headers =
2403      "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2404
2405  ConditionalizedRequestUpdatesCacheHelper(
2406      kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2407}
2408
2409// Check that when an "if-none-match" header is attached
2410// to the request, the result updates the cached entry.
2411TEST(HttpCache, ConditionalizedRequestUpdatesCache2) {
2412  // First network response for |kUrl|.
2413  static const Response kNetResponse1 = {
2414    "HTTP/1.1 200 OK",
2415    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2416    "Etag: \"ETAG1\"\n"
2417    "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n",  // Should never expire.
2418    "body1"
2419  };
2420
2421  // Second network response for |kUrl|.
2422  static const Response kNetResponse2 = {
2423    "HTTP/1.1 200 OK",
2424    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2425    "Etag: \"ETAG2\"\n"
2426    "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n",  // Should never expire.
2427    "body2"
2428  };
2429
2430  const char* extra_headers = "If-None-Match: \"ETAG1\"\r\n";
2431
2432  ConditionalizedRequestUpdatesCacheHelper(
2433      kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
2434}
2435
2436// Check that when an "if-modified-since" header is attached
2437// to a request, the 304 (not modified result) result updates the cached
2438// headers, and the 304 response is returned rather than the cached response.
2439TEST(HttpCache, ConditionalizedRequestUpdatesCache3) {
2440  // First network response for |kUrl|.
2441  static const Response kNetResponse1 = {
2442    "HTTP/1.1 200 OK",
2443    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2444    "Server: server1\n"
2445    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2446    "body1"
2447  };
2448
2449  // Second network response for |kUrl|.
2450  static const Response kNetResponse2 = {
2451    "HTTP/1.1 304 Not Modified",
2452    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2453    "Server: server2\n"
2454    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2455    ""
2456  };
2457
2458  static const Response kCachedResponse2 = {
2459    "HTTP/1.1 200 OK",
2460    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2461    "Server: server2\n"
2462    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2463    "body1"
2464  };
2465
2466  const char* extra_headers =
2467      "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2468
2469  ConditionalizedRequestUpdatesCacheHelper(
2470      kNetResponse1, kNetResponse2, kCachedResponse2, extra_headers);
2471}
2472
2473// Test that when doing an externally conditionalized if-modified-since
2474// and there is no corresponding cache entry, a new cache entry is NOT
2475// created (304 response).
2476TEST(HttpCache, ConditionalizedRequestUpdatesCache4) {
2477  MockHttpCache cache;
2478
2479  const char* kUrl = "http://foobar.com/main.css";
2480
2481  static const Response kNetResponse = {
2482    "HTTP/1.1 304 Not Modified",
2483    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2484    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2485    ""
2486  };
2487
2488  const char* kExtraRequestHeaders =
2489      "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2490
2491  // We will control the network layer's responses for |kUrl| using
2492  // |mock_network_response|.
2493  MockTransaction mock_network_response = { 0 };
2494  mock_network_response.url = kUrl;
2495  AddMockTransaction(&mock_network_response);
2496
2497  MockTransaction request = { 0 };
2498  request.url = kUrl;
2499  request.method = "GET";
2500  request.request_headers = kExtraRequestHeaders;
2501
2502  kNetResponse.AssignTo(&mock_network_response);  // Network mock.
2503  kNetResponse.AssignTo(&request);                // Expected result.
2504
2505  std::string response_headers;
2506  RunTransactionTestWithResponse(
2507      cache.http_cache(), request, &response_headers);
2508
2509  EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2510  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2511  EXPECT_EQ(0, cache.disk_cache()->open_count());
2512  EXPECT_EQ(0, cache.disk_cache()->create_count());
2513
2514  RemoveMockTransaction(&mock_network_response);
2515}
2516
2517// Test that when doing an externally conditionalized if-modified-since
2518// and there is no corresponding cache entry, a new cache entry is NOT
2519// created (200 response).
2520TEST(HttpCache, ConditionalizedRequestUpdatesCache5) {
2521  MockHttpCache cache;
2522
2523  const char* kUrl = "http://foobar.com/main.css";
2524
2525  static const Response kNetResponse = {
2526    "HTTP/1.1 200 OK",
2527    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2528    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2529    "foobar!!!"
2530  };
2531
2532  const char* kExtraRequestHeaders =
2533      "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
2534
2535  // We will control the network layer's responses for |kUrl| using
2536  // |mock_network_response|.
2537  MockTransaction mock_network_response = { 0 };
2538  mock_network_response.url = kUrl;
2539  AddMockTransaction(&mock_network_response);
2540
2541  MockTransaction request = { 0 };
2542  request.url = kUrl;
2543  request.method = "GET";
2544  request.request_headers = kExtraRequestHeaders;
2545
2546  kNetResponse.AssignTo(&mock_network_response);  // Network mock.
2547  kNetResponse.AssignTo(&request);                // Expected result.
2548
2549  std::string response_headers;
2550  RunTransactionTestWithResponse(
2551      cache.http_cache(), request, &response_headers);
2552
2553  EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
2554  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2555  EXPECT_EQ(0, cache.disk_cache()->open_count());
2556  EXPECT_EQ(0, cache.disk_cache()->create_count());
2557
2558  RemoveMockTransaction(&mock_network_response);
2559}
2560
2561// Test that when doing an externally conditionalized if-modified-since
2562// if the date does not match the cache entry's last-modified date,
2563// then we do NOT use the response (304) to update the cache.
2564// (the if-modified-since date is 2 days AFTER the cache's modification date).
2565TEST(HttpCache, ConditionalizedRequestUpdatesCache6) {
2566  static const Response kNetResponse1 = {
2567    "HTTP/1.1 200 OK",
2568    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2569    "Server: server1\n"
2570    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2571    "body1"
2572  };
2573
2574  // Second network response for |kUrl|.
2575  static const Response kNetResponse2 = {
2576    "HTTP/1.1 304 Not Modified",
2577    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2578    "Server: server2\n"
2579    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2580    ""
2581  };
2582
2583  // This is two days in the future from the original response's last-modified
2584  // date!
2585  const char* kExtraRequestHeaders =
2586      "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
2587
2588  ConditionalizedRequestUpdatesCacheHelper(
2589      kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2590}
2591
2592// Test that when doing an externally conditionalized if-none-match
2593// if the etag does not match the cache entry's etag, then we do not use the
2594// response (304) to update the cache.
2595TEST(HttpCache, ConditionalizedRequestUpdatesCache7) {
2596  static const Response kNetResponse1 = {
2597    "HTTP/1.1 200 OK",
2598    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2599    "Etag: \"Foo1\"\n"
2600    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2601    "body1"
2602  };
2603
2604  // Second network response for |kUrl|.
2605  static const Response kNetResponse2 = {
2606    "HTTP/1.1 304 Not Modified",
2607    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2608    "Etag: \"Foo2\"\n"
2609    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2610    ""
2611  };
2612
2613  // Different etag from original response.
2614  const char* kExtraRequestHeaders = "If-None-Match: \"Foo2\"\r\n";
2615
2616  ConditionalizedRequestUpdatesCacheHelper(
2617      kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2618}
2619
2620// Test that doing an externally conditionalized request with both if-none-match
2621// and if-modified-since updates the cache.
2622TEST(HttpCache, ConditionalizedRequestUpdatesCache8) {
2623  static const Response kNetResponse1 = {
2624    "HTTP/1.1 200 OK",
2625    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2626    "Etag: \"Foo1\"\n"
2627    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2628    "body1"
2629  };
2630
2631  // Second network response for |kUrl|.
2632  static const Response kNetResponse2 = {
2633    "HTTP/1.1 200 OK",
2634    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2635    "Etag: \"Foo2\"\n"
2636    "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2637    "body2"
2638  };
2639
2640  const char* kExtraRequestHeaders =
2641      "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2642      "If-None-Match: \"Foo1\"\r\n";
2643
2644  ConditionalizedRequestUpdatesCacheHelper(
2645      kNetResponse1, kNetResponse2, kNetResponse2, kExtraRequestHeaders);
2646}
2647
2648// Test that doing an externally conditionalized request with both if-none-match
2649// and if-modified-since does not update the cache with only one match.
2650TEST(HttpCache, ConditionalizedRequestUpdatesCache9) {
2651  static const Response kNetResponse1 = {
2652    "HTTP/1.1 200 OK",
2653    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2654    "Etag: \"Foo1\"\n"
2655    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2656    "body1"
2657  };
2658
2659  // Second network response for |kUrl|.
2660  static const Response kNetResponse2 = {
2661    "HTTP/1.1 200 OK",
2662    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2663    "Etag: \"Foo2\"\n"
2664    "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2665    "body2"
2666  };
2667
2668  // The etag doesn't match what we have stored.
2669  const char* kExtraRequestHeaders =
2670      "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
2671      "If-None-Match: \"Foo2\"\r\n";
2672
2673  ConditionalizedRequestUpdatesCacheHelper(
2674      kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2675}
2676
2677// Test that doing an externally conditionalized request with both if-none-match
2678// and if-modified-since does not update the cache with only one match.
2679TEST(HttpCache, ConditionalizedRequestUpdatesCache10) {
2680  static const Response kNetResponse1 = {
2681    "HTTP/1.1 200 OK",
2682    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
2683    "Etag: \"Foo1\"\n"
2684    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
2685    "body1"
2686  };
2687
2688  // Second network response for |kUrl|.
2689  static const Response kNetResponse2 = {
2690    "HTTP/1.1 200 OK",
2691    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
2692    "Etag: \"Foo2\"\n"
2693    "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
2694    "body2"
2695  };
2696
2697  // The modification date doesn't match what we have stored.
2698  const char* kExtraRequestHeaders =
2699      "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
2700      "If-None-Match: \"Foo1\"\r\n";
2701
2702  ConditionalizedRequestUpdatesCacheHelper(
2703      kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
2704}
2705
2706TEST(HttpCache, UrlContainingHash) {
2707  MockHttpCache cache;
2708
2709  // Do a typical GET request -- should write an entry into our cache.
2710  MockTransaction trans(kTypicalGET_Transaction);
2711  RunTransactionTest(cache.http_cache(), trans);
2712
2713  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2714  EXPECT_EQ(0, cache.disk_cache()->open_count());
2715  EXPECT_EQ(1, cache.disk_cache()->create_count());
2716
2717  // Request the same URL, but this time with a reference section (hash).
2718  // Since the cache key strips the hash sections, this should be a cache hit.
2719  std::string url_with_hash = std::string(trans.url) + "#multiple#hashes";
2720  trans.url = url_with_hash.c_str();
2721  trans.load_flags = net::LOAD_ONLY_FROM_CACHE;
2722
2723  RunTransactionTest(cache.http_cache(), trans);
2724
2725  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2726  EXPECT_EQ(1, cache.disk_cache()->open_count());
2727  EXPECT_EQ(1, cache.disk_cache()->create_count());
2728}
2729
2730// Tests that we skip the cache for POST requests that do not have an upload
2731// identifier.
2732TEST(HttpCache, SimplePOST_SkipsCache) {
2733  MockHttpCache cache;
2734
2735  RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
2736
2737  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2738  EXPECT_EQ(0, cache.disk_cache()->open_count());
2739  EXPECT_EQ(0, cache.disk_cache()->create_count());
2740}
2741
2742TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Miss) {
2743  MockHttpCache cache;
2744
2745  MockTransaction transaction(kSimplePOST_Transaction);
2746  transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
2747
2748  MockHttpRequest request(transaction);
2749  net::TestCompletionCallback callback;
2750
2751  scoped_ptr<net::HttpTransaction> trans;
2752  ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
2753  ASSERT_TRUE(trans.get());
2754
2755  int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
2756  ASSERT_EQ(net::ERR_CACHE_MISS, callback.GetResult(rv));
2757
2758  trans.reset();
2759
2760  EXPECT_EQ(0, cache.network_layer()->transaction_count());
2761  EXPECT_EQ(0, cache.disk_cache()->open_count());
2762  EXPECT_EQ(0, cache.disk_cache()->create_count());
2763}
2764
2765TEST(HttpCache, SimplePOST_LoadOnlyFromCache_Hit) {
2766  MockHttpCache cache;
2767
2768  // Test that we hit the cache for POST requests.
2769
2770  MockTransaction transaction(kSimplePOST_Transaction);
2771
2772  const int64 kUploadId = 1;  // Just a dummy value.
2773
2774  ScopedVector<net::UploadElementReader> element_readers;
2775  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2776  net::UploadDataStream upload_data_stream(element_readers.Pass(), kUploadId);
2777  MockHttpRequest request(transaction);
2778  request.upload_data_stream = &upload_data_stream;
2779
2780  // Populate the cache.
2781  RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2782
2783  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2784  EXPECT_EQ(0, cache.disk_cache()->open_count());
2785  EXPECT_EQ(1, cache.disk_cache()->create_count());
2786
2787  // Load from cache.
2788  request.load_flags |= net::LOAD_ONLY_FROM_CACHE;
2789  RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2790
2791  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2792  EXPECT_EQ(1, cache.disk_cache()->open_count());
2793  EXPECT_EQ(1, cache.disk_cache()->create_count());
2794}
2795
2796// Test that we don't hit the cache for POST requests if there is a byte range.
2797TEST(HttpCache, SimplePOST_WithRanges) {
2798  MockHttpCache cache;
2799
2800  MockTransaction transaction(kSimplePOST_Transaction);
2801  transaction.request_headers = "Range: bytes = 0-4\r\n";
2802
2803  const int64 kUploadId = 1;  // Just a dummy value.
2804
2805  ScopedVector<net::UploadElementReader> element_readers;
2806  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2807  net::UploadDataStream upload_data_stream(element_readers.Pass(), kUploadId);
2808
2809  MockHttpRequest request(transaction);
2810  request.upload_data_stream = &upload_data_stream;
2811
2812  // Attempt to populate the cache.
2813  RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
2814
2815  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2816  EXPECT_EQ(0, cache.disk_cache()->open_count());
2817  EXPECT_EQ(0, cache.disk_cache()->create_count());
2818}
2819
2820// Tests that a POST is cached separately from a previously cached GET.
2821TEST(HttpCache, SimplePOST_SeparateCache) {
2822  MockHttpCache cache;
2823
2824  ScopedVector<net::UploadElementReader> element_readers;
2825  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2826  net::UploadDataStream upload_data_stream(element_readers.Pass(), 1);
2827
2828  MockTransaction transaction(kSimplePOST_Transaction);
2829  MockHttpRequest req1(transaction);
2830  req1.upload_data_stream = &upload_data_stream;
2831
2832  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2833
2834  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2835  EXPECT_EQ(0, cache.disk_cache()->open_count());
2836  EXPECT_EQ(1, cache.disk_cache()->create_count());
2837
2838  transaction.method = "GET";
2839  MockHttpRequest req2(transaction);
2840
2841  RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2842
2843  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2844  EXPECT_EQ(0, cache.disk_cache()->open_count());
2845  EXPECT_EQ(2, cache.disk_cache()->create_count());
2846}
2847
2848// Tests that a successful POST invalidates a previously cached GET.
2849TEST(HttpCache, SimplePOST_Invalidate_205) {
2850  MockHttpCache cache;
2851
2852  MockTransaction transaction(kSimpleGET_Transaction);
2853  AddMockTransaction(&transaction);
2854  MockHttpRequest req1(transaction);
2855
2856  // Attempt to populate the cache.
2857  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2858
2859  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2860  EXPECT_EQ(0, cache.disk_cache()->open_count());
2861  EXPECT_EQ(1, cache.disk_cache()->create_count());
2862
2863  ScopedVector<net::UploadElementReader> element_readers;
2864  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2865  net::UploadDataStream upload_data_stream(element_readers.Pass(), 1);
2866
2867  transaction.method = "POST";
2868  transaction.status = "HTTP/1.1 205 No Content";
2869  MockHttpRequest req2(transaction);
2870  req2.upload_data_stream = &upload_data_stream;
2871
2872  RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2873
2874  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2875  EXPECT_EQ(0, cache.disk_cache()->open_count());
2876  EXPECT_EQ(2, cache.disk_cache()->create_count());
2877
2878  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2879
2880  EXPECT_EQ(3, cache.network_layer()->transaction_count());
2881  EXPECT_EQ(0, cache.disk_cache()->open_count());
2882  EXPECT_EQ(3, cache.disk_cache()->create_count());
2883  RemoveMockTransaction(&transaction);
2884}
2885
2886// Tests that a successful POST invalidates a previously cached GET, even when
2887// there is no upload identifier.
2888TEST(HttpCache, SimplePOST_NoUploadId_Invalidate_205) {
2889  MockHttpCache cache;
2890
2891  MockTransaction transaction(kSimpleGET_Transaction);
2892  AddMockTransaction(&transaction);
2893  MockHttpRequest req1(transaction);
2894
2895  // Attempt to populate the cache.
2896  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2897
2898  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2899  EXPECT_EQ(0, cache.disk_cache()->open_count());
2900  EXPECT_EQ(1, cache.disk_cache()->create_count());
2901
2902  ScopedVector<net::UploadElementReader> element_readers;
2903  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2904  net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
2905
2906  transaction.method = "POST";
2907  transaction.status = "HTTP/1.1 205 No Content";
2908  MockHttpRequest req2(transaction);
2909  req2.upload_data_stream = &upload_data_stream;
2910
2911  RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2912
2913  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2914  EXPECT_EQ(0, cache.disk_cache()->open_count());
2915  EXPECT_EQ(1, cache.disk_cache()->create_count());
2916
2917  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2918
2919  EXPECT_EQ(3, cache.network_layer()->transaction_count());
2920  EXPECT_EQ(0, cache.disk_cache()->open_count());
2921  EXPECT_EQ(2, cache.disk_cache()->create_count());
2922  RemoveMockTransaction(&transaction);
2923}
2924
2925// Tests that processing a POST before creating the backend doesn't crash.
2926TEST(HttpCache, SimplePOST_NoUploadId_NoBackend) {
2927  // This will initialize a cache object with NULL backend.
2928  MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
2929  factory->set_fail(true);
2930  factory->FinishCreation();
2931  MockHttpCache cache(factory);
2932
2933  ScopedVector<net::UploadElementReader> element_readers;
2934  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2935  net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
2936
2937  MockTransaction transaction(kSimplePOST_Transaction);
2938  AddMockTransaction(&transaction);
2939  MockHttpRequest req(transaction);
2940  req.upload_data_stream = &upload_data_stream;
2941
2942  RunTransactionTestWithRequest(cache.http_cache(), transaction, req, NULL);
2943
2944  RemoveMockTransaction(&transaction);
2945}
2946
2947// Tests that we don't invalidate entries as a result of a failed POST.
2948TEST(HttpCache, SimplePOST_DontInvalidate_100) {
2949  MockHttpCache cache;
2950
2951  MockTransaction transaction(kSimpleGET_Transaction);
2952  AddMockTransaction(&transaction);
2953  MockHttpRequest req1(transaction);
2954
2955  // Attempt to populate the cache.
2956  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2957
2958  EXPECT_EQ(1, cache.network_layer()->transaction_count());
2959  EXPECT_EQ(0, cache.disk_cache()->open_count());
2960  EXPECT_EQ(1, cache.disk_cache()->create_count());
2961
2962  ScopedVector<net::UploadElementReader> element_readers;
2963  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
2964  net::UploadDataStream upload_data_stream(element_readers.Pass(), 1);
2965
2966  transaction.method = "POST";
2967  transaction.status = "HTTP/1.1 100 Continue";
2968  MockHttpRequest req2(transaction);
2969  req2.upload_data_stream = &upload_data_stream;
2970
2971  RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
2972
2973  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2974  EXPECT_EQ(0, cache.disk_cache()->open_count());
2975  EXPECT_EQ(2, cache.disk_cache()->create_count());
2976
2977  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
2978
2979  EXPECT_EQ(2, cache.network_layer()->transaction_count());
2980  EXPECT_EQ(1, cache.disk_cache()->open_count());
2981  EXPECT_EQ(2, cache.disk_cache()->create_count());
2982  RemoveMockTransaction(&transaction);
2983}
2984
2985// Tests that a HEAD request is not cached by itself.
2986TEST(HttpCache, SimpleHEAD_LoadOnlyFromCache_Miss) {
2987  MockHttpCache cache;
2988  MockTransaction transaction(kSimplePOST_Transaction);
2989  AddMockTransaction(&transaction);
2990  transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
2991  transaction.method = "HEAD";
2992
2993  MockHttpRequest request(transaction);
2994  net::TestCompletionCallback callback;
2995
2996  scoped_ptr<net::HttpTransaction> trans;
2997  ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
2998  ASSERT_TRUE(trans.get());
2999
3000  int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
3001  ASSERT_EQ(net::ERR_CACHE_MISS, callback.GetResult(rv));
3002
3003  trans.reset();
3004
3005  EXPECT_EQ(0, cache.network_layer()->transaction_count());
3006  EXPECT_EQ(0, cache.disk_cache()->open_count());
3007  EXPECT_EQ(0, cache.disk_cache()->create_count());
3008  RemoveMockTransaction(&transaction);
3009}
3010
3011// Tests that a HEAD request is served from a cached GET.
3012TEST(HttpCache, SimpleHEAD_LoadOnlyFromCache_Hit) {
3013  MockHttpCache cache;
3014  MockTransaction transaction(kSimpleGET_Transaction);
3015  AddMockTransaction(&transaction);
3016
3017  // Populate the cache.
3018  RunTransactionTest(cache.http_cache(), transaction);
3019
3020  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3021  EXPECT_EQ(0, cache.disk_cache()->open_count());
3022  EXPECT_EQ(1, cache.disk_cache()->create_count());
3023
3024  // Load from cache.
3025  transaction.method = "HEAD";
3026  transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3027  transaction.data = "";
3028  RunTransactionTest(cache.http_cache(), transaction);
3029
3030  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3031  EXPECT_EQ(1, cache.disk_cache()->open_count());
3032  EXPECT_EQ(1, cache.disk_cache()->create_count());
3033  RemoveMockTransaction(&transaction);
3034}
3035
3036// Tests that a read-only request served from the cache preserves CL.
3037TEST(HttpCache, SimpleHEAD_ContentLengthOnHit_Read) {
3038  MockHttpCache cache;
3039  MockTransaction transaction(kSimpleGET_Transaction);
3040  AddMockTransaction(&transaction);
3041  transaction.response_headers = "Content-Length: 42\n";
3042
3043  // Populate the cache.
3044  RunTransactionTest(cache.http_cache(), transaction);
3045
3046  // Load from cache.
3047  transaction.method = "HEAD";
3048  transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3049  transaction.data = "";
3050  std::string headers;
3051
3052  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3053
3054  EXPECT_EQ("HTTP/1.1 200 OK\nContent-Length: 42\n", headers);
3055  RemoveMockTransaction(&transaction);
3056}
3057
3058// Tests that a read-write request served from the cache preserves CL.
3059TEST(HttpCache, ETagHEAD_ContentLengthOnHit_ReadWrite) {
3060  MockHttpCache cache;
3061  MockTransaction transaction(kETagGET_Transaction);
3062  AddMockTransaction(&transaction);
3063  std::string server_headers(kETagGET_Transaction.response_headers);
3064  server_headers.append("Content-Length: 42\n");
3065  transaction.response_headers = server_headers.data();
3066
3067  // Populate the cache.
3068  RunTransactionTest(cache.http_cache(), transaction);
3069
3070  // Load from cache.
3071  transaction.method = "HEAD";
3072  transaction.data = "";
3073  std::string headers;
3074
3075  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3076
3077  EXPECT_NE(std::string::npos, headers.find("Content-Length: 42\n"));
3078  RemoveMockTransaction(&transaction);
3079}
3080
3081// Tests that a HEAD request that includes byte ranges bypasses the cache.
3082TEST(HttpCache, SimpleHEAD_WithRanges) {
3083  MockHttpCache cache;
3084  MockTransaction transaction(kSimpleGET_Transaction);
3085  AddMockTransaction(&transaction);
3086
3087  // Populate the cache.
3088  RunTransactionTest(cache.http_cache(), transaction);
3089
3090  // Load from cache.
3091  transaction.method = "HEAD";
3092  transaction.request_headers = "Range: bytes = 0-4\r\n";
3093  transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3094  transaction.return_code = net::ERR_CACHE_MISS;
3095  RunTransactionTest(cache.http_cache(), transaction);
3096
3097  EXPECT_EQ(0, cache.disk_cache()->open_count());
3098  EXPECT_EQ(1, cache.disk_cache()->create_count());
3099  RemoveMockTransaction(&transaction);
3100}
3101
3102// Tests that a HEAD request can be served from a partialy cached resource.
3103TEST(HttpCache, SimpleHEAD_WithCachedRanges) {
3104  MockHttpCache cache;
3105  AddMockTransaction(&kRangeGET_TransactionOK);
3106
3107  // Write to the cache (40-49).
3108  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
3109  RemoveMockTransaction(&kRangeGET_TransactionOK);
3110
3111  MockTransaction transaction(kSimpleGET_Transaction);
3112
3113  transaction.url = kRangeGET_TransactionOK.url;
3114  transaction.method = "HEAD";
3115  transaction.data = "";
3116  AddMockTransaction(&transaction);
3117  std::string headers;
3118
3119  // Load from cache.
3120  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3121
3122  EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
3123  EXPECT_EQ(std::string::npos, headers.find("Content-Length"));
3124  EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
3125  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3126  EXPECT_EQ(1, cache.disk_cache()->open_count());
3127  EXPECT_EQ(1, cache.disk_cache()->create_count());
3128  RemoveMockTransaction(&transaction);
3129}
3130
3131// Tests that a HEAD request can be served from a truncated resource.
3132TEST(HttpCache, SimpleHEAD_WithTruncatedEntry) {
3133  MockHttpCache cache;
3134  AddMockTransaction(&kRangeGET_TransactionOK);
3135
3136  std::string raw_headers("HTTP/1.1 200 OK\n"
3137                          "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
3138                          "ETag: \"foo\"\n"
3139                          "Accept-Ranges: bytes\n"
3140                          "Content-Length: 80\n");
3141  CreateTruncatedEntry(raw_headers, &cache);
3142  RemoveMockTransaction(&kRangeGET_TransactionOK);
3143
3144  MockTransaction transaction(kSimpleGET_Transaction);
3145
3146  transaction.url = kRangeGET_TransactionOK.url;
3147  transaction.method = "HEAD";
3148  transaction.data = "";
3149  AddMockTransaction(&transaction);
3150  std::string headers;
3151
3152  // Load from cache.
3153  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3154
3155  EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
3156  EXPECT_NE(std::string::npos, headers.find("Content-Length: 80\n"));
3157  EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
3158  EXPECT_EQ(0, cache.network_layer()->transaction_count());
3159  EXPECT_EQ(1, cache.disk_cache()->open_count());
3160  EXPECT_EQ(1, cache.disk_cache()->create_count());
3161  RemoveMockTransaction(&transaction);
3162}
3163
3164// Tests that a HEAD request updates the cached response.
3165TEST(HttpCache, TypicalHEAD_UpdatesResponse) {
3166  MockHttpCache cache;
3167  MockTransaction transaction(kTypicalGET_Transaction);
3168  AddMockTransaction(&transaction);
3169
3170  // Populate the cache.
3171  RunTransactionTest(cache.http_cache(), transaction);
3172
3173  // Update the cache.
3174  transaction.method = "HEAD";
3175  transaction.response_headers = "Foo: bar\n";
3176  transaction.data = "";
3177  transaction.status = "HTTP/1.1 304 Not Modified\n";
3178  std::string headers;
3179  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3180  RemoveMockTransaction(&transaction);
3181
3182  EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
3183  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3184
3185  MockTransaction transaction2(kTypicalGET_Transaction);
3186  AddMockTransaction(&transaction2);
3187
3188  // Make sure we are done with the previous transaction.
3189  base::MessageLoop::current()->RunUntilIdle();
3190
3191  // Load from the cache.
3192  transaction2.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3193  RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3194
3195  EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
3196  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3197  EXPECT_EQ(2, cache.disk_cache()->open_count());
3198  EXPECT_EQ(1, cache.disk_cache()->create_count());
3199  RemoveMockTransaction(&transaction2);
3200}
3201
3202// Tests that an externally conditionalized HEAD request updates the cache.
3203TEST(HttpCache, TypicalHEAD_ConditionalizedRequestUpdatesResponse) {
3204  MockHttpCache cache;
3205  MockTransaction transaction(kTypicalGET_Transaction);
3206  AddMockTransaction(&transaction);
3207
3208  // Populate the cache.
3209  RunTransactionTest(cache.http_cache(), transaction);
3210
3211  // Update the cache.
3212  transaction.method = "HEAD";
3213  transaction.request_headers =
3214      "If-Modified-Since: Wed, 28 Nov 2007 00:40:09 GMT\r\n";
3215  transaction.response_headers = "Foo: bar\n";
3216  transaction.data = "";
3217  transaction.status = "HTTP/1.1 304 Not Modified\n";
3218  std::string headers;
3219  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3220  RemoveMockTransaction(&transaction);
3221
3222  EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 304 Not Modified\n"));
3223  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3224
3225  MockTransaction transaction2(kTypicalGET_Transaction);
3226  AddMockTransaction(&transaction2);
3227
3228  // Make sure we are done with the previous transaction.
3229  base::MessageLoop::current()->RunUntilIdle();
3230
3231  // Load from the cache.
3232  transaction2.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3233  RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3234
3235  EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
3236  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3237  EXPECT_EQ(2, cache.disk_cache()->open_count());
3238  EXPECT_EQ(1, cache.disk_cache()->create_count());
3239  RemoveMockTransaction(&transaction2);
3240}
3241
3242// Tests that a HEAD request invalidates an old cached entry.
3243TEST(HttpCache, SimpleHEAD_InvalidatesEntry) {
3244  MockHttpCache cache;
3245  MockTransaction transaction(kTypicalGET_Transaction);
3246  AddMockTransaction(&transaction);
3247
3248  // Populate the cache.
3249  RunTransactionTest(cache.http_cache(), transaction);
3250
3251  // Update the cache.
3252  transaction.method = "HEAD";
3253  transaction.data = "";
3254  RunTransactionTest(cache.http_cache(), transaction);
3255  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3256
3257  // Load from the cache.
3258  transaction.method = "GET";
3259  transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
3260  transaction.return_code = net::ERR_CACHE_MISS;
3261  RunTransactionTest(cache.http_cache(), transaction);
3262
3263  RemoveMockTransaction(&transaction);
3264}
3265
3266// Tests that we do not cache the response of a PUT.
3267TEST(HttpCache, SimplePUT_Miss) {
3268  MockHttpCache cache;
3269
3270  MockTransaction transaction(kSimplePOST_Transaction);
3271  transaction.method = "PUT";
3272
3273  ScopedVector<net::UploadElementReader> element_readers;
3274  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3275  net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
3276
3277  MockHttpRequest request(transaction);
3278  request.upload_data_stream = &upload_data_stream;
3279
3280  // Attempt to populate the cache.
3281  RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
3282
3283  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3284  EXPECT_EQ(0, cache.disk_cache()->open_count());
3285  EXPECT_EQ(0, cache.disk_cache()->create_count());
3286}
3287
3288// Tests that we invalidate entries as a result of a PUT.
3289TEST(HttpCache, SimplePUT_Invalidate) {
3290  MockHttpCache cache;
3291
3292  MockTransaction transaction(kSimpleGET_Transaction);
3293  MockHttpRequest req1(transaction);
3294
3295  // Attempt to populate the cache.
3296  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3297
3298  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3299  EXPECT_EQ(0, cache.disk_cache()->open_count());
3300  EXPECT_EQ(1, cache.disk_cache()->create_count());
3301
3302  ScopedVector<net::UploadElementReader> element_readers;
3303  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3304  net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
3305
3306  transaction.method = "PUT";
3307  MockHttpRequest req2(transaction);
3308  req2.upload_data_stream = &upload_data_stream;
3309
3310  RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3311
3312  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3313  EXPECT_EQ(1, cache.disk_cache()->open_count());
3314  EXPECT_EQ(1, cache.disk_cache()->create_count());
3315
3316  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3317
3318  EXPECT_EQ(3, cache.network_layer()->transaction_count());
3319  EXPECT_EQ(1, cache.disk_cache()->open_count());
3320  EXPECT_EQ(2, cache.disk_cache()->create_count());
3321}
3322
3323// Tests that we invalidate entries as a result of a PUT.
3324TEST(HttpCache, SimplePUT_Invalidate_305) {
3325  MockHttpCache cache;
3326
3327  MockTransaction transaction(kSimpleGET_Transaction);
3328  AddMockTransaction(&transaction);
3329  MockHttpRequest req1(transaction);
3330
3331  // Attempt to populate the cache.
3332  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3333
3334  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3335  EXPECT_EQ(0, cache.disk_cache()->open_count());
3336  EXPECT_EQ(1, cache.disk_cache()->create_count());
3337
3338  ScopedVector<net::UploadElementReader> element_readers;
3339  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3340  net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
3341
3342  transaction.method = "PUT";
3343  transaction.status = "HTTP/1.1 305 Use Proxy";
3344  MockHttpRequest req2(transaction);
3345  req2.upload_data_stream = &upload_data_stream;
3346
3347  RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3348
3349  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3350  EXPECT_EQ(1, cache.disk_cache()->open_count());
3351  EXPECT_EQ(1, cache.disk_cache()->create_count());
3352
3353  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3354
3355  EXPECT_EQ(3, cache.network_layer()->transaction_count());
3356  EXPECT_EQ(1, cache.disk_cache()->open_count());
3357  EXPECT_EQ(2, cache.disk_cache()->create_count());
3358  RemoveMockTransaction(&transaction);
3359}
3360
3361// Tests that we don't invalidate entries as a result of a failed PUT.
3362TEST(HttpCache, SimplePUT_DontInvalidate_404) {
3363  MockHttpCache cache;
3364
3365  MockTransaction transaction(kSimpleGET_Transaction);
3366  AddMockTransaction(&transaction);
3367  MockHttpRequest req1(transaction);
3368
3369  // Attempt to populate the cache.
3370  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3371
3372  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3373  EXPECT_EQ(0, cache.disk_cache()->open_count());
3374  EXPECT_EQ(1, cache.disk_cache()->create_count());
3375
3376  ScopedVector<net::UploadElementReader> element_readers;
3377  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3378  net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
3379
3380  transaction.method = "PUT";
3381  transaction.status = "HTTP/1.1 404 Not Found";
3382  MockHttpRequest req2(transaction);
3383  req2.upload_data_stream = &upload_data_stream;
3384
3385  RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3386
3387  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3388  EXPECT_EQ(1, cache.disk_cache()->open_count());
3389  EXPECT_EQ(1, cache.disk_cache()->create_count());
3390
3391  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3392
3393  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3394  EXPECT_EQ(2, cache.disk_cache()->open_count());
3395  EXPECT_EQ(1, cache.disk_cache()->create_count());
3396  RemoveMockTransaction(&transaction);
3397}
3398
3399// Tests that we do not cache the response of a DELETE.
3400TEST(HttpCache, SimpleDELETE_Miss) {
3401  MockHttpCache cache;
3402
3403  MockTransaction transaction(kSimplePOST_Transaction);
3404  transaction.method = "DELETE";
3405
3406  ScopedVector<net::UploadElementReader> element_readers;
3407  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3408  net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
3409
3410  MockHttpRequest request(transaction);
3411  request.upload_data_stream = &upload_data_stream;
3412
3413  // Attempt to populate the cache.
3414  RunTransactionTestWithRequest(cache.http_cache(), transaction, request, NULL);
3415
3416  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3417  EXPECT_EQ(0, cache.disk_cache()->open_count());
3418  EXPECT_EQ(0, cache.disk_cache()->create_count());
3419}
3420
3421// Tests that we invalidate entries as a result of a DELETE.
3422TEST(HttpCache, SimpleDELETE_Invalidate) {
3423  MockHttpCache cache;
3424
3425  MockTransaction transaction(kSimpleGET_Transaction);
3426  MockHttpRequest req1(transaction);
3427
3428  // Attempt to populate the cache.
3429  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3430
3431  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3432  EXPECT_EQ(0, cache.disk_cache()->open_count());
3433  EXPECT_EQ(1, cache.disk_cache()->create_count());
3434
3435  ScopedVector<net::UploadElementReader> element_readers;
3436  element_readers.push_back(new net::UploadBytesElementReader("hello", 5));
3437  net::UploadDataStream upload_data_stream(element_readers.Pass(), 0);
3438
3439  transaction.method = "DELETE";
3440  MockHttpRequest req2(transaction);
3441  req2.upload_data_stream = &upload_data_stream;
3442
3443  RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, NULL);
3444
3445  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3446  EXPECT_EQ(1, cache.disk_cache()->open_count());
3447  EXPECT_EQ(1, cache.disk_cache()->create_count());
3448
3449  RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, NULL);
3450
3451  EXPECT_EQ(3, cache.network_layer()->transaction_count());
3452  EXPECT_EQ(1, cache.disk_cache()->open_count());
3453  EXPECT_EQ(2, cache.disk_cache()->create_count());
3454}
3455
3456// Tests that we invalidate entries as a result of a DELETE.
3457TEST(HttpCache, SimpleDELETE_Invalidate_301) {
3458  MockHttpCache cache;
3459
3460  MockTransaction transaction(kSimpleGET_Transaction);
3461  AddMockTransaction(&transaction);
3462
3463  // Attempt to populate the cache.
3464  RunTransactionTest(cache.http_cache(), transaction);
3465
3466  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3467  EXPECT_EQ(0, cache.disk_cache()->open_count());
3468  EXPECT_EQ(1, cache.disk_cache()->create_count());
3469
3470  transaction.method = "DELETE";
3471  transaction.status = "HTTP/1.1 301 Moved Permanently ";
3472
3473  RunTransactionTest(cache.http_cache(), transaction);
3474
3475  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3476  EXPECT_EQ(1, cache.disk_cache()->open_count());
3477  EXPECT_EQ(1, cache.disk_cache()->create_count());
3478
3479  transaction.method = "GET";
3480  RunTransactionTest(cache.http_cache(), transaction);
3481
3482  EXPECT_EQ(3, cache.network_layer()->transaction_count());
3483  EXPECT_EQ(1, cache.disk_cache()->open_count());
3484  EXPECT_EQ(2, cache.disk_cache()->create_count());
3485  RemoveMockTransaction(&transaction);
3486}
3487
3488// Tests that we don't invalidate entries as a result of a failed DELETE.
3489TEST(HttpCache, SimpleDELETE_DontInvalidate_416) {
3490  MockHttpCache cache;
3491
3492  MockTransaction transaction(kSimpleGET_Transaction);
3493  AddMockTransaction(&transaction);
3494
3495  // Attempt to populate the cache.
3496  RunTransactionTest(cache.http_cache(), transaction);
3497
3498  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3499  EXPECT_EQ(0, cache.disk_cache()->open_count());
3500  EXPECT_EQ(1, cache.disk_cache()->create_count());
3501
3502  transaction.method = "DELETE";
3503  transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
3504
3505  RunTransactionTest(cache.http_cache(), transaction);
3506
3507  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3508  EXPECT_EQ(1, cache.disk_cache()->open_count());
3509  EXPECT_EQ(1, cache.disk_cache()->create_count());
3510
3511  transaction.method = "GET";
3512  transaction.status = "HTTP/1.1 200 OK";
3513  RunTransactionTest(cache.http_cache(), transaction);
3514
3515  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3516  EXPECT_EQ(2, cache.disk_cache()->open_count());
3517  EXPECT_EQ(1, cache.disk_cache()->create_count());
3518  RemoveMockTransaction(&transaction);
3519}
3520
3521// Tests that we don't invalidate entries after a failed network transaction.
3522TEST(HttpCache, SimpleGET_DontInvalidateOnFailure) {
3523  MockHttpCache cache;
3524
3525  // Populate the cache.
3526  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
3527  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3528
3529  // Fail the network request.
3530  MockTransaction transaction(kSimpleGET_Transaction);
3531  transaction.return_code = net::ERR_FAILED;
3532  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3533
3534  AddMockTransaction(&transaction);
3535  RunTransactionTest(cache.http_cache(), transaction);
3536  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3537  RemoveMockTransaction(&transaction);
3538
3539  transaction.load_flags = net::LOAD_ONLY_FROM_CACHE;
3540  transaction.return_code = net::OK;
3541  AddMockTransaction(&transaction);
3542  RunTransactionTest(cache.http_cache(), transaction);
3543
3544  // Make sure the transaction didn't reach the network.
3545  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3546  RemoveMockTransaction(&transaction);
3547}
3548
3549TEST(HttpCache, RangeGET_SkipsCache) {
3550  MockHttpCache cache;
3551
3552  // Test that we skip the cache for range GET requests.  Eventually, we will
3553  // want to cache these, but we'll still have cases where skipping the cache
3554  // makes sense, so we want to make sure that it works properly.
3555
3556  RunTransactionTest(cache.http_cache(), kRangeGET_Transaction);
3557
3558  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3559  EXPECT_EQ(0, cache.disk_cache()->open_count());
3560  EXPECT_EQ(0, cache.disk_cache()->create_count());
3561
3562  MockTransaction transaction(kSimpleGET_Transaction);
3563  transaction.request_headers = "If-None-Match: foo\r\n";
3564  RunTransactionTest(cache.http_cache(), transaction);
3565
3566  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3567  EXPECT_EQ(0, cache.disk_cache()->open_count());
3568  EXPECT_EQ(0, cache.disk_cache()->create_count());
3569
3570  transaction.request_headers =
3571      "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
3572  RunTransactionTest(cache.http_cache(), transaction);
3573
3574  EXPECT_EQ(3, cache.network_layer()->transaction_count());
3575  EXPECT_EQ(0, cache.disk_cache()->open_count());
3576  EXPECT_EQ(0, cache.disk_cache()->create_count());
3577}
3578
3579// Test that we skip the cache for range requests that include a validation
3580// header.
3581TEST(HttpCache, RangeGET_SkipsCache2) {
3582  MockHttpCache cache;
3583
3584  MockTransaction transaction(kRangeGET_Transaction);
3585  transaction.request_headers = "If-None-Match: foo\r\n"
3586                                EXTRA_HEADER
3587                                "Range: bytes = 40-49\r\n";
3588  RunTransactionTest(cache.http_cache(), transaction);
3589
3590  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3591  EXPECT_EQ(0, cache.disk_cache()->open_count());
3592  EXPECT_EQ(0, cache.disk_cache()->create_count());
3593
3594  transaction.request_headers =
3595      "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
3596      EXTRA_HEADER
3597      "Range: bytes = 40-49\r\n";
3598  RunTransactionTest(cache.http_cache(), transaction);
3599
3600  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3601  EXPECT_EQ(0, cache.disk_cache()->open_count());
3602  EXPECT_EQ(0, cache.disk_cache()->create_count());
3603
3604  transaction.request_headers = "If-Range: bla\r\n"
3605                                EXTRA_HEADER
3606                                "Range: bytes = 40-49\r\n";
3607  RunTransactionTest(cache.http_cache(), transaction);
3608
3609  EXPECT_EQ(3, cache.network_layer()->transaction_count());
3610  EXPECT_EQ(0, cache.disk_cache()->open_count());
3611  EXPECT_EQ(0, cache.disk_cache()->create_count());
3612}
3613
3614// Tests that receiving 206 for a regular request is handled correctly.
3615TEST(HttpCache, GET_Crazy206) {
3616  MockHttpCache cache;
3617
3618  // Write to the cache.
3619  MockTransaction transaction(kRangeGET_TransactionOK);
3620  AddMockTransaction(&transaction);
3621  transaction.request_headers = EXTRA_HEADER;
3622  transaction.handler = NULL;
3623  RunTransactionTest(cache.http_cache(), transaction);
3624
3625  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3626  EXPECT_EQ(0, cache.disk_cache()->open_count());
3627  EXPECT_EQ(1, cache.disk_cache()->create_count());
3628
3629  // This should read again from the net.
3630  RunTransactionTest(cache.http_cache(), transaction);
3631
3632  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3633  EXPECT_EQ(0, cache.disk_cache()->open_count());
3634  EXPECT_EQ(2, cache.disk_cache()->create_count());
3635  RemoveMockTransaction(&transaction);
3636}
3637
3638// Tests that receiving 416 for a regular request is handled correctly.
3639TEST(HttpCache, GET_Crazy416) {
3640  MockHttpCache cache;
3641
3642  // Write to the cache.
3643  MockTransaction transaction(kSimpleGET_Transaction);
3644  AddMockTransaction(&transaction);
3645  transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
3646  RunTransactionTest(cache.http_cache(), transaction);
3647
3648  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3649  EXPECT_EQ(0, cache.disk_cache()->open_count());
3650  EXPECT_EQ(1, cache.disk_cache()->create_count());
3651
3652  RemoveMockTransaction(&transaction);
3653}
3654
3655// Tests that we store partial responses that can't be validated, as they can
3656// be used for requests that don't require revalidation.
3657TEST(HttpCache, RangeGET_NoStrongValidators) {
3658  MockHttpCache cache;
3659  std::string headers;
3660
3661  // Write to the cache (40-49).
3662  MockTransaction transaction(kRangeGET_TransactionOK);
3663  AddMockTransaction(&transaction);
3664  transaction.response_headers = "Content-Length: 10\n"
3665                                 "Cache-Control: max-age=3600\n"
3666                                 "ETag: w/\"foo\"\n";
3667  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3668
3669  Verify206Response(headers, 40, 49);
3670  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3671  EXPECT_EQ(0, cache.disk_cache()->open_count());
3672  EXPECT_EQ(1, cache.disk_cache()->create_count());
3673
3674  // Now verify that there's cached data.
3675  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3676                                 &headers);
3677
3678  Verify206Response(headers, 40, 49);
3679  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3680  EXPECT_EQ(1, cache.disk_cache()->open_count());
3681  EXPECT_EQ(1, cache.disk_cache()->create_count());
3682
3683  RemoveMockTransaction(&transaction);
3684}
3685
3686// Tests failures to validate cache partial responses that lack strong
3687// validators.
3688TEST(HttpCache, RangeGET_NoValidation) {
3689  MockHttpCache cache;
3690  std::string headers;
3691
3692  // Write to the cache (40-49).
3693  MockTransaction transaction(kRangeGET_TransactionOK);
3694  AddMockTransaction(&transaction);
3695  transaction.response_headers = "Content-Length: 10\n"
3696                                 "ETag: w/\"foo\"\n";
3697  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3698
3699  Verify206Response(headers, 40, 49);
3700  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3701  EXPECT_EQ(0, cache.disk_cache()->open_count());
3702  EXPECT_EQ(1, cache.disk_cache()->create_count());
3703
3704  // Now verify that the cached data is not used.
3705  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3706                                 &headers);
3707
3708  Verify206Response(headers, 40, 49);
3709  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3710  EXPECT_EQ(1, cache.disk_cache()->open_count());
3711  EXPECT_EQ(2, cache.disk_cache()->create_count());
3712
3713  RemoveMockTransaction(&transaction);
3714}
3715
3716// Tests that we cache partial responses that lack content-length.
3717TEST(HttpCache, RangeGET_NoContentLength) {
3718  MockHttpCache cache;
3719  std::string headers;
3720
3721  // Attempt to write to the cache (40-49).
3722  MockTransaction transaction(kRangeGET_TransactionOK);
3723  AddMockTransaction(&transaction);
3724  transaction.response_headers = "ETag: \"foo\"\n"
3725                                 "Accept-Ranges: bytes\n"
3726                                 "Content-Range: bytes 40-49/80\n";
3727  transaction.handler = NULL;
3728  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3729
3730  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3731  EXPECT_EQ(0, cache.disk_cache()->open_count());
3732  EXPECT_EQ(1, cache.disk_cache()->create_count());
3733
3734  // Now verify that there's no cached data.
3735  transaction.handler = &RangeTransactionServer::RangeHandler;
3736  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3737                                 &headers);
3738
3739  Verify206Response(headers, 40, 49);
3740  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3741  EXPECT_EQ(1, cache.disk_cache()->open_count());
3742  EXPECT_EQ(1, cache.disk_cache()->create_count());
3743
3744  RemoveMockTransaction(&transaction);
3745}
3746
3747// Tests that we can cache range requests and fetch random blocks from the
3748// cache and the network.
3749TEST(HttpCache, RangeGET_OK) {
3750  MockHttpCache cache;
3751  AddMockTransaction(&kRangeGET_TransactionOK);
3752  std::string headers;
3753
3754  // Write to the cache (40-49).
3755  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3756                                 &headers);
3757
3758  Verify206Response(headers, 40, 49);
3759  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3760  EXPECT_EQ(0, cache.disk_cache()->open_count());
3761  EXPECT_EQ(1, cache.disk_cache()->create_count());
3762
3763  // Read from the cache (40-49).
3764  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
3765                                 &headers);
3766
3767  Verify206Response(headers, 40, 49);
3768  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3769  EXPECT_EQ(1, cache.disk_cache()->open_count());
3770  EXPECT_EQ(1, cache.disk_cache()->create_count());
3771
3772  // Make sure we are done with the previous transaction.
3773  base::MessageLoop::current()->RunUntilIdle();
3774
3775  // Write to the cache (30-39).
3776  MockTransaction transaction(kRangeGET_TransactionOK);
3777  transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3778  transaction.data = "rg: 30-39 ";
3779  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3780
3781  Verify206Response(headers, 30, 39);
3782  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3783  EXPECT_EQ(2, cache.disk_cache()->open_count());
3784  EXPECT_EQ(1, cache.disk_cache()->create_count());
3785
3786  // Make sure we are done with the previous transaction.
3787  base::MessageLoop::current()->RunUntilIdle();
3788
3789  // Write and read from the cache (20-59).
3790  transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
3791  transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3792  net::CapturingBoundNetLog log;
3793  net::LoadTimingInfo load_timing_info;
3794  RunTransactionTestWithResponseAndGetTiming(
3795      cache.http_cache(), transaction, &headers, log.bound(),
3796      &load_timing_info);
3797
3798  Verify206Response(headers, 20, 59);
3799  EXPECT_EQ(4, cache.network_layer()->transaction_count());
3800  EXPECT_EQ(3, cache.disk_cache()->open_count());
3801  EXPECT_EQ(1, cache.disk_cache()->create_count());
3802  TestLoadTimingNetworkRequest(load_timing_info);
3803
3804  RemoveMockTransaction(&kRangeGET_TransactionOK);
3805}
3806
3807// Checks that with a cache backend having Sparse IO unimplementes the cache
3808// entry would be doomed after a range request.
3809// TODO(pasko): remove when the SimpleBackendImpl implements Sparse IO.
3810TEST(HttpCache, RangeGET_SparseNotImplemented) {
3811  MockHttpCache cache;
3812  cache.disk_cache()->set_fail_sparse_requests();
3813
3814  // Run a cacheable request to prime the cache.
3815  MockTransaction transaction(kTypicalGET_Transaction);
3816  transaction.url = kRangeGET_TransactionOK.url;
3817  AddMockTransaction(&transaction);
3818  RunTransactionTest(cache.http_cache(), transaction);
3819  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3820  EXPECT_EQ(0, cache.disk_cache()->open_count());
3821  EXPECT_EQ(1, cache.disk_cache()->create_count());
3822
3823  // Verify that we added the entry.
3824  disk_cache::Entry* entry;
3825  net::TestCompletionCallback cb;
3826  int rv = cache.disk_cache()->OpenEntry(transaction.url,
3827                                         &entry,
3828                                         cb.callback());
3829  ASSERT_EQ(net::OK, cb.GetResult(rv));
3830  EXPECT_EQ(1, cache.disk_cache()->open_count());
3831  entry->Close();
3832  RemoveMockTransaction(&transaction);
3833
3834  // Request the range with the backend that does not support it.
3835  MockTransaction transaction2(kRangeGET_TransactionOK);
3836  std::string headers;
3837  AddMockTransaction(&transaction2);
3838  RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
3839  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3840  EXPECT_EQ(2, cache.disk_cache()->open_count());
3841  EXPECT_EQ(2, cache.disk_cache()->create_count());
3842
3843  // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even
3844  // if it was re-created later, so this effectively checks that the old data is
3845  // gone.
3846  disk_cache::Entry* entry2;
3847  rv = cache.disk_cache()->OpenEntry(transaction2.url,
3848                                     &entry2,
3849                                     cb.callback());
3850  ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE, cb.GetResult(rv));
3851  RemoveMockTransaction(&transaction2);
3852}
3853
3854TEST(HttpCache, RangeGET_SparseNotImplementedOnEmptyCache) {
3855  MockHttpCache cache;
3856  cache.disk_cache()->set_fail_sparse_requests();
3857
3858  // Request the range with the backend that does not support it.
3859  MockTransaction transaction(kRangeGET_TransactionOK);
3860  std::string headers;
3861  AddMockTransaction(&transaction);
3862  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3863  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3864  EXPECT_EQ(0, cache.disk_cache()->open_count());
3865  EXPECT_EQ(1, cache.disk_cache()->create_count());
3866
3867  // Mock cache would return net::ERR_CACHE_OPEN_FAILURE on a doomed entry, even
3868  // if it was re-created later, so this effectively checks that the old data is
3869  // gone as a result of a failed range write.
3870  disk_cache::Entry* entry;
3871  net::TestCompletionCallback cb;
3872  int rv = cache.disk_cache()->OpenEntry(transaction.url,
3873                                         &entry,
3874                                         cb.callback());
3875  ASSERT_EQ(net::ERR_CACHE_OPEN_FAILURE, cb.GetResult(rv));
3876  RemoveMockTransaction(&transaction);
3877}
3878
3879// Tests that we can cache range requests and fetch random blocks from the
3880// cache and the network, with synchronous responses.
3881TEST(HttpCache, RangeGET_SyncOK) {
3882  MockHttpCache cache;
3883
3884  MockTransaction transaction(kRangeGET_TransactionOK);
3885  transaction.test_mode = TEST_MODE_SYNC_ALL;
3886  AddMockTransaction(&transaction);
3887
3888  // Write to the cache (40-49).
3889  std::string headers;
3890  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3891
3892  Verify206Response(headers, 40, 49);
3893  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3894  EXPECT_EQ(0, cache.disk_cache()->open_count());
3895  EXPECT_EQ(1, cache.disk_cache()->create_count());
3896
3897  // Read from the cache (40-49).
3898  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3899
3900  Verify206Response(headers, 40, 49);
3901  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3902  EXPECT_EQ(0, cache.disk_cache()->open_count());
3903  EXPECT_EQ(1, cache.disk_cache()->create_count());
3904
3905  // Make sure we are done with the previous transaction.
3906  base::MessageLoop::current()->RunUntilIdle();
3907
3908  // Write to the cache (30-39).
3909  transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3910  transaction.data = "rg: 30-39 ";
3911  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3912
3913  Verify206Response(headers, 30, 39);
3914  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3915  EXPECT_EQ(1, cache.disk_cache()->open_count());
3916  EXPECT_EQ(1, cache.disk_cache()->create_count());
3917
3918  // Make sure we are done with the previous transaction.
3919  base::MessageLoop::current()->RunUntilIdle();
3920
3921  // Write and read from the cache (20-59).
3922  transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
3923  transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
3924  net::CapturingBoundNetLog log;
3925  net::LoadTimingInfo load_timing_info;
3926  RunTransactionTestWithResponseAndGetTiming(
3927      cache.http_cache(), transaction, &headers, log.bound(),
3928      &load_timing_info);
3929
3930  Verify206Response(headers, 20, 59);
3931  EXPECT_EQ(4, cache.network_layer()->transaction_count());
3932  EXPECT_EQ(2, cache.disk_cache()->open_count());
3933  EXPECT_EQ(1, cache.disk_cache()->create_count());
3934  TestLoadTimingNetworkRequest(load_timing_info);
3935
3936  RemoveMockTransaction(&transaction);
3937}
3938
3939// Tests that we don't revalidate an entry unless we are required to do so.
3940TEST(HttpCache, RangeGET_Revalidate1) {
3941  MockHttpCache cache;
3942  std::string headers;
3943
3944  // Write to the cache (40-49).
3945  MockTransaction transaction(kRangeGET_TransactionOK);
3946  transaction.response_headers =
3947      "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3948      "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n"  // Should never expire.
3949      "ETag: \"foo\"\n"
3950      "Accept-Ranges: bytes\n"
3951      "Content-Length: 10\n";
3952  AddMockTransaction(&transaction);
3953  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
3954
3955  Verify206Response(headers, 40, 49);
3956  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3957  EXPECT_EQ(0, cache.disk_cache()->open_count());
3958  EXPECT_EQ(1, cache.disk_cache()->create_count());
3959
3960  // Read from the cache (40-49).
3961  net::CapturingBoundNetLog log;
3962  net::LoadTimingInfo load_timing_info;
3963  RunTransactionTestWithResponseAndGetTiming(
3964      cache.http_cache(), transaction, &headers, log.bound(),
3965      &load_timing_info);
3966
3967  Verify206Response(headers, 40, 49);
3968  EXPECT_EQ(1, cache.network_layer()->transaction_count());
3969  EXPECT_EQ(1, cache.disk_cache()->open_count());
3970  EXPECT_EQ(1, cache.disk_cache()->create_count());
3971  TestLoadTimingCachedResponse(load_timing_info);
3972
3973  // Read again forcing the revalidation.
3974  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
3975  RunTransactionTestWithResponseAndGetTiming(
3976      cache.http_cache(), transaction, &headers, log.bound(),
3977      &load_timing_info);
3978
3979  Verify206Response(headers, 40, 49);
3980  EXPECT_EQ(2, cache.network_layer()->transaction_count());
3981  EXPECT_EQ(1, cache.disk_cache()->open_count());
3982  EXPECT_EQ(1, cache.disk_cache()->create_count());
3983  TestLoadTimingNetworkRequest(load_timing_info);
3984
3985  RemoveMockTransaction(&transaction);
3986}
3987
3988// Checks that we revalidate an entry when the headers say so.
3989TEST(HttpCache, RangeGET_Revalidate2) {
3990  MockHttpCache cache;
3991  std::string headers;
3992
3993  // Write to the cache (40-49).
3994  MockTransaction transaction(kRangeGET_TransactionOK);
3995  transaction.response_headers =
3996      "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
3997      "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n"  // Expired.
3998      "ETag: \"foo\"\n"
3999      "Accept-Ranges: bytes\n"
4000      "Content-Length: 10\n";
4001  AddMockTransaction(&transaction);
4002  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4003
4004  Verify206Response(headers, 40, 49);
4005  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4006  EXPECT_EQ(0, cache.disk_cache()->open_count());
4007  EXPECT_EQ(1, cache.disk_cache()->create_count());
4008
4009  // Read from the cache (40-49).
4010  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4011  Verify206Response(headers, 40, 49);
4012
4013  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4014  EXPECT_EQ(1, cache.disk_cache()->open_count());
4015  EXPECT_EQ(1, cache.disk_cache()->create_count());
4016
4017  RemoveMockTransaction(&transaction);
4018}
4019
4020// Tests that we deal with 304s for range requests.
4021TEST(HttpCache, RangeGET_304) {
4022  MockHttpCache cache;
4023  AddMockTransaction(&kRangeGET_TransactionOK);
4024  std::string headers;
4025
4026  // Write to the cache (40-49).
4027  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4028                                 &headers);
4029
4030  Verify206Response(headers, 40, 49);
4031  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4032  EXPECT_EQ(0, cache.disk_cache()->open_count());
4033  EXPECT_EQ(1, cache.disk_cache()->create_count());
4034
4035  // Read from the cache (40-49).
4036  RangeTransactionServer handler;
4037  handler.set_not_modified(true);
4038  MockTransaction transaction(kRangeGET_TransactionOK);
4039  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
4040  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4041
4042  Verify206Response(headers, 40, 49);
4043  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4044  EXPECT_EQ(1, cache.disk_cache()->open_count());
4045  EXPECT_EQ(1, cache.disk_cache()->create_count());
4046
4047  RemoveMockTransaction(&kRangeGET_TransactionOK);
4048}
4049
4050// Tests that we deal with 206s when revalidating range requests.
4051TEST(HttpCache, RangeGET_ModifiedResult) {
4052  MockHttpCache cache;
4053  AddMockTransaction(&kRangeGET_TransactionOK);
4054  std::string headers;
4055
4056  // Write to the cache (40-49).
4057  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4058                                 &headers);
4059
4060  Verify206Response(headers, 40, 49);
4061  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4062  EXPECT_EQ(0, cache.disk_cache()->open_count());
4063  EXPECT_EQ(1, cache.disk_cache()->create_count());
4064
4065  // Attempt to read from the cache (40-49).
4066  RangeTransactionServer handler;
4067  handler.set_modified(true);
4068  MockTransaction transaction(kRangeGET_TransactionOK);
4069  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
4070  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4071
4072  Verify206Response(headers, 40, 49);
4073  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4074  EXPECT_EQ(1, cache.disk_cache()->open_count());
4075  EXPECT_EQ(1, cache.disk_cache()->create_count());
4076
4077  // And the entry should be gone.
4078  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4079  EXPECT_EQ(3, cache.network_layer()->transaction_count());
4080  EXPECT_EQ(1, cache.disk_cache()->open_count());
4081  EXPECT_EQ(2, cache.disk_cache()->create_count());
4082
4083  RemoveMockTransaction(&kRangeGET_TransactionOK);
4084}
4085
4086// Tests that we cache 301s for range requests.
4087TEST(HttpCache, RangeGET_301) {
4088  MockHttpCache cache;
4089  ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4090  transaction.status = "HTTP/1.1 301 Moved Permanently";
4091  transaction.response_headers = "Location: http://www.bar.com/\n";
4092  transaction.data = "";
4093  transaction.handler = NULL;
4094  AddMockTransaction(&transaction);
4095
4096  // Write to the cache.
4097  RunTransactionTest(cache.http_cache(), transaction);
4098  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4099  EXPECT_EQ(0, cache.disk_cache()->open_count());
4100  EXPECT_EQ(1, cache.disk_cache()->create_count());
4101
4102  // Read from the cache.
4103  RunTransactionTest(cache.http_cache(), transaction);
4104  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4105  EXPECT_EQ(1, cache.disk_cache()->open_count());
4106  EXPECT_EQ(1, cache.disk_cache()->create_count());
4107
4108  RemoveMockTransaction(&transaction);
4109}
4110
4111// Tests that we can cache range requests when the start or end is unknown.
4112// We start with one suffix request, followed by a request from a given point.
4113TEST(HttpCache, UnknownRangeGET_1) {
4114  MockHttpCache cache;
4115  AddMockTransaction(&kRangeGET_TransactionOK);
4116  std::string headers;
4117
4118  // Write to the cache (70-79).
4119  MockTransaction transaction(kRangeGET_TransactionOK);
4120  transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
4121  transaction.data = "rg: 70-79 ";
4122  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4123
4124  Verify206Response(headers, 70, 79);
4125  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4126  EXPECT_EQ(0, cache.disk_cache()->open_count());
4127  EXPECT_EQ(1, cache.disk_cache()->create_count());
4128
4129  // Make sure we are done with the previous transaction.
4130  base::MessageLoop::current()->RunUntilIdle();
4131
4132  // Write and read from the cache (60-79).
4133  transaction.request_headers = "Range: bytes = 60-\r\n" EXTRA_HEADER;
4134  transaction.data = "rg: 60-69 rg: 70-79 ";
4135  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4136
4137  Verify206Response(headers, 60, 79);
4138  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4139  EXPECT_EQ(1, cache.disk_cache()->open_count());
4140  EXPECT_EQ(1, cache.disk_cache()->create_count());
4141
4142  RemoveMockTransaction(&kRangeGET_TransactionOK);
4143}
4144
4145// Tests that we can cache range requests when the start or end is unknown.
4146// We start with one request from a given point, followed by a suffix request.
4147// We'll also verify that synchronous cache responses work as intended.
4148TEST(HttpCache, UnknownRangeGET_2) {
4149  MockHttpCache cache;
4150  std::string headers;
4151
4152  MockTransaction transaction(kRangeGET_TransactionOK);
4153  transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
4154                          TEST_MODE_SYNC_CACHE_READ |
4155                          TEST_MODE_SYNC_CACHE_WRITE;
4156  AddMockTransaction(&transaction);
4157
4158  // Write to the cache (70-79).
4159  transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
4160  transaction.data = "rg: 70-79 ";
4161  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4162
4163  Verify206Response(headers, 70, 79);
4164  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4165  EXPECT_EQ(0, cache.disk_cache()->open_count());
4166  EXPECT_EQ(1, cache.disk_cache()->create_count());
4167
4168  // Make sure we are done with the previous transaction.
4169  base::MessageLoop::current()->RunUntilIdle();
4170
4171  // Write and read from the cache (60-79).
4172  transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
4173  transaction.data = "rg: 60-69 rg: 70-79 ";
4174  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4175
4176  Verify206Response(headers, 60, 79);
4177  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4178  EXPECT_EQ(1, cache.disk_cache()->open_count());
4179  EXPECT_EQ(1, cache.disk_cache()->create_count());
4180
4181  RemoveMockTransaction(&transaction);
4182}
4183
4184// Tests that receiving Not Modified when asking for an open range doesn't mess
4185// up things.
4186TEST(HttpCache, UnknownRangeGET_304) {
4187  MockHttpCache cache;
4188  std::string headers;
4189
4190  MockTransaction transaction(kRangeGET_TransactionOK);
4191  AddMockTransaction(&transaction);
4192
4193  RangeTransactionServer handler;
4194  handler.set_not_modified(true);
4195
4196  // Ask for the end of the file, without knowing the length.
4197  transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
4198  transaction.data = "";
4199  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4200
4201  // We just bypass the cache.
4202  EXPECT_EQ(0U, headers.find("HTTP/1.1 304 Not Modified\n"));
4203  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4204  EXPECT_EQ(0, cache.disk_cache()->open_count());
4205  EXPECT_EQ(1, cache.disk_cache()->create_count());
4206
4207  RunTransactionTest(cache.http_cache(), transaction);
4208  EXPECT_EQ(2, cache.disk_cache()->create_count());
4209
4210  RemoveMockTransaction(&transaction);
4211}
4212
4213// Tests that we can handle non-range requests when we have cached a range.
4214TEST(HttpCache, GET_Previous206) {
4215  MockHttpCache cache;
4216  AddMockTransaction(&kRangeGET_TransactionOK);
4217  std::string headers;
4218  net::CapturingBoundNetLog log;
4219  net::LoadTimingInfo load_timing_info;
4220
4221  // Write to the cache (40-49).
4222  RunTransactionTestWithResponseAndGetTiming(
4223      cache.http_cache(), kRangeGET_TransactionOK, &headers, log.bound(),
4224      &load_timing_info);
4225
4226  Verify206Response(headers, 40, 49);
4227  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4228  EXPECT_EQ(0, cache.disk_cache()->open_count());
4229  EXPECT_EQ(1, cache.disk_cache()->create_count());
4230  TestLoadTimingNetworkRequest(load_timing_info);
4231
4232  // Write and read from the cache (0-79), when not asked for a range.
4233  MockTransaction transaction(kRangeGET_TransactionOK);
4234  transaction.request_headers = EXTRA_HEADER;
4235  transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4236                     "rg: 50-59 rg: 60-69 rg: 70-79 ";
4237  RunTransactionTestWithResponseAndGetTiming(
4238      cache.http_cache(), transaction, &headers, log.bound(),
4239      &load_timing_info);
4240
4241  EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4242  EXPECT_EQ(3, cache.network_layer()->transaction_count());
4243  EXPECT_EQ(1, cache.disk_cache()->open_count());
4244  EXPECT_EQ(1, cache.disk_cache()->create_count());
4245  TestLoadTimingNetworkRequest(load_timing_info);
4246
4247  RemoveMockTransaction(&kRangeGET_TransactionOK);
4248}
4249
4250// Tests that we can handle non-range requests when we have cached the first
4251// part of the object and the server replies with 304 (Not Modified).
4252TEST(HttpCache, GET_Previous206_NotModified) {
4253  MockHttpCache cache;
4254
4255  MockTransaction transaction(kRangeGET_TransactionOK);
4256  AddMockTransaction(&transaction);
4257  std::string headers;
4258  net::CapturingBoundNetLog log;
4259  net::LoadTimingInfo load_timing_info;
4260
4261  // Write to the cache (0-9).
4262  transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
4263  transaction.data = "rg: 00-09 ";
4264  RunTransactionTestWithResponseAndGetTiming(
4265      cache.http_cache(), transaction, &headers, log.bound(),
4266      &load_timing_info);
4267  Verify206Response(headers, 0, 9);
4268  TestLoadTimingNetworkRequest(load_timing_info);
4269
4270  // Write to the cache (70-79).
4271  transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
4272  transaction.data = "rg: 70-79 ";
4273  RunTransactionTestWithResponseAndGetTiming(
4274      cache.http_cache(), transaction, &headers, log.bound(),
4275      &load_timing_info);
4276  Verify206Response(headers, 70, 79);
4277
4278  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4279  EXPECT_EQ(1, cache.disk_cache()->open_count());
4280  EXPECT_EQ(1, cache.disk_cache()->create_count());
4281  TestLoadTimingNetworkRequest(load_timing_info);
4282
4283  // Read from the cache (0-9), write and read from cache (10 - 79).
4284  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
4285  transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER;
4286  transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4287                     "rg: 50-59 rg: 60-69 rg: 70-79 ";
4288  RunTransactionTestWithResponseAndGetTiming(
4289      cache.http_cache(), transaction, &headers, log.bound(),
4290      &load_timing_info);
4291
4292  EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4293  EXPECT_EQ(4, cache.network_layer()->transaction_count());
4294  EXPECT_EQ(2, cache.disk_cache()->open_count());
4295  EXPECT_EQ(1, cache.disk_cache()->create_count());
4296  TestLoadTimingNetworkRequest(load_timing_info);
4297
4298  RemoveMockTransaction(&transaction);
4299}
4300
4301// Tests that we can handle a regular request to a sparse entry, that results in
4302// new content provided by the server (206).
4303TEST(HttpCache, GET_Previous206_NewContent) {
4304  MockHttpCache cache;
4305  AddMockTransaction(&kRangeGET_TransactionOK);
4306  std::string headers;
4307
4308  // Write to the cache (0-9).
4309  MockTransaction transaction(kRangeGET_TransactionOK);
4310  transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
4311  transaction.data = "rg: 00-09 ";
4312  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4313
4314  Verify206Response(headers, 0, 9);
4315  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4316  EXPECT_EQ(0, cache.disk_cache()->open_count());
4317  EXPECT_EQ(1, cache.disk_cache()->create_count());
4318
4319  // Now we'll issue a request without any range that should result first in a
4320  // 206 (when revalidating), and then in a weird standard answer: the test
4321  // server will not modify the response so we'll get the default range... a
4322  // real server will answer with 200.
4323  MockTransaction transaction2(kRangeGET_TransactionOK);
4324  transaction2.request_headers = EXTRA_HEADER;
4325  transaction2.load_flags |= net::LOAD_VALIDATE_CACHE;
4326  transaction2.data = "Not a range";
4327  RangeTransactionServer handler;
4328  handler.set_modified(true);
4329  net::CapturingBoundNetLog log;
4330  net::LoadTimingInfo load_timing_info;
4331  RunTransactionTestWithResponseAndGetTiming(
4332      cache.http_cache(), transaction2, &headers, log.bound(),
4333      &load_timing_info);
4334
4335  EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
4336  EXPECT_EQ(3, cache.network_layer()->transaction_count());
4337  EXPECT_EQ(1, cache.disk_cache()->open_count());
4338  EXPECT_EQ(1, cache.disk_cache()->create_count());
4339  TestLoadTimingNetworkRequest(load_timing_info);
4340
4341  // Verify that the previous request deleted the entry.
4342  RunTransactionTest(cache.http_cache(), transaction);
4343  EXPECT_EQ(2, cache.disk_cache()->create_count());
4344
4345  RemoveMockTransaction(&transaction);
4346}
4347
4348// Tests that we can handle cached 206 responses that are not sparse.
4349TEST(HttpCache, GET_Previous206_NotSparse) {
4350  MockHttpCache cache;
4351
4352  // Create a disk cache entry that stores 206 headers while not being sparse.
4353  disk_cache::Entry* entry;
4354  ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
4355                                       NULL));
4356
4357  std::string raw_headers(kRangeGET_TransactionOK.status);
4358  raw_headers.append("\n");
4359  raw_headers.append(kRangeGET_TransactionOK.response_headers);
4360  raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
4361                                                  raw_headers.size());
4362
4363  net::HttpResponseInfo response;
4364  response.headers = new net::HttpResponseHeaders(raw_headers);
4365  EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4366
4367  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
4368  int len = static_cast<int>(base::strlcpy(buf->data(),
4369                                           kRangeGET_TransactionOK.data, 500));
4370  net::TestCompletionCallback cb;
4371  int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
4372  EXPECT_EQ(len, cb.GetResult(rv));
4373  entry->Close();
4374
4375  // Now see that we don't use the stored entry.
4376  std::string headers;
4377  net::CapturingBoundNetLog log;
4378  net::LoadTimingInfo load_timing_info;
4379  RunTransactionTestWithResponseAndGetTiming(
4380      cache.http_cache(), kSimpleGET_Transaction, &headers, log.bound(),
4381      &load_timing_info);
4382
4383  // We are expecting a 200.
4384  std::string expected_headers(kSimpleGET_Transaction.status);
4385  expected_headers.append("\n");
4386  expected_headers.append(kSimpleGET_Transaction.response_headers);
4387  EXPECT_EQ(expected_headers, headers);
4388  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4389  EXPECT_EQ(1, cache.disk_cache()->open_count());
4390  EXPECT_EQ(2, cache.disk_cache()->create_count());
4391  TestLoadTimingNetworkRequest(load_timing_info);
4392}
4393
4394// Tests that we can handle cached 206 responses that are not sparse. This time
4395// we issue a range request and expect to receive a range.
4396TEST(HttpCache, RangeGET_Previous206_NotSparse_2) {
4397  MockHttpCache cache;
4398  AddMockTransaction(&kRangeGET_TransactionOK);
4399
4400  // Create a disk cache entry that stores 206 headers while not being sparse.
4401  disk_cache::Entry* entry;
4402  ASSERT_TRUE(cache.CreateBackendEntry(kRangeGET_TransactionOK.url, &entry,
4403                                       NULL));
4404
4405  std::string raw_headers(kRangeGET_TransactionOK.status);
4406  raw_headers.append("\n");
4407  raw_headers.append(kRangeGET_TransactionOK.response_headers);
4408  raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
4409                                                  raw_headers.size());
4410
4411  net::HttpResponseInfo response;
4412  response.headers = new net::HttpResponseHeaders(raw_headers);
4413  EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4414
4415  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
4416  int len = static_cast<int>(base::strlcpy(buf->data(),
4417                                           kRangeGET_TransactionOK.data, 500));
4418  net::TestCompletionCallback cb;
4419  int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
4420  EXPECT_EQ(len, cb.GetResult(rv));
4421  entry->Close();
4422
4423  // Now see that we don't use the stored entry.
4424  std::string headers;
4425  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4426                                 &headers);
4427
4428  // We are expecting a 206.
4429  Verify206Response(headers, 40, 49);
4430  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4431  EXPECT_EQ(1, cache.disk_cache()->open_count());
4432  EXPECT_EQ(2, cache.disk_cache()->create_count());
4433
4434  RemoveMockTransaction(&kRangeGET_TransactionOK);
4435}
4436
4437// Tests that we can handle cached 206 responses that can't be validated.
4438TEST(HttpCache, GET_Previous206_NotValidation) {
4439  MockHttpCache cache;
4440
4441  // Create a disk cache entry that stores 206 headers.
4442  disk_cache::Entry* entry;
4443  ASSERT_TRUE(cache.CreateBackendEntry(kSimpleGET_Transaction.url, &entry,
4444                                       NULL));
4445
4446  // Make sure that the headers cannot be validated with the server.
4447  std::string raw_headers(kRangeGET_TransactionOK.status);
4448  raw_headers.append("\n");
4449  raw_headers.append("Content-Length: 80\n");
4450  raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(),
4451                                                  raw_headers.size());
4452
4453  net::HttpResponseInfo response;
4454  response.headers = new net::HttpResponseHeaders(raw_headers);
4455  EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
4456
4457  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500));
4458  int len = static_cast<int>(base::strlcpy(buf->data(),
4459                                           kRangeGET_TransactionOK.data, 500));
4460  net::TestCompletionCallback cb;
4461  int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
4462  EXPECT_EQ(len, cb.GetResult(rv));
4463  entry->Close();
4464
4465  // Now see that we don't use the stored entry.
4466  std::string headers;
4467  RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
4468                                 &headers);
4469
4470  // We are expecting a 200.
4471  std::string expected_headers(kSimpleGET_Transaction.status);
4472  expected_headers.append("\n");
4473  expected_headers.append(kSimpleGET_Transaction.response_headers);
4474  EXPECT_EQ(expected_headers, headers);
4475  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4476  EXPECT_EQ(1, cache.disk_cache()->open_count());
4477  EXPECT_EQ(2, cache.disk_cache()->create_count());
4478}
4479
4480// Tests that we can handle range requests with cached 200 responses.
4481TEST(HttpCache, RangeGET_Previous200) {
4482  MockHttpCache cache;
4483
4484  // Store the whole thing with status 200.
4485  MockTransaction transaction(kTypicalGET_Transaction);
4486  transaction.url = kRangeGET_TransactionOK.url;
4487  transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
4488                     "rg: 50-59 rg: 60-69 rg: 70-79 ";
4489  AddMockTransaction(&transaction);
4490  RunTransactionTest(cache.http_cache(), transaction);
4491  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4492  EXPECT_EQ(0, cache.disk_cache()->open_count());
4493  EXPECT_EQ(1, cache.disk_cache()->create_count());
4494
4495  RemoveMockTransaction(&transaction);
4496  AddMockTransaction(&kRangeGET_TransactionOK);
4497
4498  // Now see that we use the stored entry.
4499  std::string headers;
4500  MockTransaction transaction2(kRangeGET_TransactionOK);
4501  RangeTransactionServer handler;
4502  handler.set_not_modified(true);
4503  RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4504
4505  // We are expecting a 206.
4506  Verify206Response(headers, 40, 49);
4507  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4508  EXPECT_EQ(1, cache.disk_cache()->open_count());
4509  EXPECT_EQ(1, cache.disk_cache()->create_count());
4510
4511  // The last transaction has finished so make sure the entry is deactivated.
4512  base::MessageLoop::current()->RunUntilIdle();
4513
4514  // Make a request for an invalid range.
4515  MockTransaction transaction3(kRangeGET_TransactionOK);
4516  transaction3.request_headers = "Range: bytes = 80-90\r\n" EXTRA_HEADER;
4517  transaction3.data = transaction.data;
4518  transaction3.load_flags = net::LOAD_PREFERRING_CACHE;
4519  RunTransactionTestWithResponse(cache.http_cache(), transaction3, &headers);
4520  EXPECT_EQ(2, cache.disk_cache()->open_count());
4521  EXPECT_EQ(0U, headers.find("HTTP/1.1 200 "));
4522  EXPECT_EQ(std::string::npos, headers.find("Content-Range:"));
4523  EXPECT_EQ(std::string::npos, headers.find("Content-Length: 80"));
4524
4525  // Make sure the entry is deactivated.
4526  base::MessageLoop::current()->RunUntilIdle();
4527
4528  // Even though the request was invalid, we should have the entry.
4529  RunTransactionTest(cache.http_cache(), transaction2);
4530  EXPECT_EQ(3, cache.disk_cache()->open_count());
4531
4532  // Make sure the entry is deactivated.
4533  base::MessageLoop::current()->RunUntilIdle();
4534
4535  // Now we should receive a range from the server and drop the stored entry.
4536  handler.set_not_modified(false);
4537  transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
4538  RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4539  Verify206Response(headers, 40, 49);
4540  EXPECT_EQ(4, cache.network_layer()->transaction_count());
4541  EXPECT_EQ(4, cache.disk_cache()->open_count());
4542  EXPECT_EQ(1, cache.disk_cache()->create_count());
4543
4544  RunTransactionTest(cache.http_cache(), transaction2);
4545  EXPECT_EQ(2, cache.disk_cache()->create_count());
4546
4547  RemoveMockTransaction(&kRangeGET_TransactionOK);
4548}
4549
4550// Tests that we can handle a 200 response when dealing with sparse entries.
4551TEST(HttpCache, RangeRequestResultsIn200) {
4552  MockHttpCache cache;
4553  AddMockTransaction(&kRangeGET_TransactionOK);
4554  std::string headers;
4555
4556  // Write to the cache (70-79).
4557  MockTransaction transaction(kRangeGET_TransactionOK);
4558  transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
4559  transaction.data = "rg: 70-79 ";
4560  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4561
4562  Verify206Response(headers, 70, 79);
4563  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4564  EXPECT_EQ(0, cache.disk_cache()->open_count());
4565  EXPECT_EQ(1, cache.disk_cache()->create_count());
4566
4567  // Now we'll issue a request that results in a plain 200 response, but to
4568  // the to the same URL that we used to store sparse data, and making sure
4569  // that we ask for a range.
4570  RemoveMockTransaction(&kRangeGET_TransactionOK);
4571  MockTransaction transaction2(kSimpleGET_Transaction);
4572  transaction2.url = kRangeGET_TransactionOK.url;
4573  transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
4574  AddMockTransaction(&transaction2);
4575
4576  RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
4577
4578  std::string expected_headers(kSimpleGET_Transaction.status);
4579  expected_headers.append("\n");
4580  expected_headers.append(kSimpleGET_Transaction.response_headers);
4581  EXPECT_EQ(expected_headers, headers);
4582  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4583  EXPECT_EQ(1, cache.disk_cache()->open_count());
4584  EXPECT_EQ(1, cache.disk_cache()->create_count());
4585
4586  RemoveMockTransaction(&transaction2);
4587}
4588
4589// Tests that a range request that falls outside of the size that we know about
4590// only deletes the entry if the resource has indeed changed.
4591TEST(HttpCache, RangeGET_MoreThanCurrentSize) {
4592  MockHttpCache cache;
4593  AddMockTransaction(&kRangeGET_TransactionOK);
4594  std::string headers;
4595
4596  // Write to the cache (40-49).
4597  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4598                                 &headers);
4599
4600  Verify206Response(headers, 40, 49);
4601  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4602  EXPECT_EQ(0, cache.disk_cache()->open_count());
4603  EXPECT_EQ(1, cache.disk_cache()->create_count());
4604
4605  // A weird request should not delete this entry. Ask for bytes 120-.
4606  MockTransaction transaction(kRangeGET_TransactionOK);
4607  transaction.request_headers = "Range: bytes = 120-\r\n" EXTRA_HEADER;
4608  transaction.data = "";
4609  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4610
4611  EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
4612  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4613  EXPECT_EQ(1, cache.disk_cache()->open_count());
4614  EXPECT_EQ(1, cache.disk_cache()->create_count());
4615
4616  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4617  EXPECT_EQ(2, cache.disk_cache()->open_count());
4618  EXPECT_EQ(1, cache.disk_cache()->create_count());
4619
4620  RemoveMockTransaction(&kRangeGET_TransactionOK);
4621}
4622
4623// Tests that we don't delete a sparse entry when we cancel a request.
4624TEST(HttpCache, RangeGET_Cancel) {
4625  MockHttpCache cache;
4626  AddMockTransaction(&kRangeGET_TransactionOK);
4627
4628  MockHttpRequest request(kRangeGET_TransactionOK);
4629
4630  Context* c = new Context();
4631  int rv = cache.CreateTransaction(&c->trans);
4632  ASSERT_EQ(net::OK, rv);
4633
4634  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4635  if (rv == net::ERR_IO_PENDING)
4636    rv = c->callback.WaitForResult();
4637
4638  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4639  EXPECT_EQ(0, cache.disk_cache()->open_count());
4640  EXPECT_EQ(1, cache.disk_cache()->create_count());
4641
4642  // Make sure that the entry has some data stored.
4643  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
4644  rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4645  if (rv == net::ERR_IO_PENDING)
4646    rv = c->callback.WaitForResult();
4647  EXPECT_EQ(buf->size(), rv);
4648
4649  // Destroy the transaction.
4650  delete c;
4651
4652  // Verify that the entry has not been deleted.
4653  disk_cache::Entry* entry;
4654  ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4655  entry->Close();
4656  RemoveMockTransaction(&kRangeGET_TransactionOK);
4657}
4658
4659// Tests that we don't delete a sparse entry when we start a new request after
4660// cancelling the previous one.
4661TEST(HttpCache, RangeGET_Cancel2) {
4662  MockHttpCache cache;
4663  AddMockTransaction(&kRangeGET_TransactionOK);
4664
4665  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4666  MockHttpRequest request(kRangeGET_TransactionOK);
4667  request.load_flags |= net::LOAD_VALIDATE_CACHE;
4668
4669  Context* c = new Context();
4670  int rv = cache.CreateTransaction(&c->trans);
4671  ASSERT_EQ(net::OK, rv);
4672
4673  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4674  if (rv == net::ERR_IO_PENDING)
4675    rv = c->callback.WaitForResult();
4676
4677  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4678  EXPECT_EQ(1, cache.disk_cache()->open_count());
4679  EXPECT_EQ(1, cache.disk_cache()->create_count());
4680
4681  // Make sure that we revalidate the entry and read from the cache (a single
4682  // read will return while waiting for the network).
4683  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
4684  rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4685  EXPECT_EQ(5, c->callback.GetResult(rv));
4686  rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4687  EXPECT_EQ(net::ERR_IO_PENDING, rv);
4688
4689  // Destroy the transaction before completing the read.
4690  delete c;
4691
4692  // We have the read and the delete (OnProcessPendingQueue) waiting on the
4693  // message loop. This means that a new transaction will just reuse the same
4694  // active entry (no open or create).
4695
4696  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4697
4698  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4699  EXPECT_EQ(1, cache.disk_cache()->open_count());
4700  EXPECT_EQ(1, cache.disk_cache()->create_count());
4701  RemoveMockTransaction(&kRangeGET_TransactionOK);
4702}
4703
4704// A slight variation of the previous test, this time we cancel two requests in
4705// a row, making sure that the second is waiting for the entry to be ready.
4706TEST(HttpCache, RangeGET_Cancel3) {
4707  MockHttpCache cache;
4708  AddMockTransaction(&kRangeGET_TransactionOK);
4709
4710  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4711  MockHttpRequest request(kRangeGET_TransactionOK);
4712  request.load_flags |= net::LOAD_VALIDATE_CACHE;
4713
4714  Context* c = new Context();
4715  int rv = cache.CreateTransaction(&c->trans);
4716  ASSERT_EQ(net::OK, rv);
4717
4718  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4719  EXPECT_EQ(net::ERR_IO_PENDING, rv);
4720  rv = c->callback.WaitForResult();
4721
4722  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4723  EXPECT_EQ(1, cache.disk_cache()->open_count());
4724  EXPECT_EQ(1, cache.disk_cache()->create_count());
4725
4726  // Make sure that we revalidate the entry and read from the cache (a single
4727  // read will return while waiting for the network).
4728  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
4729  rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4730  EXPECT_EQ(5, c->callback.GetResult(rv));
4731  rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
4732  EXPECT_EQ(net::ERR_IO_PENDING, rv);
4733
4734  // Destroy the transaction before completing the read.
4735  delete c;
4736
4737  // We have the read and the delete (OnProcessPendingQueue) waiting on the
4738  // message loop. This means that a new transaction will just reuse the same
4739  // active entry (no open or create).
4740
4741  c = new Context();
4742  rv = cache.CreateTransaction(&c->trans);
4743  ASSERT_EQ(net::OK, rv);
4744
4745  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
4746  EXPECT_EQ(net::ERR_IO_PENDING, rv);
4747
4748  MockDiskEntry::IgnoreCallbacks(true);
4749  base::MessageLoop::current()->RunUntilIdle();
4750  MockDiskEntry::IgnoreCallbacks(false);
4751
4752  // The new transaction is waiting for the query range callback.
4753  delete c;
4754
4755  // And we should not crash when the callback is delivered.
4756  base::MessageLoop::current()->RunUntilIdle();
4757
4758  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4759  EXPECT_EQ(1, cache.disk_cache()->open_count());
4760  EXPECT_EQ(1, cache.disk_cache()->create_count());
4761  RemoveMockTransaction(&kRangeGET_TransactionOK);
4762}
4763
4764// Tests that an invalid range response results in no cached entry.
4765TEST(HttpCache, RangeGET_InvalidResponse1) {
4766  MockHttpCache cache;
4767  std::string headers;
4768
4769  MockTransaction transaction(kRangeGET_TransactionOK);
4770  transaction.handler = NULL;
4771  transaction.response_headers = "Content-Range: bytes 40-49/45\n"
4772                                 "Content-Length: 10\n";
4773  AddMockTransaction(&transaction);
4774  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4775
4776  std::string expected(transaction.status);
4777  expected.append("\n");
4778  expected.append(transaction.response_headers);
4779  EXPECT_EQ(expected, headers);
4780
4781  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4782  EXPECT_EQ(0, cache.disk_cache()->open_count());
4783  EXPECT_EQ(1, cache.disk_cache()->create_count());
4784
4785  // Verify that we don't have a cached entry.
4786  disk_cache::Entry* entry;
4787  EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4788
4789  RemoveMockTransaction(&kRangeGET_TransactionOK);
4790}
4791
4792// Tests that we reject a range that doesn't match the content-length.
4793TEST(HttpCache, RangeGET_InvalidResponse2) {
4794  MockHttpCache cache;
4795  std::string headers;
4796
4797  MockTransaction transaction(kRangeGET_TransactionOK);
4798  transaction.handler = NULL;
4799  transaction.response_headers = "Content-Range: bytes 40-49/80\n"
4800                                 "Content-Length: 20\n";
4801  AddMockTransaction(&transaction);
4802  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4803
4804  std::string expected(transaction.status);
4805  expected.append("\n");
4806  expected.append(transaction.response_headers);
4807  EXPECT_EQ(expected, headers);
4808
4809  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4810  EXPECT_EQ(0, cache.disk_cache()->open_count());
4811  EXPECT_EQ(1, cache.disk_cache()->create_count());
4812
4813  // Verify that we don't have a cached entry.
4814  disk_cache::Entry* entry;
4815  EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
4816
4817  RemoveMockTransaction(&kRangeGET_TransactionOK);
4818}
4819
4820// Tests that if a server tells us conflicting information about a resource we
4821// ignore the response.
4822TEST(HttpCache, RangeGET_InvalidResponse3) {
4823  MockHttpCache cache;
4824  std::string headers;
4825
4826  MockTransaction transaction(kRangeGET_TransactionOK);
4827  transaction.handler = NULL;
4828  transaction.request_headers = "Range: bytes = 50-59\r\n" EXTRA_HEADER;
4829  std::string response_headers(transaction.response_headers);
4830  response_headers.append("Content-Range: bytes 50-59/160\n");
4831  transaction.response_headers = response_headers.c_str();
4832  AddMockTransaction(&transaction);
4833  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4834
4835  Verify206Response(headers, 50, 59);
4836  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4837  EXPECT_EQ(0, cache.disk_cache()->open_count());
4838  EXPECT_EQ(1, cache.disk_cache()->create_count());
4839
4840  RemoveMockTransaction(&transaction);
4841  AddMockTransaction(&kRangeGET_TransactionOK);
4842
4843  // This transaction will report a resource size of 80 bytes, and we think it's
4844  // 160 so we should ignore the response.
4845  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
4846                                 &headers);
4847
4848  Verify206Response(headers, 40, 49);
4849  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4850  EXPECT_EQ(1, cache.disk_cache()->open_count());
4851  EXPECT_EQ(1, cache.disk_cache()->create_count());
4852
4853  // Verify that we cached the first response but not the second one.
4854  disk_cache::Entry* en;
4855  ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
4856
4857  int64 cached_start = 0;
4858  net::TestCompletionCallback cb;
4859  int rv = en->GetAvailableRange(40, 20, &cached_start, cb.callback());
4860  EXPECT_EQ(10, cb.GetResult(rv));
4861  EXPECT_EQ(50, cached_start);
4862  en->Close();
4863
4864  RemoveMockTransaction(&kRangeGET_TransactionOK);
4865}
4866
4867// Tests that we handle large range values properly.
4868TEST(HttpCache, RangeGET_LargeValues) {
4869  // We need a real sparse cache for this test.
4870  MockHttpCache cache(net::HttpCache::DefaultBackend::InMemory(1024 * 1024));
4871  std::string headers;
4872
4873  MockTransaction transaction(kRangeGET_TransactionOK);
4874  transaction.handler = NULL;
4875  transaction.request_headers = "Range: bytes = 4294967288-4294967297\r\n"
4876                                EXTRA_HEADER;
4877  transaction.response_headers =
4878      "ETag: \"foo\"\n"
4879      "Content-Range: bytes 4294967288-4294967297/4294967299\n"
4880      "Content-Length: 10\n";
4881  AddMockTransaction(&transaction);
4882  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4883
4884  std::string expected(transaction.status);
4885  expected.append("\n");
4886  expected.append(transaction.response_headers);
4887  EXPECT_EQ(expected, headers);
4888
4889  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4890
4891  // Verify that we have a cached entry.
4892  disk_cache::Entry* en;
4893  ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &en));
4894  en->Close();
4895
4896  RemoveMockTransaction(&kRangeGET_TransactionOK);
4897}
4898
4899// Tests that we don't crash with a range request if the disk cache was not
4900// initialized properly.
4901TEST(HttpCache, RangeGET_NoDiskCache) {
4902  MockBlockingBackendFactory* factory = new MockBlockingBackendFactory();
4903  factory->set_fail(true);
4904  factory->FinishCreation();  // We'll complete synchronously.
4905  MockHttpCache cache(factory);
4906
4907  AddMockTransaction(&kRangeGET_TransactionOK);
4908
4909  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4910  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4911
4912  RemoveMockTransaction(&kRangeGET_TransactionOK);
4913}
4914
4915// Tests that we handle byte range requests that skip the cache.
4916TEST(HttpCache, RangeHEAD) {
4917  MockHttpCache cache;
4918  AddMockTransaction(&kRangeGET_TransactionOK);
4919
4920  MockTransaction transaction(kRangeGET_TransactionOK);
4921  transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
4922  transaction.method = "HEAD";
4923  transaction.data = "rg: 70-79 ";
4924
4925  std::string headers;
4926  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
4927
4928  Verify206Response(headers, 70, 79);
4929  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4930  EXPECT_EQ(0, cache.disk_cache()->open_count());
4931  EXPECT_EQ(0, cache.disk_cache()->create_count());
4932
4933  RemoveMockTransaction(&kRangeGET_TransactionOK);
4934}
4935
4936// Tests that we don't crash when after reading from the cache we issue a
4937// request for the next range and the server gives us a 200 synchronously.
4938TEST(HttpCache, RangeGET_FastFlakyServer) {
4939  MockHttpCache cache;
4940
4941  MockTransaction transaction(kRangeGET_TransactionOK);
4942  transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER;
4943  transaction.test_mode = TEST_MODE_SYNC_NET_START;
4944  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
4945  AddMockTransaction(&transaction);
4946
4947  // Write to the cache.
4948  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
4949
4950  // And now read from the cache and the network.
4951  RangeTransactionServer handler;
4952  handler.set_bad_200(true);
4953  transaction.data = "Not a range";
4954  RunTransactionTest(cache.http_cache(), transaction);
4955
4956  EXPECT_EQ(3, cache.network_layer()->transaction_count());
4957  EXPECT_EQ(1, cache.disk_cache()->open_count());
4958  EXPECT_EQ(1, cache.disk_cache()->create_count());
4959
4960  RemoveMockTransaction(&transaction);
4961}
4962
4963// Tests that when the server gives us less data than expected, we don't keep
4964// asking for more data.
4965TEST(HttpCache, RangeGET_FastFlakyServer2) {
4966  MockHttpCache cache;
4967
4968  // First, check with an empty cache (WRITE mode).
4969  MockTransaction transaction(kRangeGET_TransactionOK);
4970  transaction.request_headers = "Range: bytes = 40-49\r\n" EXTRA_HEADER;
4971  transaction.data = "rg: 40-";  // Less than expected.
4972  transaction.handler = NULL;
4973  std::string headers(transaction.response_headers);
4974  headers.append("Content-Range: bytes 40-49/80\n");
4975  transaction.response_headers = headers.c_str();
4976
4977  AddMockTransaction(&transaction);
4978
4979  // Write to the cache.
4980  RunTransactionTest(cache.http_cache(), transaction);
4981
4982  EXPECT_EQ(1, cache.network_layer()->transaction_count());
4983  EXPECT_EQ(0, cache.disk_cache()->open_count());
4984  EXPECT_EQ(1, cache.disk_cache()->create_count());
4985
4986  // Now verify that even in READ_WRITE mode, we forward the bad response to
4987  // the caller.
4988  transaction.request_headers = "Range: bytes = 60-69\r\n" EXTRA_HEADER;
4989  transaction.data = "rg: 60-";  // Less than expected.
4990  headers = kRangeGET_TransactionOK.response_headers;
4991  headers.append("Content-Range: bytes 60-69/80\n");
4992  transaction.response_headers = headers.c_str();
4993
4994  RunTransactionTest(cache.http_cache(), transaction);
4995
4996  EXPECT_EQ(2, cache.network_layer()->transaction_count());
4997  EXPECT_EQ(1, cache.disk_cache()->open_count());
4998  EXPECT_EQ(1, cache.disk_cache()->create_count());
4999
5000  RemoveMockTransaction(&transaction);
5001}
5002
5003#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
5004// This test hits a NOTREACHED so it is a release mode only test.
5005TEST(HttpCache, RangeGET_OK_LoadOnlyFromCache) {
5006  MockHttpCache cache;
5007  AddMockTransaction(&kRangeGET_TransactionOK);
5008
5009  // Write to the cache (40-49).
5010  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
5011  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5012  EXPECT_EQ(0, cache.disk_cache()->open_count());
5013  EXPECT_EQ(1, cache.disk_cache()->create_count());
5014
5015  // Force this transaction to read from the cache.
5016  MockTransaction transaction(kRangeGET_TransactionOK);
5017  transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5018
5019  MockHttpRequest request(transaction);
5020  net::TestCompletionCallback callback;
5021
5022  scoped_ptr<net::HttpTransaction> trans;
5023  int rv = cache.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY, &trans);
5024  EXPECT_EQ(net::OK, rv);
5025  ASSERT_TRUE(trans.get());
5026
5027  rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5028  if (rv == net::ERR_IO_PENDING)
5029    rv = callback.WaitForResult();
5030  ASSERT_EQ(net::ERR_CACHE_MISS, rv);
5031
5032  trans.reset();
5033
5034  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5035  EXPECT_EQ(1, cache.disk_cache()->open_count());
5036  EXPECT_EQ(1, cache.disk_cache()->create_count());
5037
5038  RemoveMockTransaction(&kRangeGET_TransactionOK);
5039}
5040#endif
5041
5042// Tests the handling of the "truncation" flag.
5043TEST(HttpCache, WriteResponseInfo_Truncated) {
5044  MockHttpCache cache;
5045  disk_cache::Entry* entry;
5046  ASSERT_TRUE(cache.CreateBackendEntry("http://www.google.com", &entry,
5047                                       NULL));
5048
5049  std::string headers("HTTP/1.1 200 OK");
5050  headers = net::HttpUtil::AssembleRawHeaders(headers.data(), headers.size());
5051  net::HttpResponseInfo response;
5052  response.headers = new net::HttpResponseHeaders(headers);
5053
5054  // Set the last argument for this to be an incomplete request.
5055  EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
5056  bool truncated = false;
5057  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5058  EXPECT_TRUE(truncated);
5059
5060  // And now test the opposite case.
5061  EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
5062  truncated = true;
5063  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5064  EXPECT_FALSE(truncated);
5065  entry->Close();
5066}
5067
5068// Tests basic pickling/unpickling of HttpResponseInfo.
5069TEST(HttpCache, PersistHttpResponseInfo) {
5070  // Set some fields (add more if needed.)
5071  net::HttpResponseInfo response1;
5072  response1.was_cached = false;
5073  response1.socket_address = net::HostPortPair("1.2.3.4", 80);
5074  response1.headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK");
5075
5076  // Pickle.
5077  Pickle pickle;
5078  response1.Persist(&pickle, false, false);
5079
5080  // Unpickle.
5081  net::HttpResponseInfo response2;
5082  bool response_truncated;
5083  EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated));
5084  EXPECT_FALSE(response_truncated);
5085
5086  // Verify fields.
5087  EXPECT_TRUE(response2.was_cached);  // InitFromPickle sets this flag.
5088  EXPECT_EQ("1.2.3.4", response2.socket_address.host());
5089  EXPECT_EQ(80, response2.socket_address.port());
5090  EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
5091}
5092
5093// Tests that we delete an entry when the request is cancelled before starting
5094// to read from the network.
5095TEST(HttpCache, DoomOnDestruction) {
5096  MockHttpCache cache;
5097
5098  MockHttpRequest request(kSimpleGET_Transaction);
5099
5100  Context* c = new Context();
5101  int rv = cache.CreateTransaction(&c->trans);
5102  ASSERT_EQ(net::OK, rv);
5103
5104  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5105  if (rv == net::ERR_IO_PENDING)
5106    c->result = c->callback.WaitForResult();
5107
5108  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5109  EXPECT_EQ(0, cache.disk_cache()->open_count());
5110  EXPECT_EQ(1, cache.disk_cache()->create_count());
5111
5112  // Destroy the transaction. We only have the headers so we should delete this
5113  // entry.
5114  delete c;
5115
5116  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5117
5118  EXPECT_EQ(2, cache.network_layer()->transaction_count());
5119  EXPECT_EQ(0, cache.disk_cache()->open_count());
5120  EXPECT_EQ(2, cache.disk_cache()->create_count());
5121}
5122
5123// Tests that we delete an entry when the request is cancelled if the response
5124// does not have content-length and strong validators.
5125TEST(HttpCache, DoomOnDestruction2) {
5126  MockHttpCache cache;
5127
5128  MockHttpRequest request(kSimpleGET_Transaction);
5129
5130  Context* c = new Context();
5131  int rv = cache.CreateTransaction(&c->trans);
5132  ASSERT_EQ(net::OK, rv);
5133
5134  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5135  if (rv == net::ERR_IO_PENDING)
5136    rv = c->callback.WaitForResult();
5137
5138  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5139  EXPECT_EQ(0, cache.disk_cache()->open_count());
5140  EXPECT_EQ(1, cache.disk_cache()->create_count());
5141
5142  // Make sure that the entry has some data stored.
5143  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
5144  rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5145  if (rv == net::ERR_IO_PENDING)
5146    rv = c->callback.WaitForResult();
5147  EXPECT_EQ(buf->size(), rv);
5148
5149  // Destroy the transaction.
5150  delete c;
5151
5152  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5153
5154  EXPECT_EQ(2, cache.network_layer()->transaction_count());
5155  EXPECT_EQ(0, cache.disk_cache()->open_count());
5156  EXPECT_EQ(2, cache.disk_cache()->create_count());
5157}
5158
5159// Tests that we delete an entry when the request is cancelled if the response
5160// has an "Accept-Ranges: none" header.
5161TEST(HttpCache, DoomOnDestruction3) {
5162  MockHttpCache cache;
5163
5164  MockTransaction transaction(kSimpleGET_Transaction);
5165  transaction.response_headers =
5166      "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5167      "Content-Length: 22\n"
5168      "Accept-Ranges: none\n"
5169      "Etag: \"foopy\"\n";
5170  AddMockTransaction(&transaction);
5171  MockHttpRequest request(transaction);
5172
5173  Context* c = new Context();
5174  int rv = cache.CreateTransaction(&c->trans);
5175  ASSERT_EQ(net::OK, rv);
5176
5177  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5178  if (rv == net::ERR_IO_PENDING)
5179    rv = c->callback.WaitForResult();
5180
5181  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5182  EXPECT_EQ(0, cache.disk_cache()->open_count());
5183  EXPECT_EQ(1, cache.disk_cache()->create_count());
5184
5185  // Make sure that the entry has some data stored.
5186  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
5187  rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5188  if (rv == net::ERR_IO_PENDING)
5189    rv = c->callback.WaitForResult();
5190  EXPECT_EQ(buf->size(), rv);
5191
5192  // Destroy the transaction.
5193  delete c;
5194
5195  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5196
5197  EXPECT_EQ(2, cache.network_layer()->transaction_count());
5198  EXPECT_EQ(0, cache.disk_cache()->open_count());
5199  EXPECT_EQ(2, cache.disk_cache()->create_count());
5200
5201  RemoveMockTransaction(&transaction);
5202}
5203
5204// Tests that we mark an entry as incomplete when the request is cancelled.
5205TEST(HttpCache, SetTruncatedFlag) {
5206  MockHttpCache cache;
5207
5208  MockTransaction transaction(kSimpleGET_Transaction);
5209  transaction.response_headers =
5210      "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5211      "Content-Length: 22\n"
5212      "Etag: \"foopy\"\n";
5213  AddMockTransaction(&transaction);
5214  MockHttpRequest request(transaction);
5215
5216  scoped_ptr<Context> c(new Context());
5217
5218  int rv = cache.CreateTransaction(&c->trans);
5219  ASSERT_EQ(net::OK, rv);
5220
5221  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5222  if (rv == net::ERR_IO_PENDING)
5223    rv = c->callback.WaitForResult();
5224
5225  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5226  EXPECT_EQ(0, cache.disk_cache()->open_count());
5227  EXPECT_EQ(1, cache.disk_cache()->create_count());
5228
5229  // Make sure that the entry has some data stored.
5230  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(10));
5231  rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5232  if (rv == net::ERR_IO_PENDING)
5233    rv = c->callback.WaitForResult();
5234  EXPECT_EQ(buf->size(), rv);
5235
5236  // We want to cancel the request when the transaction is busy.
5237  rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5238  EXPECT_EQ(net::ERR_IO_PENDING, rv);
5239  EXPECT_FALSE(c->callback.have_result());
5240
5241  MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL);
5242
5243  // Destroy the transaction.
5244  c->trans.reset();
5245  MockHttpCache::SetTestMode(0);
5246
5247
5248  // Make sure that we don't invoke the callback. We may have an issue if the
5249  // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
5250  // could end up with the transaction being deleted twice if we send any
5251  // notification from the transaction destructor (see http://crbug.com/31723).
5252  EXPECT_FALSE(c->callback.have_result());
5253
5254  // Verify that the entry is marked as incomplete.
5255  disk_cache::Entry* entry;
5256  ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
5257  net::HttpResponseInfo response;
5258  bool truncated = false;
5259  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5260  EXPECT_TRUE(truncated);
5261  entry->Close();
5262
5263  RemoveMockTransaction(&transaction);
5264}
5265
5266// Tests that we don't mark an entry as truncated when we read everything.
5267TEST(HttpCache, DontSetTruncatedFlag) {
5268  MockHttpCache cache;
5269
5270  MockTransaction transaction(kSimpleGET_Transaction);
5271  transaction.response_headers =
5272      "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5273      "Content-Length: 22\n"
5274      "Etag: \"foopy\"\n";
5275  AddMockTransaction(&transaction);
5276  MockHttpRequest request(transaction);
5277
5278  scoped_ptr<Context> c(new Context());
5279  int rv = cache.CreateTransaction(&c->trans);
5280  ASSERT_EQ(net::OK, rv);
5281
5282  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5283  EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5284
5285  // Read everything.
5286  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(22));
5287  rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5288  EXPECT_EQ(buf->size(), c->callback.GetResult(rv));
5289
5290  // Destroy the transaction.
5291  c->trans.reset();
5292
5293  // Verify that the entry is not marked as truncated.
5294  disk_cache::Entry* entry;
5295  ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
5296  net::HttpResponseInfo response;
5297  bool truncated = true;
5298  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5299  EXPECT_FALSE(truncated);
5300  entry->Close();
5301
5302  RemoveMockTransaction(&transaction);
5303}
5304
5305// Tests that we can continue with a request that was interrupted.
5306TEST(HttpCache, GET_IncompleteResource) {
5307  MockHttpCache cache;
5308  AddMockTransaction(&kRangeGET_TransactionOK);
5309
5310  std::string raw_headers("HTTP/1.1 200 OK\n"
5311                          "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5312                          "ETag: \"foo\"\n"
5313                          "Accept-Ranges: bytes\n"
5314                          "Content-Length: 80\n");
5315  CreateTruncatedEntry(raw_headers, &cache);
5316
5317  // Now make a regular request.
5318  std::string headers;
5319  MockTransaction transaction(kRangeGET_TransactionOK);
5320  transaction.request_headers = EXTRA_HEADER;
5321  transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5322                     "rg: 50-59 rg: 60-69 rg: 70-79 ";
5323  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5324
5325  // We update the headers with the ones received while revalidating.
5326  std::string expected_headers(
5327      "HTTP/1.1 200 OK\n"
5328      "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5329      "Accept-Ranges: bytes\n"
5330      "ETag: \"foo\"\n"
5331      "Content-Length: 80\n");
5332
5333  EXPECT_EQ(expected_headers, headers);
5334  EXPECT_EQ(2, cache.network_layer()->transaction_count());
5335  EXPECT_EQ(1, cache.disk_cache()->open_count());
5336  EXPECT_EQ(1, cache.disk_cache()->create_count());
5337
5338  // Verify that the disk entry was updated.
5339  disk_cache::Entry* entry;
5340  ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5341  EXPECT_EQ(80, entry->GetDataSize(1));
5342  bool truncated = true;
5343  net::HttpResponseInfo response;
5344  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5345  EXPECT_FALSE(truncated);
5346  entry->Close();
5347
5348  RemoveMockTransaction(&kRangeGET_TransactionOK);
5349}
5350
5351// Tests the handling of no-store when revalidating a truncated entry.
5352TEST(HttpCache, GET_IncompleteResource_NoStore) {
5353  MockHttpCache cache;
5354  AddMockTransaction(&kRangeGET_TransactionOK);
5355
5356  std::string raw_headers("HTTP/1.1 200 OK\n"
5357                          "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5358                          "ETag: \"foo\"\n"
5359                          "Accept-Ranges: bytes\n"
5360                          "Content-Length: 80\n");
5361  CreateTruncatedEntry(raw_headers, &cache);
5362  RemoveMockTransaction(&kRangeGET_TransactionOK);
5363
5364  // Now make a regular request.
5365  MockTransaction transaction(kRangeGET_TransactionOK);
5366  transaction.request_headers = EXTRA_HEADER;
5367  std::string response_headers(transaction.response_headers);
5368  response_headers += ("Cache-Control: no-store\n");
5369  transaction.response_headers = response_headers.c_str();
5370  transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5371                     "rg: 50-59 rg: 60-69 rg: 70-79 ";
5372  AddMockTransaction(&transaction);
5373
5374  std::string headers;
5375  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5376
5377  // We update the headers with the ones received while revalidating.
5378  std::string expected_headers(
5379      "HTTP/1.1 200 OK\n"
5380      "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5381      "Accept-Ranges: bytes\n"
5382      "Cache-Control: no-store\n"
5383      "ETag: \"foo\"\n"
5384      "Content-Length: 80\n");
5385
5386  EXPECT_EQ(expected_headers, headers);
5387  EXPECT_EQ(2, cache.network_layer()->transaction_count());
5388  EXPECT_EQ(1, cache.disk_cache()->open_count());
5389  EXPECT_EQ(1, cache.disk_cache()->create_count());
5390
5391  // Verify that the disk entry was deleted.
5392  disk_cache::Entry* entry;
5393  EXPECT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5394  RemoveMockTransaction(&transaction);
5395}
5396
5397// Tests cancelling a request after the server sent no-store.
5398TEST(HttpCache, GET_IncompleteResource_Cancel) {
5399  MockHttpCache cache;
5400  AddMockTransaction(&kRangeGET_TransactionOK);
5401
5402  std::string raw_headers("HTTP/1.1 200 OK\n"
5403                          "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5404                          "ETag: \"foo\"\n"
5405                          "Accept-Ranges: bytes\n"
5406                          "Content-Length: 80\n");
5407  CreateTruncatedEntry(raw_headers, &cache);
5408  RemoveMockTransaction(&kRangeGET_TransactionOK);
5409
5410  // Now make a regular request.
5411  MockTransaction transaction(kRangeGET_TransactionOK);
5412  transaction.request_headers = EXTRA_HEADER;
5413  std::string response_headers(transaction.response_headers);
5414  response_headers += ("Cache-Control: no-store\n");
5415  transaction.response_headers = response_headers.c_str();
5416  transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5417                     "rg: 50-59 rg: 60-69 rg: 70-79 ";
5418  AddMockTransaction(&transaction);
5419
5420  MockHttpRequest request(transaction);
5421  Context* c = new Context();
5422
5423  int rv = cache.CreateTransaction(&c->trans);
5424  ASSERT_EQ(net::OK, rv);
5425
5426  // Queue another request to this transaction. We have to start this request
5427  // before the first one gets the response from the server and dooms the entry,
5428  // otherwise it will just create a new entry without being queued to the first
5429  // request.
5430  Context* pending = new Context();
5431  ASSERT_EQ(net::OK, cache.CreateTransaction(&pending->trans));
5432
5433  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5434  EXPECT_EQ(net::ERR_IO_PENDING,
5435            pending->trans->Start(&request, pending->callback.callback(),
5436                                  net::BoundNetLog()));
5437  EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5438
5439  // Make sure that the entry has some data stored.
5440  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(5));
5441  rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
5442  EXPECT_EQ(5, c->callback.GetResult(rv));
5443
5444  // Cancel the requests.
5445  delete c;
5446  delete pending;
5447
5448  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5449  EXPECT_EQ(1, cache.disk_cache()->open_count());
5450  EXPECT_EQ(2, cache.disk_cache()->create_count());
5451
5452  base::MessageLoop::current()->RunUntilIdle();
5453  RemoveMockTransaction(&transaction);
5454}
5455
5456// Tests that we delete truncated entries if the server changes its mind midway.
5457TEST(HttpCache, GET_IncompleteResource2) {
5458  MockHttpCache cache;
5459  AddMockTransaction(&kRangeGET_TransactionOK);
5460
5461  // Content-length will be intentionally bad.
5462  std::string raw_headers("HTTP/1.1 200 OK\n"
5463                          "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5464                          "ETag: \"foo\"\n"
5465                          "Accept-Ranges: bytes\n"
5466                          "Content-Length: 50\n");
5467  CreateTruncatedEntry(raw_headers, &cache);
5468
5469  // Now make a regular request. We expect the code to fail the validation and
5470  // retry the request without using byte ranges.
5471  std::string headers;
5472  MockTransaction transaction(kRangeGET_TransactionOK);
5473  transaction.request_headers = EXTRA_HEADER;
5474  transaction.data = "Not a range";
5475  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5476
5477  // The server will return 200 instead of a byte range.
5478  std::string expected_headers(
5479      "HTTP/1.1 200 OK\n"
5480      "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
5481
5482  EXPECT_EQ(expected_headers, headers);
5483  EXPECT_EQ(2, cache.network_layer()->transaction_count());
5484  EXPECT_EQ(1, cache.disk_cache()->open_count());
5485  EXPECT_EQ(1, cache.disk_cache()->create_count());
5486
5487  // Verify that the disk entry was deleted.
5488  disk_cache::Entry* entry;
5489  ASSERT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5490  RemoveMockTransaction(&kRangeGET_TransactionOK);
5491}
5492
5493// Tests that we always validate a truncated request.
5494TEST(HttpCache, GET_IncompleteResource3) {
5495  MockHttpCache cache;
5496  AddMockTransaction(&kRangeGET_TransactionOK);
5497
5498  // This should not require validation for 10 hours.
5499  std::string raw_headers("HTTP/1.1 200 OK\n"
5500                          "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5501                          "ETag: \"foo\"\n"
5502                          "Cache-Control: max-age= 36000\n"
5503                          "Accept-Ranges: bytes\n"
5504                          "Content-Length: 80\n");
5505  CreateTruncatedEntry(raw_headers, &cache);
5506
5507  // Now make a regular request.
5508  std::string headers;
5509  MockTransaction transaction(kRangeGET_TransactionOK);
5510  transaction.request_headers = EXTRA_HEADER;
5511  transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5512                     "rg: 50-59 rg: 60-69 rg: 70-79 ";
5513
5514  scoped_ptr<Context> c(new Context);
5515  int rv = cache.CreateTransaction(&c->trans);
5516  ASSERT_EQ(net::OK, rv);
5517
5518  MockHttpRequest request(transaction);
5519  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5520  EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5521
5522  // We should have checked with the server before finishing Start().
5523  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5524  EXPECT_EQ(1, cache.disk_cache()->open_count());
5525  EXPECT_EQ(1, cache.disk_cache()->create_count());
5526
5527  RemoveMockTransaction(&kRangeGET_TransactionOK);
5528}
5529
5530// Tests that we handle 401s for truncated resources.
5531TEST(HttpCache, GET_IncompleteResourceWithAuth) {
5532  MockHttpCache cache;
5533  AddMockTransaction(&kRangeGET_TransactionOK);
5534
5535  std::string raw_headers("HTTP/1.1 200 OK\n"
5536                          "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
5537                          "ETag: \"foo\"\n"
5538                          "Accept-Ranges: bytes\n"
5539                          "Content-Length: 80\n");
5540  CreateTruncatedEntry(raw_headers, &cache);
5541
5542  // Now make a regular request.
5543  MockTransaction transaction(kRangeGET_TransactionOK);
5544  transaction.request_headers = "X-Require-Mock-Auth: dummy\r\n"
5545                                EXTRA_HEADER;
5546  transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
5547                     "rg: 50-59 rg: 60-69 rg: 70-79 ";
5548  RangeTransactionServer handler;
5549
5550  scoped_ptr<Context> c(new Context);
5551  int rv = cache.CreateTransaction(&c->trans);
5552  ASSERT_EQ(net::OK, rv);
5553
5554  MockHttpRequest request(transaction);
5555  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5556  EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5557
5558  const net::HttpResponseInfo* response = c->trans->GetResponseInfo();
5559  ASSERT_TRUE(response);
5560  ASSERT_EQ(401, response->headers->response_code());
5561  rv = c->trans->RestartWithAuth(net::AuthCredentials(),
5562                                 c->callback.callback());
5563  EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5564  response = c->trans->GetResponseInfo();
5565  ASSERT_TRUE(response);
5566  ASSERT_EQ(200, response->headers->response_code());
5567
5568  ReadAndVerifyTransaction(c->trans.get(), transaction);
5569  c.reset();  // The destructor could delete the entry.
5570  EXPECT_EQ(2, cache.network_layer()->transaction_count());
5571
5572  // Verify that the entry was not deleted.
5573  disk_cache::Entry* entry;
5574  ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5575  entry->Close();
5576
5577  RemoveMockTransaction(&kRangeGET_TransactionOK);
5578}
5579
5580// Tests that we cache a 200 response to the validation request.
5581TEST(HttpCache, GET_IncompleteResource4) {
5582  MockHttpCache cache;
5583  AddMockTransaction(&kRangeGET_TransactionOK);
5584
5585  std::string raw_headers("HTTP/1.1 200 OK\n"
5586                          "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5587                          "ETag: \"foo\"\n"
5588                          "Accept-Ranges: bytes\n"
5589                          "Content-Length: 80\n");
5590  CreateTruncatedEntry(raw_headers, &cache);
5591
5592  // Now make a regular request.
5593  std::string headers;
5594  MockTransaction transaction(kRangeGET_TransactionOK);
5595  transaction.request_headers = EXTRA_HEADER;
5596  transaction.data = "Not a range";
5597  RangeTransactionServer handler;
5598  handler.set_bad_200(true);
5599  RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
5600
5601  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5602  EXPECT_EQ(1, cache.disk_cache()->open_count());
5603  EXPECT_EQ(1, cache.disk_cache()->create_count());
5604
5605  // Verify that the disk entry was updated.
5606  disk_cache::Entry* entry;
5607  ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5608  EXPECT_EQ(11, entry->GetDataSize(1));
5609  bool truncated = true;
5610  net::HttpResponseInfo response;
5611  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5612  EXPECT_FALSE(truncated);
5613  entry->Close();
5614
5615  RemoveMockTransaction(&kRangeGET_TransactionOK);
5616}
5617
5618// Tests that when we cancel a request that was interrupted, we mark it again
5619// as truncated.
5620TEST(HttpCache, GET_CancelIncompleteResource) {
5621  MockHttpCache cache;
5622  AddMockTransaction(&kRangeGET_TransactionOK);
5623
5624  std::string raw_headers("HTTP/1.1 200 OK\n"
5625                          "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
5626                          "ETag: \"foo\"\n"
5627                          "Accept-Ranges: bytes\n"
5628                          "Content-Length: 80\n");
5629  CreateTruncatedEntry(raw_headers, &cache);
5630
5631  // Now make a regular request.
5632  MockTransaction transaction(kRangeGET_TransactionOK);
5633  transaction.request_headers = EXTRA_HEADER;
5634
5635  MockHttpRequest request(transaction);
5636  Context* c = new Context();
5637  int rv = cache.CreateTransaction(&c->trans);
5638  ASSERT_EQ(net::OK, rv);
5639
5640  rv = c->trans->Start(&request, c->callback.callback(), net::BoundNetLog());
5641  EXPECT_EQ(net::OK, c->callback.GetResult(rv));
5642
5643  // Read 20 bytes from the cache, and 10 from the net.
5644  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100));
5645  rv = c->trans->Read(buf.get(), 20, c->callback.callback());
5646  EXPECT_EQ(20, c->callback.GetResult(rv));
5647  rv = c->trans->Read(buf.get(), 10, c->callback.callback());
5648  EXPECT_EQ(10, c->callback.GetResult(rv));
5649
5650  // At this point, we are already reading so canceling the request should leave
5651  // a truncated one.
5652  delete c;
5653
5654  EXPECT_EQ(2, cache.network_layer()->transaction_count());
5655  EXPECT_EQ(1, cache.disk_cache()->open_count());
5656  EXPECT_EQ(1, cache.disk_cache()->create_count());
5657
5658  // Verify that the disk entry was updated: now we have 30 bytes.
5659  disk_cache::Entry* entry;
5660  ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
5661  EXPECT_EQ(30, entry->GetDataSize(1));
5662  bool truncated = false;
5663  net::HttpResponseInfo response;
5664  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
5665  EXPECT_TRUE(truncated);
5666  entry->Close();
5667  RemoveMockTransaction(&kRangeGET_TransactionOK);
5668}
5669
5670// Tests that we can handle range requests when we have a truncated entry.
5671TEST(HttpCache, RangeGET_IncompleteResource) {
5672  MockHttpCache cache;
5673  AddMockTransaction(&kRangeGET_TransactionOK);
5674
5675  // Content-length will be intentionally bogus.
5676  std::string raw_headers("HTTP/1.1 200 OK\n"
5677                          "Last-Modified: something\n"
5678                          "ETag: \"foo\"\n"
5679                          "Accept-Ranges: bytes\n"
5680                          "Content-Length: 10\n");
5681  CreateTruncatedEntry(raw_headers, &cache);
5682
5683  // Now make a range request.
5684  std::string headers;
5685  RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
5686                                 &headers);
5687
5688  Verify206Response(headers, 40, 49);
5689  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5690  EXPECT_EQ(1, cache.disk_cache()->open_count());
5691  EXPECT_EQ(2, cache.disk_cache()->create_count());
5692
5693  RemoveMockTransaction(&kRangeGET_TransactionOK);
5694}
5695
5696TEST(HttpCache, SyncRead) {
5697  MockHttpCache cache;
5698
5699  // This test ensures that a read that completes synchronously does not cause
5700  // any problems.
5701
5702  ScopedMockTransaction transaction(kSimpleGET_Transaction);
5703  transaction.test_mode |= (TEST_MODE_SYNC_CACHE_START |
5704                            TEST_MODE_SYNC_CACHE_READ |
5705                            TEST_MODE_SYNC_CACHE_WRITE);
5706
5707  MockHttpRequest r1(transaction),
5708                  r2(transaction),
5709                  r3(transaction);
5710
5711  TestTransactionConsumer c1(net::DEFAULT_PRIORITY, cache.http_cache()),
5712                          c2(net::DEFAULT_PRIORITY, cache.http_cache()),
5713                          c3(net::DEFAULT_PRIORITY, cache.http_cache());
5714
5715  c1.Start(&r1, net::BoundNetLog());
5716
5717  r2.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5718  c2.Start(&r2, net::BoundNetLog());
5719
5720  r3.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5721  c3.Start(&r3, net::BoundNetLog());
5722
5723  base::MessageLoop::current()->Run();
5724
5725  EXPECT_TRUE(c1.is_done());
5726  EXPECT_TRUE(c2.is_done());
5727  EXPECT_TRUE(c3.is_done());
5728
5729  EXPECT_EQ(net::OK, c1.error());
5730  EXPECT_EQ(net::OK, c2.error());
5731  EXPECT_EQ(net::OK, c3.error());
5732}
5733
5734TEST(HttpCache, ValidationResultsIn200) {
5735  MockHttpCache cache;
5736
5737  // This test ensures that a conditional request, which results in a 200
5738  // instead of a 304, properly truncates the existing response data.
5739
5740  // write to the cache
5741  RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
5742
5743  // force this transaction to validate the cache
5744  MockTransaction transaction(kETagGET_Transaction);
5745  transaction.load_flags |= net::LOAD_VALIDATE_CACHE;
5746  RunTransactionTest(cache.http_cache(), transaction);
5747
5748  // read from the cache
5749  RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
5750}
5751
5752TEST(HttpCache, CachedRedirect) {
5753  MockHttpCache cache;
5754
5755  ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction);
5756  kTestTransaction.status = "HTTP/1.1 301 Moved Permanently";
5757  kTestTransaction.response_headers = "Location: http://www.bar.com/\n";
5758
5759  MockHttpRequest request(kTestTransaction);
5760  net::TestCompletionCallback callback;
5761
5762  // Write to the cache.
5763  {
5764    scoped_ptr<net::HttpTransaction> trans;
5765    ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
5766
5767    int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5768    if (rv == net::ERR_IO_PENDING)
5769      rv = callback.WaitForResult();
5770    ASSERT_EQ(net::OK, rv);
5771
5772    const net::HttpResponseInfo* info = trans->GetResponseInfo();
5773    ASSERT_TRUE(info);
5774
5775    EXPECT_EQ(info->headers->response_code(), 301);
5776
5777    std::string location;
5778    info->headers->EnumerateHeader(NULL, "Location", &location);
5779    EXPECT_EQ(location, "http://www.bar.com/");
5780
5781    // Mark the transaction as completed so it is cached.
5782    trans->DoneReading();
5783
5784    // Destroy transaction when going out of scope. We have not actually
5785    // read the response body -- want to test that it is still getting cached.
5786  }
5787  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5788  EXPECT_EQ(0, cache.disk_cache()->open_count());
5789  EXPECT_EQ(1, cache.disk_cache()->create_count());
5790
5791  // Active entries in the cache are not retired synchronously. Make
5792  // sure the next run hits the MockHttpCache and open_count is
5793  // correct.
5794  base::MessageLoop::current()->RunUntilIdle();
5795
5796  // Read from the cache.
5797  {
5798    scoped_ptr<net::HttpTransaction> trans;
5799    ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
5800
5801    int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5802    if (rv == net::ERR_IO_PENDING)
5803      rv = callback.WaitForResult();
5804    ASSERT_EQ(net::OK, rv);
5805
5806    const net::HttpResponseInfo* info = trans->GetResponseInfo();
5807    ASSERT_TRUE(info);
5808
5809    EXPECT_EQ(info->headers->response_code(), 301);
5810
5811    std::string location;
5812    info->headers->EnumerateHeader(NULL, "Location", &location);
5813    EXPECT_EQ(location, "http://www.bar.com/");
5814
5815    // Mark the transaction as completed so it is cached.
5816    trans->DoneReading();
5817
5818    // Destroy transaction when going out of scope. We have not actually
5819    // read the response body -- want to test that it is still getting cached.
5820  }
5821  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5822  EXPECT_EQ(1, cache.disk_cache()->open_count());
5823  EXPECT_EQ(1, cache.disk_cache()->create_count());
5824}
5825
5826// Verify that no-cache resources are stored in cache, but are not fetched from
5827// cache during normal loads.
5828TEST(HttpCache, CacheControlNoCacheNormalLoad) {
5829  MockHttpCache cache;
5830
5831  ScopedMockTransaction transaction(kSimpleGET_Transaction);
5832  transaction.response_headers = "cache-control: no-cache\n";
5833
5834  // Initial load.
5835  RunTransactionTest(cache.http_cache(), transaction);
5836
5837  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5838  EXPECT_EQ(0, cache.disk_cache()->open_count());
5839  EXPECT_EQ(1, cache.disk_cache()->create_count());
5840
5841  // Try loading again; it should result in a network fetch.
5842  RunTransactionTest(cache.http_cache(), transaction);
5843
5844  EXPECT_EQ(2, cache.network_layer()->transaction_count());
5845  EXPECT_EQ(1, cache.disk_cache()->open_count());
5846  EXPECT_EQ(1, cache.disk_cache()->create_count());
5847
5848  disk_cache::Entry* entry;
5849  EXPECT_TRUE(cache.OpenBackendEntry(transaction.url, &entry));
5850  entry->Close();
5851}
5852
5853// Verify that no-cache resources are stored in cache and fetched from cache
5854// when the LOAD_PREFERRING_CACHE flag is set.
5855TEST(HttpCache, CacheControlNoCacheHistoryLoad) {
5856  MockHttpCache cache;
5857
5858  ScopedMockTransaction transaction(kSimpleGET_Transaction);
5859  transaction.response_headers = "cache-control: no-cache\n";
5860
5861  // Initial load.
5862  RunTransactionTest(cache.http_cache(), transaction);
5863
5864  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5865  EXPECT_EQ(0, cache.disk_cache()->open_count());
5866  EXPECT_EQ(1, cache.disk_cache()->create_count());
5867
5868  // Try loading again with LOAD_PREFERRING_CACHE.
5869  transaction.load_flags = net::LOAD_PREFERRING_CACHE;
5870  RunTransactionTest(cache.http_cache(), transaction);
5871
5872  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5873  EXPECT_EQ(1, cache.disk_cache()->open_count());
5874  EXPECT_EQ(1, cache.disk_cache()->create_count());
5875
5876  disk_cache::Entry* entry;
5877  EXPECT_TRUE(cache.OpenBackendEntry(transaction.url, &entry));
5878  entry->Close();
5879}
5880
5881TEST(HttpCache, CacheControlNoStore) {
5882  MockHttpCache cache;
5883
5884  ScopedMockTransaction transaction(kSimpleGET_Transaction);
5885  transaction.response_headers = "cache-control: no-store\n";
5886
5887  // initial load
5888  RunTransactionTest(cache.http_cache(), transaction);
5889
5890  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5891  EXPECT_EQ(0, cache.disk_cache()->open_count());
5892  EXPECT_EQ(1, cache.disk_cache()->create_count());
5893
5894  // try loading again; it should result in a network fetch
5895  RunTransactionTest(cache.http_cache(), transaction);
5896
5897  EXPECT_EQ(2, cache.network_layer()->transaction_count());
5898  EXPECT_EQ(0, cache.disk_cache()->open_count());
5899  EXPECT_EQ(2, cache.disk_cache()->create_count());
5900
5901  disk_cache::Entry* entry;
5902  EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
5903}
5904
5905TEST(HttpCache, CacheControlNoStore2) {
5906  // this test is similar to the above test, except that the initial response
5907  // is cachable, but when it is validated, no-store is received causing the
5908  // cached document to be deleted.
5909  MockHttpCache cache;
5910
5911  ScopedMockTransaction transaction(kETagGET_Transaction);
5912
5913  // initial load
5914  RunTransactionTest(cache.http_cache(), transaction);
5915
5916  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5917  EXPECT_EQ(0, cache.disk_cache()->open_count());
5918  EXPECT_EQ(1, cache.disk_cache()->create_count());
5919
5920  // try loading again; it should result in a network fetch
5921  transaction.load_flags = net::LOAD_VALIDATE_CACHE;
5922  transaction.response_headers = "cache-control: no-store\n";
5923  RunTransactionTest(cache.http_cache(), transaction);
5924
5925  EXPECT_EQ(2, cache.network_layer()->transaction_count());
5926  EXPECT_EQ(1, cache.disk_cache()->open_count());
5927  EXPECT_EQ(1, cache.disk_cache()->create_count());
5928
5929  disk_cache::Entry* entry;
5930  EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
5931}
5932
5933TEST(HttpCache, CacheControlNoStore3) {
5934  // this test is similar to the above test, except that the response is a 304
5935  // instead of a 200.  this should never happen in practice, but it seems like
5936  // a good thing to verify that we still destroy the cache entry.
5937  MockHttpCache cache;
5938
5939  ScopedMockTransaction transaction(kETagGET_Transaction);
5940
5941  // initial load
5942  RunTransactionTest(cache.http_cache(), transaction);
5943
5944  EXPECT_EQ(1, cache.network_layer()->transaction_count());
5945  EXPECT_EQ(0, cache.disk_cache()->open_count());
5946  EXPECT_EQ(1, cache.disk_cache()->create_count());
5947
5948  // try loading again; it should result in a network fetch
5949  transaction.load_flags = net::LOAD_VALIDATE_CACHE;
5950  transaction.response_headers = "cache-control: no-store\n";
5951  transaction.status = "HTTP/1.1 304 Not Modified";
5952  RunTransactionTest(cache.http_cache(), transaction);
5953
5954  EXPECT_EQ(2, cache.network_layer()->transaction_count());
5955  EXPECT_EQ(1, cache.disk_cache()->open_count());
5956  EXPECT_EQ(1, cache.disk_cache()->create_count());
5957
5958  disk_cache::Entry* entry;
5959  EXPECT_FALSE(cache.OpenBackendEntry(transaction.url, &entry));
5960}
5961
5962// Ensure that we don't cache requests served over bad HTTPS.
5963TEST(HttpCache, SimpleGET_SSLError) {
5964  MockHttpCache cache;
5965
5966  MockTransaction transaction = kSimpleGET_Transaction;
5967  transaction.cert_status = net::CERT_STATUS_REVOKED;
5968  ScopedMockTransaction scoped_transaction(transaction);
5969
5970  // write to the cache
5971  RunTransactionTest(cache.http_cache(), transaction);
5972
5973  // Test that it was not cached.
5974  transaction.load_flags |= net::LOAD_ONLY_FROM_CACHE;
5975
5976  MockHttpRequest request(transaction);
5977  net::TestCompletionCallback callback;
5978
5979  scoped_ptr<net::HttpTransaction> trans;
5980  ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
5981
5982  int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
5983  if (rv == net::ERR_IO_PENDING)
5984    rv = callback.WaitForResult();
5985  ASSERT_EQ(net::ERR_CACHE_MISS, rv);
5986}
5987
5988// Ensure that we don't crash by if left-behind transactions.
5989TEST(HttpCache, OutlivedTransactions) {
5990  MockHttpCache* cache = new MockHttpCache;
5991
5992  scoped_ptr<net::HttpTransaction> trans;
5993  EXPECT_EQ(net::OK, cache->CreateTransaction(&trans));
5994
5995  delete cache;
5996  trans.reset();
5997}
5998
5999// Test that the disabled mode works.
6000TEST(HttpCache, CacheDisabledMode) {
6001  MockHttpCache cache;
6002
6003  // write to the cache
6004  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6005
6006  // go into disabled mode
6007  cache.http_cache()->set_mode(net::HttpCache::DISABLE);
6008
6009  // force this transaction to write to the cache again
6010  MockTransaction transaction(kSimpleGET_Transaction);
6011
6012  RunTransactionTest(cache.http_cache(), transaction);
6013
6014  EXPECT_EQ(2, cache.network_layer()->transaction_count());
6015  EXPECT_EQ(0, cache.disk_cache()->open_count());
6016  EXPECT_EQ(1, cache.disk_cache()->create_count());
6017}
6018
6019// Other tests check that the response headers of the cached response
6020// get updated on 304. Here we specifically check that the
6021// HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
6022// fields also gets updated.
6023// http://crbug.com/20594.
6024TEST(HttpCache, UpdatesRequestResponseTimeOn304) {
6025  MockHttpCache cache;
6026
6027  const char* kUrl = "http://foobar";
6028  const char* kData = "body";
6029
6030  MockTransaction mock_network_response = { 0 };
6031  mock_network_response.url = kUrl;
6032
6033  AddMockTransaction(&mock_network_response);
6034
6035  // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
6036
6037  MockTransaction request = { 0 };
6038  request.url = kUrl;
6039  request.method = "GET";
6040  request.request_headers = "\r\n";
6041  request.data = kData;
6042
6043  static const Response kNetResponse1 = {
6044    "HTTP/1.1 200 OK",
6045    "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6046    "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6047    kData
6048  };
6049
6050  kNetResponse1.AssignTo(&mock_network_response);
6051
6052  RunTransactionTest(cache.http_cache(), request);
6053
6054  // Request |kUrl| again, this time validating the cache and getting
6055  // a 304 back.
6056
6057  request.load_flags = net::LOAD_VALIDATE_CACHE;
6058
6059  static const Response kNetResponse2 = {
6060    "HTTP/1.1 304 Not Modified",
6061    "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
6062    ""
6063  };
6064
6065  kNetResponse2.AssignTo(&mock_network_response);
6066
6067  base::Time request_time = base::Time() + base::TimeDelta::FromHours(1234);
6068  base::Time response_time = base::Time() + base::TimeDelta::FromHours(1235);
6069
6070  mock_network_response.request_time = request_time;
6071  mock_network_response.response_time = response_time;
6072
6073  net::HttpResponseInfo response;
6074  RunTransactionTestWithResponseInfo(cache.http_cache(), request, &response);
6075
6076  // The request and response times should have been updated.
6077  EXPECT_EQ(request_time.ToInternalValue(),
6078            response.request_time.ToInternalValue());
6079  EXPECT_EQ(response_time.ToInternalValue(),
6080            response.response_time.ToInternalValue());
6081
6082  std::string headers;
6083  response.headers->GetNormalizedHeaders(&headers);
6084
6085  EXPECT_EQ("HTTP/1.1 200 OK\n"
6086            "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6087            "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6088            headers);
6089
6090  RemoveMockTransaction(&mock_network_response);
6091}
6092
6093// Tests that we can write metadata to an entry.
6094TEST(HttpCache, WriteMetadata_OK) {
6095  MockHttpCache cache;
6096
6097  // Write to the cache
6098  net::HttpResponseInfo response;
6099  RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6100                                     &response);
6101  EXPECT_TRUE(response.metadata.get() == NULL);
6102
6103  // Trivial call.
6104  cache.http_cache()->WriteMetadata(GURL("foo"), net::DEFAULT_PRIORITY,
6105                                    Time::Now(), NULL, 0);
6106
6107  // Write meta data to the same entry.
6108  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
6109  memset(buf->data(), 0, buf->size());
6110  base::strlcpy(buf->data(), "Hi there", buf->size());
6111  cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
6112                                    net::DEFAULT_PRIORITY,
6113                                    response.response_time,
6114                                    buf.get(),
6115                                    buf->size());
6116
6117  // Release the buffer before the operation takes place.
6118  buf = NULL;
6119
6120  // Makes sure we finish pending operations.
6121  base::MessageLoop::current()->RunUntilIdle();
6122
6123  RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6124                                     &response);
6125  ASSERT_TRUE(response.metadata.get() != NULL);
6126  EXPECT_EQ(50, response.metadata->size());
6127  EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
6128
6129  EXPECT_EQ(1, cache.network_layer()->transaction_count());
6130  EXPECT_EQ(2, cache.disk_cache()->open_count());
6131  EXPECT_EQ(1, cache.disk_cache()->create_count());
6132}
6133
6134// Tests that we only write metadata to an entry if the time stamp matches.
6135TEST(HttpCache, WriteMetadata_Fail) {
6136  MockHttpCache cache;
6137
6138  // Write to the cache
6139  net::HttpResponseInfo response;
6140  RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6141                                     &response);
6142  EXPECT_TRUE(response.metadata.get() == NULL);
6143
6144  // Attempt to write meta data to the same entry.
6145  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
6146  memset(buf->data(), 0, buf->size());
6147  base::strlcpy(buf->data(), "Hi there", buf->size());
6148  base::Time expected_time = response.response_time -
6149                             base::TimeDelta::FromMilliseconds(20);
6150  cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url),
6151                                    net::DEFAULT_PRIORITY,
6152                                    expected_time,
6153                                    buf.get(),
6154                                    buf->size());
6155
6156  // Makes sure we finish pending operations.
6157  base::MessageLoop::current()->RunUntilIdle();
6158
6159  RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
6160                                     &response);
6161  EXPECT_TRUE(response.metadata.get() == NULL);
6162
6163  EXPECT_EQ(1, cache.network_layer()->transaction_count());
6164  EXPECT_EQ(2, cache.disk_cache()->open_count());
6165  EXPECT_EQ(1, cache.disk_cache()->create_count());
6166}
6167
6168// Tests that we can read metadata after validating the entry and with READ mode
6169// transactions.
6170TEST(HttpCache, ReadMetadata) {
6171  MockHttpCache cache;
6172
6173  // Write to the cache
6174  net::HttpResponseInfo response;
6175  RunTransactionTestWithResponseInfo(cache.http_cache(),
6176                                     kTypicalGET_Transaction, &response);
6177  EXPECT_TRUE(response.metadata.get() == NULL);
6178
6179  // Write meta data to the same entry.
6180  scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(50));
6181  memset(buf->data(), 0, buf->size());
6182  base::strlcpy(buf->data(), "Hi there", buf->size());
6183  cache.http_cache()->WriteMetadata(GURL(kTypicalGET_Transaction.url),
6184                                    net::DEFAULT_PRIORITY,
6185                                    response.response_time,
6186                                    buf.get(),
6187                                    buf->size());
6188
6189  // Makes sure we finish pending operations.
6190  base::MessageLoop::current()->RunUntilIdle();
6191
6192  // Start with a READ mode transaction.
6193  MockTransaction trans1(kTypicalGET_Transaction);
6194  trans1.load_flags = net::LOAD_ONLY_FROM_CACHE;
6195
6196  RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
6197  ASSERT_TRUE(response.metadata.get() != NULL);
6198  EXPECT_EQ(50, response.metadata->size());
6199  EXPECT_EQ(0, strcmp(response.metadata->data(), "Hi there"));
6200
6201  EXPECT_EQ(1, cache.network_layer()->transaction_count());
6202  EXPECT_EQ(2, cache.disk_cache()->open_count());
6203  EXPECT_EQ(1, cache.disk_cache()->create_count());
6204  base::MessageLoop::current()->RunUntilIdle();
6205
6206  // Now make sure that the entry is re-validated with the server.
6207  trans1.load_flags = net::LOAD_VALIDATE_CACHE;
6208  trans1.status = "HTTP/1.1 304 Not Modified";
6209  AddMockTransaction(&trans1);
6210
6211  response.metadata = NULL;
6212  RunTransactionTestWithResponseInfo(cache.http_cache(), trans1, &response);
6213  EXPECT_TRUE(response.metadata.get() != NULL);
6214
6215  EXPECT_EQ(2, cache.network_layer()->transaction_count());
6216  EXPECT_EQ(3, cache.disk_cache()->open_count());
6217  EXPECT_EQ(1, cache.disk_cache()->create_count());
6218  base::MessageLoop::current()->RunUntilIdle();
6219  RemoveMockTransaction(&trans1);
6220
6221  // Now return 200 when validating the entry so the metadata will be lost.
6222  MockTransaction trans2(kTypicalGET_Transaction);
6223  trans2.load_flags = net::LOAD_VALIDATE_CACHE;
6224  RunTransactionTestWithResponseInfo(cache.http_cache(), trans2, &response);
6225  EXPECT_TRUE(response.metadata.get() == NULL);
6226
6227  EXPECT_EQ(3, cache.network_layer()->transaction_count());
6228  EXPECT_EQ(4, cache.disk_cache()->open_count());
6229  EXPECT_EQ(1, cache.disk_cache()->create_count());
6230}
6231
6232// Tests that we don't mark entries as truncated when a filter detects the end
6233// of the stream.
6234TEST(HttpCache, FilterCompletion) {
6235  MockHttpCache cache;
6236  net::TestCompletionCallback callback;
6237
6238  {
6239    scoped_ptr<net::HttpTransaction> trans;
6240    ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6241
6242    MockHttpRequest request(kSimpleGET_Transaction);
6243    int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6244    EXPECT_EQ(net::OK, callback.GetResult(rv));
6245
6246    scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6247    rv = trans->Read(buf.get(), 256, callback.callback());
6248    EXPECT_GT(callback.GetResult(rv), 0);
6249
6250    // Now make sure that the entry is preserved.
6251    trans->DoneReading();
6252  }
6253
6254  // Make sure that the ActiveEntry is gone.
6255  base::MessageLoop::current()->RunUntilIdle();
6256
6257  // Read from the cache.
6258  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6259
6260  EXPECT_EQ(1, cache.network_layer()->transaction_count());
6261  EXPECT_EQ(1, cache.disk_cache()->open_count());
6262  EXPECT_EQ(1, cache.disk_cache()->create_count());
6263}
6264
6265// Tests that we don't mark entries as truncated and release the cache
6266// entry when DoneReading() is called before any Read() calls, such as
6267// for a redirect.
6268TEST(HttpCache, DoneReading) {
6269  MockHttpCache cache;
6270  net::TestCompletionCallback callback;
6271
6272  ScopedMockTransaction transaction(kSimpleGET_Transaction);
6273  transaction.data = "";
6274
6275  scoped_ptr<net::HttpTransaction> trans;
6276  ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6277
6278  MockHttpRequest request(transaction);
6279  int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6280  EXPECT_EQ(net::OK, callback.GetResult(rv));
6281
6282  trans->DoneReading();
6283  // Leave the transaction around.
6284
6285  // Make sure that the ActiveEntry is gone.
6286  base::MessageLoop::current()->RunUntilIdle();
6287
6288  // Read from the cache. This should not deadlock.
6289  RunTransactionTest(cache.http_cache(), transaction);
6290
6291  EXPECT_EQ(1, cache.network_layer()->transaction_count());
6292  EXPECT_EQ(1, cache.disk_cache()->open_count());
6293  EXPECT_EQ(1, cache.disk_cache()->create_count());
6294}
6295
6296// Tests that we stop caching when told.
6297TEST(HttpCache, StopCachingDeletesEntry) {
6298  MockHttpCache cache;
6299  net::TestCompletionCallback callback;
6300  MockHttpRequest request(kSimpleGET_Transaction);
6301
6302  {
6303    scoped_ptr<net::HttpTransaction> trans;
6304    ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6305
6306    int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6307    EXPECT_EQ(net::OK, callback.GetResult(rv));
6308
6309    scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6310    rv = trans->Read(buf.get(), 10, callback.callback());
6311    EXPECT_EQ(10, callback.GetResult(rv));
6312
6313    trans->StopCaching();
6314
6315    // We should be able to keep reading.
6316    rv = trans->Read(buf.get(), 256, callback.callback());
6317    EXPECT_GT(callback.GetResult(rv), 0);
6318    rv = trans->Read(buf.get(), 256, callback.callback());
6319    EXPECT_EQ(0, callback.GetResult(rv));
6320  }
6321
6322  // Make sure that the ActiveEntry is gone.
6323  base::MessageLoop::current()->RunUntilIdle();
6324
6325  // Verify that the entry is gone.
6326  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6327
6328  EXPECT_EQ(2, cache.network_layer()->transaction_count());
6329  EXPECT_EQ(0, cache.disk_cache()->open_count());
6330  EXPECT_EQ(2, cache.disk_cache()->create_count());
6331}
6332
6333// Tests that we stop caching when told, even if DoneReading is called
6334// after StopCaching.
6335TEST(HttpCache, StopCachingThenDoneReadingDeletesEntry) {
6336  MockHttpCache cache;
6337  net::TestCompletionCallback callback;
6338  MockHttpRequest request(kSimpleGET_Transaction);
6339
6340  {
6341    scoped_ptr<net::HttpTransaction> trans;
6342    ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6343
6344    int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6345    EXPECT_EQ(net::OK, callback.GetResult(rv));
6346
6347    scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6348    rv = trans->Read(buf.get(), 10, callback.callback());
6349    EXPECT_EQ(10, callback.GetResult(rv));
6350
6351    trans->StopCaching();
6352
6353    // We should be able to keep reading.
6354    rv = trans->Read(buf.get(), 256, callback.callback());
6355    EXPECT_GT(callback.GetResult(rv), 0);
6356    rv = trans->Read(buf.get(), 256, callback.callback());
6357    EXPECT_EQ(0, callback.GetResult(rv));
6358
6359    // We should be able to call DoneReading.
6360    trans->DoneReading();
6361  }
6362
6363  // Make sure that the ActiveEntry is gone.
6364  base::MessageLoop::current()->RunUntilIdle();
6365
6366  // Verify that the entry is gone.
6367  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6368
6369  EXPECT_EQ(2, cache.network_layer()->transaction_count());
6370  EXPECT_EQ(0, cache.disk_cache()->open_count());
6371  EXPECT_EQ(2, cache.disk_cache()->create_count());
6372}
6373
6374// Tests that we stop caching when told, when using auth.
6375TEST(HttpCache, StopCachingWithAuthDeletesEntry) {
6376  MockHttpCache cache;
6377  net::TestCompletionCallback callback;
6378  MockTransaction mock_transaction(kSimpleGET_Transaction);
6379  mock_transaction.status = "HTTP/1.1 401 Unauthorized";
6380  AddMockTransaction(&mock_transaction);
6381  MockHttpRequest request(mock_transaction);
6382
6383  {
6384    scoped_ptr<net::HttpTransaction> trans;
6385    ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6386
6387    int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6388    EXPECT_EQ(net::OK, callback.GetResult(rv));
6389
6390    trans->StopCaching();
6391
6392    scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6393    rv = trans->Read(buf.get(), 10, callback.callback());
6394    EXPECT_EQ(callback.GetResult(rv), 10);
6395  }
6396  RemoveMockTransaction(&mock_transaction);
6397
6398  // Make sure that the ActiveEntry is gone.
6399  base::MessageLoop::current()->RunUntilIdle();
6400
6401  // Verify that the entry is gone.
6402  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6403
6404  EXPECT_EQ(2, cache.network_layer()->transaction_count());
6405  EXPECT_EQ(0, cache.disk_cache()->open_count());
6406  EXPECT_EQ(2, cache.disk_cache()->create_count());
6407}
6408
6409// Tests that when we are told to stop caching we don't throw away valid data.
6410TEST(HttpCache, StopCachingSavesEntry) {
6411  MockHttpCache cache;
6412  net::TestCompletionCallback callback;
6413  MockHttpRequest request(kSimpleGET_Transaction);
6414
6415  {
6416    scoped_ptr<net::HttpTransaction> trans;
6417    ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6418
6419    // Force a response that can be resumed.
6420    MockTransaction mock_transaction(kSimpleGET_Transaction);
6421    AddMockTransaction(&mock_transaction);
6422    mock_transaction.response_headers = "Cache-Control: max-age=10000\n"
6423                                        "Content-Length: 42\n"
6424                                        "Etag: \"foo\"\n";
6425
6426    int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6427    EXPECT_EQ(net::OK, callback.GetResult(rv));
6428
6429    scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6430    rv = trans->Read(buf.get(), 10, callback.callback());
6431    EXPECT_EQ(callback.GetResult(rv), 10);
6432
6433    trans->StopCaching();
6434
6435    // We should be able to keep reading.
6436    rv = trans->Read(buf.get(), 256, callback.callback());
6437    EXPECT_GT(callback.GetResult(rv), 0);
6438    rv = trans->Read(buf.get(), 256, callback.callback());
6439    EXPECT_EQ(callback.GetResult(rv), 0);
6440
6441    RemoveMockTransaction(&mock_transaction);
6442  }
6443
6444  // Verify that the entry is marked as incomplete.
6445  disk_cache::Entry* entry;
6446  ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
6447  net::HttpResponseInfo response;
6448  bool truncated = false;
6449  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6450  EXPECT_TRUE(truncated);
6451  entry->Close();
6452}
6453
6454// Tests that we handle truncated enries when StopCaching is called.
6455TEST(HttpCache, StopCachingTruncatedEntry) {
6456  MockHttpCache cache;
6457  net::TestCompletionCallback callback;
6458  MockHttpRequest request(kRangeGET_TransactionOK);
6459  request.extra_headers.Clear();
6460  request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE);
6461  AddMockTransaction(&kRangeGET_TransactionOK);
6462
6463  std::string raw_headers("HTTP/1.1 200 OK\n"
6464                          "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6465                          "ETag: \"foo\"\n"
6466                          "Accept-Ranges: bytes\n"
6467                          "Content-Length: 80\n");
6468  CreateTruncatedEntry(raw_headers, &cache);
6469
6470  {
6471    // Now make a regular request.
6472    scoped_ptr<net::HttpTransaction> trans;
6473    ASSERT_EQ(net::OK, cache.CreateTransaction(&trans));
6474
6475    int rv = trans->Start(&request, callback.callback(), net::BoundNetLog());
6476    EXPECT_EQ(net::OK, callback.GetResult(rv));
6477
6478    scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
6479    rv = trans->Read(buf.get(), 10, callback.callback());
6480    EXPECT_EQ(callback.GetResult(rv), 10);
6481
6482    // This is actually going to do nothing.
6483    trans->StopCaching();
6484
6485    // We should be able to keep reading.
6486    rv = trans->Read(buf.get(), 256, callback.callback());
6487    EXPECT_GT(callback.GetResult(rv), 0);
6488    rv = trans->Read(buf.get(), 256, callback.callback());
6489    EXPECT_GT(callback.GetResult(rv), 0);
6490    rv = trans->Read(buf.get(), 256, callback.callback());
6491    EXPECT_EQ(callback.GetResult(rv), 0);
6492  }
6493
6494  // Verify that the disk entry was updated.
6495  disk_cache::Entry* entry;
6496  ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry));
6497  EXPECT_EQ(80, entry->GetDataSize(1));
6498  bool truncated = true;
6499  net::HttpResponseInfo response;
6500  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6501  EXPECT_FALSE(truncated);
6502  entry->Close();
6503
6504  RemoveMockTransaction(&kRangeGET_TransactionOK);
6505}
6506
6507// Tests that we detect truncated resources from the net when there is
6508// a Content-Length header.
6509TEST(HttpCache, TruncatedByContentLength) {
6510  MockHttpCache cache;
6511  net::TestCompletionCallback callback;
6512
6513  MockTransaction transaction(kSimpleGET_Transaction);
6514  AddMockTransaction(&transaction);
6515  transaction.response_headers = "Cache-Control: max-age=10000\n"
6516                                 "Content-Length: 100\n";
6517  RunTransactionTest(cache.http_cache(), transaction);
6518  RemoveMockTransaction(&transaction);
6519
6520  // Read from the cache.
6521  RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
6522
6523  EXPECT_EQ(2, cache.network_layer()->transaction_count());
6524  EXPECT_EQ(0, cache.disk_cache()->open_count());
6525  EXPECT_EQ(2, cache.disk_cache()->create_count());
6526}
6527
6528// Tests that we actually flag entries as truncated when we detect an error
6529// from the net.
6530TEST(HttpCache, TruncatedByContentLength2) {
6531  MockHttpCache cache;
6532  net::TestCompletionCallback callback;
6533
6534  MockTransaction transaction(kSimpleGET_Transaction);
6535  AddMockTransaction(&transaction);
6536  transaction.response_headers = "Cache-Control: max-age=10000\n"
6537                                 "Content-Length: 100\n"
6538                                 "Etag: \"foo\"\n";
6539  RunTransactionTest(cache.http_cache(), transaction);
6540  RemoveMockTransaction(&transaction);
6541
6542  // Verify that the entry is marked as incomplete.
6543  disk_cache::Entry* entry;
6544  ASSERT_TRUE(cache.OpenBackendEntry(kSimpleGET_Transaction.url, &entry));
6545  net::HttpResponseInfo response;
6546  bool truncated = false;
6547  EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
6548  EXPECT_TRUE(truncated);
6549  entry->Close();
6550}
6551
6552// Make sure that calling SetPriority on a cache transaction passes on
6553// its priority updates to its underlying network transaction.
6554TEST(HttpCache, SetPriority) {
6555  MockHttpCache cache;
6556
6557  scoped_ptr<net::HttpTransaction> trans;
6558  ASSERT_EQ(net::OK, cache.http_cache()->CreateTransaction(net::IDLE, &trans));
6559
6560  // Shouldn't crash, but doesn't do anything either.
6561  trans->SetPriority(net::LOW);
6562
6563  EXPECT_FALSE(cache.network_layer()->last_transaction());
6564  EXPECT_EQ(net::DEFAULT_PRIORITY,
6565            cache.network_layer()->last_create_transaction_priority());
6566
6567  net::HttpRequestInfo info;
6568  info.url = GURL(kSimpleGET_Transaction.url);
6569  net::TestCompletionCallback callback;
6570  EXPECT_EQ(net::ERR_IO_PENDING,
6571            trans->Start(&info, callback.callback(), net::BoundNetLog()));
6572
6573  EXPECT_TRUE(cache.network_layer()->last_transaction());
6574  if (cache.network_layer()->last_transaction()) {
6575    EXPECT_EQ(net::LOW,
6576              cache.network_layer()->last_create_transaction_priority());
6577    EXPECT_EQ(net::LOW,
6578              cache.network_layer()->last_transaction()->priority());
6579  }
6580
6581  trans->SetPriority(net::HIGHEST);
6582
6583  if (cache.network_layer()->last_transaction()) {
6584    EXPECT_EQ(net::LOW,
6585              cache.network_layer()->last_create_transaction_priority());
6586    EXPECT_EQ(net::HIGHEST,
6587              cache.network_layer()->last_transaction()->priority());
6588  }
6589
6590  EXPECT_EQ(net::OK, callback.WaitForResult());
6591}
6592
6593// Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
6594// transaction passes on its argument to the underlying network transaction.
6595TEST(HttpCache, SetWebSocketHandshakeStreamCreateHelper) {
6596  MockHttpCache cache;
6597
6598  FakeWebSocketHandshakeStreamCreateHelper create_helper;
6599  scoped_ptr<net::HttpTransaction> trans;
6600  ASSERT_EQ(net::OK, cache.http_cache()->CreateTransaction(net::IDLE, &trans));
6601
6602  EXPECT_FALSE(cache.network_layer()->last_transaction());
6603
6604  net::HttpRequestInfo info;
6605  info.url = GURL(kSimpleGET_Transaction.url);
6606  net::TestCompletionCallback callback;
6607  EXPECT_EQ(net::ERR_IO_PENDING,
6608            trans->Start(&info, callback.callback(), net::BoundNetLog()));
6609
6610  ASSERT_TRUE(cache.network_layer()->last_transaction());
6611  EXPECT_FALSE(cache.network_layer()->last_transaction()->
6612               websocket_handshake_stream_create_helper());
6613  trans->SetWebSocketHandshakeStreamCreateHelper(&create_helper);
6614  EXPECT_EQ(&create_helper,
6615            cache.network_layer()->last_transaction()->
6616            websocket_handshake_stream_create_helper());
6617  EXPECT_EQ(net::OK, callback.WaitForResult());
6618}
6619
6620// Make sure that a cache transaction passes on its priority to
6621// newly-created network transactions.
6622TEST(HttpCache, SetPriorityNewTransaction) {
6623  MockHttpCache cache;
6624  AddMockTransaction(&kRangeGET_TransactionOK);
6625
6626  std::string raw_headers("HTTP/1.1 200 OK\n"
6627                          "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6628                          "ETag: \"foo\"\n"
6629                          "Accept-Ranges: bytes\n"
6630                          "Content-Length: 80\n");
6631  CreateTruncatedEntry(raw_headers, &cache);
6632
6633  // Now make a regular request.
6634  std::string headers;
6635  MockTransaction transaction(kRangeGET_TransactionOK);
6636  transaction.request_headers = EXTRA_HEADER;
6637  transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 "
6638                     "rg: 50-59 rg: 60-69 rg: 70-79 ";
6639
6640  scoped_ptr<net::HttpTransaction> trans;
6641  ASSERT_EQ(net::OK,
6642            cache.http_cache()->CreateTransaction(net::MEDIUM, &trans));
6643  EXPECT_EQ(net::DEFAULT_PRIORITY,
6644            cache.network_layer()->last_create_transaction_priority());
6645
6646  MockHttpRequest info(transaction);
6647  net::TestCompletionCallback callback;
6648  EXPECT_EQ(net::ERR_IO_PENDING,
6649            trans->Start(&info, callback.callback(), net::BoundNetLog()));
6650  EXPECT_EQ(net::OK, callback.WaitForResult());
6651
6652  EXPECT_EQ(net::MEDIUM,
6653            cache.network_layer()->last_create_transaction_priority());
6654
6655  trans->SetPriority(net::HIGHEST);
6656  // Should trigger a new network transaction and pick up the new
6657  // priority.
6658  ReadAndVerifyTransaction(trans.get(), transaction);
6659
6660  EXPECT_EQ(net::HIGHEST,
6661            cache.network_layer()->last_create_transaction_priority());
6662
6663  RemoveMockTransaction(&kRangeGET_TransactionOK);
6664}
6665
6666int64 RunTransactionAndGetReceivedBytes(
6667    MockHttpCache& cache,
6668    const MockTransaction& trans_info) {
6669  int64 received_bytes = -1;
6670  RunTransactionTestBase(cache.http_cache(), trans_info,
6671                         MockHttpRequest(trans_info), NULL, net::BoundNetLog(),
6672                         NULL, &received_bytes);
6673  return received_bytes;
6674}
6675
6676int64 TransactionSize(const MockTransaction& transaction) {
6677  return strlen(transaction.status) + strlen(transaction.response_headers) +
6678         strlen(transaction.data);
6679}
6680
6681TEST(HttpCache, ReceivedBytesCacheMissAndThenHit) {
6682  MockHttpCache cache;
6683
6684  MockTransaction transaction(kSimpleGET_Transaction);
6685  int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6686  EXPECT_EQ(TransactionSize(transaction), received_bytes);
6687
6688  received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6689  EXPECT_EQ(0, received_bytes);
6690}
6691
6692TEST(HttpCache, ReceivedBytesConditionalRequest304) {
6693  MockHttpCache cache;
6694
6695  ScopedMockTransaction transaction(kETagGET_Transaction);
6696  int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6697  EXPECT_EQ(TransactionSize(transaction), received_bytes);
6698
6699  transaction.load_flags = net::LOAD_VALIDATE_CACHE;
6700  transaction.handler = ETagGet_ConditionalRequest_Handler;
6701  received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6702  EXPECT_EQ(TransactionSize(transaction), received_bytes);
6703}
6704
6705TEST(HttpCache, ReceivedBytesConditionalRequest200) {
6706  MockHttpCache cache;
6707
6708  MockTransaction transaction(kTypicalGET_Transaction);
6709  transaction.request_headers = "Foo: bar\r\n";
6710  transaction.response_headers =
6711      "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6712      "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6713      "Etag: \"foopy\"\n"
6714      "Cache-Control: max-age=0\n"
6715      "Vary: Foo\n";
6716  AddMockTransaction(&transaction);
6717  int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6718  EXPECT_EQ(TransactionSize(transaction), received_bytes);
6719
6720  RevalidationServer server;
6721  transaction.handler = server.Handler;
6722  transaction.request_headers = "Foo: none\r\n";
6723  received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6724  EXPECT_EQ(TransactionSize(transaction), received_bytes);
6725
6726  RemoveMockTransaction(&transaction);
6727}
6728
6729TEST(HttpCache, ReceivedBytesRange) {
6730  MockHttpCache cache;
6731  AddMockTransaction(&kRangeGET_TransactionOK);
6732  MockTransaction transaction(kRangeGET_TransactionOK);
6733
6734  // Read bytes 40-49 from the network.
6735  int64 received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6736  int64 range_response_size = TransactionSize(transaction);
6737  EXPECT_EQ(range_response_size, received_bytes);
6738
6739  // Read bytes 40-49 from the cache.
6740  received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6741  EXPECT_EQ(0, received_bytes);
6742  base::MessageLoop::current()->RunUntilIdle();
6743
6744  // Read bytes 30-39 from the network.
6745  transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
6746  transaction.data = "rg: 30-39 ";
6747  received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6748  EXPECT_EQ(range_response_size, received_bytes);
6749  base::MessageLoop::current()->RunUntilIdle();
6750
6751  // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
6752  transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
6753  transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
6754  received_bytes = RunTransactionAndGetReceivedBytes(cache, transaction);
6755  EXPECT_EQ(range_response_size * 2, received_bytes);
6756
6757  RemoveMockTransaction(&kRangeGET_TransactionOK);
6758}
6759
6760static void CheckResourceFreshnessHeader(const net::HttpRequestInfo* request,
6761                                         std::string* response_status,
6762                                         std::string* response_headers,
6763                                         std::string* response_data) {
6764  std::string value;
6765  EXPECT_TRUE(request->extra_headers.GetHeader("Resource-Freshness", &value));
6766  EXPECT_EQ("max-age=3600,stale-while-revalidate=7200,age=10801", value);
6767}
6768
6769// Verify that the Resource-Freshness header is sent on a revalidation if the
6770// stale-while-revalidate directive was on the response.
6771TEST(HttpCache, ResourceFreshnessHeaderSent) {
6772  MockHttpCache cache;
6773
6774  ScopedMockTransaction stale_while_revalidate_transaction(
6775      kSimpleGET_Transaction);
6776  stale_while_revalidate_transaction.response_headers =
6777      "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6778      "Age: 10801\n"
6779      "Cache-Control: max-age=3600,stale-while-revalidate=7200\n";
6780
6781  // Write to the cache.
6782  RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
6783
6784  EXPECT_EQ(1, cache.network_layer()->transaction_count());
6785
6786  // Send the request again and check that Resource-Freshness header is added.
6787  stale_while_revalidate_transaction.handler = CheckResourceFreshnessHeader;
6788
6789  RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
6790
6791  EXPECT_EQ(2, cache.network_layer()->transaction_count());
6792}
6793
6794static void CheckResourceFreshnessAbsent(const net::HttpRequestInfo* request,
6795                                         std::string* response_status,
6796                                         std::string* response_headers,
6797                                         std::string* response_data) {
6798  EXPECT_FALSE(request->extra_headers.HasHeader("Resource-Freshness"));
6799}
6800
6801// Verify that the Resource-Freshness header is not sent when
6802// stale-while-revalidate is 0.
6803TEST(HttpCache, ResourceFreshnessHeaderNotSent) {
6804  MockHttpCache cache;
6805
6806  ScopedMockTransaction stale_while_revalidate_transaction(
6807      kSimpleGET_Transaction);
6808  stale_while_revalidate_transaction.response_headers =
6809      "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
6810      "Age: 10801\n"
6811      "Cache-Control: max-age=3600,stale-while-revalidate=0\n";
6812
6813  // Write to the cache.
6814  RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
6815
6816  EXPECT_EQ(1, cache.network_layer()->transaction_count());
6817
6818  // Send the request again and check that Resource-Freshness header is absent.
6819  stale_while_revalidate_transaction.handler = CheckResourceFreshnessAbsent;
6820
6821  RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
6822
6823  EXPECT_EQ(2, cache.network_layer()->transaction_count());
6824}
6825
6826// Tests that we allow multiple simultaneous, non-overlapping transactions to
6827// take place on a sparse entry.
6828TEST(HttpCache, RangeGET_MultipleRequests) {
6829  MockHttpCache cache;
6830
6831  // Create a transaction for bytes 0-9.
6832  MockHttpRequest request(kRangeGET_TransactionOK);
6833  MockTransaction transaction(kRangeGET_TransactionOK);
6834  transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
6835  transaction.data = "rg: 00-09 ";
6836  AddMockTransaction(&transaction);
6837
6838  net::TestCompletionCallback callback;
6839  scoped_ptr<net::HttpTransaction> trans;
6840  int rv = cache.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY, &trans);
6841  EXPECT_EQ(net::OK, rv);
6842  ASSERT_TRUE(trans.get());
6843
6844  // Start our transaction.
6845  trans->Start(&request, callback.callback(), net::BoundNetLog());
6846
6847  // A second transaction on a different part of the file (the default
6848  // kRangeGET_TransactionOK requests 40-49) should not be blocked by
6849  // the already pending transaction.
6850  RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
6851
6852  // Let the first transaction complete.
6853  callback.WaitForResult();
6854
6855  RemoveMockTransaction(&transaction);
6856}
6857