• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
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 <stdint.h>
8 
9 #include <algorithm>
10 #include <memory>
11 #include <set>
12 #include <utility>
13 #include <vector>
14 
15 #include "base/containers/cxx20_erase.h"
16 #include "base/files/scoped_temp_dir.h"
17 #include "base/format_macros.h"
18 #include "base/functional/bind.h"
19 #include "base/functional/callback_helpers.h"
20 #include "base/memory/ptr_util.h"
21 #include "base/memory/raw_ptr.h"
22 #include "base/run_loop.h"
23 #include "base/strings/strcat.h"
24 #include "base/strings/string_number_conversions.h"
25 #include "base/strings/string_util.h"
26 #include "base/strings/stringprintf.h"
27 #include "base/test/metrics/histogram_tester.h"
28 #include "base/test/scoped_feature_list.h"
29 #include "base/test/simple_test_clock.h"
30 #include "base/time/time.h"
31 #include "base/trace_event/memory_dump_request_args.h"
32 #include "base/trace_event/process_memory_dump.h"
33 #include "net/base/cache_type.h"
34 #include "net/base/completion_repeating_callback.h"
35 #include "net/base/elements_upload_data_stream.h"
36 #include "net/base/features.h"
37 #include "net/base/host_port_pair.h"
38 #include "net/base/ip_address.h"
39 #include "net/base/ip_endpoint.h"
40 #include "net/base/load_flags.h"
41 #include "net/base/load_timing_info.h"
42 #include "net/base/load_timing_info_test_util.h"
43 #include "net/base/net_errors.h"
44 #include "net/base/schemeful_site.h"
45 #include "net/base/tracing.h"
46 #include "net/base/upload_bytes_element_reader.h"
47 #include "net/cert/cert_status_flags.h"
48 #include "net/cert/x509_certificate.h"
49 #include "net/disk_cache/disk_cache.h"
50 #include "net/http/http_byte_range.h"
51 #include "net/http/http_cache_transaction.h"
52 #include "net/http/http_request_headers.h"
53 #include "net/http/http_request_info.h"
54 #include "net/http/http_response_headers.h"
55 #include "net/http/http_response_info.h"
56 #include "net/http/http_transaction.h"
57 #include "net/http/http_transaction_test_util.h"
58 #include "net/http/http_util.h"
59 #include "net/http/mock_http_cache.h"
60 #include "net/log/net_log_event_type.h"
61 #include "net/log/net_log_source.h"
62 #include "net/log/net_log_with_source.h"
63 #include "net/log/test_net_log.h"
64 #include "net/log/test_net_log_util.h"
65 #include "net/socket/client_socket_handle.h"
66 #include "net/ssl/ssl_cert_request_info.h"
67 #include "net/ssl/ssl_connection_status_flags.h"
68 #include "net/test/cert_test_util.h"
69 #include "net/test/gtest_util.h"
70 #include "net/test/test_data_directory.h"
71 #include "net/test/test_with_task_environment.h"
72 #include "net/websockets/websocket_handshake_stream_base.h"
73 #include "testing/gmock/include/gmock/gmock.h"
74 #include "testing/gtest/include/gtest/gtest.h"
75 #include "third_party/abseil-cpp/absl/types/optional.h"
76 #include "url/origin.h"
77 
78 using net::test::IsError;
79 using net::test::IsOk;
80 using testing::AllOf;
81 using testing::ByRef;
82 using testing::Contains;
83 using testing::ElementsAre;
84 using testing::Eq;
85 using testing::Field;
86 using testing::Gt;
87 using testing::IsEmpty;
88 using testing::NotNull;
89 
90 using base::Time;
91 
92 namespace net {
93 
94 using CacheEntryStatus = HttpResponseInfo::CacheEntryStatus;
95 
96 class WebSocketEndpointLockManager;
97 
98 namespace {
99 
100 // Returns a simple text serialization of the given
101 // |HttpResponseHeaders|. This is used by tests to verify that an
102 // |HttpResponseHeaders| matches an expectation string.
103 //
104 //  * One line per header, written as:
105 //        HEADER_NAME: HEADER_VALUE\n
106 //  * The original case of header names is preserved.
107 //  * Whitespace around head names/values is stripped.
108 //  * Repeated headers are not aggregated.
109 //  * Headers are listed in their original order.
110 // TODO(tfarina): this is a duplicate function from
111 // http_response_headers_unittest.cc:ToSimpleString(). Figure out how to merge
112 // them. crbug.com/488593
ToSimpleString(const scoped_refptr<HttpResponseHeaders> & parsed)113 std::string ToSimpleString(const scoped_refptr<HttpResponseHeaders>& parsed) {
114   std::string result = parsed->GetStatusLine() + "\n";
115 
116   size_t iter = 0;
117   std::string name;
118   std::string value;
119   while (parsed->EnumerateHeaderLines(&iter, &name, &value)) {
120     std::string new_line = name + ": " + value + "\n";
121 
122     result += new_line;
123   }
124 
125   return result;
126 }
127 
128 // Tests the load timing values of a request that goes through a
129 // MockNetworkTransaction.
TestLoadTimingNetworkRequest(const LoadTimingInfo & load_timing_info)130 void TestLoadTimingNetworkRequest(const LoadTimingInfo& load_timing_info) {
131   EXPECT_FALSE(load_timing_info.socket_reused);
132   EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
133 
134   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
135   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
136 
137   ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
138                               CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
139   EXPECT_LE(load_timing_info.connect_timing.connect_end,
140             load_timing_info.send_start);
141 
142   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
143 
144   // Set by URLRequest / URLRequestHttpJob, at a higher level.
145   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
146   EXPECT_TRUE(load_timing_info.request_start.is_null());
147   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
148 }
149 
150 // Tests the load timing values of a request that receives a cached response.
TestLoadTimingCachedResponse(const LoadTimingInfo & load_timing_info)151 void TestLoadTimingCachedResponse(const LoadTimingInfo& load_timing_info) {
152   EXPECT_FALSE(load_timing_info.socket_reused);
153   EXPECT_EQ(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
154 
155   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
156   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
157 
158   ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
159 
160   // Only the send start / end times should be sent, and they should have the
161   // same value.
162   EXPECT_FALSE(load_timing_info.send_start.is_null());
163   EXPECT_EQ(load_timing_info.send_start, load_timing_info.send_end);
164 
165   // Set by URLRequest / URLRequestHttpJob, at a higher level.
166   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
167   EXPECT_TRUE(load_timing_info.request_start.is_null());
168   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
169 }
170 
DeferCallback(bool * defer)171 void DeferCallback(bool* defer) {
172   *defer = true;
173 }
174 
175 class DeleteCacheCompletionCallback : public TestCompletionCallbackBase {
176  public:
DeleteCacheCompletionCallback(std::unique_ptr<MockHttpCache> cache)177   explicit DeleteCacheCompletionCallback(std::unique_ptr<MockHttpCache> cache)
178       : cache_(std::move(cache)) {}
179 
180   DeleteCacheCompletionCallback(const DeleteCacheCompletionCallback&) = delete;
181   DeleteCacheCompletionCallback& operator=(
182       const DeleteCacheCompletionCallback&) = delete;
183 
callback()184   CompletionOnceCallback callback() {
185     return base::BindOnce(&DeleteCacheCompletionCallback::OnComplete,
186                           base::Unretained(this));
187   }
188 
189  private:
OnComplete(int result)190   void OnComplete(int result) {
191     cache_.reset();
192     SetResult(result);
193   }
194 
195   std::unique_ptr<MockHttpCache> cache_;
196 };
197 
198 //-----------------------------------------------------------------------------
199 // helpers
200 
ReadAndVerifyTransaction(HttpTransaction * trans,const MockTransaction & trans_info)201 void ReadAndVerifyTransaction(HttpTransaction* trans,
202                               const MockTransaction& trans_info) {
203   std::string content;
204   int rv = ReadTransaction(trans, &content);
205 
206   EXPECT_THAT(rv, IsOk());
207   std::string expected(trans_info.data);
208   EXPECT_EQ(expected, content);
209 }
210 
ReadRemainingAndVerifyTransaction(HttpTransaction * trans,const std::string & already_read,const MockTransaction & trans_info)211 void ReadRemainingAndVerifyTransaction(HttpTransaction* trans,
212                                        const std::string& already_read,
213                                        const MockTransaction& trans_info) {
214   std::string content;
215   int rv = ReadTransaction(trans, &content);
216   EXPECT_THAT(rv, IsOk());
217 
218   std::string expected(trans_info.data);
219   EXPECT_EQ(expected, already_read + content);
220 }
221 
RunTransactionTestBase(HttpCache * cache,const MockTransaction & trans_info,const MockHttpRequest & request,HttpResponseInfo * response_info,const NetLogWithSource & net_log,LoadTimingInfo * load_timing_info,int64_t * sent_bytes,int64_t * received_bytes,IPEndPoint * remote_endpoint)222 void RunTransactionTestBase(HttpCache* cache,
223                             const MockTransaction& trans_info,
224                             const MockHttpRequest& request,
225                             HttpResponseInfo* response_info,
226                             const NetLogWithSource& net_log,
227                             LoadTimingInfo* load_timing_info,
228                             int64_t* sent_bytes,
229                             int64_t* received_bytes,
230                             IPEndPoint* remote_endpoint) {
231   TestCompletionCallback callback;
232 
233   // write to the cache
234 
235   std::unique_ptr<HttpTransaction> trans;
236   int rv = cache->CreateTransaction(DEFAULT_PRIORITY, &trans);
237   EXPECT_THAT(rv, IsOk());
238   ASSERT_TRUE(trans.get());
239 
240   rv = trans->Start(&request, callback.callback(), net_log);
241   if (rv == ERR_IO_PENDING)
242     rv = callback.WaitForResult();
243   ASSERT_EQ(trans_info.start_return_code, rv);
244 
245   if (OK != rv)
246     return;
247 
248   const HttpResponseInfo* response = trans->GetResponseInfo();
249   ASSERT_TRUE(response);
250 
251   if (response_info)
252     *response_info = *response;
253 
254   if (load_timing_info) {
255     // If a fake network connection is used, need a NetLog to get a fake socket
256     // ID.
257     EXPECT_TRUE(net_log.net_log());
258     *load_timing_info = LoadTimingInfo();
259     trans->GetLoadTimingInfo(load_timing_info);
260   }
261 
262   if (remote_endpoint)
263     ASSERT_TRUE(trans->GetRemoteEndpoint(remote_endpoint));
264 
265   ReadAndVerifyTransaction(trans.get(), trans_info);
266 
267   if (sent_bytes)
268     *sent_bytes = trans->GetTotalSentBytes();
269   if (received_bytes)
270     *received_bytes = trans->GetTotalReceivedBytes();
271 }
272 
RunTransactionTestWithRequest(HttpCache * cache,const MockTransaction & trans_info,const MockHttpRequest & request,HttpResponseInfo * response_info)273 void RunTransactionTestWithRequest(HttpCache* cache,
274                                    const MockTransaction& trans_info,
275                                    const MockHttpRequest& request,
276                                    HttpResponseInfo* response_info) {
277   RunTransactionTestBase(cache, trans_info, request, response_info,
278                          NetLogWithSource(), nullptr, nullptr, nullptr,
279                          nullptr);
280 }
281 
RunTransactionTestAndGetTiming(HttpCache * cache,const MockTransaction & trans_info,const NetLogWithSource & log,LoadTimingInfo * load_timing_info)282 void RunTransactionTestAndGetTiming(HttpCache* cache,
283                                     const MockTransaction& trans_info,
284                                     const NetLogWithSource& log,
285                                     LoadTimingInfo* load_timing_info) {
286   RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
287                          nullptr, log, load_timing_info, nullptr, nullptr,
288                          nullptr);
289 }
290 
RunTransactionTestAndGetTimingAndConnectedSocketAddress(HttpCache * cache,const MockTransaction & trans_info,const NetLogWithSource & log,LoadTimingInfo * load_timing_info,IPEndPoint * remote_endpoint)291 void RunTransactionTestAndGetTimingAndConnectedSocketAddress(
292     HttpCache* cache,
293     const MockTransaction& trans_info,
294     const NetLogWithSource& log,
295     LoadTimingInfo* load_timing_info,
296     IPEndPoint* remote_endpoint) {
297   RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
298                          nullptr, log, load_timing_info, nullptr, nullptr,
299                          remote_endpoint);
300 }
301 
RunTransactionTest(HttpCache * cache,const MockTransaction & trans_info)302 void RunTransactionTest(HttpCache* cache, const MockTransaction& trans_info) {
303   RunTransactionTestAndGetTiming(cache, trans_info, NetLogWithSource(),
304                                  nullptr);
305 }
306 
RunTransactionTestWithLog(HttpCache * cache,const MockTransaction & trans_info,const NetLogWithSource & log)307 void RunTransactionTestWithLog(HttpCache* cache,
308                                const MockTransaction& trans_info,
309                                const NetLogWithSource& log) {
310   RunTransactionTestAndGetTiming(cache, trans_info, log, nullptr);
311 }
312 
RunTransactionTestWithResponseInfo(HttpCache * cache,const MockTransaction & trans_info,HttpResponseInfo * response)313 void RunTransactionTestWithResponseInfo(HttpCache* cache,
314                                         const MockTransaction& trans_info,
315                                         HttpResponseInfo* response) {
316   RunTransactionTestWithRequest(cache, trans_info, MockHttpRequest(trans_info),
317                                 response);
318 }
319 
RunTransactionTestWithResponseInfoAndGetTiming(HttpCache * cache,const MockTransaction & trans_info,HttpResponseInfo * response,const NetLogWithSource & log,LoadTimingInfo * load_timing_info)320 void RunTransactionTestWithResponseInfoAndGetTiming(
321     HttpCache* cache,
322     const MockTransaction& trans_info,
323     HttpResponseInfo* response,
324     const NetLogWithSource& log,
325     LoadTimingInfo* load_timing_info) {
326   RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
327                          response, log, load_timing_info, nullptr, nullptr,
328                          nullptr);
329 }
330 
RunTransactionTestWithResponse(HttpCache * cache,const MockTransaction & trans_info,std::string * response_headers)331 void RunTransactionTestWithResponse(HttpCache* cache,
332                                     const MockTransaction& trans_info,
333                                     std::string* response_headers) {
334   HttpResponseInfo response;
335   RunTransactionTestWithResponseInfo(cache, trans_info, &response);
336   *response_headers = ToSimpleString(response.headers);
337 }
338 
RunTransactionTestWithResponseAndGetTiming(HttpCache * cache,const MockTransaction & trans_info,std::string * response_headers,const NetLogWithSource & log,LoadTimingInfo * load_timing_info)339 void RunTransactionTestWithResponseAndGetTiming(
340     HttpCache* cache,
341     const MockTransaction& trans_info,
342     std::string* response_headers,
343     const NetLogWithSource& log,
344     LoadTimingInfo* load_timing_info) {
345   HttpResponseInfo response;
346   RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
347                          &response, log, load_timing_info, nullptr, nullptr,
348                          nullptr);
349   *response_headers = ToSimpleString(response.headers);
350 }
351 
352 // This class provides a handler for kFastNoStoreGET_Transaction so that the
353 // no-store header can be included on demand.
354 class FastTransactionServer {
355  public:
FastTransactionServer()356   FastTransactionServer() {
357     no_store = false;
358   }
359 
360   FastTransactionServer(const FastTransactionServer&) = delete;
361   FastTransactionServer& operator=(const FastTransactionServer&) = delete;
362 
363   ~FastTransactionServer() = default;
364 
set_no_store(bool value)365   void set_no_store(bool value) { no_store = value; }
366 
FastNoStoreHandler(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)367   static void FastNoStoreHandler(const HttpRequestInfo* request,
368                                  std::string* response_status,
369                                  std::string* response_headers,
370                                  std::string* response_data) {
371     if (no_store)
372       *response_headers = "Cache-Control: no-store\n";
373   }
374 
375  private:
376   static bool no_store;
377 };
378 bool FastTransactionServer::no_store;
379 
380 const MockTransaction kFastNoStoreGET_Transaction = {
381     "http://www.google.com/nostore",
382     "GET",
383     base::Time(),
384     "",
385     LOAD_VALIDATE_CACHE,
386     DefaultTransportInfo(),
387     "HTTP/1.1 200 OK",
388     "Cache-Control: max-age=10000\n",
389     base::Time(),
390     "<html><body>Google Blah Blah</body></html>",
391     {},
392     absl::nullopt,
393     absl::nullopt,
394     TEST_MODE_SYNC_NET_START,
395     &FastTransactionServer::FastNoStoreHandler,
396     nullptr,
397     nullptr,
398     0,
399     0,
400     OK,
401 };
402 
403 // This class provides a handler for kRangeGET_TransactionOK so that the range
404 // request can be served on demand.
405 class RangeTransactionServer {
406  public:
RangeTransactionServer()407   RangeTransactionServer() {
408     not_modified_ = false;
409     modified_ = false;
410     bad_200_ = false;
411     redirect_ = false;
412     length_ = 80;
413   }
414 
415   RangeTransactionServer(const RangeTransactionServer&) = delete;
416   RangeTransactionServer& operator=(const RangeTransactionServer&) = delete;
417 
~RangeTransactionServer()418   ~RangeTransactionServer() {
419     not_modified_ = false;
420     modified_ = false;
421     bad_200_ = false;
422     redirect_ = false;
423     length_ = 80;
424   }
425 
426   // Returns only 416 or 304 when set.
set_not_modified(bool value)427   void set_not_modified(bool value) { not_modified_ = value; }
428 
429   // Returns 206 when revalidating a range (instead of 304).
set_modified(bool value)430   void set_modified(bool value) { modified_ = value; }
431 
432   // Returns 200 instead of 206 (a malformed response overall).
set_bad_200(bool value)433   void set_bad_200(bool value) { bad_200_ = value; }
434 
435   // Sets how long the resource is. (Default is 80)
set_length(int64_t length)436   void set_length(int64_t length) { length_ = length; }
437 
438   // Sets whether to return a 301 instead of normal return.
set_redirect(bool redirect)439   void set_redirect(bool redirect) { redirect_ = redirect; }
440 
441   // Other than regular range related behavior (and the flags mentioned above),
442   // the server reacts to requests headers like so:
443   //   X-Require-Mock-Auth -> return 401.
444   //   X-Require-Mock-Auth-Alt -> return 401.
445   //   X-Return-Default-Range -> assume 40-49 was requested.
446   // The -Alt variant doesn't cause the MockNetworkTransaction to
447   // report that it IsReadyToRestartForAuth().
448   static void RangeHandler(const HttpRequestInfo* request,
449                            std::string* response_status,
450                            std::string* response_headers,
451                            std::string* response_data);
452 
453  private:
454   static bool not_modified_;
455   static bool modified_;
456   static bool bad_200_;
457   static bool redirect_;
458   static int64_t length_;
459 };
460 bool RangeTransactionServer::not_modified_ = false;
461 bool RangeTransactionServer::modified_ = false;
462 bool RangeTransactionServer::bad_200_ = false;
463 bool RangeTransactionServer::redirect_ = false;
464 int64_t RangeTransactionServer::length_ = 80;
465 
466 // A dummy extra header that must be preserved on a given request.
467 
468 // EXTRA_HEADER_LINE doesn't include a line terminator because it
469 // will be passed to AddHeaderFromString() which doesn't accept them.
470 #define EXTRA_HEADER_LINE "Extra: header"
471 
472 // EXTRA_HEADER contains a line terminator, as expected by
473 // AddHeadersFromString() (_not_ AddHeaderFromString()).
474 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
475 
476 static const char kExtraHeaderKey[] = "Extra";
477 
478 // Static.
RangeHandler(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)479 void RangeTransactionServer::RangeHandler(const HttpRequestInfo* request,
480                                           std::string* response_status,
481                                           std::string* response_headers,
482                                           std::string* response_data) {
483   if (request->extra_headers.IsEmpty()) {
484     response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
485     response_data->clear();
486     return;
487   }
488 
489   // We want to make sure we don't delete extra headers.
490   EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
491 
492   bool require_auth =
493       request->extra_headers.HasHeader("X-Require-Mock-Auth") ||
494       request->extra_headers.HasHeader("X-Require-Mock-Auth-Alt");
495 
496   if (require_auth && !request->extra_headers.HasHeader("Authorization")) {
497     response_status->assign("HTTP/1.1 401 Unauthorized");
498     response_data->assign("WWW-Authenticate: Foo\n");
499     return;
500   }
501 
502   if (redirect_) {
503     response_status->assign("HTTP/1.1 301 Moved Permanently");
504     response_headers->assign("Location: /elsewhere\nContent-Length: 5");
505     response_data->assign("12345");
506     return;
507   }
508 
509   if (not_modified_) {
510     response_status->assign("HTTP/1.1 304 Not Modified");
511     response_data->clear();
512     return;
513   }
514 
515   std::vector<HttpByteRange> ranges;
516   std::string range_header;
517   if (!request->extra_headers.GetHeader(HttpRequestHeaders::kRange,
518                                         &range_header) ||
519       !HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ ||
520       ranges.size() != 1 ||
521       (modified_ && request->extra_headers.HasHeader("If-Range"))) {
522     // This is not a byte range request, or a failed If-Range. We return 200.
523     response_status->assign("HTTP/1.1 200 OK");
524     response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
525     response_data->assign("Not a range");
526     return;
527   }
528 
529   // We can handle this range request.
530   HttpByteRange byte_range = ranges[0];
531 
532   if (request->extra_headers.HasHeader("X-Return-Default-Range")) {
533     byte_range.set_first_byte_position(40);
534     byte_range.set_last_byte_position(49);
535   }
536 
537   if (byte_range.first_byte_position() >= length_) {
538     response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
539     response_data->clear();
540     return;
541   }
542 
543   EXPECT_TRUE(byte_range.ComputeBounds(length_));
544   int64_t start = byte_range.first_byte_position();
545   int64_t end = byte_range.last_byte_position();
546 
547   EXPECT_LT(end, length_);
548 
549   std::string content_range = base::StringPrintf("Content-Range: bytes %" PRId64
550                                                  "-%" PRId64 "/%" PRId64 "\n",
551                                                  start, end, length_);
552   response_headers->append(content_range);
553 
554   if (!request->extra_headers.HasHeader("If-None-Match") || modified_) {
555     std::string data;
556     if (end == start) {
557       EXPECT_EQ(0, end % 10);
558       data = "r";
559     } else {
560       EXPECT_EQ(9, (end - start) % 10);
561       for (int64_t block_start = start; block_start < end; block_start += 10) {
562         base::StringAppendF(&data, "rg: %02" PRId64 "-%02" PRId64 " ",
563                             block_start % 100, (block_start + 9) % 100);
564       }
565     }
566     *response_data = data;
567 
568     if (end - start != 9) {
569       // We also have to fix content-length.
570       int64_t len = end - start + 1;
571       std::string content_length =
572           base::StringPrintf("Content-Length: %" PRId64 "\n", len);
573       response_headers->replace(response_headers->find("Content-Length:"),
574                                 content_length.size(), content_length);
575     }
576   } else {
577     response_status->assign("HTTP/1.1 304 Not Modified");
578     response_data->clear();
579   }
580 }
581 
582 const MockTransaction kRangeGET_TransactionOK = {
583     "http://www.google.com/range",
584     "GET",
585     base::Time(),
586     "Range: bytes = 40-49\r\n" EXTRA_HEADER,
587     LOAD_NORMAL,
588     DefaultTransportInfo(),
589     "HTTP/1.1 206 Partial Content",
590     "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
591     "ETag: \"foo\"\n"
592     "Accept-Ranges: bytes\n"
593     "Content-Length: 10\n",
594     base::Time(),
595     "rg: 40-49 ",
596     {},
597     absl::nullopt,
598     absl::nullopt,
599     TEST_MODE_NORMAL,
600     &RangeTransactionServer::RangeHandler,
601     nullptr,
602     nullptr,
603     0,
604     0,
605     OK,
606 };
607 
608 const char kFullRangeData[] =
609     "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 "
610     "rg: 40-49 rg: 50-59 rg: 60-69 rg: 70-79 ";
611 
612 // Verifies the response headers (|response|) match a partial content
613 // response for the range starting at |start| and ending at |end|.
Verify206Response(const std::string & response,int start,int end)614 void Verify206Response(const std::string& response, int start, int end) {
615   auto headers = base::MakeRefCounted<HttpResponseHeaders>(
616       HttpUtil::AssembleRawHeaders(response));
617 
618   ASSERT_EQ(206, headers->response_code());
619 
620   int64_t range_start, range_end, object_size;
621   ASSERT_TRUE(
622       headers->GetContentRangeFor206(&range_start, &range_end, &object_size));
623   int64_t content_length = headers->GetContentLength();
624 
625   int length = end - start + 1;
626   ASSERT_EQ(length, content_length);
627   ASSERT_EQ(start, range_start);
628   ASSERT_EQ(end, range_end);
629 }
630 
631 // Creates a truncated entry that can be resumed using byte ranges.
CreateTruncatedEntry(std::string raw_headers,MockHttpCache * cache)632 void CreateTruncatedEntry(std::string raw_headers, MockHttpCache* cache) {
633   // Create a disk cache entry that stores an incomplete resource.
634   disk_cache::Entry* entry;
635   MockHttpRequest request(kRangeGET_TransactionOK);
636   ASSERT_TRUE(cache->CreateBackendEntry(request.CacheKey(), &entry, nullptr));
637 
638   HttpResponseInfo response;
639   response.response_time = base::Time::Now();
640   response.request_time = base::Time::Now();
641   response.headers = base::MakeRefCounted<HttpResponseHeaders>(
642       HttpUtil::AssembleRawHeaders(raw_headers));
643   // Set the last argument for this to be an incomplete request.
644   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
645 
646   scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(100);
647   int len = static_cast<int>(base::strlcpy(buf->data(),
648                                            "rg: 00-09 rg: 10-19 ", 100));
649   TestCompletionCallback cb;
650   int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
651   EXPECT_EQ(len, cb.GetResult(rv));
652   entry->Close();
653 }
654 
655 // Verifies that there's an entry with this |key| with the truncated flag set to
656 // |flag_value|, and with an optional |data_size| (if not zero).
VerifyTruncatedFlag(MockHttpCache * cache,const std::string & key,bool flag_value,int data_size)657 void VerifyTruncatedFlag(MockHttpCache* cache,
658                          const std::string& key,
659                          bool flag_value,
660                          int data_size) {
661   disk_cache::Entry* entry;
662   ASSERT_TRUE(cache->OpenBackendEntry(key, &entry));
663   disk_cache::ScopedEntryPtr closer(entry);
664 
665   HttpResponseInfo response;
666   bool truncated = !flag_value;
667   EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
668   EXPECT_EQ(flag_value, truncated);
669   if (data_size)
670     EXPECT_EQ(data_size, entry->GetDataSize(1));
671 }
672 
673 // Helper to represent a network HTTP response.
674 struct Response {
675   // Set this response into |trans|.
AssignTonet::__anonc87d1e5b0111::Response676   void AssignTo(MockTransaction* trans) const {
677     trans->status = status;
678     trans->response_headers = headers;
679     trans->data = body;
680   }
681 
status_and_headersnet::__anonc87d1e5b0111::Response682   std::string status_and_headers() const {
683     return std::string(status) + "\n" + std::string(headers);
684   }
685 
686   const char* status;
687   const char* headers;
688   const char* body;
689 };
690 
691 struct Context {
692   Context() = default;
693 
694   int result = ERR_IO_PENDING;
695   TestCompletionCallback callback;
696   std::unique_ptr<HttpTransaction> trans;
697 };
698 
699 class FakeWebSocketHandshakeStreamCreateHelper
700     : public WebSocketHandshakeStreamBase::CreateHelper {
701  public:
702   ~FakeWebSocketHandshakeStreamCreateHelper() override = default;
CreateBasicStream(std::unique_ptr<ClientSocketHandle> connect,bool using_proxy,WebSocketEndpointLockManager * websocket_endpoint_lock_manager)703   std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
704       std::unique_ptr<ClientSocketHandle> connect,
705       bool using_proxy,
706       WebSocketEndpointLockManager* websocket_endpoint_lock_manager) override {
707     return nullptr;
708   }
CreateHttp2Stream(base::WeakPtr<SpdySession> session,std::set<std::string> dns_aliases)709   std::unique_ptr<WebSocketHandshakeStreamBase> CreateHttp2Stream(
710       base::WeakPtr<SpdySession> session,
711       std::set<std::string> dns_aliases) override {
712     NOTREACHED();
713     return nullptr;
714   }
CreateHttp3Stream(std::unique_ptr<QuicChromiumClientSession::Handle> session,std::set<std::string> dns_aliases)715   std::unique_ptr<WebSocketHandshakeStreamBase> CreateHttp3Stream(
716       std::unique_ptr<QuicChromiumClientSession::Handle> session,
717       std::set<std::string> dns_aliases) override {
718     NOTREACHED();
719     return nullptr;
720   }
721 };
722 
723 // Returns true if |entry| is not one of the log types paid attention to in this
724 // test. Note that HTTP_CACHE_WRITE_INFO and HTTP_CACHE_*_DATA are
725 // ignored.
ShouldIgnoreLogEntry(const NetLogEntry & entry)726 bool ShouldIgnoreLogEntry(const NetLogEntry& entry) {
727   switch (entry.type) {
728     case NetLogEventType::HTTP_CACHE_GET_BACKEND:
729     case NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY:
730     case NetLogEventType::HTTP_CACHE_OPEN_ENTRY:
731     case NetLogEventType::HTTP_CACHE_CREATE_ENTRY:
732     case NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY:
733     case NetLogEventType::HTTP_CACHE_DOOM_ENTRY:
734     case NetLogEventType::HTTP_CACHE_READ_INFO:
735       return false;
736     default:
737       return true;
738   }
739 }
740 
741 // Gets the entries from |net_log| created by the cache layer and asserted on in
742 // these tests.
GetFilteredNetLogEntries(const RecordingNetLogObserver & net_log_observer)743 std::vector<NetLogEntry> GetFilteredNetLogEntries(
744     const RecordingNetLogObserver& net_log_observer) {
745   auto entries = net_log_observer.GetEntries();
746   base::EraseIf(entries, ShouldIgnoreLogEntry);
747   return entries;
748 }
749 
LogContainsEventType(const RecordingNetLogObserver & net_log_observer,NetLogEventType expected)750 bool LogContainsEventType(const RecordingNetLogObserver& net_log_observer,
751                           NetLogEventType expected) {
752   return !net_log_observer.GetEntriesWithType(expected).empty();
753 }
754 
755 // Returns a TransportInfo distinct from the default for mock transactions,
756 // with the given port number.
TestTransportInfoWithPort(uint16_t port)757 TransportInfo TestTransportInfoWithPort(uint16_t port) {
758   TransportInfo result;
759   result.endpoint = IPEndPoint(IPAddress(42, 0, 1, 2), port);
760   return result;
761 }
762 
763 // Returns a TransportInfo distinct from the default for mock transactions.
TestTransportInfo()764 TransportInfo TestTransportInfo() {
765   return TestTransportInfoWithPort(1337);
766 }
767 
CachedTestTransportInfo()768 TransportInfo CachedTestTransportInfo() {
769   TransportInfo result = TestTransportInfo();
770   result.type = TransportType::kCached;
771   return result;
772 }
773 
774 // Helper function, generating valid HTTP cache key from `url`.
775 // See also: HttpCache::GenerateCacheKey(..)
GenerateCacheKey(const std::string & url)776 std::string GenerateCacheKey(const std::string& url) {
777   return "1/0/" + url;
778 }
779 
780 }  // namespace
781 
782 using HttpCacheTest = TestWithTaskEnvironment;
783 class HttpCacheIOCallbackTest : public HttpCacheTest {
784  public:
785   HttpCacheIOCallbackTest() = default;
786   ~HttpCacheIOCallbackTest() override = default;
787 
788   // HttpCache::ActiveEntry is private, doing this allows tests to use it
789   using ActiveEntry = HttpCache::ActiveEntry;
790   using Transaction = HttpCache::Transaction;
791 
792   // The below functions are forwarding calls to the HttpCache class.
OpenEntry(HttpCache * cache,const std::string & url,HttpCache::ActiveEntry ** entry,HttpCache::Transaction * trans)793   int OpenEntry(HttpCache* cache,
794                 const std::string& url,
795                 HttpCache::ActiveEntry** entry,
796                 HttpCache::Transaction* trans) {
797     return cache->OpenEntry(GenerateCacheKey(url), entry, trans);
798   }
799 
OpenOrCreateEntry(HttpCache * cache,const std::string & url,HttpCache::ActiveEntry ** entry,HttpCache::Transaction * trans)800   int OpenOrCreateEntry(HttpCache* cache,
801                         const std::string& url,
802                         HttpCache::ActiveEntry** entry,
803                         HttpCache::Transaction* trans) {
804     return cache->OpenOrCreateEntry(GenerateCacheKey(url), entry, trans);
805   }
806 
CreateEntry(HttpCache * cache,const std::string & url,HttpCache::ActiveEntry ** entry,HttpCache::Transaction * trans)807   int CreateEntry(HttpCache* cache,
808                   const std::string& url,
809                   HttpCache::ActiveEntry** entry,
810                   HttpCache::Transaction* trans) {
811     return cache->CreateEntry(GenerateCacheKey(url), entry, trans);
812   }
813 
DoomEntry(HttpCache * cache,const std::string & url,HttpCache::Transaction * trans)814   int DoomEntry(HttpCache* cache,
815                 const std::string& url,
816                 HttpCache::Transaction* trans) {
817     return cache->DoomEntry(GenerateCacheKey(url), trans);
818   }
819 
DeactivateEntry(HttpCache * cache,ActiveEntry * entry)820   void DeactivateEntry(HttpCache* cache, ActiveEntry* entry) {
821     cache->DeactivateEntry(entry);
822   }
823 };
824 
825 class HttpSplitCacheKeyTest : public HttpCacheTest {
826  public:
827   HttpSplitCacheKeyTest() = default;
828   ~HttpSplitCacheKeyTest() override = default;
829 
ComputeCacheKey(const std::string & url_string)830   std::string ComputeCacheKey(const std::string& url_string) {
831     GURL url(url_string);
832     SchemefulSite site(url);
833     net::HttpRequestInfo request_info;
834     request_info.url = url;
835     request_info.method = "GET";
836     request_info.network_isolation_key = net::NetworkIsolationKey(site, site);
837     request_info.network_anonymization_key =
838         net::NetworkAnonymizationKey::CreateSameSite(site);
839     MockHttpCache cache;
840     return *cache.http_cache()->GenerateCacheKeyForRequest(&request_info);
841   }
842 };
843 
844 //-----------------------------------------------------------------------------
845 // Tests.
846 
TEST_F(HttpCacheTest,CreateThenDestroy)847 TEST_F(HttpCacheTest, CreateThenDestroy) {
848   MockHttpCache cache;
849 
850   std::unique_ptr<HttpTransaction> trans;
851   EXPECT_THAT(cache.CreateTransaction(&trans), IsOk());
852   ASSERT_TRUE(trans.get());
853 }
854 
TEST_F(HttpCacheTest,GetBackend)855 TEST_F(HttpCacheTest, GetBackend) {
856   MockHttpCache cache(HttpCache::DefaultBackend::InMemory(0));
857 
858   disk_cache::Backend* backend;
859   TestCompletionCallback cb;
860   // This will lazily initialize the backend.
861   int rv = cache.http_cache()->GetBackend(&backend, cb.callback());
862   EXPECT_THAT(cb.GetResult(rv), IsOk());
863 }
864 
TEST_F(HttpCacheTest,SimpleGET)865 TEST_F(HttpCacheTest, SimpleGET) {
866   MockHttpCache cache;
867   LoadTimingInfo load_timing_info;
868 
869   // Write to the cache.
870   RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
871                                  NetLogWithSource::Make(NetLogSourceType::NONE),
872                                  &load_timing_info);
873 
874   EXPECT_EQ(1, cache.network_layer()->transaction_count());
875   EXPECT_EQ(0, cache.disk_cache()->open_count());
876   EXPECT_EQ(1, cache.disk_cache()->create_count());
877   TestLoadTimingNetworkRequest(load_timing_info);
878 }
879 
880 // This test verifies that the callback passed to SetConnectedCallback() is
881 // called once for simple GET calls that traverse the cache.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallback)882 TEST_F(HttpCacheTest, SimpleGET_ConnectedCallback) {
883   MockHttpCache cache;
884 
885   ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
886   mock_transaction.transport_info = TestTransportInfo();
887   MockHttpRequest request(mock_transaction);
888 
889   ConnectedHandler connected_handler;
890 
891   std::unique_ptr<HttpTransaction> transaction;
892   EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
893   ASSERT_THAT(transaction, NotNull());
894 
895   transaction->SetConnectedCallback(connected_handler.Callback());
896 
897   TestCompletionCallback callback;
898   ASSERT_THAT(
899       transaction->Start(&request, callback.callback(), NetLogWithSource()),
900       IsError(ERR_IO_PENDING));
901   EXPECT_THAT(callback.WaitForResult(), IsOk());
902 
903   EXPECT_THAT(connected_handler.transports(), ElementsAre(TestTransportInfo()));
904 }
905 
906 // This test verifies that when the callback passed to SetConnectedCallback()
907 // returns an error, the transaction fails with that error.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackReturnError)908 TEST_F(HttpCacheTest, SimpleGET_ConnectedCallbackReturnError) {
909   MockHttpCache cache;
910   MockHttpRequest request(kSimpleGET_Transaction);
911   ConnectedHandler connected_handler;
912 
913   std::unique_ptr<HttpTransaction> transaction;
914   EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
915   ASSERT_THAT(transaction, NotNull());
916 
917   // The exact error code does not matter. We only care that it is passed to
918   // the transaction's completion callback unmodified.
919   connected_handler.set_result(ERR_NOT_IMPLEMENTED);
920   transaction->SetConnectedCallback(connected_handler.Callback());
921 
922   TestCompletionCallback callback;
923   ASSERT_THAT(
924       transaction->Start(&request, callback.callback(), NetLogWithSource()),
925       IsError(ERR_IO_PENDING));
926   EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NOT_IMPLEMENTED));
927 }
928 
929 // This test verifies that the callback passed to SetConnectedCallback() is
930 // called once for requests that hit the cache.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackOnCacheHit)931 TEST_F(HttpCacheTest, SimpleGET_ConnectedCallbackOnCacheHit) {
932   MockHttpCache cache;
933 
934   {
935     // Populate the cache.
936     ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
937     mock_transaction.transport_info = TestTransportInfo();
938     RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
939   }
940 
941   // Establish a baseline.
942   EXPECT_EQ(1, cache.network_layer()->transaction_count());
943 
944   // Load from the cache (only), observe the callback being called.
945 
946   ConnectedHandler connected_handler;
947   MockHttpRequest request(kSimpleGET_Transaction);
948 
949   std::unique_ptr<HttpTransaction> transaction;
950   EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
951   ASSERT_THAT(transaction, NotNull());
952 
953   transaction->SetConnectedCallback(connected_handler.Callback());
954 
955   TestCompletionCallback callback;
956   ASSERT_THAT(
957       transaction->Start(&request, callback.callback(), NetLogWithSource()),
958       IsError(ERR_IO_PENDING));
959   EXPECT_THAT(callback.WaitForResult(), IsOk());
960 
961   // Still only 1 transaction for the previous request. The connected callback
962   // was not called by a second network transaction.
963   EXPECT_EQ(1, cache.network_layer()->transaction_count());
964 
965   EXPECT_THAT(connected_handler.transports(),
966               ElementsAre(CachedTestTransportInfo()));
967 }
968 
969 // This test verifies that when the callback passed to SetConnectedCallback()
970 // is called for a request that hit the cache and returns an error, the cache
971 // entry is reusable.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackOnCacheHitReturnError)972 TEST_F(HttpCacheTest, SimpleGET_ConnectedCallbackOnCacheHitReturnError) {
973   MockHttpCache cache;
974 
975   {
976     // Populate the cache.
977     ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
978     mock_transaction.transport_info = TestTransportInfo();
979     RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
980   }
981 
982   MockHttpRequest request(kSimpleGET_Transaction);
983 
984   {
985     // Attempt to read from cache entry, but abort transaction due to a
986     // connected callback error.
987     ConnectedHandler connected_handler;
988     connected_handler.set_result(ERR_FAILED);
989 
990     std::unique_ptr<HttpTransaction> transaction;
991     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
992     ASSERT_THAT(transaction, NotNull());
993 
994     transaction->SetConnectedCallback(connected_handler.Callback());
995 
996     TestCompletionCallback callback;
997     ASSERT_THAT(
998         transaction->Start(&request, callback.callback(), NetLogWithSource()),
999         IsError(ERR_IO_PENDING));
1000     EXPECT_THAT(callback.WaitForResult(), IsError(ERR_FAILED));
1001 
1002     // Used the cache entry only.
1003     EXPECT_THAT(connected_handler.transports(),
1004                 ElementsAre(CachedTestTransportInfo()));
1005   }
1006 
1007   {
1008     // Request the same resource once more, observe that it is read from cache.
1009     ConnectedHandler connected_handler;
1010 
1011     std::unique_ptr<HttpTransaction> transaction;
1012     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
1013     ASSERT_THAT(transaction, NotNull());
1014 
1015     transaction->SetConnectedCallback(connected_handler.Callback());
1016 
1017     TestCompletionCallback callback;
1018     ASSERT_THAT(
1019         transaction->Start(&request, callback.callback(), NetLogWithSource()),
1020         IsError(ERR_IO_PENDING));
1021     EXPECT_THAT(callback.WaitForResult(), IsOk());
1022 
1023     // Used the cache entry only.
1024     EXPECT_THAT(connected_handler.transports(),
1025                 ElementsAre(CachedTestTransportInfo()));
1026   }
1027 }
1028 
1029 // This test verifies that when the callback passed to SetConnectedCallback()
1030 // returns `ERR_INCONSISTENT_IP_ADDRESS_SPACE`, the cache entry is invalidated.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackOnCacheHitReturnInconsistentIpError)1031 TEST_F(HttpCacheTest,
1032        SimpleGET_ConnectedCallbackOnCacheHitReturnInconsistentIpError) {
1033   MockHttpCache cache;
1034 
1035   ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
1036   mock_transaction.transport_info = TestTransportInfo();
1037 
1038   // Populate the cache.
1039   RunTransactionTest(cache.http_cache(), mock_transaction);
1040 
1041   MockHttpRequest request(kSimpleGET_Transaction);
1042 
1043   {
1044     // Attempt to read from cache entry, but abort transaction due to a
1045     // connected callback error.
1046     ConnectedHandler connected_handler;
1047     connected_handler.set_result(ERR_INCONSISTENT_IP_ADDRESS_SPACE);
1048 
1049     std::unique_ptr<HttpTransaction> transaction;
1050     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
1051     ASSERT_THAT(transaction, NotNull());
1052 
1053     transaction->SetConnectedCallback(connected_handler.Callback());
1054 
1055     TestCompletionCallback callback;
1056     ASSERT_THAT(
1057         transaction->Start(&request, callback.callback(), NetLogWithSource()),
1058         IsError(ERR_IO_PENDING));
1059     EXPECT_THAT(callback.WaitForResult(),
1060                 IsError(ERR_INCONSISTENT_IP_ADDRESS_SPACE));
1061 
1062     // Used the cache entry only.
1063     EXPECT_THAT(connected_handler.transports(),
1064                 ElementsAre(CachedTestTransportInfo()));
1065   }
1066 
1067   {
1068     // Request the same resource once more, observe that it is not read from
1069     // cache.
1070     ConnectedHandler connected_handler;
1071 
1072     std::unique_ptr<HttpTransaction> transaction;
1073     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
1074     ASSERT_THAT(transaction, NotNull());
1075 
1076     transaction->SetConnectedCallback(connected_handler.Callback());
1077 
1078     TestCompletionCallback callback;
1079     ASSERT_THAT(
1080         transaction->Start(&request, callback.callback(), NetLogWithSource()),
1081         IsError(ERR_IO_PENDING));
1082     EXPECT_THAT(callback.WaitForResult(), IsOk());
1083 
1084     // Used the network only.
1085     EXPECT_THAT(connected_handler.transports(),
1086                 ElementsAre(TestTransportInfo()));
1087   }
1088 }
1089 
1090 // This test verifies that when the callback passed to SetConnectedCallback()
1091 // returns
1092 // `ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_LOCAL_NETWORK_ACCESS_POLICY`, the
1093 // cache entry is invalidated, and we'll retry the connection from the network.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackOnCacheHitReturnLocalNetworkAccessBlockedError)1094 TEST_F(
1095     HttpCacheTest,
1096     SimpleGET_ConnectedCallbackOnCacheHitReturnLocalNetworkAccessBlockedError) {
1097   MockHttpCache cache;
1098 
1099   ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
1100   mock_transaction.transport_info = TestTransportInfo();
1101 
1102   // Populate the cache.
1103   RunTransactionTest(cache.http_cache(), mock_transaction);
1104 
1105   MockHttpRequest request(kSimpleGET_Transaction);
1106 
1107   {
1108     // Attempt to read from cache entry, but abort transaction due to a
1109     // connected callback error.
1110     ConnectedHandler connected_handler;
1111     connected_handler.set_result(
1112         ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_LOCAL_NETWORK_ACCESS_POLICY);
1113 
1114     std::unique_ptr<HttpTransaction> transaction;
1115     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
1116     ASSERT_THAT(transaction, NotNull());
1117 
1118     transaction->SetConnectedCallback(connected_handler.Callback());
1119 
1120     TestCompletionCallback callback;
1121     ASSERT_THAT(
1122         transaction->Start(&request, callback.callback(), NetLogWithSource()),
1123         IsError(ERR_IO_PENDING));
1124     EXPECT_THAT(
1125         callback.WaitForResult(),
1126         IsError(
1127             ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_LOCAL_NETWORK_ACCESS_POLICY));
1128 
1129     // Used the cache entry only.
1130     EXPECT_THAT(connected_handler.transports(),
1131                 ElementsAre(CachedTestTransportInfo(), TestTransportInfo()));
1132   }
1133 
1134   {
1135     // Request the same resource once more, observe that it is not read from
1136     // cache.
1137     ConnectedHandler connected_handler;
1138 
1139     std::unique_ptr<HttpTransaction> transaction;
1140     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
1141     ASSERT_THAT(transaction, NotNull());
1142 
1143     transaction->SetConnectedCallback(connected_handler.Callback());
1144 
1145     TestCompletionCallback callback;
1146     ASSERT_THAT(
1147         transaction->Start(&request, callback.callback(), NetLogWithSource()),
1148         IsError(ERR_IO_PENDING));
1149     EXPECT_THAT(callback.WaitForResult(), IsOk());
1150 
1151     // Used the network only.
1152     EXPECT_THAT(connected_handler.transports(),
1153                 ElementsAre(TestTransportInfo()));
1154   }
1155 }
1156 
1157 // This test verifies that the callback passed to SetConnectedCallback() is
1158 // called with the right transport type when the cached entry was originally
1159 // fetched via proxy.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackOnCacheHitFromProxy)1160 TEST_F(HttpCacheTest, SimpleGET_ConnectedCallbackOnCacheHitFromProxy) {
1161   MockHttpCache cache;
1162 
1163   TransportInfo proxied_transport_info = TestTransportInfo();
1164   proxied_transport_info.type = TransportType::kProxied;
1165 
1166   {
1167     // Populate the cache.
1168     ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
1169     mock_transaction.transport_info = proxied_transport_info;
1170     RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1171   }
1172 
1173   // Establish a baseline.
1174   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1175 
1176   // Load from the cache (only), observe the callback being called.
1177 
1178   ConnectedHandler connected_handler;
1179   MockHttpRequest request(kSimpleGET_Transaction);
1180 
1181   std::unique_ptr<HttpTransaction> transaction;
1182   EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
1183   ASSERT_THAT(transaction, NotNull());
1184 
1185   transaction->SetConnectedCallback(connected_handler.Callback());
1186 
1187   TestCompletionCallback callback;
1188   ASSERT_THAT(
1189       transaction->Start(&request, callback.callback(), NetLogWithSource()),
1190       IsError(ERR_IO_PENDING));
1191   EXPECT_THAT(callback.WaitForResult(), IsOk());
1192 
1193   // Still only 1 transaction for the previous request. The connected callback
1194   // was not called by a second network transaction.
1195   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1196 
1197   // The transport info mentions both the cache and the original proxy.
1198   TransportInfo expected_transport_info = TestTransportInfo();
1199   expected_transport_info.type = TransportType::kCachedFromProxy;
1200 
1201   EXPECT_THAT(connected_handler.transports(),
1202               ElementsAre(expected_transport_info));
1203 }
1204 
1205 enum class SplitCacheTestCase {
1206   kSplitCacheDisabled,
1207   kSplitCacheNikFrameSiteEnabled,
1208   kSplitCacheNikCrossSiteFlagEnabled,
1209 };
1210 
InitializeSplitCacheScopedFeatureList(base::test::ScopedFeatureList & scoped_feature_list,SplitCacheTestCase test_case)1211 void InitializeSplitCacheScopedFeatureList(
1212     base::test::ScopedFeatureList& scoped_feature_list,
1213     SplitCacheTestCase test_case) {
1214   std::vector<base::test::FeatureRef> enabled_features;
1215   std::vector<base::test::FeatureRef> disabled_features;
1216 
1217   if (test_case == SplitCacheTestCase::kSplitCacheDisabled) {
1218     disabled_features.push_back(
1219         net::features::kSplitCacheByNetworkIsolationKey);
1220   } else {
1221     enabled_features.push_back(net::features::kSplitCacheByNetworkIsolationKey);
1222   }
1223 
1224   if (test_case == SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled) {
1225     enabled_features.push_back(
1226         net::features::kEnableCrossSiteFlagNetworkIsolationKey);
1227   } else {
1228     disabled_features.push_back(
1229         net::features::kEnableCrossSiteFlagNetworkIsolationKey);
1230   }
1231   scoped_feature_list.InitWithFeatures(enabled_features, disabled_features);
1232 }
1233 
1234 class HttpCacheTest_SplitCacheFeature
1235     : public HttpCacheTest,
1236       public ::testing::WithParamInterface<SplitCacheTestCase> {
1237  public:
HttpCacheTest_SplitCacheFeature()1238   HttpCacheTest_SplitCacheFeature() {
1239     InitializeSplitCacheScopedFeatureList(feature_list_, GetParam());
1240   }
1241 
IsSplitCacheEnabled() const1242   bool IsSplitCacheEnabled() const {
1243     return GetParam() != SplitCacheTestCase::kSplitCacheDisabled;
1244   }
1245 
IsNikFrameSiteEnabled() const1246   bool IsNikFrameSiteEnabled() const {
1247     return GetParam() == SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled;
1248   }
1249 
1250  private:
1251   base::test::ScopedFeatureList feature_list_;
1252 };
1253 
TEST_P(HttpCacheTest_SplitCacheFeature,SimpleGETVerifyGoogleFontMetrics)1254 TEST_P(HttpCacheTest_SplitCacheFeature, SimpleGETVerifyGoogleFontMetrics) {
1255   base::HistogramTester histograms;
1256   const std::string histogram_name = "WebFont.HttpCacheStatus_roboto";
1257 
1258   SchemefulSite site_a(GURL("http://www.a.com"));
1259 
1260   MockHttpCache cache;
1261 
1262   MockTransaction transaction(kSimpleGET_Transaction);
1263   transaction.url = "http://themes.googleusercontent.com/static/fonts/roboto";
1264   AddMockTransaction(&transaction);
1265   MockHttpRequest request(transaction);
1266   request.network_isolation_key = NetworkIsolationKey(site_a, site_a);
1267   request.network_anonymization_key =
1268       net::NetworkAnonymizationKey::CreateSameSite(site_a);
1269 
1270   // Attempt to populate the cache.
1271   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
1272                                 nullptr);
1273 
1274   histograms.ExpectUniqueSample(
1275       histogram_name, static_cast<int>(CacheEntryStatus::ENTRY_NOT_IN_CACHE),
1276       1);
1277 
1278   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
1279                                 nullptr);
1280 
1281   histograms.ExpectBucketCount(
1282       histogram_name, static_cast<int>(CacheEntryStatus::ENTRY_USED), 1);
1283 }
1284 
1285 INSTANTIATE_TEST_SUITE_P(
1286     All,
1287     HttpCacheTest_SplitCacheFeature,
1288     testing::ValuesIn({SplitCacheTestCase::kSplitCacheDisabled,
1289                        SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled,
1290                        SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled}),
__anonc87d1e5b0202(const testing::TestParamInfo<SplitCacheTestCase>& info) 1291     [](const testing::TestParamInfo<SplitCacheTestCase>& info) {
1292       switch (info.param) {
1293         case (SplitCacheTestCase::kSplitCacheDisabled):
1294           return "SplitCacheDisabled";
1295         case (SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled):
1296           return "SplitCacheNikFrameSiteEnabled";
1297         case (SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled):
1298           return "SplitCacheNikCrossSiteFlagEnabled";
1299       }
1300     });
1301 
1302 class HttpCacheTest_SplitCacheFeatureEnabled
1303     : public HttpCacheTest_SplitCacheFeature {
1304  public:
HttpCacheTest_SplitCacheFeatureEnabled()1305   HttpCacheTest_SplitCacheFeatureEnabled() {
1306     CHECK(base::FeatureList::IsEnabled(
1307         net::features::kSplitCacheByNetworkIsolationKey));
1308   }
1309 };
1310 
1311 INSTANTIATE_TEST_SUITE_P(
1312     All,
1313     HttpCacheTest_SplitCacheFeatureEnabled,
1314     testing::ValuesIn({SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled,
1315                        SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled}),
__anonc87d1e5b0302(const testing::TestParamInfo<SplitCacheTestCase>& info) 1316     [](const testing::TestParamInfo<SplitCacheTestCase>& info) {
1317       switch (info.param) {
1318         case (SplitCacheTestCase::kSplitCacheDisabled):
1319           return "NotUsedForThisTestSuite";
1320         case (SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled):
1321           return "SplitCacheNikFrameSiteEnabled";
1322         case (SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled):
1323           return "SplitCacheNikCrossSiteFlagEnabled";
1324       }
1325     });
1326 
TEST_F(HttpCacheTest,SimpleGETNoDiskCache)1327 TEST_F(HttpCacheTest, SimpleGETNoDiskCache) {
1328   MockHttpCache cache;
1329 
1330   cache.disk_cache()->set_fail_requests(true);
1331 
1332   RecordingNetLogObserver net_log_observer;
1333   LoadTimingInfo load_timing_info;
1334 
1335   // Read from the network, and don't use the cache.
1336   RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
1337                                  NetLogWithSource::Make(NetLogSourceType::NONE),
1338                                  &load_timing_info);
1339 
1340   // Check that the NetLog was filled as expected.
1341   // (We attempted to OpenOrCreate entries, but fail).
1342   auto entries = GetFilteredNetLogEntries(net_log_observer);
1343 
1344   EXPECT_EQ(4u, entries.size());
1345   EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
1346                                     NetLogEventType::HTTP_CACHE_GET_BACKEND));
1347   EXPECT_TRUE(
1348       LogContainsEndEvent(entries, 1, NetLogEventType::HTTP_CACHE_GET_BACKEND));
1349   EXPECT_TRUE(LogContainsBeginEvent(
1350       entries, 2, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1351   EXPECT_TRUE(LogContainsEndEvent(
1352       entries, 3, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1353 
1354   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1355   EXPECT_EQ(0, cache.disk_cache()->open_count());
1356   EXPECT_EQ(0, cache.disk_cache()->create_count());
1357   TestLoadTimingNetworkRequest(load_timing_info);
1358 }
1359 
TEST_F(HttpCacheTest,SimpleGETNoDiskCache2)1360 TEST_F(HttpCacheTest, SimpleGETNoDiskCache2) {
1361   // This will initialize a cache object with NULL backend.
1362   auto factory = std::make_unique<MockBlockingBackendFactory>();
1363   factory->set_fail(true);
1364   factory->FinishCreation();  // We'll complete synchronously.
1365   MockHttpCache cache(std::move(factory));
1366 
1367   // Read from the network, and don't use the cache.
1368   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1369 
1370   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1371   EXPECT_FALSE(cache.http_cache()->GetCurrentBackend());
1372 }
1373 
1374 // Tests that IOBuffers are not referenced after IO completes.
TEST_F(HttpCacheTest,ReleaseBuffer)1375 TEST_F(HttpCacheTest, ReleaseBuffer) {
1376   MockHttpCache cache;
1377 
1378   // Write to the cache.
1379   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1380 
1381   MockHttpRequest request(kSimpleGET_Transaction);
1382   std::unique_ptr<HttpTransaction> trans;
1383   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
1384 
1385   const int kBufferSize = 10;
1386   scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<IOBuffer>(kBufferSize);
1387   ReleaseBufferCompletionCallback cb(buffer.get());
1388 
1389   int rv = trans->Start(&request, cb.callback(), NetLogWithSource());
1390   EXPECT_THAT(cb.GetResult(rv), IsOk());
1391 
1392   rv = trans->Read(buffer.get(), kBufferSize, cb.callback());
1393   EXPECT_EQ(kBufferSize, cb.GetResult(rv));
1394 }
1395 
TEST_F(HttpCacheTest,SimpleGETWithDiskFailures)1396 TEST_F(HttpCacheTest, SimpleGETWithDiskFailures) {
1397   MockHttpCache cache;
1398 
1399   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_ALL);
1400 
1401   // Read from the network, and fail to write to the cache.
1402   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1403 
1404   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1405   EXPECT_EQ(0, cache.disk_cache()->open_count());
1406   EXPECT_EQ(1, cache.disk_cache()->create_count());
1407 
1408   // This one should see an empty cache again.
1409   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1410 
1411   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1412   EXPECT_EQ(0, cache.disk_cache()->open_count());
1413   EXPECT_EQ(2, cache.disk_cache()->create_count());
1414 }
1415 
1416 // Tests that disk failures after the transaction has started don't cause the
1417 // request to fail.
TEST_F(HttpCacheTest,SimpleGETWithDiskFailures2)1418 TEST_F(HttpCacheTest, SimpleGETWithDiskFailures2) {
1419   MockHttpCache cache;
1420 
1421   MockHttpRequest request(kSimpleGET_Transaction);
1422 
1423   auto c = std::make_unique<Context>();
1424   int rv = cache.CreateTransaction(&c->trans);
1425   ASSERT_THAT(rv, IsOk());
1426 
1427   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1428   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1429   rv = c->callback.WaitForResult();
1430 
1431   // Start failing request now.
1432   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_ALL);
1433 
1434   // We have to open the entry again to propagate the failure flag.
1435   disk_cache::Entry* en;
1436   ASSERT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &en));
1437   en->Close();
1438 
1439   ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1440   c.reset();
1441 
1442   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1443   EXPECT_EQ(1, cache.disk_cache()->open_count());
1444   EXPECT_EQ(1, cache.disk_cache()->create_count());
1445 
1446   // This one should see an empty cache again.
1447   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1448 
1449   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1450   EXPECT_EQ(1, cache.disk_cache()->open_count());
1451   EXPECT_EQ(2, cache.disk_cache()->create_count());
1452 }
1453 
1454 // Tests that we handle failures to read from the cache.
TEST_F(HttpCacheTest,SimpleGETWithDiskFailures3)1455 TEST_F(HttpCacheTest, SimpleGETWithDiskFailures3) {
1456   MockHttpCache cache;
1457 
1458   // Read from the network, and write to the cache.
1459   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1460 
1461   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1462   EXPECT_EQ(0, cache.disk_cache()->open_count());
1463   EXPECT_EQ(1, cache.disk_cache()->create_count());
1464 
1465   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_ALL);
1466 
1467   MockHttpRequest request(kSimpleGET_Transaction);
1468 
1469   // Now fail to read from the cache.
1470   auto c = std::make_unique<Context>();
1471   int rv = cache.CreateTransaction(&c->trans);
1472   ASSERT_THAT(rv, IsOk());
1473 
1474   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1475   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
1476 
1477   // Now verify that the entry was removed from the cache.
1478   cache.disk_cache()->set_soft_failures_mask(0);
1479 
1480   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1481   EXPECT_EQ(1, cache.disk_cache()->open_count());
1482   EXPECT_EQ(2, cache.disk_cache()->create_count());
1483 
1484   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1485 
1486   EXPECT_EQ(3, cache.network_layer()->transaction_count());
1487   EXPECT_EQ(1, cache.disk_cache()->open_count());
1488   EXPECT_EQ(3, cache.disk_cache()->create_count());
1489 }
1490 
TEST_F(HttpCacheTest,SimpleGET_LoadOnlyFromCache_Hit)1491 TEST_F(HttpCacheTest, SimpleGET_LoadOnlyFromCache_Hit) {
1492   MockHttpCache cache;
1493 
1494   RecordingNetLogObserver net_log_observer;
1495   NetLogWithSource net_log_with_source =
1496       NetLogWithSource::Make(NetLogSourceType::NONE);
1497   LoadTimingInfo load_timing_info;
1498 
1499   // Write to the cache.
1500   RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
1501                                  net_log_with_source, &load_timing_info);
1502 
1503   // Check that the NetLog was filled as expected.
1504   auto entries = GetFilteredNetLogEntries(net_log_observer);
1505 
1506   EXPECT_EQ(6u, entries.size());
1507   EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
1508                                     NetLogEventType::HTTP_CACHE_GET_BACKEND));
1509   EXPECT_TRUE(
1510       LogContainsEndEvent(entries, 1, NetLogEventType::HTTP_CACHE_GET_BACKEND));
1511   EXPECT_TRUE(LogContainsBeginEvent(
1512       entries, 2, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1513   EXPECT_TRUE(LogContainsEndEvent(
1514       entries, 3, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1515   EXPECT_TRUE(LogContainsBeginEvent(entries, 4,
1516                                     NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1517   EXPECT_TRUE(LogContainsEndEvent(entries, 5,
1518                                   NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1519 
1520   TestLoadTimingNetworkRequest(load_timing_info);
1521 
1522   // Force this transaction to read from the cache.
1523   MockTransaction transaction(kSimpleGET_Transaction);
1524   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
1525 
1526   net_log_observer.Clear();
1527 
1528   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
1529                                  net_log_with_source, &load_timing_info);
1530 
1531   // Check that the NetLog was filled as expected.
1532   entries = GetFilteredNetLogEntries(net_log_observer);
1533 
1534   EXPECT_EQ(8u, entries.size());
1535   EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
1536                                     NetLogEventType::HTTP_CACHE_GET_BACKEND));
1537   EXPECT_TRUE(
1538       LogContainsEndEvent(entries, 1, NetLogEventType::HTTP_CACHE_GET_BACKEND));
1539   EXPECT_TRUE(LogContainsBeginEvent(
1540       entries, 2, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1541   EXPECT_TRUE(LogContainsEndEvent(
1542       entries, 3, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1543   EXPECT_TRUE(LogContainsBeginEvent(entries, 4,
1544                                     NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1545   EXPECT_TRUE(LogContainsEndEvent(entries, 5,
1546                                   NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1547   EXPECT_TRUE(
1548       LogContainsBeginEvent(entries, 6, NetLogEventType::HTTP_CACHE_READ_INFO));
1549   EXPECT_TRUE(
1550       LogContainsEndEvent(entries, 7, NetLogEventType::HTTP_CACHE_READ_INFO));
1551 
1552   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1553   EXPECT_EQ(1, cache.disk_cache()->open_count());
1554   EXPECT_EQ(1, cache.disk_cache()->create_count());
1555   TestLoadTimingCachedResponse(load_timing_info);
1556 }
1557 
TEST_F(HttpCacheTest,SimpleGET_LoadOnlyFromCache_Miss)1558 TEST_F(HttpCacheTest, SimpleGET_LoadOnlyFromCache_Miss) {
1559   MockHttpCache cache;
1560 
1561   // force this transaction to read from the cache
1562   MockTransaction transaction(kSimpleGET_Transaction);
1563   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
1564 
1565   MockHttpRequest request(transaction);
1566   TestCompletionCallback callback;
1567 
1568   std::unique_ptr<HttpTransaction> trans;
1569   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
1570 
1571   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
1572   if (rv == ERR_IO_PENDING)
1573     rv = callback.WaitForResult();
1574   ASSERT_THAT(rv, IsError(ERR_CACHE_MISS));
1575 
1576   trans.reset();
1577 
1578   EXPECT_EQ(0, cache.network_layer()->transaction_count());
1579   EXPECT_EQ(0, cache.disk_cache()->open_count());
1580   EXPECT_EQ(0, cache.disk_cache()->create_count());
1581 }
1582 
TEST_F(HttpCacheTest,SimpleGET_LoadPreferringCache_Hit)1583 TEST_F(HttpCacheTest, SimpleGET_LoadPreferringCache_Hit) {
1584   MockHttpCache cache;
1585 
1586   // write to the cache
1587   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1588 
1589   // force this transaction to read from the cache if valid
1590   MockTransaction transaction(kSimpleGET_Transaction);
1591   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
1592 
1593   RunTransactionTest(cache.http_cache(), transaction);
1594 
1595   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1596   EXPECT_EQ(1, cache.disk_cache()->open_count());
1597   EXPECT_EQ(1, cache.disk_cache()->create_count());
1598 }
1599 
TEST_F(HttpCacheTest,SimpleGET_LoadPreferringCache_Miss)1600 TEST_F(HttpCacheTest, SimpleGET_LoadPreferringCache_Miss) {
1601   MockHttpCache cache;
1602 
1603   // force this transaction to read from the cache if valid
1604   MockTransaction transaction(kSimpleGET_Transaction);
1605   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
1606 
1607   RunTransactionTest(cache.http_cache(), transaction);
1608 
1609   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1610   EXPECT_EQ(0, cache.disk_cache()->open_count());
1611   EXPECT_EQ(1, cache.disk_cache()->create_count());
1612 }
1613 
1614 // Tests LOAD_SKIP_CACHE_VALIDATION in the presence of vary headers.
TEST_F(HttpCacheTest,SimpleGET_LoadPreferringCache_VaryMatch)1615 TEST_F(HttpCacheTest, SimpleGET_LoadPreferringCache_VaryMatch) {
1616   MockHttpCache cache;
1617 
1618   // Write to the cache.
1619   MockTransaction transaction(kSimpleGET_Transaction);
1620   transaction.request_headers = "Foo: bar\r\n";
1621   transaction.response_headers = "Cache-Control: max-age=10000\n"
1622                                  "Vary: Foo\n";
1623   AddMockTransaction(&transaction);
1624   RunTransactionTest(cache.http_cache(), transaction);
1625 
1626   // Read from the cache.
1627   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
1628   RunTransactionTest(cache.http_cache(), transaction);
1629 
1630   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1631   EXPECT_EQ(1, cache.disk_cache()->open_count());
1632   EXPECT_EQ(1, cache.disk_cache()->create_count());
1633   RemoveMockTransaction(&transaction);
1634 }
1635 
1636 // Tests LOAD_SKIP_CACHE_VALIDATION in the presence of vary headers.
TEST_F(HttpCacheTest,SimpleGET_LoadPreferringCache_VaryMismatch)1637 TEST_F(HttpCacheTest, SimpleGET_LoadPreferringCache_VaryMismatch) {
1638   MockHttpCache cache;
1639 
1640   // Write to the cache.
1641   MockTransaction transaction(kSimpleGET_Transaction);
1642   transaction.request_headers = "Foo: bar\r\n";
1643   transaction.response_headers = "Cache-Control: max-age=10000\n"
1644                                  "Vary: Foo\n";
1645   AddMockTransaction(&transaction);
1646   RunTransactionTest(cache.http_cache(), transaction);
1647 
1648   // Attempt to read from the cache... this is a vary mismatch that must reach
1649   // the network again.
1650   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
1651   transaction.request_headers = "Foo: none\r\n";
1652   LoadTimingInfo load_timing_info;
1653   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
1654                                  NetLogWithSource::Make(NetLogSourceType::NONE),
1655                                  &load_timing_info);
1656 
1657   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1658   EXPECT_EQ(1, cache.disk_cache()->open_count());
1659   EXPECT_EQ(1, cache.disk_cache()->create_count());
1660   TestLoadTimingNetworkRequest(load_timing_info);
1661   RemoveMockTransaction(&transaction);
1662 }
1663 
1664 // Tests that we honor Vary: * with LOAD_SKIP_CACHE_VALIDATION (crbug/778681)
TEST_F(HttpCacheTest,SimpleGET_LoadSkipCacheValidation_VaryStar)1665 TEST_F(HttpCacheTest, SimpleGET_LoadSkipCacheValidation_VaryStar) {
1666   MockHttpCache cache;
1667 
1668   // Write to the cache.
1669   MockTransaction transaction(kSimpleGET_Transaction);
1670   transaction.response_headers =
1671       "Cache-Control: max-age=10000\n"
1672       "Vary: *\n";
1673   AddMockTransaction(&transaction);
1674   RunTransactionTest(cache.http_cache(), transaction);
1675 
1676   // Attempt to read from the cache... we will still load it from network,
1677   // since Vary: * doesn't match.
1678   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
1679   LoadTimingInfo load_timing_info;
1680   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
1681                                  NetLogWithSource::Make(NetLogSourceType::NONE),
1682                                  &load_timing_info);
1683 
1684   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1685   EXPECT_EQ(1, cache.disk_cache()->open_count());
1686   EXPECT_EQ(1, cache.disk_cache()->create_count());
1687   RemoveMockTransaction(&transaction);
1688 }
1689 
1690 // Tests that was_cached was set properly on a failure, even if the cached
1691 // response wasn't returned.
TEST_F(HttpCacheTest,SimpleGET_CacheSignal_Failure)1692 TEST_F(HttpCacheTest, SimpleGET_CacheSignal_Failure) {
1693   for (bool use_memory_entry_data : {false, true}) {
1694     MockHttpCache cache;
1695     cache.disk_cache()->set_support_in_memory_entry_data(use_memory_entry_data);
1696 
1697     // Prime cache.
1698     MockTransaction transaction(kSimpleGET_Transaction);
1699     transaction.response_headers = "Cache-Control: no-cache\n";
1700 
1701     AddMockTransaction(&transaction);
1702     RunTransactionTest(cache.http_cache(), transaction);
1703     EXPECT_EQ(1, cache.network_layer()->transaction_count());
1704     EXPECT_EQ(1, cache.disk_cache()->create_count());
1705     EXPECT_EQ(0, cache.disk_cache()->open_count());
1706     RemoveMockTransaction(&transaction);
1707 
1708     // Network failure with error; should fail but have was_cached set.
1709     transaction.start_return_code = ERR_FAILED;
1710     AddMockTransaction(&transaction);
1711 
1712     MockHttpRequest request(transaction);
1713     TestCompletionCallback callback;
1714     std::unique_ptr<HttpTransaction> trans;
1715     int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
1716     EXPECT_THAT(rv, IsOk());
1717     ASSERT_TRUE(trans.get());
1718     rv = trans->Start(&request, callback.callback(), NetLogWithSource());
1719     EXPECT_THAT(callback.GetResult(rv), IsError(ERR_FAILED));
1720 
1721     const HttpResponseInfo* response_info = trans->GetResponseInfo();
1722     ASSERT_TRUE(response_info);
1723     // If use_memory_entry_data is true, we will not bother opening the entry,
1724     // and just kick it out, so was_cached will end up false.
1725     EXPECT_EQ(2, cache.network_layer()->transaction_count());
1726     if (use_memory_entry_data) {
1727       EXPECT_EQ(false, response_info->was_cached);
1728       EXPECT_EQ(2, cache.disk_cache()->create_count());
1729       EXPECT_EQ(0, cache.disk_cache()->open_count());
1730     } else {
1731       EXPECT_EQ(true, response_info->was_cached);
1732       EXPECT_EQ(1, cache.disk_cache()->create_count());
1733       EXPECT_EQ(1, cache.disk_cache()->open_count());
1734     }
1735 
1736     RemoveMockTransaction(&transaction);
1737   }
1738 }
1739 
1740 // Tests that if the transaction is destroyed right after setting the
1741 // cache_entry_status_ as CANT_CONDITIONALIZE, then RecordHistograms should not
1742 // hit a dcheck.
TEST_F(HttpCacheTest,RecordHistogramsCantConditionalize)1743 TEST_F(HttpCacheTest, RecordHistogramsCantConditionalize) {
1744   MockHttpCache cache;
1745   cache.disk_cache()->set_support_in_memory_entry_data(true);
1746 
1747   {
1748     // Prime cache.
1749     ScopedMockTransaction transaction(kSimpleGET_Transaction);
1750     transaction.response_headers = "Cache-Control: no-cache\n";
1751     RunTransactionTest(cache.http_cache(), transaction);
1752     EXPECT_EQ(1, cache.network_layer()->transaction_count());
1753     EXPECT_EQ(1, cache.disk_cache()->create_count());
1754     EXPECT_EQ(0, cache.disk_cache()->open_count());
1755   }
1756 
1757   {
1758     ScopedMockTransaction transaction(kSimpleGET_Transaction);
1759     MockHttpRequest request(transaction);
1760     TestCompletionCallback callback;
1761     std::unique_ptr<HttpTransaction> trans;
1762     int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
1763     EXPECT_THAT(rv, IsOk());
1764     ASSERT_TRUE(trans.get());
1765     rv = trans->Start(&request, callback.callback(), NetLogWithSource());
1766     // Now destroy the transaction so that RecordHistograms gets invoked.
1767     trans.reset();
1768   }
1769 }
1770 
1771 // Confirm if we have an empty cache, a read is marked as network verified.
TEST_F(HttpCacheTest,SimpleGET_NetworkAccessed_Network)1772 TEST_F(HttpCacheTest, SimpleGET_NetworkAccessed_Network) {
1773   MockHttpCache cache;
1774 
1775   // write to the cache
1776   HttpResponseInfo response_info;
1777   RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
1778                                      &response_info);
1779 
1780   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1781   EXPECT_EQ(0, cache.disk_cache()->open_count());
1782   EXPECT_EQ(1, cache.disk_cache()->create_count());
1783   EXPECT_TRUE(response_info.network_accessed);
1784   EXPECT_EQ(CacheEntryStatus::ENTRY_NOT_IN_CACHE,
1785             response_info.cache_entry_status);
1786 }
1787 
1788 // Confirm if we have a fresh entry in cache, it isn't marked as
1789 // network verified.
TEST_F(HttpCacheTest,SimpleGET_NetworkAccessed_Cache)1790 TEST_F(HttpCacheTest, SimpleGET_NetworkAccessed_Cache) {
1791   MockHttpCache cache;
1792 
1793   // Prime cache.
1794   MockTransaction transaction(kSimpleGET_Transaction);
1795 
1796   RunTransactionTest(cache.http_cache(), transaction);
1797   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1798   EXPECT_EQ(1, cache.disk_cache()->create_count());
1799 
1800   // Re-run transaction; make sure we don't mark the network as accessed.
1801   HttpResponseInfo response_info;
1802   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1803                                      &response_info);
1804 
1805   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1806   EXPECT_FALSE(response_info.network_accessed);
1807   EXPECT_EQ(CacheEntryStatus::ENTRY_USED, response_info.cache_entry_status);
1808 }
1809 
TEST_F(HttpCacheTest,SimpleGET_LoadBypassCache)1810 TEST_F(HttpCacheTest, SimpleGET_LoadBypassCache) {
1811   MockHttpCache cache;
1812 
1813   // Write to the cache.
1814   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1815 
1816   // Force this transaction to write to the cache again.
1817   MockTransaction transaction(kSimpleGET_Transaction);
1818   transaction.load_flags |= LOAD_BYPASS_CACHE;
1819 
1820   RecordingNetLogObserver net_log_observer;
1821   LoadTimingInfo load_timing_info;
1822 
1823   // Write to the cache.
1824   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
1825                                  NetLogWithSource::Make(NetLogSourceType::NONE),
1826                                  &load_timing_info);
1827 
1828   // Check that the NetLog was filled as expected.
1829   auto entries = GetFilteredNetLogEntries(net_log_observer);
1830 
1831   EXPECT_EQ(8u, entries.size());
1832   EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
1833                                     NetLogEventType::HTTP_CACHE_GET_BACKEND));
1834   EXPECT_TRUE(
1835       LogContainsEndEvent(entries, 1, NetLogEventType::HTTP_CACHE_GET_BACKEND));
1836   EXPECT_TRUE(LogContainsBeginEvent(entries, 2,
1837                                     NetLogEventType::HTTP_CACHE_DOOM_ENTRY));
1838   EXPECT_TRUE(
1839       LogContainsEndEvent(entries, 3, NetLogEventType::HTTP_CACHE_DOOM_ENTRY));
1840   EXPECT_TRUE(LogContainsBeginEvent(entries, 4,
1841                                     NetLogEventType::HTTP_CACHE_CREATE_ENTRY));
1842   EXPECT_TRUE(LogContainsEndEvent(entries, 5,
1843                                   NetLogEventType::HTTP_CACHE_CREATE_ENTRY));
1844   EXPECT_TRUE(LogContainsBeginEvent(entries, 6,
1845                                     NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1846   EXPECT_TRUE(LogContainsEndEvent(entries, 7,
1847                                   NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1848 
1849   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1850   EXPECT_EQ(0, cache.disk_cache()->open_count());
1851   EXPECT_EQ(2, cache.disk_cache()->create_count());
1852   TestLoadTimingNetworkRequest(load_timing_info);
1853 }
1854 
TEST_F(HttpCacheTest,SimpleGET_LoadBypassCache_Implicit)1855 TEST_F(HttpCacheTest, SimpleGET_LoadBypassCache_Implicit) {
1856   MockHttpCache cache;
1857 
1858   // write to the cache
1859   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1860 
1861   // force this transaction to write to the cache again
1862   MockTransaction transaction(kSimpleGET_Transaction);
1863   transaction.request_headers = "pragma: no-cache\r\n";
1864 
1865   RunTransactionTest(cache.http_cache(), transaction);
1866 
1867   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1868   EXPECT_EQ(0, cache.disk_cache()->open_count());
1869   EXPECT_EQ(2, cache.disk_cache()->create_count());
1870 }
1871 
TEST_F(HttpCacheTest,SimpleGET_LoadBypassCache_Implicit2)1872 TEST_F(HttpCacheTest, SimpleGET_LoadBypassCache_Implicit2) {
1873   MockHttpCache cache;
1874 
1875   // write to the cache
1876   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1877 
1878   // force this transaction to write to the cache again
1879   MockTransaction transaction(kSimpleGET_Transaction);
1880   transaction.request_headers = "cache-control: no-cache\r\n";
1881 
1882   RunTransactionTest(cache.http_cache(), transaction);
1883 
1884   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1885   EXPECT_EQ(0, cache.disk_cache()->open_count());
1886   EXPECT_EQ(2, cache.disk_cache()->create_count());
1887 }
1888 
TEST_F(HttpCacheTest,SimpleGET_LoadValidateCache)1889 TEST_F(HttpCacheTest, SimpleGET_LoadValidateCache) {
1890   MockHttpCache cache;
1891 
1892   // Write to the cache.
1893   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1894 
1895   // Read from the cache.
1896   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1897 
1898   // Force this transaction to validate the cache.
1899   MockTransaction transaction(kSimpleGET_Transaction);
1900   transaction.load_flags |= LOAD_VALIDATE_CACHE;
1901 
1902   HttpResponseInfo response_info;
1903   LoadTimingInfo load_timing_info;
1904   RunTransactionTestWithResponseInfoAndGetTiming(
1905       cache.http_cache(), transaction, &response_info,
1906       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info);
1907 
1908   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1909   EXPECT_EQ(1, cache.disk_cache()->open_count());
1910   EXPECT_EQ(1, cache.disk_cache()->create_count());
1911   EXPECT_TRUE(response_info.network_accessed);
1912   TestLoadTimingNetworkRequest(load_timing_info);
1913 }
1914 
TEST_F(HttpCacheTest,SimpleGET_LoadValidateCache_Implicit)1915 TEST_F(HttpCacheTest, SimpleGET_LoadValidateCache_Implicit) {
1916   MockHttpCache cache;
1917 
1918   // write to the cache
1919   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1920 
1921   // read from the cache
1922   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1923 
1924   // force this transaction to validate the cache
1925   MockTransaction transaction(kSimpleGET_Transaction);
1926   transaction.request_headers = "cache-control: max-age=0\r\n";
1927 
1928   RunTransactionTest(cache.http_cache(), transaction);
1929 
1930   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1931   EXPECT_EQ(1, cache.disk_cache()->open_count());
1932   EXPECT_EQ(1, cache.disk_cache()->create_count());
1933 }
1934 
1935 // Tests that |unused_since_prefetch| is updated accordingly (e.g. it is set to
1936 // true after a prefetch and set back to false when the prefetch is used).
TEST_F(HttpCacheTest,SimpleGET_UnusedSincePrefetch)1937 TEST_F(HttpCacheTest, SimpleGET_UnusedSincePrefetch) {
1938   MockHttpCache cache;
1939   HttpResponseInfo response_info;
1940 
1941   // A normal load does not have |unused_since_prefetch| set.
1942   RunTransactionTestWithResponseInfoAndGetTiming(
1943       cache.http_cache(), kSimpleGET_Transaction, &response_info,
1944       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1945   EXPECT_FALSE(response_info.unused_since_prefetch);
1946   EXPECT_FALSE(response_info.was_cached);
1947 
1948   // The prefetch itself does not have |unused_since_prefetch| set.
1949   MockTransaction prefetch_transaction(kSimpleGET_Transaction);
1950   prefetch_transaction.load_flags |= LOAD_PREFETCH;
1951   RunTransactionTestWithResponseInfoAndGetTiming(
1952       cache.http_cache(), prefetch_transaction, &response_info,
1953       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1954   EXPECT_FALSE(response_info.unused_since_prefetch);
1955   EXPECT_TRUE(response_info.was_cached);
1956 
1957   // A duplicated prefetch has |unused_since_prefetch| set.
1958   RunTransactionTestWithResponseInfoAndGetTiming(
1959       cache.http_cache(), prefetch_transaction, &response_info,
1960       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1961   EXPECT_TRUE(response_info.unused_since_prefetch);
1962   EXPECT_TRUE(response_info.was_cached);
1963 
1964   // |unused_since_prefetch| is still true after two prefetches in a row.
1965   RunTransactionTestWithResponseInfoAndGetTiming(
1966       cache.http_cache(), kSimpleGET_Transaction, &response_info,
1967       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1968   EXPECT_TRUE(response_info.unused_since_prefetch);
1969   EXPECT_TRUE(response_info.was_cached);
1970 
1971   // The resource has now been used, back to normal behavior.
1972   RunTransactionTestWithResponseInfoAndGetTiming(
1973       cache.http_cache(), kSimpleGET_Transaction, &response_info,
1974       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1975   EXPECT_FALSE(response_info.unused_since_prefetch);
1976   EXPECT_TRUE(response_info.was_cached);
1977 }
1978 
1979 // Tests that requests made with the LOAD_RESTRICTED_PREFETCH load flag result
1980 // in HttpResponseInfo entries with the |restricted_prefetch| flag set. Also
1981 // tests that responses with |restricted_prefetch| flag set can only be used by
1982 // requests that have the LOAD_CAN_USE_RESTRICTED_PREFETCH load flag.
TEST_F(HttpCacheTest,SimpleGET_RestrictedPrefetchIsRestrictedUntilReuse)1983 TEST_F(HttpCacheTest, SimpleGET_RestrictedPrefetchIsRestrictedUntilReuse) {
1984   MockHttpCache cache;
1985   HttpResponseInfo response_info;
1986 
1987   // A normal load does not have |restricted_prefetch| set.
1988   RunTransactionTestWithResponseInfoAndGetTiming(
1989       cache.http_cache(), kTypicalGET_Transaction, &response_info,
1990       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1991   EXPECT_FALSE(response_info.restricted_prefetch);
1992   EXPECT_FALSE(response_info.was_cached);
1993   EXPECT_TRUE(response_info.network_accessed);
1994 
1995   // A restricted prefetch is marked as |restricted_prefetch|.
1996   MockTransaction prefetch_transaction(kSimpleGET_Transaction);
1997   prefetch_transaction.load_flags |= LOAD_PREFETCH;
1998   prefetch_transaction.load_flags |= LOAD_RESTRICTED_PREFETCH;
1999   RunTransactionTestWithResponseInfoAndGetTiming(
2000       cache.http_cache(), prefetch_transaction, &response_info,
2001       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2002   EXPECT_TRUE(response_info.restricted_prefetch);
2003   EXPECT_FALSE(response_info.was_cached);
2004   EXPECT_TRUE(response_info.network_accessed);
2005 
2006   // Requests that are marked as able to reuse restricted prefetches can do so
2007   // correctly. Once it is reused, it is no longer considered as or marked
2008   // restricted.
2009   MockTransaction can_use_restricted_prefetch_transaction(
2010       kSimpleGET_Transaction);
2011   can_use_restricted_prefetch_transaction.load_flags |=
2012       LOAD_CAN_USE_RESTRICTED_PREFETCH;
2013   RunTransactionTestWithResponseInfoAndGetTiming(
2014       cache.http_cache(), can_use_restricted_prefetch_transaction,
2015       &response_info, NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2016   EXPECT_TRUE(response_info.restricted_prefetch);
2017   EXPECT_TRUE(response_info.was_cached);
2018   EXPECT_FALSE(response_info.network_accessed);
2019 
2020   // Later reuse is still no longer marked restricted.
2021   RunTransactionTestWithResponseInfoAndGetTiming(
2022       cache.http_cache(), kSimpleGET_Transaction, &response_info,
2023       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2024   EXPECT_FALSE(response_info.restricted_prefetch);
2025   EXPECT_TRUE(response_info.was_cached);
2026   EXPECT_FALSE(response_info.network_accessed);
2027 }
2028 
TEST_F(HttpCacheTest,SimpleGET_RestrictedPrefetchReuseIsLimited)2029 TEST_F(HttpCacheTest, SimpleGET_RestrictedPrefetchReuseIsLimited) {
2030   MockHttpCache cache;
2031   HttpResponseInfo response_info;
2032 
2033   // A restricted prefetch is marked as |restricted_prefetch|.
2034   MockTransaction prefetch_transaction(kSimpleGET_Transaction);
2035   prefetch_transaction.load_flags |= LOAD_PREFETCH;
2036   prefetch_transaction.load_flags |= LOAD_RESTRICTED_PREFETCH;
2037   RunTransactionTestWithResponseInfoAndGetTiming(
2038       cache.http_cache(), prefetch_transaction, &response_info,
2039       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2040   EXPECT_TRUE(response_info.restricted_prefetch);
2041   EXPECT_FALSE(response_info.was_cached);
2042   EXPECT_TRUE(response_info.network_accessed);
2043 
2044   // Requests that cannot reuse restricted prefetches fail to do so. The network
2045   // is accessed and the resulting response is not marked as
2046   // |restricted_prefetch|.
2047   RunTransactionTestWithResponseInfoAndGetTiming(
2048       cache.http_cache(), kSimpleGET_Transaction, &response_info,
2049       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2050   EXPECT_FALSE(response_info.restricted_prefetch);
2051   EXPECT_FALSE(response_info.was_cached);
2052   EXPECT_TRUE(response_info.network_accessed);
2053 
2054   // Future requests that are not marked as able to reuse restricted prefetches
2055   // can use the entry in the cache now, since it has been evicted in favor of
2056   // an unrestricted one.
2057   RunTransactionTestWithResponseInfoAndGetTiming(
2058       cache.http_cache(), kSimpleGET_Transaction, &response_info,
2059       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2060   EXPECT_FALSE(response_info.restricted_prefetch);
2061   EXPECT_TRUE(response_info.was_cached);
2062   EXPECT_FALSE(response_info.network_accessed);
2063 }
2064 
TEST_F(HttpCacheTest,SimpleGET_UnusedSincePrefetchWriteError)2065 TEST_F(HttpCacheTest, SimpleGET_UnusedSincePrefetchWriteError) {
2066   MockHttpCache cache;
2067   HttpResponseInfo response_info;
2068 
2069   // Do a prefetch.
2070   MockTransaction prefetch_transaction(kSimpleGET_Transaction);
2071   prefetch_transaction.load_flags |= LOAD_PREFETCH;
2072   RunTransactionTestWithResponseInfoAndGetTiming(
2073       cache.http_cache(), prefetch_transaction, &response_info,
2074       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2075   EXPECT_TRUE(response_info.unused_since_prefetch);
2076   EXPECT_FALSE(response_info.was_cached);
2077 
2078   // Try to use it while injecting a failure on write.
2079   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_WRITE);
2080   RunTransactionTestWithResponseInfoAndGetTiming(
2081       cache.http_cache(), kSimpleGET_Transaction, &response_info,
2082       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2083 }
2084 
2085 // Make sure that if a prefetch entry is truncated, then an attempt to re-use it
2086 // gets aborted in connected handler that truncated bit is not lost.
TEST_F(HttpCacheTest,PrefetchTruncateCancelInConnectedCallback)2087 TEST_F(HttpCacheTest, PrefetchTruncateCancelInConnectedCallback) {
2088   MockHttpCache cache;
2089 
2090   ScopedMockTransaction transaction(kSimpleGET_Transaction);
2091   transaction.response_headers =
2092       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2093       "Content-Length: 20\n"
2094       "Etag: \"foopy\"\n";
2095   transaction.data = "01234567890123456789";
2096   transaction.load_flags |= LOAD_PREFETCH | LOAD_CAN_USE_RESTRICTED_PREFETCH;
2097 
2098   // Do a truncated read of a prefetch request.
2099   {
2100     MockHttpRequest request(transaction);
2101     Context c;
2102 
2103     int rv = cache.CreateTransaction(&c.trans);
2104     ASSERT_THAT(rv, IsOk());
2105 
2106     rv = c.callback.GetResult(
2107         c.trans->Start(&request, c.callback.callback(), NetLogWithSource()));
2108     ASSERT_THAT(rv, IsOk());
2109 
2110     // Read less than the whole thing.
2111     scoped_refptr<IOBufferWithSize> buf =
2112         base::MakeRefCounted<IOBufferWithSize>(10);
2113     rv = c.callback.GetResult(
2114         c.trans->Read(buf.get(), buf->size(), c.callback.callback()));
2115     EXPECT_EQ(buf->size(), rv);
2116 
2117     // Destroy the transaction.
2118     c.trans.reset();
2119     base::RunLoop().RunUntilIdle();
2120 
2121     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/true,
2122                         /*data_size=*/10);
2123   }
2124 
2125   // Do a fetch that can use prefetch that aborts in connected handler.
2126   transaction.load_flags &= ~LOAD_PREFETCH;
2127   {
2128     MockHttpRequest request(transaction);
2129     Context c;
2130 
2131     int rv = cache.CreateTransaction(&c.trans);
2132     ASSERT_THAT(rv, IsOk());
2133     c.trans->SetConnectedCallback(base::BindRepeating(
2134         [](const TransportInfo& info, CompletionOnceCallback callback) -> int {
2135           return net::ERR_ABORTED;
2136         }));
2137     rv = c.callback.GetResult(
2138         c.trans->Start(&request, c.callback.callback(), NetLogWithSource()));
2139     EXPECT_EQ(net::ERR_ABORTED, rv);
2140 
2141     // Destroy the transaction.
2142     c.trans.reset();
2143     base::RunLoop().RunUntilIdle();
2144 
2145     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/true,
2146                         /*data_size=*/10);
2147   }
2148 
2149   // Now try again without abort.
2150   {
2151     MockHttpRequest request(transaction);
2152     RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
2153                                   /*response_info=*/nullptr);
2154     base::RunLoop().RunUntilIdle();
2155 
2156     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/false,
2157                         /*data_size=*/20);
2158   }
2159 }
2160 
2161 // Make sure that if a stale-while-revalidate entry is truncated, then an
2162 // attempt to re-use it gets aborted in connected handler that truncated bit is
2163 // not lost.
TEST_F(HttpCacheTest,StaleWhiteRevalidateTruncateCancelInConnectedCallback)2164 TEST_F(HttpCacheTest, StaleWhiteRevalidateTruncateCancelInConnectedCallback) {
2165   MockHttpCache cache;
2166 
2167   ScopedMockTransaction transaction(kSimpleGET_Transaction);
2168   transaction.response_headers =
2169       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2170       "Content-Length: 20\n"
2171       "Cache-Control: max-age=0, stale-while-revalidate=60\n"
2172       "Etag: \"foopy\"\n";
2173   transaction.data = "01234567890123456789";
2174   transaction.load_flags |= LOAD_SUPPORT_ASYNC_REVALIDATION;
2175 
2176   // Do a truncated read of a stale-while-revalidate resource.
2177   {
2178     MockHttpRequest request(transaction);
2179     Context c;
2180 
2181     int rv = cache.CreateTransaction(&c.trans);
2182     ASSERT_THAT(rv, IsOk());
2183 
2184     rv = c.callback.GetResult(
2185         c.trans->Start(&request, c.callback.callback(), NetLogWithSource()));
2186     ASSERT_THAT(rv, IsOk());
2187 
2188     // Read less than the whole thing.
2189     scoped_refptr<IOBufferWithSize> buf =
2190         base::MakeRefCounted<IOBufferWithSize>(10);
2191     rv = c.callback.GetResult(
2192         c.trans->Read(buf.get(), buf->size(), c.callback.callback()));
2193     EXPECT_EQ(buf->size(), rv);
2194 
2195     // Destroy the transaction.
2196     c.trans.reset();
2197     base::RunLoop().RunUntilIdle();
2198 
2199     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/true,
2200                         /*data_size=*/10);
2201   }
2202 
2203   // Do a fetch that uses that resource that aborts in connected handler.
2204   {
2205     MockHttpRequest request(transaction);
2206     Context c;
2207 
2208     int rv = cache.CreateTransaction(&c.trans);
2209     ASSERT_THAT(rv, IsOk());
2210     c.trans->SetConnectedCallback(base::BindRepeating(
2211         [](const TransportInfo& info, CompletionOnceCallback callback) -> int {
2212           return net::ERR_ABORTED;
2213         }));
2214     rv = c.callback.GetResult(
2215         c.trans->Start(&request, c.callback.callback(), NetLogWithSource()));
2216     EXPECT_EQ(net::ERR_ABORTED, rv);
2217 
2218     // Destroy the transaction.
2219     c.trans.reset();
2220     base::RunLoop().RunUntilIdle();
2221 
2222     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/true,
2223                         /*data_size=*/10);
2224   }
2225 
2226   // Now try again without abort.
2227   {
2228     MockHttpRequest request(transaction);
2229     RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
2230                                   /*response_info=*/nullptr);
2231     base::RunLoop().RunUntilIdle();
2232 
2233     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/false,
2234                         /*data_size=*/20);
2235   }
2236 }
2237 
PreserveRequestHeaders_Handler(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)2238 static void PreserveRequestHeaders_Handler(const HttpRequestInfo* request,
2239                                            std::string* response_status,
2240                                            std::string* response_headers,
2241                                            std::string* response_data) {
2242   EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
2243 }
2244 
2245 // Tests that we don't remove extra headers for simple requests.
TEST_F(HttpCacheTest,SimpleGET_PreserveRequestHeaders)2246 TEST_F(HttpCacheTest, SimpleGET_PreserveRequestHeaders) {
2247   for (bool use_memory_entry_data : {false, true}) {
2248     MockHttpCache cache;
2249     cache.disk_cache()->set_support_in_memory_entry_data(use_memory_entry_data);
2250 
2251     MockTransaction transaction(kSimpleGET_Transaction);
2252     transaction.handler = PreserveRequestHeaders_Handler;
2253     transaction.request_headers = EXTRA_HEADER;
2254     transaction.response_headers = "Cache-Control: max-age=0\n";
2255     AddMockTransaction(&transaction);
2256 
2257     // Write, then revalidate the entry.
2258     RunTransactionTest(cache.http_cache(), transaction);
2259     RunTransactionTest(cache.http_cache(), transaction);
2260 
2261     EXPECT_EQ(2, cache.network_layer()->transaction_count());
2262 
2263     // If the backend supports memory entry data, we can figure out that the
2264     // entry has caching-hostile headers w/o opening it.
2265     if (use_memory_entry_data) {
2266       EXPECT_EQ(0, cache.disk_cache()->open_count());
2267       EXPECT_EQ(2, cache.disk_cache()->create_count());
2268     } else {
2269       EXPECT_EQ(1, cache.disk_cache()->open_count());
2270       EXPECT_EQ(1, cache.disk_cache()->create_count());
2271     }
2272     RemoveMockTransaction(&transaction);
2273   }
2274 }
2275 
2276 // Tests that we don't remove extra headers for conditionalized requests.
TEST_F(HttpCacheTest,ConditionalizedGET_PreserveRequestHeaders)2277 TEST_F(HttpCacheTest, ConditionalizedGET_PreserveRequestHeaders) {
2278   for (bool use_memory_entry_data : {false, true}) {
2279     MockHttpCache cache;
2280     // Unlike in SimpleGET_PreserveRequestHeaders, this entry can be
2281     // conditionalized, so memory hints don't affect behavior.
2282     cache.disk_cache()->set_support_in_memory_entry_data(use_memory_entry_data);
2283 
2284     // Write to the cache.
2285     RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
2286 
2287     MockTransaction transaction(kETagGET_Transaction);
2288     transaction.handler = PreserveRequestHeaders_Handler;
2289     transaction.request_headers = "If-None-Match: \"foopy\"\r\n" EXTRA_HEADER;
2290     AddMockTransaction(&transaction);
2291 
2292     RunTransactionTest(cache.http_cache(), transaction);
2293 
2294     EXPECT_EQ(2, cache.network_layer()->transaction_count());
2295     EXPECT_EQ(1, cache.disk_cache()->open_count());
2296     EXPECT_EQ(1, cache.disk_cache()->create_count());
2297     RemoveMockTransaction(&transaction);
2298   }
2299 }
2300 
TEST_F(HttpCacheTest,SimpleGET_ManyReaders)2301 TEST_F(HttpCacheTest, SimpleGET_ManyReaders) {
2302   MockHttpCache cache;
2303 
2304   MockHttpRequest request(kSimpleGET_Transaction);
2305 
2306   std::vector<std::unique_ptr<Context>> context_list;
2307   const int kNumTransactions = 5;
2308 
2309   for (int i = 0; i < kNumTransactions; ++i) {
2310     context_list.push_back(std::make_unique<Context>());
2311     auto& c = context_list[i];
2312 
2313     c->result = cache.CreateTransaction(&c->trans);
2314     ASSERT_THAT(c->result, IsOk());
2315     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
2316 
2317     c->result =
2318         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
2319   }
2320 
2321   // All requests are waiting for the active entry.
2322   for (auto& context : context_list) {
2323     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
2324   }
2325 
2326   // Allow all requests to move from the Create queue to the active entry.
2327   base::RunLoop().RunUntilIdle();
2328 
2329   // All requests are added to writers.
2330   std::string cache_key = request.CacheKey();
2331   EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
2332 
2333   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2334   EXPECT_EQ(0, cache.disk_cache()->open_count());
2335   EXPECT_EQ(1, cache.disk_cache()->create_count());
2336 
2337   // All requests are between Start and Read, i.e. idle.
2338   for (auto& context : context_list) {
2339     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
2340   }
2341 
2342   for (int i = 0; i < kNumTransactions; ++i) {
2343     auto& c = context_list[i];
2344     if (c->result == ERR_IO_PENDING)
2345       c->result = c->callback.WaitForResult();
2346 
2347     // After the 1st transaction has completed the response, all transactions
2348     // get added to readers.
2349     if (i > 0) {
2350       EXPECT_FALSE(cache.IsWriterPresent(cache_key));
2351       EXPECT_EQ(kNumTransactions - i, cache.GetCountReaders(cache_key));
2352     }
2353 
2354     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
2355   }
2356 
2357   // We should not have had to re-open the disk entry
2358   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2359   EXPECT_EQ(0, cache.disk_cache()->open_count());
2360   EXPECT_EQ(1, cache.disk_cache()->create_count());
2361 }
2362 
TEST_F(HttpCacheTest,RangeGET_FullAfterPartial)2363 TEST_F(HttpCacheTest, RangeGET_FullAfterPartial) {
2364   MockHttpCache cache;
2365 
2366   // Request a prefix.
2367   {
2368     ScopedMockTransaction transaction_pre(kRangeGET_TransactionOK);
2369     transaction_pre.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
2370     transaction_pre.data = "rg: 00-09 ";
2371     MockHttpRequest request_pre(transaction_pre);
2372 
2373     HttpResponseInfo response_pre;
2374     RunTransactionTestWithRequest(cache.http_cache(), transaction_pre,
2375                                   request_pre, &response_pre);
2376     ASSERT_TRUE(response_pre.headers != nullptr);
2377     EXPECT_EQ(206, response_pre.headers->response_code());
2378     EXPECT_EQ(1, cache.network_layer()->transaction_count());
2379     EXPECT_EQ(0, cache.disk_cache()->open_count());
2380     EXPECT_EQ(1, cache.disk_cache()->create_count());
2381   }
2382 
2383   {
2384     // Now request the full thing, but set validation to fail. This would
2385     // previously fail in the middle of data and truncate it; current behavior
2386     // restarts it, somewhat wastefully but gets the data back.
2387     RangeTransactionServer handler;
2388     handler.set_modified(true);
2389 
2390     ScopedMockTransaction transaction_all(kRangeGET_TransactionOK);
2391     transaction_all.request_headers = EXTRA_HEADER;
2392     transaction_all.data = "Not a range";
2393     MockHttpRequest request_all(transaction_all);
2394 
2395     HttpResponseInfo response_all;
2396     RunTransactionTestWithRequest(cache.http_cache(), transaction_all,
2397                                   request_all, &response_all);
2398     ASSERT_TRUE(response_all.headers != nullptr);
2399     EXPECT_EQ(200, response_all.headers->response_code());
2400     // 1 from previous test, failed validation, and re-try.
2401     EXPECT_EQ(3, cache.network_layer()->transaction_count());
2402     EXPECT_EQ(1, cache.disk_cache()->open_count());
2403     EXPECT_EQ(1, cache.disk_cache()->create_count());
2404   }
2405 }
2406 
2407 // Tests that when a range request transaction becomes a writer for the first
2408 // range and then fails conditionalization for the next range and decides to
2409 // doom the entry, then there should not be a dcheck assertion hit.
TEST_F(HttpCacheTest,RangeGET_OverlappingRangesCouldntConditionalize)2410 TEST_F(HttpCacheTest, RangeGET_OverlappingRangesCouldntConditionalize) {
2411   MockHttpCache cache;
2412 
2413   {
2414     ScopedMockTransaction transaction_pre(kRangeGET_TransactionOK);
2415     transaction_pre.request_headers = "Range: bytes = 10-19\r\n" EXTRA_HEADER;
2416     transaction_pre.data = "rg: 10-19 ";
2417     MockHttpRequest request_pre(transaction_pre);
2418 
2419     HttpResponseInfo response_pre;
2420     RunTransactionTestWithRequest(cache.http_cache(), transaction_pre,
2421                                   request_pre, &response_pre);
2422     ASSERT_TRUE(response_pre.headers != nullptr);
2423     EXPECT_EQ(206, response_pre.headers->response_code());
2424     EXPECT_EQ(1, cache.network_layer()->transaction_count());
2425     EXPECT_EQ(0, cache.disk_cache()->open_count());
2426     EXPECT_EQ(1, cache.disk_cache()->create_count());
2427   }
2428 
2429   {
2430     // First range skips validation because the response is fresh while the
2431     // second range requires validation since that range is not present in the
2432     // cache and during validation it fails conditionalization.
2433     cache.FailConditionalizations();
2434     ScopedMockTransaction transaction_pre(kRangeGET_TransactionOK);
2435     transaction_pre.request_headers = "Range: bytes = 10-29\r\n" EXTRA_HEADER;
2436 
2437     // TODO(crbug.com/992521): Fix this scenario to not return the cached bytes
2438     // repeatedly.
2439     transaction_pre.data = "rg: 10-19 rg: 10-19 rg: 20-29 ";
2440     MockHttpRequest request_pre(transaction_pre);
2441     HttpResponseInfo response_pre;
2442     RunTransactionTestWithRequest(cache.http_cache(), transaction_pre,
2443                                   request_pre, &response_pre);
2444     ASSERT_TRUE(response_pre.headers != nullptr);
2445     EXPECT_EQ(2, cache.network_layer()->transaction_count());
2446     EXPECT_EQ(1, cache.disk_cache()->open_count());
2447     EXPECT_EQ(2, cache.disk_cache()->create_count());
2448   }
2449 }
2450 
TEST_F(HttpCacheTest,RangeGET_FullAfterPartialReuse)2451 TEST_F(HttpCacheTest, RangeGET_FullAfterPartialReuse) {
2452   MockHttpCache cache;
2453 
2454   // Request a prefix.
2455   {
2456     ScopedMockTransaction transaction_pre(kRangeGET_TransactionOK);
2457     transaction_pre.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
2458     transaction_pre.data = "rg: 00-09 ";
2459     MockHttpRequest request_pre(transaction_pre);
2460 
2461     HttpResponseInfo response_pre;
2462     RunTransactionTestWithRequest(cache.http_cache(), transaction_pre,
2463                                   request_pre, &response_pre);
2464     ASSERT_TRUE(response_pre.headers != nullptr);
2465     EXPECT_EQ(206, response_pre.headers->response_code());
2466     EXPECT_EQ(1, cache.network_layer()->transaction_count());
2467     EXPECT_EQ(0, cache.disk_cache()->open_count());
2468     EXPECT_EQ(1, cache.disk_cache()->create_count());
2469   }
2470 
2471   {
2472     // Now request the full thing, revalidating successfully, so the full
2473     // file gets stored via a sparse-entry.
2474     ScopedMockTransaction transaction_all(kRangeGET_TransactionOK);
2475     transaction_all.request_headers = EXTRA_HEADER;
2476     transaction_all.data =
2477         "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49"
2478         " rg: 50-59 rg: 60-69 rg: 70-79 ";
2479     MockHttpRequest request_all(transaction_all);
2480 
2481     HttpResponseInfo response_all;
2482     RunTransactionTestWithRequest(cache.http_cache(), transaction_all,
2483                                   request_all, &response_all);
2484     ASSERT_TRUE(response_all.headers != nullptr);
2485     EXPECT_EQ(200, response_all.headers->response_code());
2486     // 1 from previous test, validation, and second chunk
2487     EXPECT_EQ(3, cache.network_layer()->transaction_count());
2488     EXPECT_EQ(1, cache.disk_cache()->open_count());
2489     EXPECT_EQ(1, cache.disk_cache()->create_count());
2490   }
2491 
2492   {
2493     // Grab it again, should not need re-validation.
2494     ScopedMockTransaction transaction_all2(kRangeGET_TransactionOK);
2495     transaction_all2.request_headers = EXTRA_HEADER;
2496     transaction_all2.data =
2497         "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49"
2498         " rg: 50-59 rg: 60-69 rg: 70-79 ";
2499     MockHttpRequest request_all2(transaction_all2);
2500 
2501     HttpResponseInfo response_all2;
2502     RunTransactionTestWithRequest(cache.http_cache(), transaction_all2,
2503                                   request_all2, &response_all2);
2504     ASSERT_TRUE(response_all2.headers != nullptr);
2505     EXPECT_EQ(200, response_all2.headers->response_code());
2506 
2507     // Only one more cache open, no new network traffic.
2508     EXPECT_EQ(3, cache.network_layer()->transaction_count());
2509     EXPECT_EQ(2, cache.disk_cache()->open_count());
2510     EXPECT_EQ(1, cache.disk_cache()->create_count());
2511   }
2512 }
2513 
2514 // This test verifies that the ConnectedCallback passed to a cache transaction
2515 // is called once per subrange in the case of a range request with a partial
2516 // cache hit.
TEST_F(HttpCacheTest,RangeGET_ConnectedCallbackCalledForEachRange)2517 TEST_F(HttpCacheTest, RangeGET_ConnectedCallbackCalledForEachRange) {
2518   MockHttpCache cache;
2519 
2520   // Request an infix range and populate the cache with it.
2521   {
2522     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2523     mock_transaction.request_headers = "Range: bytes = 20-29\r\n" EXTRA_HEADER;
2524     mock_transaction.data = "rg: 20-29 ";
2525     mock_transaction.transport_info = TestTransportInfo();
2526 
2527     RunTransactionTest(cache.http_cache(), mock_transaction);
2528   }
2529 
2530   // Request a surrounding range and observe that the callback is called once
2531   // per subrange, as split up by cache hits.
2532   {
2533     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2534     mock_transaction.request_headers = "Range: bytes = 10-39\r\n" EXTRA_HEADER;
2535     mock_transaction.data = "rg: 10-19 rg: 20-29 rg: 30-39 ";
2536     mock_transaction.transport_info = TestTransportInfo();
2537     MockHttpRequest request(mock_transaction);
2538 
2539     ConnectedHandler connected_handler;
2540 
2541     std::unique_ptr<HttpTransaction> transaction;
2542     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2543     ASSERT_THAT(transaction, NotNull());
2544 
2545     transaction->SetConnectedCallback(connected_handler.Callback());
2546 
2547     TestCompletionCallback callback;
2548     ASSERT_THAT(
2549         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2550         IsError(ERR_IO_PENDING));
2551     EXPECT_THAT(callback.WaitForResult(), IsOk());
2552 
2553     // 1 call for the first range's network transaction.
2554     EXPECT_THAT(connected_handler.transports(),
2555                 ElementsAre(TestTransportInfo()));
2556 
2557     // Switch the endpoint for the next network transaction to observe.
2558     // For ease, we just switch the port number.
2559     //
2560     // NOTE: This works because only the mock transaction struct's address is
2561     // registered with the mocking framework - the pointee data is consulted
2562     // each time it is read.
2563     mock_transaction.transport_info = TestTransportInfoWithPort(123);
2564 
2565     ReadAndVerifyTransaction(transaction.get(), mock_transaction);
2566 
2567     // A second call for the cached range, reported as coming from the original
2568     // endpoint it was cached from. A third call for the last range's network
2569     // transaction.
2570     EXPECT_THAT(connected_handler.transports(),
2571                 ElementsAre(TestTransportInfo(), CachedTestTransportInfo(),
2572                             TestTransportInfoWithPort(123)));
2573   }
2574 }
2575 
2576 // This test verifies that when the ConnectedCallback passed to a cache range
2577 // transaction returns an `ERR_INCONSISTENT_IP_ADDRESS_SPACE` error during a
2578 // partial read from cache, then the cache entry is invalidated.
TEST_F(HttpCacheTest,RangeGET_ConnectedCallbackReturnInconsistentIpError)2579 TEST_F(HttpCacheTest, RangeGET_ConnectedCallbackReturnInconsistentIpError) {
2580   MockHttpCache cache;
2581 
2582   // Request an infix range and populate the cache with it.
2583   {
2584     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2585     mock_transaction.request_headers = "Range: bytes = 20-29\r\n" EXTRA_HEADER;
2586     mock_transaction.data = "rg: 20-29 ";
2587     mock_transaction.transport_info = TestTransportInfo();
2588 
2589     RunTransactionTest(cache.http_cache(), mock_transaction);
2590   }
2591 
2592   ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2593   mock_transaction.request_headers = "Range: bytes = 10-39\r\n" EXTRA_HEADER;
2594   mock_transaction.data = "rg: 10-19 rg: 20-29 rg: 30-39 ";
2595   mock_transaction.transport_info = TestTransportInfo();
2596   MockHttpRequest request(mock_transaction);
2597 
2598   // Request a surrounding range. This *should* be read in three parts:
2599   //
2600   // 1. for the prefix: from the network
2601   // 2. for the cached infix: from the cache
2602   // 3. for the suffix: from the network
2603   //
2604   // The connected callback returns OK for 1), but fails during 2). As a result,
2605   // the transaction fails partway and 3) is never created. The cache entry is
2606   // invalidated as a result of the specific error code.
2607   {
2608     ConnectedHandler connected_handler;
2609 
2610     std::unique_ptr<HttpTransaction> transaction;
2611     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2612     ASSERT_THAT(transaction, NotNull());
2613 
2614     transaction->SetConnectedCallback(connected_handler.Callback());
2615 
2616     TestCompletionCallback callback;
2617     ASSERT_THAT(
2618         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2619         IsError(ERR_IO_PENDING));
2620     EXPECT_THAT(callback.WaitForResult(), IsOk());
2621 
2622     // 1 call for the first range's network transaction.
2623     EXPECT_THAT(connected_handler.transports(),
2624                 ElementsAre(TestTransportInfo()));
2625 
2626     // Set the callback to return an error the next time it is called.
2627     connected_handler.set_result(ERR_INCONSISTENT_IP_ADDRESS_SPACE);
2628 
2629     std::string content;
2630     EXPECT_THAT(ReadTransaction(transaction.get(), &content),
2631                 IsError(ERR_INCONSISTENT_IP_ADDRESS_SPACE));
2632 
2633     // A second call that failed.
2634     EXPECT_THAT(connected_handler.transports(),
2635                 ElementsAre(TestTransportInfo(), CachedTestTransportInfo()));
2636   }
2637 
2638   // Request the same range again, observe that nothing is read from cache.
2639   {
2640     ConnectedHandler connected_handler;
2641 
2642     std::unique_ptr<HttpTransaction> transaction;
2643     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2644     ASSERT_THAT(transaction, NotNull());
2645 
2646     transaction->SetConnectedCallback(connected_handler.Callback());
2647 
2648     TestCompletionCallback callback;
2649     ASSERT_THAT(
2650         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2651         IsError(ERR_IO_PENDING));
2652     EXPECT_THAT(callback.WaitForResult(), IsOk());
2653 
2654     std::string content;
2655     EXPECT_THAT(ReadTransaction(transaction.get(), &content), IsOk());
2656     EXPECT_EQ(content, mock_transaction.data);
2657 
2658     // 1 call for the network transaction from which the whole response was
2659     // read. The first 20 bytes were cached by the previous two requests, but
2660     // the cache entry was doomed during the last transaction so they are not
2661     // used here.
2662     EXPECT_THAT(connected_handler.transports(),
2663                 ElementsAre(TestTransportInfo()));
2664   }
2665 }
2666 
2667 // This test verifies that when the ConnectedCallback passed to a cache range
2668 // transaction returns an `ERR_INCONSISTENT_IP_ADDRESS_SPACE` error during a
2669 // network transaction, then the cache entry is invalidated.
TEST_F(HttpCacheTest,RangeGET_ConnectedCallbackReturnInconsistentIpErrorForNetwork)2670 TEST_F(HttpCacheTest,
2671        RangeGET_ConnectedCallbackReturnInconsistentIpErrorForNetwork) {
2672   MockHttpCache cache;
2673 
2674   // Request a prefix range and populate the cache with it.
2675   {
2676     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2677     mock_transaction.request_headers = "Range: bytes = 10-19\r\n" EXTRA_HEADER;
2678     mock_transaction.data = "rg: 10-19 ";
2679     mock_transaction.transport_info = TestTransportInfo();
2680 
2681     RunTransactionTest(cache.http_cache(), mock_transaction);
2682   }
2683 
2684   ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2685   mock_transaction.request_headers = "Range: bytes = 10-29\r\n" EXTRA_HEADER;
2686   mock_transaction.data = "rg: 10-19 rg: 20-29 ";
2687   mock_transaction.transport_info = TestTransportInfo();
2688   MockHttpRequest request(mock_transaction);
2689 
2690   // Request a longer range. This *should* be read in two parts:
2691   //
2692   // 1. for the prefix: from the cache
2693   // 2. for the suffix: from the network
2694   {
2695     ConnectedHandler connected_handler;
2696 
2697     std::unique_ptr<HttpTransaction> transaction;
2698     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2699     ASSERT_THAT(transaction, NotNull());
2700 
2701     transaction->SetConnectedCallback(connected_handler.Callback());
2702 
2703     TestCompletionCallback callback;
2704     ASSERT_THAT(
2705         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2706         IsError(ERR_IO_PENDING));
2707     EXPECT_THAT(callback.WaitForResult(), IsOk());
2708 
2709     // 1 call for the first range's network transaction.
2710     EXPECT_THAT(connected_handler.transports(),
2711                 ElementsAre(CachedTestTransportInfo()));
2712 
2713     // Set the callback to return an error the next time it is called.
2714     connected_handler.set_result(ERR_INCONSISTENT_IP_ADDRESS_SPACE);
2715 
2716     std::string content;
2717     EXPECT_THAT(ReadTransaction(transaction.get(), &content),
2718                 IsError(ERR_INCONSISTENT_IP_ADDRESS_SPACE));
2719 
2720     // A second call that failed.
2721     EXPECT_THAT(connected_handler.transports(),
2722                 ElementsAre(CachedTestTransportInfo(), TestTransportInfo()));
2723   }
2724 
2725   // Request the same range again, observe that nothing is read from cache.
2726   {
2727     ConnectedHandler connected_handler;
2728 
2729     std::unique_ptr<HttpTransaction> transaction;
2730     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2731     ASSERT_THAT(transaction, NotNull());
2732 
2733     transaction->SetConnectedCallback(connected_handler.Callback());
2734 
2735     TestCompletionCallback callback;
2736     ASSERT_THAT(
2737         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2738         IsError(ERR_IO_PENDING));
2739     EXPECT_THAT(callback.WaitForResult(), IsOk());
2740 
2741     std::string content;
2742     EXPECT_THAT(ReadTransaction(transaction.get(), &content), IsOk());
2743     EXPECT_EQ(content, mock_transaction.data);
2744 
2745     // 1 call for the network transaction from which the whole response was
2746     // read. The first 20 bytes were cached by the previous two requests, but
2747     // the cache entry was doomed during the last transaction so they are not
2748     // used here.
2749     EXPECT_THAT(connected_handler.transports(),
2750                 ElementsAre(TestTransportInfo()));
2751   }
2752 }
2753 
2754 // This test verifies that when the ConnectedCallback passed to a cache
2755 // transaction returns an error for the second (or third) subrange transaction,
2756 // the overall cache transaction fails with that error. The cache entry is still
2757 // usable after that.
TEST_F(HttpCacheTest,RangeGET_ConnectedCallbackReturnErrorSecondTime)2758 TEST_F(HttpCacheTest, RangeGET_ConnectedCallbackReturnErrorSecondTime) {
2759   MockHttpCache cache;
2760 
2761   // Request an infix range and populate the cache with it.
2762   {
2763     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2764     mock_transaction.request_headers = "Range: bytes = 20-29\r\n" EXTRA_HEADER;
2765     mock_transaction.data = "rg: 20-29 ";
2766     mock_transaction.transport_info = TestTransportInfo();
2767 
2768     RunTransactionTest(cache.http_cache(), mock_transaction);
2769   }
2770 
2771   ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2772   mock_transaction.request_headers = "Range: bytes = 10-39\r\n" EXTRA_HEADER;
2773   mock_transaction.data = "rg: 10-19 rg: 20-29 rg: 30-39 ";
2774   mock_transaction.transport_info = TestTransportInfo();
2775   MockHttpRequest request(mock_transaction);
2776 
2777   // Request a surrounding range. This *should* be read in three parts:
2778   //
2779   // 1. for the prefix: from the network
2780   // 2. for the cached infix: from the cache
2781   // 3. for the suffix: from the network
2782   //
2783   // The connected callback returns OK for 1), but fails during 2). As a result,
2784   // the transaction fails partway and 3) is never created. The prefix is still
2785   // cached, such that the cache entry ends up with both the prefix and infix.
2786   {
2787     ConnectedHandler connected_handler;
2788 
2789     std::unique_ptr<HttpTransaction> transaction;
2790     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2791     ASSERT_THAT(transaction, NotNull());
2792 
2793     transaction->SetConnectedCallback(connected_handler.Callback());
2794 
2795     TestCompletionCallback callback;
2796     ASSERT_THAT(
2797         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2798         IsError(ERR_IO_PENDING));
2799     EXPECT_THAT(callback.WaitForResult(), IsOk());
2800 
2801     // 1 call for the first range's network transaction.
2802     EXPECT_THAT(connected_handler.transports(),
2803                 ElementsAre(TestTransportInfo()));
2804 
2805     // Set the callback to return an error the next time it is called. The exact
2806     // error code is irrelevant, what matters is that it is reflected in the
2807     // overall status of the transaction.
2808     connected_handler.set_result(ERR_NOT_IMPLEMENTED);
2809 
2810     std::string content;
2811     EXPECT_THAT(ReadTransaction(transaction.get(), &content),
2812                 IsError(ERR_NOT_IMPLEMENTED));
2813 
2814     // A second call that failed.
2815     EXPECT_THAT(connected_handler.transports(),
2816                 ElementsAre(TestTransportInfo(), CachedTestTransportInfo()));
2817   }
2818 
2819   // Request the same range again, observe that the prefix and infix are both
2820   // read from cache. Only the suffix is fetched from the network.
2821   {
2822     ConnectedHandler connected_handler;
2823 
2824     std::unique_ptr<HttpTransaction> transaction;
2825     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2826     ASSERT_THAT(transaction, NotNull());
2827 
2828     transaction->SetConnectedCallback(connected_handler.Callback());
2829 
2830     TestCompletionCallback callback;
2831     ASSERT_THAT(
2832         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2833         IsError(ERR_IO_PENDING));
2834     EXPECT_THAT(callback.WaitForResult(), IsOk());
2835 
2836     // 1 call for the first range's cache transaction: the first 20 bytes were
2837     // cached by the previous two requests.
2838     EXPECT_THAT(connected_handler.transports(),
2839                 ElementsAre(CachedTestTransportInfo()));
2840 
2841     std::string content;
2842     EXPECT_THAT(ReadTransaction(transaction.get(), &content), IsOk());
2843     EXPECT_EQ(content, mock_transaction.data);
2844 
2845     // A second call from the network transaction for the last 10 bytes.
2846     EXPECT_THAT(connected_handler.transports(),
2847                 ElementsAre(CachedTestTransportInfo(), TestTransportInfo()));
2848   }
2849 }
2850 
2851 // This test verifies that the ConnectedCallback passed to a cache transaction
2852 // is called once per subrange in the case of a range request with a partial
2853 // cache hit, even when a prefix of the range is cached.
TEST_F(HttpCacheTest,RangeGET_ConnectedCallbackCalledForEachRangeWithPrefix)2854 TEST_F(HttpCacheTest, RangeGET_ConnectedCallbackCalledForEachRangeWithPrefix) {
2855   MockHttpCache cache;
2856 
2857   // Request a prefix range and populate the cache with it.
2858   {
2859     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2860     mock_transaction.request_headers = "Range: bytes = 10-19\r\n" EXTRA_HEADER;
2861     mock_transaction.data = "rg: 10-19 ";
2862     mock_transaction.transport_info = TestTransportInfo();
2863 
2864     RunTransactionTest(cache.http_cache(), mock_transaction);
2865   }
2866 
2867   // Request a surrounding range and observe that the callback is called once
2868   // per subrange, as split up by cache hits.
2869   {
2870     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2871     mock_transaction.request_headers = "Range: bytes = 10-39\r\n" EXTRA_HEADER;
2872     mock_transaction.data = "rg: 10-19 rg: 20-29 rg: 30-39 ";
2873     mock_transaction.transport_info = TestTransportInfoWithPort(123);
2874     MockHttpRequest request(mock_transaction);
2875 
2876     ConnectedHandler connected_handler;
2877 
2878     std::unique_ptr<HttpTransaction> transaction;
2879     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2880     ASSERT_THAT(transaction, NotNull());
2881 
2882     transaction->SetConnectedCallback(connected_handler.Callback());
2883 
2884     TestCompletionCallback callback;
2885     ASSERT_THAT(
2886         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2887         IsError(ERR_IO_PENDING));
2888     EXPECT_THAT(callback.WaitForResult(), IsOk());
2889 
2890     // 1 call for the first range from the cache, reported as coming from the
2891     // endpoint which initially served the cached range.
2892     EXPECT_THAT(connected_handler.transports(),
2893                 ElementsAre(CachedTestTransportInfo()));
2894 
2895     ReadAndVerifyTransaction(transaction.get(), mock_transaction);
2896 
2897     // A second call for the last range's network transaction.
2898     EXPECT_THAT(
2899         connected_handler.transports(),
2900         ElementsAre(CachedTestTransportInfo(), TestTransportInfoWithPort(123)));
2901   }
2902 }
2903 
2904 // Tests that a range transaction is still usable even if it's unable to access
2905 // the cache.
TEST_F(HttpCacheTest,RangeGET_FailedCacheAccess)2906 TEST_F(HttpCacheTest, RangeGET_FailedCacheAccess) {
2907   MockHttpCache cache;
2908 
2909   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
2910   MockHttpRequest request(transaction);
2911 
2912   auto c = std::make_unique<Context>();
2913   c->result = cache.CreateTransaction(&c->trans);
2914   ASSERT_THAT(c->result, IsOk());
2915   EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
2916 
2917   cache.disk_cache()->set_fail_requests(true);
2918 
2919   c->result =
2920       c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
2921 
2922   base::RunLoop().RunUntilIdle();
2923 
2924   EXPECT_FALSE(cache.IsWriterPresent(kRangeGET_TransactionOK.url));
2925 
2926   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2927   EXPECT_EQ(0, cache.disk_cache()->open_count());
2928   EXPECT_EQ(0, cache.disk_cache()->create_count());
2929 
2930   c->result = c->callback.WaitForResult();
2931 
2932   ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK);
2933 
2934   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2935   EXPECT_EQ(0, cache.disk_cache()->open_count());
2936   EXPECT_EQ(0, cache.disk_cache()->create_count());
2937 }
2938 
2939 // Tests that we can have parallel validation on range requests.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationNoMatch)2940 TEST_F(HttpCacheTest, RangeGET_ParallelValidationNoMatch) {
2941   MockHttpCache cache;
2942 
2943   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
2944   MockHttpRequest request(transaction);
2945 
2946   std::vector<std::unique_ptr<Context>> context_list;
2947   const int kNumTransactions = 5;
2948 
2949   for (int i = 0; i < kNumTransactions; ++i) {
2950     context_list.push_back(std::make_unique<Context>());
2951     auto& c = context_list[i];
2952 
2953     c->result = cache.CreateTransaction(&c->trans);
2954     ASSERT_THAT(c->result, IsOk());
2955     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
2956 
2957     c->result =
2958         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
2959   }
2960 
2961   // All requests are waiting for the active entry.
2962   for (auto& context : context_list) {
2963     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
2964   }
2965 
2966   // Allow all requests to move from the Create queue to the active entry.
2967   base::RunLoop().RunUntilIdle();
2968 
2969   // First entry created is doomed due to 2nd transaction's validation leading
2970   // to restarting of the queued transactions.
2971   EXPECT_TRUE(cache.IsWriterPresent(request.CacheKey()));
2972 
2973   // TODO(shivanisha): The restarted transactions race for creating the entry
2974   // and thus instead of all 4 succeeding, 2 of them succeed. This is very
2975   // implementation specific and happens because the queued transactions get
2976   // restarted synchronously and get to the queue of creating the entry before
2977   // the transaction that is restarting them. Fix the test to make it less
2978   // vulnerable to any scheduling changes in the code.
2979   EXPECT_EQ(5, cache.network_layer()->transaction_count());
2980   EXPECT_EQ(0, cache.disk_cache()->open_count());
2981   EXPECT_EQ(3, cache.disk_cache()->create_count());
2982 
2983   for (auto& context : context_list) {
2984     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
2985   }
2986 
2987   for (int i = 0; i < kNumTransactions; ++i) {
2988     auto& c = context_list[i];
2989     if (c->result == ERR_IO_PENDING)
2990       c->result = c->callback.WaitForResult();
2991 
2992     ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK);
2993   }
2994 
2995   EXPECT_EQ(5, cache.network_layer()->transaction_count());
2996   EXPECT_EQ(0, cache.disk_cache()->open_count());
2997   EXPECT_EQ(3, cache.disk_cache()->create_count());
2998 }
2999 
3000 // Tests that if a transaction is dooming the entry and the entry was doomed by
3001 // another transaction that was not part of the entry and created a new entry,
3002 // the new entry should not be incorrectly doomed. (crbug.com/736993)
TEST_F(HttpCacheTest,RangeGET_ParallelValidationNoMatchDoomEntry)3003 TEST_F(HttpCacheTest, RangeGET_ParallelValidationNoMatchDoomEntry) {
3004   MockHttpCache cache;
3005 
3006   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3007   MockHttpRequest request(transaction);
3008 
3009   MockTransaction dooming_transaction(kRangeGET_TransactionOK);
3010   dooming_transaction.load_flags |= LOAD_BYPASS_CACHE;
3011   MockHttpRequest dooming_request(dooming_transaction);
3012 
3013   std::vector<std::unique_ptr<Context>> context_list;
3014   const int kNumTransactions = 3;
3015 
3016   scoped_refptr<MockDiskEntry> first_entry;
3017   scoped_refptr<MockDiskEntry> second_entry;
3018   for (int i = 0; i < kNumTransactions; ++i) {
3019     context_list.push_back(std::make_unique<Context>());
3020     auto& c = context_list[i];
3021 
3022     c->result = cache.CreateTransaction(&c->trans);
3023     ASSERT_THAT(c->result, IsOk());
3024     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3025 
3026     MockHttpRequest* this_request = &request;
3027 
3028     if (i == 2)
3029       this_request = &dooming_request;
3030 
3031     if (i == 1) {
3032       ASSERT_TRUE(first_entry);
3033       first_entry->SetDefer(MockDiskEntry::DEFER_READ);
3034     }
3035 
3036     c->result = c->trans->Start(this_request, c->callback.callback(),
3037                                 NetLogWithSource());
3038 
3039     // Continue the transactions. 2nd will pause at the cache reading state and
3040     // 3rd transaction will doom the entry.
3041     base::RunLoop().RunUntilIdle();
3042 
3043     std::string cache_key = request.CacheKey();
3044     // Check status of the first and second entries after every transaction.
3045     switch (i) {
3046       case 0:
3047         first_entry = cache.disk_cache()->GetDiskEntryRef(cache_key);
3048         break;
3049       case 1:
3050         EXPECT_FALSE(first_entry->is_doomed());
3051         break;
3052       case 2:
3053         EXPECT_TRUE(first_entry->is_doomed());
3054         second_entry = cache.disk_cache()->GetDiskEntryRef(cache_key);
3055         EXPECT_FALSE(second_entry->is_doomed());
3056         break;
3057     }
3058   }
3059   // Resume cache read by 1st transaction which will lead to dooming the entry
3060   // as well since the entry cannot be validated. This double dooming should not
3061   // lead to an assertion.
3062   first_entry->ResumeDiskEntryOperation();
3063   base::RunLoop().RunUntilIdle();
3064 
3065   // Since second_entry is already created, when 1st transaction goes on to
3066   // create an entry, it will get ERR_CACHE_RACE leading to dooming of
3067   // second_entry and creation of a third entry.
3068   EXPECT_TRUE(second_entry->is_doomed());
3069 
3070   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3071   EXPECT_EQ(0, cache.disk_cache()->open_count());
3072   EXPECT_EQ(3, cache.disk_cache()->create_count());
3073 
3074   for (auto& context : context_list) {
3075     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
3076   }
3077 
3078   for (auto& c : context_list) {
3079     ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK);
3080   }
3081 
3082   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3083   EXPECT_EQ(0, cache.disk_cache()->open_count());
3084   EXPECT_EQ(3, cache.disk_cache()->create_count());
3085 }
3086 
3087 // Same as above but tests that the 2nd transaction does not do anything if
3088 // there is nothing to doom. (crbug.com/736993)
TEST_F(HttpCacheTest,RangeGET_ParallelValidationNoMatchDoomEntry1)3089 TEST_F(HttpCacheTest, RangeGET_ParallelValidationNoMatchDoomEntry1) {
3090   MockHttpCache cache;
3091 
3092   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3093   MockHttpRequest request(transaction);
3094 
3095   MockTransaction dooming_transaction(kRangeGET_TransactionOK);
3096   dooming_transaction.load_flags |= LOAD_BYPASS_CACHE;
3097   MockHttpRequest dooming_request(dooming_transaction);
3098 
3099   std::vector<std::unique_ptr<Context>> context_list;
3100   const int kNumTransactions = 3;
3101 
3102   scoped_refptr<MockDiskEntry> first_entry;
3103   for (int i = 0; i < kNumTransactions; ++i) {
3104     context_list.push_back(std::make_unique<Context>());
3105     auto& c = context_list[i];
3106 
3107     c->result = cache.CreateTransaction(&c->trans);
3108     ASSERT_THAT(c->result, IsOk());
3109     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3110 
3111     MockHttpRequest* this_request = &request;
3112 
3113     if (i == 2) {
3114       this_request = &dooming_request;
3115       cache.disk_cache()->SetDefer(MockDiskEntry::DEFER_CREATE);
3116     }
3117 
3118     if (i == 1) {
3119       ASSERT_TRUE(first_entry);
3120       first_entry->SetDefer(MockDiskEntry::DEFER_READ);
3121     }
3122 
3123     c->result = c->trans->Start(this_request, c->callback.callback(),
3124                                 NetLogWithSource());
3125 
3126     // Continue the transactions. 2nd will pause at the cache reading state and
3127     // 3rd transaction will doom the entry and pause before creating a new
3128     // entry.
3129     base::RunLoop().RunUntilIdle();
3130 
3131     // Check status of the entry after every transaction.
3132     switch (i) {
3133       case 0:
3134         first_entry = cache.disk_cache()->GetDiskEntryRef(request.CacheKey());
3135         break;
3136       case 1:
3137         EXPECT_FALSE(first_entry->is_doomed());
3138         break;
3139       case 2:
3140         EXPECT_TRUE(first_entry->is_doomed());
3141         break;
3142     }
3143   }
3144   // Resume cache read by 2nd transaction which will lead to dooming the entry
3145   // as well since the entry cannot be validated. This double dooming should not
3146   // lead to an assertion.
3147   first_entry->ResumeDiskEntryOperation();
3148   base::RunLoop().RunUntilIdle();
3149 
3150   // Resume creation of entry by 3rd transaction.
3151   cache.disk_cache()->ResumeCacheOperation();
3152   base::RunLoop().RunUntilIdle();
3153 
3154   // Note that since 3rd transaction's entry is already created but its
3155   // callback is deferred, MockDiskCache's implementation returns
3156   // ERR_CACHE_CREATE_FAILURE when 2nd transaction tries to create an entry
3157   // during that time, leading to it switching over to pass-through mode.
3158   // Thus the number of entries is 2 below.
3159   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3160   EXPECT_EQ(0, cache.disk_cache()->open_count());
3161   EXPECT_EQ(2, cache.disk_cache()->create_count());
3162 
3163   for (auto& context : context_list) {
3164     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
3165   }
3166 
3167   for (auto& c : context_list) {
3168     ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK);
3169   }
3170 
3171   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3172   EXPECT_EQ(0, cache.disk_cache()->open_count());
3173   EXPECT_EQ(2, cache.disk_cache()->create_count());
3174 }
3175 
3176 // Tests parallel validation on range requests with non-overlapping ranges.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationDifferentRanges)3177 TEST_F(HttpCacheTest, RangeGET_ParallelValidationDifferentRanges) {
3178   MockHttpCache cache;
3179 
3180   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3181 
3182   std::vector<std::unique_ptr<Context>> context_list;
3183   const int kNumTransactions = 2;
3184 
3185   for (int i = 0; i < kNumTransactions; ++i) {
3186     context_list.push_back(std::make_unique<Context>());
3187   }
3188 
3189   // Let 1st transaction complete headers phase for ranges 40-49.
3190   std::string first_read;
3191   MockHttpRequest request1(transaction);
3192   {
3193     auto& c = context_list[0];
3194     c->result = cache.CreateTransaction(&c->trans);
3195     ASSERT_THAT(c->result, IsOk());
3196     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3197 
3198     c->result =
3199         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3200     base::RunLoop().RunUntilIdle();
3201 
3202     // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns
3203     // true.
3204     const int kBufferSize = 5;
3205     scoped_refptr<IOBuffer> buffer =
3206         base::MakeRefCounted<IOBuffer>(kBufferSize);
3207     ReleaseBufferCompletionCallback cb(buffer.get());
3208     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3209     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3210 
3211     std::string data_read(buffer->data(), kBufferSize);
3212     first_read = data_read;
3213 
3214     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3215   }
3216 
3217   // 2nd transaction requests ranges 30-39.
3218   transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3219   MockHttpRequest request2(transaction);
3220   {
3221     auto& c = context_list[1];
3222     c->result = cache.CreateTransaction(&c->trans);
3223     ASSERT_THAT(c->result, IsOk());
3224     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3225 
3226     c->result =
3227         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3228     base::RunLoop().RunUntilIdle();
3229 
3230     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3231   }
3232 
3233   std::string cache_key = request2.CacheKey();
3234   EXPECT_TRUE(cache.IsWriterPresent(cache_key));
3235   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
3236 
3237   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3238   EXPECT_EQ(0, cache.disk_cache()->open_count());
3239   EXPECT_EQ(1, cache.disk_cache()->create_count());
3240 
3241   for (int i = 0; i < kNumTransactions; ++i) {
3242     auto& c = context_list[i];
3243     if (c->result == ERR_IO_PENDING)
3244       c->result = c->callback.WaitForResult();
3245 
3246     if (i == 0) {
3247       ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
3248                                         transaction);
3249       continue;
3250     }
3251 
3252     transaction.data = "rg: 30-39 ";
3253     ReadAndVerifyTransaction(c->trans.get(), transaction);
3254   }
3255 
3256   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3257   EXPECT_EQ(0, cache.disk_cache()->open_count());
3258   EXPECT_EQ(1, cache.disk_cache()->create_count());
3259 
3260   // Fetch from the cache to check that ranges 30-49 have been successfully
3261   // cached.
3262   {
3263     MockTransaction range_transaction(kRangeGET_TransactionOK);
3264     range_transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
3265     range_transaction.data = "rg: 30-39 rg: 40-49 ";
3266     std::string headers;
3267     RunTransactionTestWithResponse(cache.http_cache(), range_transaction,
3268                                    &headers);
3269     Verify206Response(headers, 30, 49);
3270   }
3271 
3272   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3273   EXPECT_EQ(1, cache.disk_cache()->open_count());
3274   EXPECT_EQ(1, cache.disk_cache()->create_count());
3275 
3276   context_list.clear();
3277 }
3278 
3279 // Tests that a request does not create Writers when readers is not empty.
TEST_F(HttpCacheTest,RangeGET_DoNotCreateWritersWhenReaderExists)3280 TEST_F(HttpCacheTest, RangeGET_DoNotCreateWritersWhenReaderExists) {
3281   MockHttpCache cache;
3282 
3283   // Save a request in the cache so that the next request can become a
3284   // reader.
3285   MockTransaction transaction(kRangeGET_Transaction);
3286   transaction.request_headers = EXTRA_HEADER;
3287   AddMockTransaction(&transaction);
3288   RunTransactionTest(cache.http_cache(), transaction);
3289 
3290   // Let this request be a reader since it doesn't need validation as per its
3291   // load flag.
3292   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
3293   MockHttpRequest request(transaction);
3294   Context context;
3295   context.result = cache.CreateTransaction(&context.trans);
3296   ASSERT_THAT(context.result, IsOk());
3297   context.result = context.trans->Start(&request, context.callback.callback(),
3298                                         NetLogWithSource());
3299   base::RunLoop().RunUntilIdle();
3300   std::string cache_key = request.CacheKey();
3301   EXPECT_EQ(1, cache.GetCountReaders(cache_key));
3302   RemoveMockTransaction(&transaction);
3303 
3304   // A range request should now "not" create Writers while readers is still
3305   // non-empty.
3306   MockTransaction range_transaction(kRangeGET_Transaction);
3307   range_transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
3308   AddMockTransaction(&range_transaction);
3309   MockHttpRequest range_request(range_transaction);
3310   Context range_context;
3311   range_context.result = cache.CreateTransaction(&range_context.trans);
3312   ASSERT_THAT(range_context.result, IsOk());
3313   range_context.result = range_context.trans->Start(
3314       &range_request, range_context.callback.callback(), NetLogWithSource());
3315   base::RunLoop().RunUntilIdle();
3316 
3317   EXPECT_EQ(1, cache.GetCountReaders(cache_key));
3318   EXPECT_FALSE(cache.IsWriterPresent(cache_key));
3319   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
3320 
3321   RemoveMockTransaction(&range_transaction);
3322 }
3323 
3324 // Tests parallel validation on range requests can be successfully restarted
3325 // when there is a cache lock timeout.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationCacheLockTimeout)3326 TEST_F(HttpCacheTest, RangeGET_ParallelValidationCacheLockTimeout) {
3327   MockHttpCache cache;
3328 
3329   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3330 
3331   std::vector<std::unique_ptr<Context>> context_list;
3332   const int kNumTransactions = 2;
3333 
3334   for (int i = 0; i < kNumTransactions; ++i) {
3335     context_list.push_back(std::make_unique<Context>());
3336   }
3337 
3338   // Let 1st transaction complete headers phase for ranges 40-49.
3339   std::string first_read;
3340   MockHttpRequest request1(transaction);
3341   {
3342     auto& c = context_list[0];
3343     c->result = cache.CreateTransaction(&c->trans);
3344     ASSERT_THAT(c->result, IsOk());
3345     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3346 
3347     c->result =
3348         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3349     base::RunLoop().RunUntilIdle();
3350 
3351     // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns
3352     // true.
3353     const int kBufferSize = 5;
3354     scoped_refptr<IOBuffer> buffer =
3355         base::MakeRefCounted<IOBuffer>(kBufferSize);
3356     ReleaseBufferCompletionCallback cb(buffer.get());
3357     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3358     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3359 
3360     std::string data_read(buffer->data(), kBufferSize);
3361     first_read = data_read;
3362 
3363     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3364   }
3365 
3366   // Cache lock timeout will lead to dooming the entry since the transaction may
3367   // have already written the headers.
3368   cache.SimulateCacheLockTimeoutAfterHeaders();
3369 
3370   // 2nd transaction requests ranges 30-39.
3371   transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3372   MockHttpRequest request2(transaction);
3373   {
3374     auto& c = context_list[1];
3375     c->result = cache.CreateTransaction(&c->trans);
3376     ASSERT_THAT(c->result, IsOk());
3377     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3378 
3379     c->result =
3380         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3381     base::RunLoop().RunUntilIdle();
3382 
3383     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3384   }
3385 
3386   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(request1.CacheKey()));
3387 
3388   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3389   EXPECT_EQ(0, cache.disk_cache()->open_count());
3390   EXPECT_EQ(1, cache.disk_cache()->create_count());
3391 
3392   for (int i = 0; i < kNumTransactions; ++i) {
3393     auto& c = context_list[i];
3394     if (c->result == ERR_IO_PENDING)
3395       c->result = c->callback.WaitForResult();
3396 
3397     if (i == 0) {
3398       ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
3399                                         transaction);
3400       continue;
3401     }
3402 
3403     transaction.data = "rg: 30-39 ";
3404     ReadAndVerifyTransaction(c->trans.get(), transaction);
3405   }
3406 
3407   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3408   EXPECT_EQ(0, cache.disk_cache()->open_count());
3409   EXPECT_EQ(1, cache.disk_cache()->create_count());
3410 }
3411 
3412 // Tests a full request and a simultaneous range request and the range request
3413 // dooms the entry created by the full request due to not being able to
3414 // conditionalize.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationCouldntConditionalize)3415 TEST_F(HttpCacheTest, RangeGET_ParallelValidationCouldntConditionalize) {
3416   MockHttpCache cache;
3417 
3418   MockTransaction mock_transaction(kSimpleGET_Transaction);
3419   mock_transaction.url = kRangeGET_TransactionOK.url;
3420   ScopedMockTransaction transaction(mock_transaction);
3421 
3422   // Remove the cache-control and other headers so that the response cannot be
3423   // conditionalized.
3424   transaction.response_headers = "";
3425 
3426   std::vector<std::unique_ptr<Context>> context_list;
3427   const int kNumTransactions = 2;
3428 
3429   for (int i = 0; i < kNumTransactions; ++i) {
3430     context_list.push_back(std::make_unique<Context>());
3431   }
3432 
3433   // Let 1st transaction complete headers phase for no range and read some part
3434   // of the response and write in the cache.
3435   std::string first_read;
3436   MockHttpRequest request1(transaction);
3437   {
3438     request1.url = GURL(kRangeGET_TransactionOK.url);
3439     auto& c = context_list[0];
3440     c->result = cache.CreateTransaction(&c->trans);
3441     ASSERT_THAT(c->result, IsOk());
3442     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3443 
3444     c->result =
3445         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3446     base::RunLoop().RunUntilIdle();
3447 
3448     const int kBufferSize = 5;
3449     scoped_refptr<IOBuffer> buffer =
3450         base::MakeRefCounted<IOBuffer>(kBufferSize);
3451     ReleaseBufferCompletionCallback cb(buffer.get());
3452     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3453     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3454 
3455     std::string data_read(buffer->data(), kBufferSize);
3456     first_read = data_read;
3457 
3458     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3459   }
3460 
3461   // 2nd transaction requests a range.
3462   ScopedMockTransaction range_transaction(kRangeGET_TransactionOK);
3463   range_transaction.request_headers = "Range: bytes = 0-29\r\n" EXTRA_HEADER;
3464   MockHttpRequest request2(range_transaction);
3465   {
3466     auto& c = context_list[1];
3467     c->result = cache.CreateTransaction(&c->trans);
3468     ASSERT_THAT(c->result, IsOk());
3469     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3470 
3471     c->result =
3472         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3473     base::RunLoop().RunUntilIdle();
3474 
3475     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3476   }
3477 
3478   // The second request would have doomed the 1st entry and created a new entry.
3479   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3480   EXPECT_EQ(0, cache.disk_cache()->open_count());
3481   EXPECT_EQ(2, cache.disk_cache()->create_count());
3482 
3483   for (int i = 0; i < kNumTransactions; ++i) {
3484     auto& c = context_list[i];
3485     if (c->result == ERR_IO_PENDING)
3486       c->result = c->callback.WaitForResult();
3487 
3488     if (i == 0) {
3489       ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
3490                                         transaction);
3491       continue;
3492     }
3493     range_transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 ";
3494     ReadAndVerifyTransaction(c->trans.get(), range_transaction);
3495   }
3496   context_list.clear();
3497 }
3498 
3499 // Tests a 200 request and a simultaneous range request where conditionalization
3500 // is possible.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationCouldConditionalize)3501 TEST_F(HttpCacheTest, RangeGET_ParallelValidationCouldConditionalize) {
3502   MockHttpCache cache;
3503 
3504   MockTransaction mock_transaction(kSimpleGET_Transaction);
3505   mock_transaction.url = kRangeGET_TransactionOK.url;
3506   mock_transaction.data = kFullRangeData;
3507   std::string response_headers_str = base::StrCat(
3508       {"ETag: StrongOne\n",
3509        "Content-Length:", base::NumberToString(strlen(kFullRangeData)), "\n"});
3510   mock_transaction.response_headers = response_headers_str.c_str();
3511 
3512   ScopedMockTransaction transaction(mock_transaction);
3513 
3514   std::vector<std::unique_ptr<Context>> context_list;
3515   const int kNumTransactions = 2;
3516 
3517   for (int i = 0; i < kNumTransactions; ++i) {
3518     context_list.push_back(std::make_unique<Context>());
3519   }
3520 
3521   // Let 1st transaction complete headers phase for no range and read some part
3522   // of the response and write in the cache.
3523   std::string first_read;
3524   MockHttpRequest request1(transaction);
3525   {
3526     request1.url = GURL(kRangeGET_TransactionOK.url);
3527     auto& c = context_list[0];
3528     c->result = cache.CreateTransaction(&c->trans);
3529     ASSERT_THAT(c->result, IsOk());
3530     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3531 
3532     c->result =
3533         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3534     base::RunLoop().RunUntilIdle();
3535 
3536     const int kBufferSize = 5;
3537     scoped_refptr<IOBuffer> buffer =
3538         base::MakeRefCounted<IOBuffer>(kBufferSize);
3539     ReleaseBufferCompletionCallback cb(buffer.get());
3540     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3541     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3542 
3543     std::string data_read(buffer->data(), kBufferSize);
3544     first_read = data_read;
3545 
3546     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3547   }
3548 
3549   // 2nd transaction requests a range.
3550   ScopedMockTransaction range_transaction(kRangeGET_TransactionOK);
3551   range_transaction.request_headers = "Range: bytes = 0-29\r\n" EXTRA_HEADER;
3552   MockHttpRequest request2(range_transaction);
3553   {
3554     auto& c = context_list[1];
3555     c->result = cache.CreateTransaction(&c->trans);
3556     ASSERT_THAT(c->result, IsOk());
3557     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3558 
3559     c->result =
3560         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3561     base::RunLoop().RunUntilIdle();
3562 
3563     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3564   }
3565 
3566   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3567   EXPECT_EQ(0, cache.disk_cache()->open_count());
3568   EXPECT_EQ(1, cache.disk_cache()->create_count());
3569 
3570   // Finish and verify the first request.
3571   auto& c0 = context_list[0];
3572   c0->result = c0->callback.WaitForResult();
3573   ReadRemainingAndVerifyTransaction(c0->trans.get(), first_read, transaction);
3574 
3575   // And the second.
3576   auto& c1 = context_list[1];
3577   c1->result = c1->callback.WaitForResult();
3578 
3579   range_transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 ";
3580   ReadAndVerifyTransaction(c1->trans.get(), range_transaction);
3581   context_list.clear();
3582 }
3583 
3584 // Tests parallel validation on range requests with overlapping ranges.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationOverlappingRanges)3585 TEST_F(HttpCacheTest, RangeGET_ParallelValidationOverlappingRanges) {
3586   MockHttpCache cache;
3587 
3588   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3589 
3590   std::vector<std::unique_ptr<Context>> context_list;
3591   const int kNumTransactions = 2;
3592 
3593   for (int i = 0; i < kNumTransactions; ++i) {
3594     context_list.push_back(std::make_unique<Context>());
3595   }
3596 
3597   // Let 1st transaction complete headers phase for ranges 40-49.
3598   std::string first_read;
3599   MockHttpRequest request1(transaction);
3600   {
3601     auto& c = context_list[0];
3602     c->result = cache.CreateTransaction(&c->trans);
3603     ASSERT_THAT(c->result, IsOk());
3604     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3605 
3606     c->result =
3607         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3608     base::RunLoop().RunUntilIdle();
3609 
3610     // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns
3611     // true.
3612     const int kBufferSize = 5;
3613     scoped_refptr<IOBuffer> buffer =
3614         base::MakeRefCounted<IOBuffer>(kBufferSize);
3615     ReleaseBufferCompletionCallback cb(buffer.get());
3616     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3617     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3618 
3619     std::string data_read(buffer->data(), kBufferSize);
3620     first_read = data_read;
3621 
3622     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3623   }
3624 
3625   // 2nd transaction requests ranges 30-49.
3626   transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
3627   MockHttpRequest request2(transaction);
3628   {
3629     auto& c = context_list[1];
3630     c->result = cache.CreateTransaction(&c->trans);
3631     ASSERT_THAT(c->result, IsOk());
3632     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3633 
3634     c->result =
3635         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3636     base::RunLoop().RunUntilIdle();
3637 
3638     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3639   }
3640 
3641   std::string cache_key = request1.CacheKey();
3642   EXPECT_TRUE(cache.IsWriterPresent(cache_key));
3643   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
3644 
3645   // Should have created another transaction for the uncached range.
3646   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3647   EXPECT_EQ(0, cache.disk_cache()->open_count());
3648   EXPECT_EQ(1, cache.disk_cache()->create_count());
3649 
3650   for (int i = 0; i < kNumTransactions; ++i) {
3651     auto& c = context_list[i];
3652     if (c->result == ERR_IO_PENDING)
3653       c->result = c->callback.WaitForResult();
3654 
3655     if (i == 0) {
3656       ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
3657                                         transaction);
3658       continue;
3659     }
3660 
3661     transaction.data = "rg: 30-39 rg: 40-49 ";
3662     ReadAndVerifyTransaction(c->trans.get(), transaction);
3663   }
3664 
3665   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3666   EXPECT_EQ(0, cache.disk_cache()->open_count());
3667   EXPECT_EQ(1, cache.disk_cache()->create_count());
3668 
3669   // Fetch from the cache to check that ranges 30-49 have been successfully
3670   // cached.
3671   {
3672     MockTransaction range_transaction(kRangeGET_TransactionOK);
3673     range_transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
3674     range_transaction.data = "rg: 30-39 rg: 40-49 ";
3675     std::string headers;
3676     RunTransactionTestWithResponse(cache.http_cache(), range_transaction,
3677                                    &headers);
3678     Verify206Response(headers, 30, 49);
3679   }
3680 
3681   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3682   EXPECT_EQ(0, cache.disk_cache()->open_count());
3683   EXPECT_EQ(1, cache.disk_cache()->create_count());
3684 }
3685 
3686 // Tests parallel validation on range requests with overlapping ranges and the
3687 // impact of deleting the writer on transactions that have validated.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationRestartDoneHeaders)3688 TEST_F(HttpCacheTest, RangeGET_ParallelValidationRestartDoneHeaders) {
3689   MockHttpCache cache;
3690 
3691   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3692 
3693   std::vector<std::unique_ptr<Context>> context_list;
3694   const int kNumTransactions = 2;
3695 
3696   for (int i = 0; i < kNumTransactions; ++i) {
3697     context_list.push_back(std::make_unique<Context>());
3698   }
3699 
3700   // Let 1st transaction complete headers phase for ranges 40-59.
3701   std::string first_read;
3702   transaction.request_headers = "Range: bytes = 40-59\r\n" EXTRA_HEADER;
3703   MockHttpRequest request1(transaction);
3704   {
3705     auto& c = context_list[0];
3706     c->result = cache.CreateTransaction(&c->trans);
3707     ASSERT_THAT(c->result, IsOk());
3708     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3709 
3710     c->result =
3711         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3712     base::RunLoop().RunUntilIdle();
3713 
3714     // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns
3715     // true.
3716     const int kBufferSize = 10;
3717     scoped_refptr<IOBuffer> buffer =
3718         base::MakeRefCounted<IOBuffer>(kBufferSize);
3719     ReleaseBufferCompletionCallback cb(buffer.get());
3720     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3721     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3722 
3723     std::string data_read(buffer->data(), kBufferSize);
3724     first_read = data_read;
3725 
3726     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3727   }
3728 
3729   // 2nd transaction requests ranges 30-59.
3730   transaction.request_headers = "Range: bytes = 30-59\r\n" EXTRA_HEADER;
3731   MockHttpRequest request2(transaction);
3732   {
3733     auto& c = context_list[1];
3734     c->result = cache.CreateTransaction(&c->trans);
3735     ASSERT_THAT(c->result, IsOk());
3736     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3737 
3738     c->result =
3739         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3740     base::RunLoop().RunUntilIdle();
3741 
3742     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3743   }
3744 
3745   std::string cache_key = request1.CacheKey();
3746   EXPECT_TRUE(cache.IsWriterPresent(cache_key));
3747   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
3748 
3749   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3750   EXPECT_EQ(0, cache.disk_cache()->open_count());
3751   EXPECT_EQ(1, cache.disk_cache()->create_count());
3752 
3753   // Delete the writer transaction.
3754   context_list[0].reset();
3755 
3756   base::RunLoop().RunUntilIdle();
3757 
3758   transaction.data = "rg: 30-39 rg: 40-49 rg: 50-59 ";
3759   ReadAndVerifyTransaction(context_list[1]->trans.get(), transaction);
3760 
3761   // Create another network transaction since the 2nd transaction is restarted.
3762   // 30-39 will be read from network, 40-49 from the cache and 50-59 from the
3763   // network.
3764   EXPECT_EQ(4, cache.network_layer()->transaction_count());
3765   EXPECT_EQ(0, cache.disk_cache()->open_count());
3766   EXPECT_EQ(1, cache.disk_cache()->create_count());
3767 
3768   // Fetch from the cache to check that ranges 30-49 have been successfully
3769   // cached.
3770   {
3771     MockTransaction range_transaction(kRangeGET_TransactionOK);
3772     range_transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
3773     range_transaction.data = "rg: 30-39 rg: 40-49 ";
3774     std::string headers;
3775     RunTransactionTestWithResponse(cache.http_cache(), range_transaction,
3776                                    &headers);
3777     Verify206Response(headers, 30, 49);
3778   }
3779 
3780   EXPECT_EQ(4, cache.network_layer()->transaction_count());
3781   EXPECT_EQ(1, cache.disk_cache()->open_count());
3782   EXPECT_EQ(1, cache.disk_cache()->create_count());
3783 }
3784 
3785 // A test of doing a range request to a cached 301 response
TEST_F(HttpCacheTest,RangeGET_CachedRedirect)3786 TEST_F(HttpCacheTest, RangeGET_CachedRedirect) {
3787   RangeTransactionServer handler;
3788   handler.set_redirect(true);
3789 
3790   MockHttpCache cache;
3791   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3792   transaction.request_headers = "Range: bytes = 0-\r\n" EXTRA_HEADER;
3793   transaction.status = "HTTP/1.1 301 Moved Permanently";
3794   transaction.response_headers = "Location: /elsewhere\nContent-Length:5";
3795   transaction.data = "12345";
3796   MockHttpRequest request(transaction);
3797 
3798   TestCompletionCallback callback;
3799 
3800   // Write to the cache.
3801   {
3802     std::unique_ptr<HttpTransaction> trans;
3803     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
3804 
3805     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
3806     if (rv == ERR_IO_PENDING)
3807       rv = callback.WaitForResult();
3808     ASSERT_THAT(rv, IsOk());
3809 
3810     const HttpResponseInfo* info = trans->GetResponseInfo();
3811     ASSERT_TRUE(info);
3812 
3813     EXPECT_EQ(info->headers->response_code(), 301);
3814 
3815     std::string location;
3816     info->headers->EnumerateHeader(nullptr, "Location", &location);
3817     EXPECT_EQ(location, "/elsewhere");
3818 
3819     ReadAndVerifyTransaction(trans.get(), transaction);
3820   }
3821   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3822   EXPECT_EQ(0, cache.disk_cache()->open_count());
3823   EXPECT_EQ(1, cache.disk_cache()->create_count());
3824 
3825   // Active entries in the cache are not retired synchronously. Make
3826   // sure the next run hits the MockHttpCache and open_count is
3827   // correct.
3828   base::RunLoop().RunUntilIdle();
3829 
3830   // Read from the cache.
3831   {
3832     std::unique_ptr<HttpTransaction> trans;
3833     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
3834 
3835     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
3836     if (rv == ERR_IO_PENDING)
3837       rv = callback.WaitForResult();
3838     ASSERT_THAT(rv, IsOk());
3839 
3840     const HttpResponseInfo* info = trans->GetResponseInfo();
3841     ASSERT_TRUE(info);
3842 
3843     EXPECT_EQ(info->headers->response_code(), 301);
3844 
3845     std::string location;
3846     info->headers->EnumerateHeader(nullptr, "Location", &location);
3847     EXPECT_EQ(location, "/elsewhere");
3848 
3849     trans->DoneReading();
3850   }
3851   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3852   EXPECT_EQ(1, cache.disk_cache()->open_count());
3853   EXPECT_EQ(1, cache.disk_cache()->create_count());
3854 
3855   // Now read the full body. This normally would not be done for a 301 by
3856   // higher layers, but e.g. a 500 could hit a further bug here.
3857   {
3858     std::unique_ptr<HttpTransaction> trans;
3859     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
3860 
3861     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
3862     if (rv == ERR_IO_PENDING)
3863       rv = callback.WaitForResult();
3864     ASSERT_THAT(rv, IsOk());
3865 
3866     const HttpResponseInfo* info = trans->GetResponseInfo();
3867     ASSERT_TRUE(info);
3868 
3869     EXPECT_EQ(info->headers->response_code(), 301);
3870 
3871     std::string location;
3872     info->headers->EnumerateHeader(nullptr, "Location", &location);
3873     EXPECT_EQ(location, "/elsewhere");
3874 
3875     ReadAndVerifyTransaction(trans.get(), transaction);
3876   }
3877   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3878   // No extra open since it picks up a previous ActiveEntry.
3879   EXPECT_EQ(1, cache.disk_cache()->open_count());
3880   EXPECT_EQ(1, cache.disk_cache()->create_count());
3881 }
3882 
3883 // A transaction that fails to validate an entry, while attempting to write
3884 // the response, should still get data to its consumer even if the attempt to
3885 // create a new entry fails.
TEST_F(HttpCacheTest,SimpleGET_ValidationFailureWithCreateFailure)3886 TEST_F(HttpCacheTest, SimpleGET_ValidationFailureWithCreateFailure) {
3887   MockHttpCache cache;
3888   MockHttpRequest request(kSimpleGET_Transaction);
3889   request.load_flags |= LOAD_VALIDATE_CACHE;
3890   std::vector<std::unique_ptr<Context>> context_list;
3891 
3892   // Create and run the first, successful, transaction to prime the cache.
3893   context_list.push_back(std::make_unique<Context>());
3894   auto& c1 = context_list.back();
3895   c1->result = cache.CreateTransaction(&c1->trans);
3896   ASSERT_THAT(c1->result, IsOk());
3897   EXPECT_EQ(LOAD_STATE_IDLE, c1->trans->GetLoadState());
3898   c1->result =
3899       c1->trans->Start(&request, c1->callback.callback(), NetLogWithSource());
3900   EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, c1->trans->GetLoadState());
3901   base::RunLoop().RunUntilIdle();
3902 
3903   EXPECT_TRUE(cache.IsWriterPresent(request.CacheKey()));
3904   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3905   EXPECT_EQ(0, cache.disk_cache()->open_count());
3906   EXPECT_EQ(1, cache.disk_cache()->create_count());
3907 
3908   // Create and start the second transaction, which will fail its validation
3909   // during the call to RunUntilIdle().
3910   context_list.push_back(std::make_unique<Context>());
3911   auto& c2 = context_list.back();
3912   c2->result = cache.CreateTransaction(&c2->trans);
3913   ASSERT_THAT(c2->result, IsOk());
3914   EXPECT_EQ(LOAD_STATE_IDLE, c2->trans->GetLoadState());
3915   c2->result =
3916       c2->trans->Start(&request, c2->callback.callback(), NetLogWithSource());
3917   // Expect idle at this point because we should be able to find and use the
3918   // Active Entry that c1 created instead of waiting on the cache to open the
3919   // entry.
3920   EXPECT_EQ(LOAD_STATE_IDLE, c2->trans->GetLoadState());
3921 
3922   cache.disk_cache()->set_fail_requests(true);
3923   // The transaction, c2, should now attempt to validate the entry, fail when it
3924   // receives a 200 OK response, attempt to create a new entry, fail to create,
3925   // and then continue onward without an entry.
3926   base::RunLoop().RunUntilIdle();
3927 
3928   // All requests depend on the writer, and the writer is between Start and
3929   // Read, i.e. idle.
3930   for (auto& context : context_list) {
3931     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
3932   }
3933 
3934   // Confirm that both transactions correctly Read() the data.
3935   for (auto& context : context_list) {
3936     if (context->result == ERR_IO_PENDING)
3937       context->result = context->callback.WaitForResult();
3938     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
3939   }
3940 
3941   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3942   EXPECT_EQ(0, cache.disk_cache()->open_count());
3943   EXPECT_EQ(1, cache.disk_cache()->create_count());
3944 }
3945 
3946 // Parallel validation results in 200.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationNoMatch)3947 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationNoMatch) {
3948   MockHttpCache cache;
3949   MockHttpRequest request(kSimpleGET_Transaction);
3950   request.load_flags |= LOAD_VALIDATE_CACHE;
3951   std::vector<std::unique_ptr<Context>> context_list;
3952   const int kNumTransactions = 5;
3953   for (int i = 0; i < kNumTransactions; ++i) {
3954     context_list.push_back(std::make_unique<Context>());
3955     auto& c = context_list[i];
3956     c->result = cache.CreateTransaction(&c->trans);
3957     ASSERT_THAT(c->result, IsOk());
3958     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3959     c->result =
3960         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
3961   }
3962 
3963   // All requests are waiting for the active entry.
3964   for (auto& context : context_list) {
3965     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
3966   }
3967 
3968   // Allow all requests to move from the Create queue to the active entry.
3969   base::RunLoop().RunUntilIdle();
3970 
3971   // The first request should be a writer at this point, and the subsequent
3972   // requests should have passed the validation phase and created their own
3973   // entries since none of them matched the headers of the earlier one.
3974   EXPECT_TRUE(cache.IsWriterPresent(request.CacheKey()));
3975 
3976   EXPECT_EQ(5, cache.network_layer()->transaction_count());
3977   EXPECT_EQ(0, cache.disk_cache()->open_count());
3978   EXPECT_EQ(5, cache.disk_cache()->create_count());
3979 
3980   // All requests depend on the writer, and the writer is between Start and
3981   // Read, i.e. idle.
3982   for (auto& context : context_list) {
3983     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
3984   }
3985 
3986   for (auto& context : context_list) {
3987     if (context->result == ERR_IO_PENDING)
3988       context->result = context->callback.WaitForResult();
3989     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
3990   }
3991 
3992   EXPECT_EQ(5, cache.network_layer()->transaction_count());
3993   EXPECT_EQ(0, cache.disk_cache()->open_count());
3994   EXPECT_EQ(5, cache.disk_cache()->create_count());
3995 }
3996 
TEST_F(HttpCacheTest,RangeGET_Enormous)3997 TEST_F(HttpCacheTest, RangeGET_Enormous) {
3998   // Test for how blockfile's limit on range namespace interacts with
3999   // HttpCache::Transaction.
4000   // See https://crbug.com/770694
4001   base::ScopedTempDir temp_dir;
4002   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
4003 
4004   auto backend_factory = std::make_unique<HttpCache::DefaultBackend>(
4005       DISK_CACHE, CACHE_BACKEND_BLOCKFILE,
4006       /*file_operations_factory=*/nullptr, temp_dir.GetPath(), 1024 * 1024,
4007       false);
4008   MockHttpCache cache(std::move(backend_factory));
4009 
4010   RangeTransactionServer handler;
4011   handler.set_length(2305843009213693962);
4012 
4013   // Prime with a range it can store.
4014   {
4015     ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4016     transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
4017     transaction.data = "rg: 00-09 ";
4018     MockHttpRequest request(transaction);
4019 
4020     HttpResponseInfo response;
4021     RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
4022                                   &response);
4023     ASSERT_TRUE(response.headers != nullptr);
4024     EXPECT_EQ(206, response.headers->response_code());
4025     EXPECT_EQ(1, cache.network_layer()->transaction_count());
4026   }
4027 
4028   // Try with a range it can't. Should still work.
4029   {
4030     ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4031     transaction.request_headers =
4032         "Range: bytes = "
4033         "2305843009213693952-2305843009213693961\r\n" EXTRA_HEADER;
4034     transaction.data = "rg: 52-61 ";
4035     MockHttpRequest request(transaction);
4036 
4037     HttpResponseInfo response;
4038     RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
4039                                   &response);
4040     ASSERT_TRUE(response.headers != nullptr);
4041     EXPECT_EQ(206, response.headers->response_code());
4042     EXPECT_EQ(2, cache.network_layer()->transaction_count());
4043   }
4044 
4045   // Can't actually cache it due to backend limitations. If the network
4046   // transaction count is 2, this test isn't covering what it needs to.
4047   {
4048     ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4049     transaction.request_headers =
4050         "Range: bytes = "
4051         "2305843009213693952-2305843009213693961\r\n" EXTRA_HEADER;
4052     transaction.data = "rg: 52-61 ";
4053     MockHttpRequest request(transaction);
4054 
4055     HttpResponseInfo response;
4056     RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
4057                                   &response);
4058     ASSERT_TRUE(response.headers != nullptr);
4059     EXPECT_EQ(206, response.headers->response_code());
4060     EXPECT_EQ(3, cache.network_layer()->transaction_count());
4061   }
4062 }
4063 
4064 // Parallel validation results in 200 for 1 transaction and validation matches
4065 // for subsequent transactions.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationNoMatch1)4066 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationNoMatch1) {
4067   MockHttpCache cache;
4068   MockHttpRequest request(kSimpleGET_Transaction);
4069 
4070   MockTransaction transaction(kSimpleGET_Transaction);
4071   transaction.load_flags |= LOAD_VALIDATE_CACHE;
4072   MockHttpRequest validate_request(transaction);
4073   std::vector<std::unique_ptr<Context>> context_list;
4074   const int kNumTransactions = 5;
4075   for (int i = 0; i < kNumTransactions; ++i) {
4076     context_list.push_back(std::make_unique<Context>());
4077     auto& c = context_list[i];
4078     c->result = cache.CreateTransaction(&c->trans);
4079     ASSERT_THAT(c->result, IsOk());
4080     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
4081 
4082     MockHttpRequest* this_request = &request;
4083     if (i == 1)
4084       this_request = &validate_request;
4085 
4086     c->result = c->trans->Start(this_request, c->callback.callback(),
4087                                 NetLogWithSource());
4088   }
4089 
4090   // All requests are waiting for the active entry.
4091   for (auto& context : context_list) {
4092     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
4093   }
4094 
4095   // Allow all requests to move from the Create queue to the active entry.
4096   base::RunLoop().RunUntilIdle();
4097 
4098   // The new entry will have all the transactions except the first one which
4099   // will continue in the doomed entry.
4100   EXPECT_EQ(kNumTransactions - 1,
4101             cache.GetCountWriterTransactions(validate_request.CacheKey()));
4102 
4103   EXPECT_EQ(1, cache.disk_cache()->doomed_count());
4104 
4105   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4106   EXPECT_EQ(0, cache.disk_cache()->open_count());
4107   EXPECT_EQ(2, cache.disk_cache()->create_count());
4108 
4109   for (auto& context : context_list) {
4110     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
4111   }
4112 
4113   for (auto& context : context_list) {
4114     if (context->result == ERR_IO_PENDING)
4115       context->result = context->callback.WaitForResult();
4116 
4117     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
4118   }
4119 
4120   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4121   EXPECT_EQ(0, cache.disk_cache()->open_count());
4122   EXPECT_EQ(2, cache.disk_cache()->create_count());
4123 }
4124 
4125 // Tests that a GET followed by a DELETE results in DELETE immediately starting
4126 // the headers phase and the entry is doomed.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationDelete)4127 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationDelete) {
4128   MockHttpCache cache;
4129 
4130   MockHttpRequest request(kSimpleGET_Transaction);
4131   request.load_flags |= LOAD_VALIDATE_CACHE;
4132 
4133   MockHttpRequest delete_request(kSimpleGET_Transaction);
4134   delete_request.method = "DELETE";
4135 
4136   std::vector<std::unique_ptr<Context>> context_list;
4137   const int kNumTransactions = 2;
4138 
4139   for (int i = 0; i < kNumTransactions; ++i) {
4140     context_list.push_back(std::make_unique<Context>());
4141     auto& c = context_list[i];
4142 
4143     MockHttpRequest* this_request = &request;
4144     if (i == 1)
4145       this_request = &delete_request;
4146 
4147     c->result = cache.CreateTransaction(&c->trans);
4148     ASSERT_THAT(c->result, IsOk());
4149     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
4150 
4151     c->result = c->trans->Start(this_request, c->callback.callback(),
4152                                 NetLogWithSource());
4153   }
4154 
4155   // All requests are waiting for the active entry.
4156   for (auto& context : context_list) {
4157     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
4158   }
4159 
4160   // Allow all requests to move from the Create queue to the active entry.
4161   base::RunLoop().RunUntilIdle();
4162 
4163   // The first request should be a writer at this point, and the subsequent
4164   // request should have passed the validation phase and doomed the existing
4165   // entry.
4166   EXPECT_TRUE(cache.disk_cache()->IsDiskEntryDoomed(request.CacheKey()));
4167 
4168   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4169   EXPECT_EQ(0, cache.disk_cache()->open_count());
4170   EXPECT_EQ(1, cache.disk_cache()->create_count());
4171 
4172   // All requests depend on the writer, and the writer is between Start and
4173   // Read, i.e. idle.
4174   for (auto& context : context_list) {
4175     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
4176   }
4177 
4178   for (auto& context : context_list) {
4179     if (context->result == ERR_IO_PENDING)
4180       context->result = context->callback.WaitForResult();
4181     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
4182   }
4183 
4184   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4185   EXPECT_EQ(0, cache.disk_cache()->open_count());
4186   EXPECT_EQ(1, cache.disk_cache()->create_count());
4187 }
4188 
4189 // Tests that a transaction which is in validated queue can be destroyed without
4190 // any impact to other transactions.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationCancelValidated)4191 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationCancelValidated) {
4192   MockHttpCache cache;
4193 
4194   MockHttpRequest request(kSimpleGET_Transaction);
4195 
4196   MockTransaction transaction(kSimpleGET_Transaction);
4197   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
4198   MockHttpRequest read_only_request(transaction);
4199 
4200   std::vector<std::unique_ptr<Context>> context_list;
4201   const int kNumTransactions = 2;
4202 
4203   for (int i = 0; i < kNumTransactions; ++i) {
4204     context_list.push_back(std::make_unique<Context>());
4205     auto& c = context_list[i];
4206 
4207     c->result = cache.CreateTransaction(&c->trans);
4208     ASSERT_THAT(c->result, IsOk());
4209 
4210     MockHttpRequest* current_request = i == 1 ? &read_only_request : &request;
4211 
4212     c->result = c->trans->Start(current_request, c->callback.callback(),
4213                                 NetLogWithSource());
4214   }
4215 
4216   // Allow all requests to move from the Create queue to the active entry.
4217   base::RunLoop().RunUntilIdle();
4218 
4219   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4220   EXPECT_EQ(0, cache.disk_cache()->open_count());
4221   EXPECT_EQ(1, cache.disk_cache()->create_count());
4222 
4223   std::string cache_key = request.CacheKey();
4224   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
4225   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
4226 
4227   context_list[1].reset();
4228 
4229   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(cache_key));
4230 
4231   // Complete the rest of the transactions.
4232   for (auto& context : context_list) {
4233     if (!context)
4234       continue;
4235     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
4236   }
4237 
4238   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4239   EXPECT_EQ(0, cache.disk_cache()->open_count());
4240   EXPECT_EQ(1, cache.disk_cache()->create_count());
4241 }
4242 
4243 // Tests that an idle writer transaction can be deleted without impacting the
4244 // existing writers.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingCancelIdleTransaction)4245 TEST_F(HttpCacheTest, SimpleGET_ParallelWritingCancelIdleTransaction) {
4246   MockHttpCache cache;
4247 
4248   MockHttpRequest request(kSimpleGET_Transaction);
4249 
4250   std::vector<std::unique_ptr<Context>> context_list;
4251   const int kNumTransactions = 2;
4252 
4253   for (int i = 0; i < kNumTransactions; ++i) {
4254     context_list.push_back(std::make_unique<Context>());
4255     auto& c = context_list[i];
4256 
4257     c->result = cache.CreateTransaction(&c->trans);
4258     ASSERT_THAT(c->result, IsOk());
4259 
4260     c->result =
4261         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
4262   }
4263 
4264   // Allow all requests to move from the Create queue to the active entry.
4265   base::RunLoop().RunUntilIdle();
4266 
4267   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4268   EXPECT_EQ(0, cache.disk_cache()->open_count());
4269   EXPECT_EQ(1, cache.disk_cache()->create_count());
4270 
4271   // Both transactions would be added to writers.
4272   std::string cache_key = request.CacheKey();
4273   EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
4274 
4275   context_list[1].reset();
4276 
4277   EXPECT_EQ(kNumTransactions - 1, cache.GetCountWriterTransactions(cache_key));
4278 
4279   // Complete the rest of the transactions.
4280   for (auto& context : context_list) {
4281     if (!context)
4282       continue;
4283     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
4284   }
4285 
4286   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4287   EXPECT_EQ(0, cache.disk_cache()->open_count());
4288   EXPECT_EQ(1, cache.disk_cache()->create_count());
4289 }
4290 
4291 // Tests that a transaction which is in validated queue can timeout and start
4292 // the headers phase again.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationValidatedTimeout)4293 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationValidatedTimeout) {
4294   MockHttpCache cache;
4295 
4296   MockHttpRequest request(kSimpleGET_Transaction);
4297 
4298   MockTransaction transaction(kSimpleGET_Transaction);
4299   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
4300   MockHttpRequest read_only_request(transaction);
4301 
4302   std::vector<std::unique_ptr<Context>> context_list;
4303   const int kNumTransactions = 2;
4304 
4305   for (int i = 0; i < kNumTransactions; ++i) {
4306     context_list.push_back(std::make_unique<Context>());
4307     auto& c = context_list[i];
4308 
4309     MockHttpRequest* this_request = &request;
4310     if (i == 1) {
4311       this_request = &read_only_request;
4312       cache.SimulateCacheLockTimeoutAfterHeaders();
4313     }
4314 
4315     c->result = cache.CreateTransaction(&c->trans);
4316     ASSERT_THAT(c->result, IsOk());
4317 
4318     c->result = c->trans->Start(this_request, c->callback.callback(),
4319                                 NetLogWithSource());
4320   }
4321 
4322   // Allow all requests to move from the Create queue to the active entry.
4323   base::RunLoop().RunUntilIdle();
4324 
4325   // The first request should be a writer at this point, and the subsequent
4326   // requests should have completed validation, timed out and restarted.
4327   // Since it is a read only request, it will error out.
4328 
4329   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4330   EXPECT_EQ(0, cache.disk_cache()->open_count());
4331   EXPECT_EQ(1, cache.disk_cache()->create_count());
4332 
4333   std::string cache_key = request.CacheKey();
4334   EXPECT_TRUE(cache.IsWriterPresent(cache_key));
4335   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(cache_key));
4336 
4337   base::RunLoop().RunUntilIdle();
4338 
4339   int rv = context_list[1]->callback.WaitForResult();
4340   EXPECT_EQ(ERR_CACHE_MISS, rv);
4341 
4342   ReadAndVerifyTransaction(context_list[0]->trans.get(),
4343                            kSimpleGET_Transaction);
4344 }
4345 
4346 // Tests that a transaction which is in readers can be destroyed without
4347 // any impact to other transactions.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationCancelReader)4348 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationCancelReader) {
4349   MockHttpCache cache;
4350 
4351   MockHttpRequest request(kSimpleGET_Transaction);
4352 
4353   MockTransaction transaction(kSimpleGET_Transaction);
4354   transaction.load_flags |= LOAD_VALIDATE_CACHE;
4355   MockHttpRequest validate_request(transaction);
4356 
4357   int kNumTransactions = 4;
4358   std::vector<std::unique_ptr<Context>> context_list;
4359 
4360   for (int i = 0; i < kNumTransactions; ++i) {
4361     context_list.push_back(std::make_unique<Context>());
4362     auto& c = context_list[i];
4363 
4364     c->result = cache.CreateTransaction(&c->trans);
4365     ASSERT_THAT(c->result, IsOk());
4366 
4367     MockHttpRequest* this_request = &request;
4368     if (i == 3) {
4369       this_request = &validate_request;
4370       c->trans->SetBeforeNetworkStartCallback(base::BindOnce(&DeferCallback));
4371     }
4372 
4373     c->result = c->trans->Start(this_request, c->callback.callback(),
4374                                 NetLogWithSource());
4375   }
4376 
4377   // Allow all requests to move from the Create queue to the active entry.
4378   base::RunLoop().RunUntilIdle();
4379 
4380   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4381   EXPECT_EQ(0, cache.disk_cache()->open_count());
4382   EXPECT_EQ(1, cache.disk_cache()->create_count());
4383 
4384   std::string cache_key = request.CacheKey();
4385 
4386   EXPECT_EQ(kNumTransactions - 1, cache.GetCountWriterTransactions(cache_key));
4387   EXPECT_TRUE(cache.IsHeadersTransactionPresent(cache_key));
4388 
4389   // Complete the response body.
4390   ReadAndVerifyTransaction(context_list[0]->trans.get(),
4391                            kSimpleGET_Transaction);
4392 
4393   // Rest of the transactions should move to readers.
4394   EXPECT_FALSE(cache.IsWriterPresent(cache_key));
4395   EXPECT_EQ(kNumTransactions - 2, cache.GetCountReaders(cache_key));
4396   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(cache_key));
4397   EXPECT_TRUE(cache.IsHeadersTransactionPresent(cache_key));
4398 
4399   // Add 2 new transactions.
4400   kNumTransactions = 6;
4401 
4402   for (int i = 4; i < kNumTransactions; ++i) {
4403     context_list.push_back(std::make_unique<Context>());
4404     auto& c = context_list[i];
4405 
4406     c->result = cache.CreateTransaction(&c->trans);
4407     ASSERT_THAT(c->result, IsOk());
4408 
4409     c->result =
4410         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
4411   }
4412 
4413   EXPECT_EQ(2, cache.GetCountAddToEntryQueue(cache_key));
4414 
4415   // Delete a reader.
4416   context_list[1].reset();
4417 
4418   // Deleting the reader did not impact any other transaction.
4419   EXPECT_EQ(1, cache.GetCountReaders(cache_key));
4420   EXPECT_EQ(2, cache.GetCountAddToEntryQueue(cache_key));
4421   EXPECT_TRUE(cache.IsHeadersTransactionPresent(cache_key));
4422 
4423   // Resume network start for headers_transaction. It will doom the entry as it
4424   // will be a 200 and will go to network for the response body.
4425   context_list[3]->trans->ResumeNetworkStart();
4426 
4427   // The pending transactions will be added to a new entry as writers.
4428   base::RunLoop().RunUntilIdle();
4429 
4430   EXPECT_EQ(3, cache.GetCountWriterTransactions(cache_key));
4431 
4432   // Complete the rest of the transactions.
4433   for (int i = 2; i < kNumTransactions; ++i) {
4434     ReadAndVerifyTransaction(context_list[i]->trans.get(),
4435                              kSimpleGET_Transaction);
4436   }
4437 
4438   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4439   EXPECT_EQ(0, cache.disk_cache()->open_count());
4440   EXPECT_EQ(2, cache.disk_cache()->create_count());
4441 }
4442 
4443 // Tests that when the only writer goes away, it immediately cleans up rather
4444 // than wait for the network request to finish. See https://crbug.com/804868.
TEST_F(HttpCacheTest,SimpleGET_HangingCacheWriteCleanup)4445 TEST_F(HttpCacheTest, SimpleGET_HangingCacheWriteCleanup) {
4446   MockHttpCache mock_cache;
4447   MockHttpRequest request(kSimpleGET_Transaction);
4448 
4449   std::unique_ptr<HttpTransaction> transaction;
4450   mock_cache.CreateTransaction(&transaction);
4451   TestCompletionCallback callback;
4452   int result =
4453       transaction->Start(&request, callback.callback(), NetLogWithSource());
4454 
4455   // Get the transaction ready to read.
4456   result = callback.GetResult(result);
4457 
4458   // Read the first byte.
4459   scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<IOBuffer>(1);
4460   ReleaseBufferCompletionCallback buffer_callback(buffer.get());
4461   result = transaction->Read(buffer.get(), 1, buffer_callback.callback());
4462   EXPECT_EQ(1, buffer_callback.GetResult(result));
4463 
4464   // Read the second byte, but leave the cache write hanging.
4465   std::string cache_key = request.CacheKey();
4466   scoped_refptr<MockDiskEntry> entry =
4467       mock_cache.disk_cache()->GetDiskEntryRef(cache_key);
4468   entry->SetDefer(MockDiskEntry::DEFER_WRITE);
4469 
4470   buffer = base::MakeRefCounted<IOBuffer>(1);
4471   ReleaseBufferCompletionCallback buffer_callback2(buffer.get());
4472   result = transaction->Read(buffer.get(), 1, buffer_callback2.callback());
4473   EXPECT_EQ(ERR_IO_PENDING, result);
4474   base::RunLoop().RunUntilIdle();
4475   EXPECT_TRUE(mock_cache.IsWriterPresent(cache_key));
4476 
4477   // At this point the next byte should have been read from the network but is
4478   // waiting to be written to the cache. Destroy the transaction and make sure
4479   // that everything has been cleaned up.
4480   transaction = nullptr;
4481   EXPECT_FALSE(mock_cache.IsWriterPresent(cache_key));
4482   EXPECT_FALSE(mock_cache.network_layer()->last_transaction());
4483 }
4484 
4485 // Tests that a transaction writer can be destroyed mid-read.
4486 // A waiting for read transaction should be able to read the data that was
4487 // driven by the Read started by the cancelled writer.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingCancelWriter)4488 TEST_F(HttpCacheTest, SimpleGET_ParallelWritingCancelWriter) {
4489   MockHttpCache cache;
4490 
4491   MockHttpRequest request(kSimpleGET_Transaction);
4492 
4493   MockTransaction transaction(kSimpleGET_Transaction);
4494   transaction.load_flags |= LOAD_VALIDATE_CACHE;
4495   MockHttpRequest validate_request(transaction);
4496 
4497   const int kNumTransactions = 3;
4498   std::vector<std::unique_ptr<Context>> context_list;
4499 
4500   for (int i = 0; i < kNumTransactions; ++i) {
4501     context_list.push_back(std::make_unique<Context>());
4502     auto& c = context_list[i];
4503 
4504     c->result = cache.CreateTransaction(&c->trans);
4505     ASSERT_THAT(c->result, IsOk());
4506 
4507     MockHttpRequest* this_request = &request;
4508     if (i == 2) {
4509       this_request = &validate_request;
4510       c->trans->SetBeforeNetworkStartCallback(base::BindOnce(&DeferCallback));
4511     }
4512 
4513     c->result = c->trans->Start(this_request, c->callback.callback(),
4514                                 NetLogWithSource());
4515   }
4516 
4517   // Allow all requests to move from the Create queue to the active entry.
4518   base::RunLoop().RunUntilIdle();
4519 
4520   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4521   EXPECT_EQ(0, cache.disk_cache()->open_count());
4522   EXPECT_EQ(1, cache.disk_cache()->create_count());
4523 
4524   std::string cache_key = validate_request.CacheKey();
4525   EXPECT_TRUE(cache.IsHeadersTransactionPresent(cache_key));
4526   EXPECT_EQ(2, cache.GetCountWriterTransactions(cache_key));
4527 
4528   // Initiate Read from both writers and kill 1 of them mid-read.
4529   std::string first_read;
4530   for (int i = 0; i < 2; i++) {
4531     auto& c = context_list[i];
4532     const int kBufferSize = 5;
4533     scoped_refptr<IOBuffer> buffer =
4534         base::MakeRefCounted<IOBuffer>(kBufferSize);
4535     ReleaseBufferCompletionCallback cb(buffer.get());
4536     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
4537     EXPECT_EQ(ERR_IO_PENDING, c->result);
4538     // Deleting one writer at this point will not impact other transactions
4539     // since writers contain more transactions.
4540     if (i == 1) {
4541       context_list[0].reset();
4542       base::RunLoop().RunUntilIdle();
4543       EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
4544       std::string data_read(buffer->data(), kBufferSize);
4545       first_read = data_read;
4546     }
4547   }
4548 
4549   // Resume network start for headers_transaction. It will doom the existing
4550   // entry and create a new entry due to validation returning a 200.
4551   auto& c = context_list[2];
4552   c->trans->ResumeNetworkStart();
4553 
4554   base::RunLoop().RunUntilIdle();
4555 
4556   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
4557 
4558   // Complete the rest of the transactions.
4559   for (int i = 0; i < kNumTransactions; i++) {
4560     auto& context = context_list[i];
4561     if (!context)
4562       continue;
4563     if (i == 1)
4564       ReadRemainingAndVerifyTransaction(context->trans.get(), first_read,
4565                                         kSimpleGET_Transaction);
4566     else
4567       ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
4568   }
4569 
4570   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4571   EXPECT_EQ(0, cache.disk_cache()->open_count());
4572   EXPECT_EQ(2, cache.disk_cache()->create_count());
4573 }
4574 
4575 // Tests the case when network read failure happens. Idle and waiting
4576 // transactions should fail and headers transaction should be restarted.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingNetworkReadFailed)4577 TEST_F(HttpCacheTest, SimpleGET_ParallelWritingNetworkReadFailed) {
4578   MockHttpCache cache;
4579 
4580   ScopedMockTransaction fail_transaction(kSimpleGET_Transaction);
4581   fail_transaction.read_return_code = ERR_INTERNET_DISCONNECTED;
4582   MockHttpRequest failing_request(fail_transaction);
4583 
4584   MockHttpRequest request(kSimpleGET_Transaction);
4585 
4586   MockTransaction transaction(kSimpleGET_Transaction);
4587   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
4588   MockHttpRequest read_request(transaction);
4589 
4590   const int kNumTransactions = 4;
4591   std::vector<std::unique_ptr<Context>> context_list;
4592 
4593   for (int i = 0; i < kNumTransactions; ++i) {
4594     context_list.push_back(std::make_unique<Context>());
4595     auto& c = context_list[i];
4596 
4597     c->result = cache.CreateTransaction(&c->trans);
4598     ASSERT_THAT(c->result, IsOk());
4599 
4600     MockHttpRequest* this_request = &request;
4601     if (i == 0)
4602       this_request = &failing_request;
4603     if (i == 3)
4604       this_request = &read_request;
4605 
4606     c->result = c->trans->Start(this_request, c->callback.callback(),
4607                                 NetLogWithSource());
4608   }
4609 
4610   // Allow all requests to move from the Create queue to the active entry.
4611   base::RunLoop().RunUntilIdle();
4612 
4613   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4614   EXPECT_EQ(0, cache.disk_cache()->open_count());
4615   EXPECT_EQ(1, cache.disk_cache()->create_count());
4616 
4617   std::string cache_key = read_request.CacheKey();
4618   EXPECT_EQ(3, cache.GetCountWriterTransactions(cache_key));
4619   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
4620 
4621   // Initiate Read from two writers and let the first get a network failure.
4622   for (int i = 0; i < 2; i++) {
4623     auto& c = context_list[i];
4624     const int kBufferSize = 5;
4625     scoped_refptr<IOBuffer> buffer =
4626         base::MakeRefCounted<IOBuffer>(kBufferSize);
4627     c->result =
4628         c->trans->Read(buffer.get(), kBufferSize, c->callback.callback());
4629     EXPECT_EQ(ERR_IO_PENDING, c->result);
4630   }
4631 
4632   base::RunLoop().RunUntilIdle();
4633   for (int i = 0; i < 2; i++) {
4634     auto& c = context_list[i];
4635     c->result = c->callback.WaitForResult();
4636     EXPECT_EQ(ERR_INTERNET_DISCONNECTED, c->result);
4637   }
4638 
4639   // The entry should have been doomed and destroyed and the headers transaction
4640   // restarted. Since headers transaction is read-only it will error out.
4641   auto& read_only = context_list[3];
4642   read_only->result = read_only->callback.WaitForResult();
4643   EXPECT_EQ(ERR_CACHE_MISS, read_only->result);
4644 
4645   EXPECT_FALSE(cache.IsWriterPresent(cache_key));
4646 
4647   // Invoke Read on the 3rd transaction and it should get the error code back.
4648   auto& c = context_list[2];
4649   const int kBufferSize = 5;
4650   scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<IOBuffer>(kBufferSize);
4651   c->result = c->trans->Read(buffer.get(), kBufferSize, c->callback.callback());
4652   EXPECT_EQ(ERR_INTERNET_DISCONNECTED, c->result);
4653 }
4654 
4655 // Tests the case when cache write failure happens. Idle and waiting
4656 // transactions should fail and headers transaction should be restarted.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingCacheWriteFailed)4657 TEST_F(HttpCacheTest, SimpleGET_ParallelWritingCacheWriteFailed) {
4658   MockHttpCache cache;
4659 
4660   MockHttpRequest request(kSimpleGET_Transaction);
4661 
4662   MockTransaction transaction(kSimpleGET_Transaction);
4663   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
4664   MockHttpRequest read_request(transaction);
4665 
4666   const int kNumTransactions = 4;
4667   std::vector<std::unique_ptr<Context>> context_list;
4668 
4669   for (int i = 0; i < kNumTransactions; ++i) {
4670     context_list.push_back(std::make_unique<Context>());
4671     auto& c = context_list[i];
4672 
4673     c->result = cache.CreateTransaction(&c->trans);
4674     ASSERT_THAT(c->result, IsOk());
4675 
4676     MockHttpRequest* this_request = &request;
4677     if (i == 3)
4678       this_request = &read_request;
4679 
4680     c->result = c->trans->Start(this_request, c->callback.callback(),
4681                                 NetLogWithSource());
4682   }
4683 
4684   // Allow all requests to move from the Create queue to the active entry.
4685   base::RunLoop().RunUntilIdle();
4686 
4687   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4688   EXPECT_EQ(0, cache.disk_cache()->open_count());
4689   EXPECT_EQ(1, cache.disk_cache()->create_count());
4690 
4691   std::string cache_key = read_request.CacheKey();
4692   EXPECT_EQ(3, cache.GetCountWriterTransactions(cache_key));
4693   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
4694 
4695   // Initiate Read from two writers and let the first get a cache write failure.
4696   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_ALL);
4697   // We have to open the entry again to propagate the failure flag.
4698   disk_cache::Entry* en;
4699   cache.OpenBackendEntry(cache_key, &en);
4700   en->Close();
4701   const int kBufferSize = 5;
4702   std::vector<scoped_refptr<IOBuffer>> buffer(
4703       3, base::MakeRefCounted<IOBuffer>(kBufferSize));
4704   for (int i = 0; i < 2; i++) {
4705     auto& c = context_list[i];
4706     c->result =
4707         c->trans->Read(buffer[i].get(), kBufferSize, c->callback.callback());
4708     EXPECT_EQ(ERR_IO_PENDING, c->result);
4709   }
4710 
4711   std::string first_read;
4712   base::RunLoop().RunUntilIdle();
4713   for (int i = 0; i < 2; i++) {
4714     auto& c = context_list[i];
4715     c->result = c->callback.WaitForResult();
4716     if (i == 0) {
4717       EXPECT_EQ(5, c->result);
4718       std::string data_read(buffer[i]->data(), kBufferSize);
4719       first_read = data_read;
4720     } else {
4721       EXPECT_EQ(ERR_CACHE_WRITE_FAILURE, c->result);
4722     }
4723   }
4724 
4725   // The entry should have been doomed and destroyed and the headers transaction
4726   // restarted. Since headers transaction is read-only it will error out.
4727   auto& read_only = context_list[3];
4728   read_only->result = read_only->callback.WaitForResult();
4729   EXPECT_EQ(ERR_CACHE_MISS, read_only->result);
4730 
4731   EXPECT_FALSE(cache.IsWriterPresent(cache_key));
4732 
4733   // Invoke Read on the 3rd transaction and it should get the error code back.
4734   auto& c = context_list[2];
4735   c->result =
4736       c->trans->Read(buffer[2].get(), kBufferSize, c->callback.callback());
4737   EXPECT_EQ(ERR_CACHE_WRITE_FAILURE, c->result);
4738 
4739   // The first transaction should be able to continue to read from the network
4740   // without writing to the cache.
4741   auto& succ_read = context_list[0];
4742   ReadRemainingAndVerifyTransaction(succ_read->trans.get(), first_read,
4743                                     kSimpleGET_Transaction);
4744 }
4745 
4746 // Tests that POST requests do not join existing transactions for parallel
4747 // writing to the cache. Note that two POSTs only map to the same entry if their
4748 // upload data identifier is same and that should happen for back-forward case
4749 // (LOAD_ONLY_FROM_CACHE). But this test tests without LOAD_ONLY_FROM_CACHE
4750 // because read-only transactions anyways do not join parallel writing.
4751 // TODO(shivanisha) Testing this because it is allowed by the code but looks
4752 // like the code should disallow two POSTs without LOAD_ONLY_FROM_CACHE with the
4753 // same upload data identifier to map to the same entry.
TEST_F(HttpCacheTest,SimplePOST_ParallelWritingDisallowed)4754 TEST_F(HttpCacheTest, SimplePOST_ParallelWritingDisallowed) {
4755   MockHttpCache cache;
4756 
4757   MockTransaction transaction(kSimplePOST_Transaction);
4758 
4759   const int64_t kUploadId = 1;  // Just a dummy value.
4760 
4761   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
4762   element_readers.push_back(
4763       std::make_unique<UploadBytesElementReader>("hello", 5));
4764   ElementsUploadDataStream upload_data_stream(std::move(element_readers),
4765                                               kUploadId);
4766 
4767   // Note that both transactions should have the same upload_data_stream
4768   // identifier to map to the same entry.
4769   transaction.load_flags = LOAD_SKIP_CACHE_VALIDATION;
4770   MockHttpRequest request(transaction);
4771   request.upload_data_stream = &upload_data_stream;
4772 
4773   const int kNumTransactions = 2;
4774   std::vector<std::unique_ptr<Context>> context_list;
4775 
4776   for (int i = 0; i < kNumTransactions; ++i) {
4777     context_list.push_back(std::make_unique<Context>());
4778     auto& c = context_list[i];
4779 
4780     c->result = cache.CreateTransaction(&c->trans);
4781     ASSERT_THAT(c->result, IsOk());
4782 
4783     c->result =
4784         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
4785 
4786     // Complete the headers phase request.
4787     base::RunLoop().RunUntilIdle();
4788   }
4789 
4790   std::string cache_key = request.CacheKey();
4791   // Only the 1st transaction gets added to writers.
4792   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
4793   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
4794 
4795   // Read the 1st transaction.
4796   ReadAndVerifyTransaction(context_list[0]->trans.get(),
4797                            kSimplePOST_Transaction);
4798 
4799   // 2nd transaction should now become a reader.
4800   base::RunLoop().RunUntilIdle();
4801   EXPECT_EQ(1, cache.GetCountReaders(cache_key));
4802   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(cache_key));
4803   ReadAndVerifyTransaction(context_list[1]->trans.get(),
4804                            kSimplePOST_Transaction);
4805 
4806   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4807   EXPECT_EQ(0, cache.disk_cache()->open_count());
4808   EXPECT_EQ(1, cache.disk_cache()->create_count());
4809 
4810   context_list.clear();
4811 }
4812 
4813 // Tests the case when parallel writing succeeds. Tests both idle and waiting
4814 // transactions.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingSuccess)4815 TEST_F(HttpCacheTest, SimpleGET_ParallelWritingSuccess) {
4816   MockHttpCache cache;
4817 
4818   MockHttpRequest request(kSimpleGET_Transaction);
4819 
4820   MockTransaction transaction(kSimpleGET_Transaction);
4821   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
4822   MockHttpRequest read_request(transaction);
4823 
4824   const int kNumTransactions = 4;
4825   std::vector<std::unique_ptr<Context>> context_list;
4826 
4827   for (int i = 0; i < kNumTransactions; ++i) {
4828     context_list.push_back(std::make_unique<Context>());
4829     auto& c = context_list[i];
4830 
4831     c->result = cache.CreateTransaction(&c->trans);
4832     ASSERT_THAT(c->result, IsOk());
4833 
4834     MockHttpRequest* this_request = &request;
4835     if (i == 3)
4836       this_request = &read_request;
4837 
4838     c->result = c->trans->Start(this_request, c->callback.callback(),
4839                                 NetLogWithSource());
4840   }
4841 
4842   // Allow all requests to move from the Create queue to the active entry.
4843   base::RunLoop().RunUntilIdle();
4844 
4845   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4846   EXPECT_EQ(0, cache.disk_cache()->open_count());
4847   EXPECT_EQ(1, cache.disk_cache()->create_count());
4848 
4849   std::string cache_key = request.CacheKey();
4850   EXPECT_EQ(3, cache.GetCountWriterTransactions(cache_key));
4851   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
4852 
4853   // Initiate Read from two writers.
4854   const int kBufferSize = 5;
4855   std::vector<scoped_refptr<IOBuffer>> buffer(
4856       3, base::MakeRefCounted<IOBuffer>(kBufferSize));
4857   for (int i = 0; i < 2; i++) {
4858     auto& c = context_list[i];
4859     c->result =
4860         c->trans->Read(buffer[i].get(), kBufferSize, c->callback.callback());
4861     EXPECT_EQ(ERR_IO_PENDING, c->result);
4862   }
4863 
4864   std::vector<std::string> first_read(2);
4865   base::RunLoop().RunUntilIdle();
4866   for (int i = 0; i < 2; i++) {
4867     auto& c = context_list[i];
4868     c->result = c->callback.WaitForResult();
4869     EXPECT_EQ(5, c->result);
4870     std::string data_read(buffer[i]->data(), kBufferSize);
4871     first_read[i] = data_read;
4872   }
4873   EXPECT_EQ(first_read[0], first_read[1]);
4874 
4875   // The first transaction should be able to continue to read from the network
4876   // without writing to the cache.
4877   for (int i = 0; i < 2; i++) {
4878     auto& c = context_list[i];
4879     ReadRemainingAndVerifyTransaction(c->trans.get(), first_read[i],
4880                                       kSimpleGET_Transaction);
4881     if (i == 0) {
4882       // Remaining transactions should now be readers.
4883       EXPECT_EQ(3, cache.GetCountReaders(cache_key));
4884     }
4885   }
4886 
4887   // Verify the rest of the transactions.
4888   for (int i = 2; i < kNumTransactions; i++) {
4889     auto& c = context_list[i];
4890     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
4891   }
4892 
4893   context_list.clear();
4894 }
4895 
4896 // Tests the case when parallel writing involves things bigger than what cache
4897 // can store. In this case, the best we can do is re-fetch it.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingHuge)4898 TEST_F(HttpCacheTest, SimpleGET_ParallelWritingHuge) {
4899   MockHttpCache cache;
4900   cache.disk_cache()->set_max_file_size(10);
4901 
4902   MockTransaction transaction(kSimpleGET_Transaction);
4903   std::string response_headers = base::StrCat(
4904       {kSimpleGET_Transaction.response_headers, "Content-Length: ",
4905        base::NumberToString(strlen(kSimpleGET_Transaction.data)), "\n"});
4906   transaction.response_headers = response_headers.c_str();
4907   AddMockTransaction(&transaction);
4908   MockHttpRequest request(transaction);
4909 
4910   const int kNumTransactions = 4;
4911   std::vector<std::unique_ptr<Context>> context_list;
4912 
4913   for (int i = 0; i < kNumTransactions; ++i) {
4914     context_list.push_back(std::make_unique<Context>());
4915     auto& c = context_list[i];
4916 
4917     c->result = cache.CreateTransaction(&c->trans);
4918     ASSERT_THAT(c->result, IsOk());
4919 
4920     MockHttpRequest* this_request = &request;
4921     c->result = c->trans->Start(this_request, c->callback.callback(),
4922                                 NetLogWithSource());
4923   }
4924 
4925   // Start them up.
4926   base::RunLoop().RunUntilIdle();
4927 
4928   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4929   EXPECT_EQ(0, cache.disk_cache()->open_count());
4930   EXPECT_EQ(1, cache.disk_cache()->create_count());
4931 
4932   std::string cache_key = request.CacheKey();
4933   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
4934   EXPECT_EQ(kNumTransactions - 1, cache.GetCountDoneHeadersQueue(cache_key));
4935 
4936   // Initiate Read from first transaction.
4937   const int kBufferSize = 5;
4938   std::vector<scoped_refptr<IOBuffer>> buffer(
4939       kNumTransactions, base::MakeRefCounted<IOBuffer>(kBufferSize));
4940   auto& c = context_list[0];
4941   c->result =
4942       c->trans->Read(buffer[0].get(), kBufferSize, c->callback.callback());
4943   EXPECT_EQ(ERR_IO_PENDING, c->result);
4944 
4945   // ... and complete it.
4946   std::vector<std::string> first_read(kNumTransactions);
4947   base::RunLoop().RunUntilIdle();
4948   c->result = c->callback.WaitForResult();
4949   EXPECT_EQ(kBufferSize, c->result);
4950   std::string data_read(buffer[0]->data(), kBufferSize);
4951   first_read[0] = data_read;
4952   EXPECT_EQ("<html", first_read[0]);
4953 
4954   // Complete all of them.
4955   for (int i = 0; i < kNumTransactions; i++) {
4956     ReadRemainingAndVerifyTransaction(context_list[i]->trans.get(),
4957                                       first_read[i], kSimpleGET_Transaction);
4958   }
4959 
4960   // Sadly all of them have to hit the network
4961   EXPECT_EQ(kNumTransactions, cache.network_layer()->transaction_count());
4962 
4963   context_list.clear();
4964   RemoveMockTransaction(&transaction);
4965 }
4966 
4967 // Tests that network transaction's info is saved correctly when a writer
4968 // transaction that created the network transaction becomes a reader. Also
4969 // verifies that the network bytes are only attributed to the transaction that
4970 // created the network transaction.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingVerifyNetworkBytes)4971 TEST_F(HttpCacheTest, SimpleGET_ParallelWritingVerifyNetworkBytes) {
4972   MockHttpCache cache;
4973 
4974   MockHttpRequest request(kSimpleGET_Transaction);
4975 
4976   const int kNumTransactions = 2;
4977   std::vector<std::unique_ptr<Context>> context_list;
4978 
4979   for (int i = 0; i < kNumTransactions; ++i) {
4980     context_list.push_back(std::make_unique<Context>());
4981     auto& c = context_list[i];
4982 
4983     c->result = cache.CreateTransaction(&c->trans);
4984     ASSERT_THAT(c->result, IsOk());
4985 
4986     c->result =
4987         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
4988   }
4989 
4990   // Allow all requests to move from the Create queue to the active entry.
4991   base::RunLoop().RunUntilIdle();
4992 
4993   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4994   EXPECT_EQ(0, cache.disk_cache()->open_count());
4995   EXPECT_EQ(1, cache.disk_cache()->create_count());
4996 
4997   std::string cache_key = request.CacheKey();
4998   EXPECT_EQ(2, cache.GetCountWriterTransactions(cache_key));
4999   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(cache_key));
5000 
5001   // Get the network bytes read by the first transaction.
5002   int total_received_bytes = context_list[0]->trans->GetTotalReceivedBytes();
5003   EXPECT_GT(total_received_bytes, 0);
5004 
5005   // Complete Read by the 2nd transaction so that the 1st transaction that
5006   // created the network transaction is now a reader.
5007   ReadAndVerifyTransaction(context_list[1]->trans.get(),
5008                            kSimpleGET_Transaction);
5009 
5010   EXPECT_EQ(1, cache.GetCountReaders(cache_key));
5011 
5012   // Verify that the network bytes read are not attributed to the 2nd
5013   // transaction but to the 1st.
5014   EXPECT_EQ(0, context_list[1]->trans->GetTotalReceivedBytes());
5015 
5016   EXPECT_GE(total_received_bytes,
5017             context_list[0]->trans->GetTotalReceivedBytes());
5018 
5019   ReadAndVerifyTransaction(context_list[0]->trans.get(),
5020                            kSimpleGET_Transaction);
5021 }
5022 
5023 // Tests than extra Read from the consumer should not hang/crash the browser.
TEST_F(HttpCacheTest,SimpleGET_ExtraRead)5024 TEST_F(HttpCacheTest, SimpleGET_ExtraRead) {
5025   MockHttpCache cache;
5026   MockHttpRequest request(kSimpleGET_Transaction);
5027   Context c;
5028 
5029   c.result = cache.CreateTransaction(&c.trans);
5030   ASSERT_THAT(c.result, IsOk());
5031 
5032   c.result =
5033       c.trans->Start(&request, c.callback.callback(), NetLogWithSource());
5034 
5035   base::RunLoop().RunUntilIdle();
5036 
5037   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5038   EXPECT_EQ(0, cache.disk_cache()->open_count());
5039   EXPECT_EQ(1, cache.disk_cache()->create_count());
5040 
5041   std::string cache_key = request.CacheKey();
5042   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
5043   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(cache_key));
5044 
5045   ReadAndVerifyTransaction(c.trans.get(), kSimpleGET_Transaction);
5046 
5047   // Perform an extra Read.
5048   const int kBufferSize = 10;
5049   scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<IOBuffer>(kBufferSize);
5050   c.result = c.trans->Read(buffer.get(), kBufferSize, c.callback.callback());
5051   EXPECT_EQ(0, c.result);
5052 }
5053 
5054 // Tests when a writer is destroyed mid-read, all the other writer transactions
5055 // can continue writing to the entry.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationCancelWriter)5056 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationCancelWriter) {
5057   MockHttpCache cache;
5058 
5059   ScopedMockTransaction transaction(kSimpleGET_Transaction);
5060   transaction.response_headers =
5061       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5062       "Content-Length: 22\n"
5063       "Etag: \"foopy\"\n";
5064   MockHttpRequest request(transaction);
5065 
5066   const int kNumTransactions = 3;
5067   std::vector<std::unique_ptr<Context>> context_list;
5068 
5069   for (int i = 0; i < kNumTransactions; ++i) {
5070     context_list.push_back(std::make_unique<Context>());
5071     auto& c = context_list[i];
5072 
5073     c->result = cache.CreateTransaction(&c->trans);
5074     ASSERT_THAT(c->result, IsOk());
5075 
5076     c->result =
5077         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5078   }
5079 
5080   // Allow all requests to move from the Create queue to the active entry.
5081   base::RunLoop().RunUntilIdle();
5082 
5083   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5084   EXPECT_EQ(0, cache.disk_cache()->open_count());
5085   EXPECT_EQ(1, cache.disk_cache()->create_count());
5086 
5087   std::string cache_key = request.CacheKey();
5088   EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
5089 
5090   // Let first transaction read some bytes.
5091   {
5092     auto& c = context_list[0];
5093     const int kBufferSize = 5;
5094     scoped_refptr<IOBuffer> buffer =
5095         base::MakeRefCounted<IOBuffer>(kBufferSize);
5096     ReleaseBufferCompletionCallback cb(buffer.get());
5097     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
5098     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
5099   }
5100 
5101   // Deleting the active transaction at this point will not impact the other
5102   // transactions since there are other transactions in writers.
5103   context_list[0].reset();
5104 
5105   base::RunLoop().RunUntilIdle();
5106 
5107   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5108   EXPECT_EQ(0, cache.disk_cache()->open_count());
5109   EXPECT_EQ(1, cache.disk_cache()->create_count());
5110 
5111   // Complete the rest of the transactions.
5112   for (auto& context : context_list) {
5113     if (!context)
5114       continue;
5115     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
5116   }
5117 }
5118 
5119 // Tests that when StopCaching is invoked on a writer, dependent transactions
5120 // are restarted.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationStopCaching)5121 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationStopCaching) {
5122   MockHttpCache cache;
5123 
5124   MockHttpRequest request(kSimpleGET_Transaction);
5125 
5126   MockTransaction transaction(kSimpleGET_Transaction);
5127   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
5128   MockHttpRequest read_only_request(transaction);
5129 
5130   const int kNumTransactions = 2;
5131   std::vector<std::unique_ptr<Context>> context_list;
5132 
5133   for (int i = 0; i < kNumTransactions; ++i) {
5134     context_list.push_back(std::make_unique<Context>());
5135     auto& c = context_list[i];
5136 
5137     c->result = cache.CreateTransaction(&c->trans);
5138     ASSERT_THAT(c->result, IsOk());
5139 
5140     MockHttpRequest* this_request = &request;
5141     if (i == 1) {
5142       this_request = &read_only_request;
5143     }
5144 
5145     c->result = c->trans->Start(this_request, c->callback.callback(),
5146                                 NetLogWithSource());
5147   }
5148 
5149   // Allow all requests to move from the Create queue to the active entry.
5150   base::RunLoop().RunUntilIdle();
5151 
5152   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5153   EXPECT_EQ(0, cache.disk_cache()->open_count());
5154   EXPECT_EQ(1, cache.disk_cache()->create_count());
5155 
5156   std::string cache_key = request.CacheKey();
5157   EXPECT_EQ(kNumTransactions - 1, cache.GetCountWriterTransactions(cache_key));
5158   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
5159 
5160   // Invoking StopCaching on the writer will lead to dooming the entry and
5161   // restarting the validated transactions. Since it is a read-only transaction
5162   // it will error out.
5163   context_list[0]->trans->StopCaching();
5164 
5165   base::RunLoop().RunUntilIdle();
5166 
5167   int rv = context_list[1]->callback.WaitForResult();
5168   EXPECT_EQ(ERR_CACHE_MISS, rv);
5169 
5170   ReadAndVerifyTransaction(context_list[0]->trans.get(),
5171                            kSimpleGET_Transaction);
5172 }
5173 
5174 // Tests that when StopCaching is invoked on a writer transaction, it is a
5175 // no-op if there are other writer transactions.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritersStopCachingNoOp)5176 TEST_F(HttpCacheTest, SimpleGET_ParallelWritersStopCachingNoOp) {
5177   MockHttpCache cache;
5178 
5179   MockHttpRequest request(kSimpleGET_Transaction);
5180 
5181   MockTransaction transaction(kSimpleGET_Transaction);
5182   transaction.load_flags |= LOAD_VALIDATE_CACHE;
5183   MockHttpRequest validate_request(transaction);
5184 
5185   const int kNumTransactions = 3;
5186   std::vector<std::unique_ptr<Context>> context_list;
5187 
5188   for (int i = 0; i < kNumTransactions; ++i) {
5189     context_list.push_back(std::make_unique<Context>());
5190     auto& c = context_list[i];
5191 
5192     c->result = cache.CreateTransaction(&c->trans);
5193     ASSERT_THAT(c->result, IsOk());
5194 
5195     MockHttpRequest* this_request = &request;
5196     if (i == 2) {
5197       this_request = &validate_request;
5198       c->trans->SetBeforeNetworkStartCallback(base::BindOnce(&DeferCallback));
5199     }
5200 
5201     c->result = c->trans->Start(this_request, c->callback.callback(),
5202                                 NetLogWithSource());
5203   }
5204 
5205   // Allow all requests to move from the Create queue to the active entry.
5206   base::RunLoop().RunUntilIdle();
5207 
5208   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5209   EXPECT_EQ(0, cache.disk_cache()->open_count());
5210   EXPECT_EQ(1, cache.disk_cache()->create_count());
5211 
5212   std::string cache_key = request.CacheKey();
5213   EXPECT_TRUE(cache.IsHeadersTransactionPresent(cache_key));
5214   EXPECT_EQ(kNumTransactions - 1, cache.GetCountWriterTransactions(cache_key));
5215 
5216   // Invoking StopCaching on the writer will be a no-op since there are multiple
5217   // transaction in writers.
5218   context_list[0]->trans->StopCaching();
5219 
5220   // Resume network start for headers_transaction.
5221   auto& c = context_list[2];
5222   c->trans->ResumeNetworkStart();
5223   base::RunLoop().RunUntilIdle();
5224   // After validation old entry will be doomed and headers_transaction will be
5225   // added to the new entry.
5226   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
5227 
5228   // Complete the rest of the transactions.
5229   for (auto& context : context_list) {
5230     if (!context)
5231       continue;
5232     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
5233   }
5234 
5235   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5236   EXPECT_EQ(0, cache.disk_cache()->open_count());
5237   EXPECT_EQ(2, cache.disk_cache()->create_count());
5238 }
5239 
5240 // Tests that a transaction is currently in headers phase and is destroyed
5241 // leading to destroying the entry.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationCancelHeaders)5242 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationCancelHeaders) {
5243   MockHttpCache cache;
5244 
5245   MockHttpRequest request(kSimpleGET_Transaction);
5246 
5247   const int kNumTransactions = 2;
5248   std::vector<std::unique_ptr<Context>> context_list;
5249 
5250   for (int i = 0; i < kNumTransactions; ++i) {
5251     context_list.push_back(std::make_unique<Context>());
5252     auto& c = context_list[i];
5253 
5254     c->result = cache.CreateTransaction(&c->trans);
5255     ASSERT_THAT(c->result, IsOk());
5256 
5257     if (i == 0)
5258       c->trans->SetBeforeNetworkStartCallback(base::BindOnce(&DeferCallback));
5259 
5260     c->result =
5261         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5262   }
5263 
5264   base::RunLoop().RunUntilIdle();
5265 
5266   std::string cache_key = request.CacheKey();
5267   EXPECT_TRUE(cache.IsHeadersTransactionPresent(cache_key));
5268   EXPECT_EQ(1, cache.GetCountAddToEntryQueue(cache_key));
5269 
5270   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5271   EXPECT_EQ(0, cache.disk_cache()->open_count());
5272   EXPECT_EQ(1, cache.disk_cache()->create_count());
5273 
5274   // Delete the headers transaction.
5275   context_list[0].reset();
5276 
5277   base::RunLoop().RunUntilIdle();
5278 
5279   // Complete the rest of the transactions.
5280   for (auto& context : context_list) {
5281     if (!context)
5282       continue;
5283     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
5284   }
5285 
5286   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5287   EXPECT_EQ(0, cache.disk_cache()->open_count());
5288   EXPECT_EQ(2, cache.disk_cache()->create_count());
5289 }
5290 
5291 // Similar to the above test, except here cache write fails and the
5292 // validated transactions should be restarted.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritersFailWrite)5293 TEST_F(HttpCacheTest, SimpleGET_ParallelWritersFailWrite) {
5294   MockHttpCache cache;
5295 
5296   MockHttpRequest request(kSimpleGET_Transaction);
5297 
5298   const int kNumTransactions = 5;
5299   std::vector<std::unique_ptr<Context>> context_list;
5300 
5301   for (int i = 0; i < kNumTransactions; ++i) {
5302     context_list.push_back(std::make_unique<Context>());
5303     auto& c = context_list[i];
5304 
5305     c->result = cache.CreateTransaction(&c->trans);
5306     ASSERT_THAT(c->result, IsOk());
5307     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
5308 
5309     c->result =
5310         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5311   }
5312 
5313   // All requests are waiting for the active entry.
5314   for (auto& context : context_list) {
5315     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
5316   }
5317 
5318   // Allow all requests to move from the Create queue to the active entry.
5319   base::RunLoop().RunUntilIdle();
5320 
5321   // All transactions become writers.
5322   std::string cache_key = request.CacheKey();
5323   EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
5324 
5325   // All requests depend on the writer, and the writer is between Start and
5326   // Read, i.e. idle.
5327   for (auto& context : context_list) {
5328     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
5329   }
5330 
5331   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5332   EXPECT_EQ(0, cache.disk_cache()->open_count());
5333   EXPECT_EQ(1, cache.disk_cache()->create_count());
5334 
5335   // Fail the request.
5336   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_ALL);
5337   // We have to open the entry again to propagate the failure flag.
5338   disk_cache::Entry* en;
5339   cache.OpenBackendEntry(cache_key, &en);
5340   en->Close();
5341 
5342   for (int i = 0; i < kNumTransactions; ++i) {
5343     auto& c = context_list[i];
5344     if (c->result == ERR_IO_PENDING)
5345       c->result = c->callback.WaitForResult();
5346     if (i == 1) {
5347       // The earlier entry must be destroyed and its disk entry doomed.
5348       EXPECT_TRUE(cache.disk_cache()->IsDiskEntryDoomed(cache_key));
5349     }
5350 
5351     if (i == 0) {
5352       // Consumer gets the response even if cache write failed.
5353       ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5354     } else {
5355       // Read should lead to a failure being returned.
5356       const int kBufferSize = 5;
5357       scoped_refptr<IOBuffer> buffer =
5358           base::MakeRefCounted<IOBuffer>(kBufferSize);
5359       ReleaseBufferCompletionCallback cb(buffer.get());
5360       c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
5361       EXPECT_EQ(ERR_CACHE_WRITE_FAILURE, cb.GetResult(c->result));
5362     }
5363   }
5364 }
5365 
5366 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
5367 // If cancelling a request is racing with another request for the same resource
5368 // finishing, we have to make sure that we remove both transactions from the
5369 // entry.
TEST_F(HttpCacheTest,SimpleGET_RacingReaders)5370 TEST_F(HttpCacheTest, SimpleGET_RacingReaders) {
5371   MockHttpCache cache;
5372 
5373   MockHttpRequest request(kSimpleGET_Transaction);
5374   MockHttpRequest reader_request(kSimpleGET_Transaction);
5375   reader_request.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
5376 
5377   std::vector<std::unique_ptr<Context>> context_list;
5378   const int kNumTransactions = 5;
5379 
5380   for (int i = 0; i < kNumTransactions; ++i) {
5381     context_list.push_back(std::make_unique<Context>());
5382     Context* c = context_list[i].get();
5383 
5384     c->result = cache.CreateTransaction(&c->trans);
5385     ASSERT_THAT(c->result, IsOk());
5386 
5387     MockHttpRequest* this_request = &request;
5388     if (i == 1 || i == 2)
5389       this_request = &reader_request;
5390 
5391     c->result = c->trans->Start(this_request, c->callback.callback(),
5392                                 NetLogWithSource());
5393   }
5394 
5395   // Allow all requests to move from the Create queue to the active entry.
5396   base::RunLoop().RunUntilIdle();
5397 
5398   // The first request should be a writer at this point, and the subsequent
5399   // requests should be pending.
5400 
5401   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5402   EXPECT_EQ(0, cache.disk_cache()->open_count());
5403   EXPECT_EQ(1, cache.disk_cache()->create_count());
5404 
5405   Context* c = context_list[0].get();
5406   ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
5407   c->result = c->callback.WaitForResult();
5408   ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5409 
5410   // Now all transactions should be waiting for read to be invoked. Two readers
5411   // are because of the load flags and remaining two transactions were converted
5412   // to readers after skipping validation. Note that the remaining two went on
5413   // to process the headers in parallel with readers present on the entry.
5414   EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState());
5415   EXPECT_EQ(LOAD_STATE_IDLE, context_list[3]->trans->GetLoadState());
5416 
5417   c = context_list[1].get();
5418   ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
5419   c->result = c->callback.WaitForResult();
5420   if (c->result == OK)
5421     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5422 
5423   // At this point we have one reader, two pending transactions and a task on
5424   // the queue to move to the next transaction. Now we cancel the request that
5425   // is the current reader, and expect the queued task to be able to start the
5426   // next request.
5427 
5428   c = context_list[2].get();
5429   c->trans.reset();
5430 
5431   for (int i = 3; i < kNumTransactions; ++i) {
5432     c = context_list[i].get();
5433     if (c->result == ERR_IO_PENDING)
5434       c->result = c->callback.WaitForResult();
5435     if (c->result == OK)
5436       ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5437   }
5438 
5439   // We should not have had to re-open the disk entry.
5440 
5441   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5442   EXPECT_EQ(0, cache.disk_cache()->open_count());
5443   EXPECT_EQ(1, cache.disk_cache()->create_count());
5444 }
5445 
5446 // Tests that we can doom an entry with pending transactions and delete one of
5447 // the pending transactions before the first one completes.
5448 // See http://code.google.com/p/chromium/issues/detail?id=25588
TEST_F(HttpCacheTest,SimpleGET_DoomWithPending)5449 TEST_F(HttpCacheTest, SimpleGET_DoomWithPending) {
5450   // We need simultaneous doomed / not_doomed entries so let's use a real cache.
5451   MockHttpCache cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
5452 
5453   MockHttpRequest request(kSimpleGET_Transaction);
5454   MockHttpRequest writer_request(kSimpleGET_Transaction);
5455   writer_request.load_flags = LOAD_BYPASS_CACHE;
5456 
5457   std::vector<std::unique_ptr<Context>> context_list;
5458   const int kNumTransactions = 4;
5459 
5460   for (int i = 0; i < kNumTransactions; ++i) {
5461     context_list.push_back(std::make_unique<Context>());
5462     Context* c = context_list[i].get();
5463 
5464     c->result = cache.CreateTransaction(&c->trans);
5465     ASSERT_THAT(c->result, IsOk());
5466 
5467     MockHttpRequest* this_request = &request;
5468     if (i == 3)
5469       this_request = &writer_request;
5470 
5471     c->result = c->trans->Start(this_request, c->callback.callback(),
5472                                 NetLogWithSource());
5473   }
5474 
5475   base::RunLoop().RunUntilIdle();
5476 
5477   // The first request should be a writer at this point, and the two subsequent
5478   // requests should be pending. The last request doomed the first entry.
5479 
5480   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5481 
5482   // Cancel the second transaction. Note that this and the 3rd transactions
5483   // would have completed their headers phase and would be waiting in the
5484   // done_headers_queue when the 2nd transaction is cancelled.
5485   context_list[1].reset();
5486 
5487   for (int i = 0; i < kNumTransactions; ++i) {
5488     if (i == 1)
5489       continue;
5490     Context* c = context_list[i].get();
5491     ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
5492     c->result = c->callback.WaitForResult();
5493     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5494   }
5495 }
5496 
TEST_F(HttpCacheTest,DoomDoesNotSetHints)5497 TEST_F(HttpCacheTest, DoomDoesNotSetHints) {
5498   // Test that a doomed writer doesn't set in-memory index hints.
5499   MockHttpCache cache;
5500   cache.disk_cache()->set_support_in_memory_entry_data(true);
5501 
5502   // Request 1 is a normal one to a no-cache/no-etag resource, to potentially
5503   // set a "this is unvalidatable" hint in the cache. We also need it to
5504   // actually write out to the doomed entry after request 2 does its thing,
5505   // so its transaction is paused.
5506   MockTransaction no_cache_transaction(kSimpleGET_Transaction);
5507   no_cache_transaction.response_headers = "Cache-Control: no-cache\n";
5508   AddMockTransaction(&no_cache_transaction);
5509   MockHttpRequest request1(no_cache_transaction);
5510 
5511   Context c1;
5512   c1.result = cache.CreateTransaction(&c1.trans);
5513   ASSERT_THAT(c1.result, IsOk());
5514   c1.trans->SetBeforeNetworkStartCallback(
5515       base::BindOnce([](bool* defer) { *defer = true; }));
5516   c1.result =
5517       c1.trans->Start(&request1, c1.callback.callback(), NetLogWithSource());
5518   ASSERT_THAT(c1.result, IsError(ERR_IO_PENDING));
5519 
5520   // It starts, copies over headers info, but doesn't get to proceed.
5521   base::RunLoop().RunUntilIdle();
5522   RemoveMockTransaction(&no_cache_transaction);
5523 
5524   // Request 2 sets LOAD_BYPASS_CACHE to force the first one to be doomed ---
5525   // it'll want to be a writer.
5526   MockHttpRequest request2(kSimpleGET_Transaction);
5527   request2.load_flags = LOAD_BYPASS_CACHE;
5528 
5529   Context c2;
5530   c2.result = cache.CreateTransaction(&c2.trans);
5531   ASSERT_THAT(c2.result, IsOk());
5532   c2.result =
5533       c2.trans->Start(&request2, c2.callback.callback(), NetLogWithSource());
5534   ASSERT_THAT(c2.result, IsError(ERR_IO_PENDING));
5535 
5536   // Run Request2, then let the first one wrap up.
5537   base::RunLoop().RunUntilIdle();
5538   c2.callback.WaitForResult();
5539   ReadAndVerifyTransaction(c2.trans.get(), kSimpleGET_Transaction);
5540 
5541   c1.trans->ResumeNetworkStart();
5542   c1.callback.WaitForResult();
5543   ReadAndVerifyTransaction(c1.trans.get(), no_cache_transaction);
5544 
5545   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5546   EXPECT_EQ(0, cache.disk_cache()->open_count());
5547   EXPECT_EQ(2, cache.disk_cache()->create_count());
5548 
5549   // Request 3 tries to read from cache, and it should successfully do so. It's
5550   // run after the previous two transactions finish so it doesn't try to
5551   // cooperate with them, and is entirely driven by the state of the cache.
5552   MockHttpRequest request3(kSimpleGET_Transaction);
5553   Context context3;
5554   context3.result = cache.CreateTransaction(&context3.trans);
5555   ASSERT_THAT(context3.result, IsOk());
5556   context3.result = context3.trans->Start(
5557       &request3, context3.callback.callback(), NetLogWithSource());
5558   base::RunLoop().RunUntilIdle();
5559   ASSERT_THAT(context3.result, IsError(ERR_IO_PENDING));
5560   context3.result = context3.callback.WaitForResult();
5561   ReadAndVerifyTransaction(context3.trans.get(), kSimpleGET_Transaction);
5562 
5563   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5564   EXPECT_EQ(1, cache.disk_cache()->open_count());
5565   EXPECT_EQ(2, cache.disk_cache()->create_count());
5566 }
5567 
5568 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
5569 // We may attempt to delete an entry synchronously with the act of adding a new
5570 // transaction to said entry.
TEST_F(HttpCacheTest,FastNoStoreGET_DoneWithPending)5571 TEST_F(HttpCacheTest, FastNoStoreGET_DoneWithPending) {
5572   MockHttpCache cache;
5573 
5574   // The headers will be served right from the call to Start() the request.
5575   MockHttpRequest request(kFastNoStoreGET_Transaction);
5576   FastTransactionServer request_handler;
5577   AddMockTransaction(&kFastNoStoreGET_Transaction);
5578 
5579   std::vector<std::unique_ptr<Context>> context_list;
5580   const int kNumTransactions = 3;
5581 
5582   for (int i = 0; i < kNumTransactions; ++i) {
5583     context_list.push_back(std::make_unique<Context>());
5584     Context* c = context_list[i].get();
5585 
5586     c->result = cache.CreateTransaction(&c->trans);
5587     ASSERT_THAT(c->result, IsOk());
5588 
5589     c->result =
5590         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5591   }
5592 
5593   // Allow all requests to move from the Create queue to the active entry.
5594   base::RunLoop().RunUntilIdle();
5595 
5596   // The first request should be a writer at this point, and the subsequent
5597   // requests should have completed validation. Since the validation does not
5598   // result in a match, a new entry would be created.
5599 
5600   EXPECT_EQ(3, cache.network_layer()->transaction_count());
5601   EXPECT_EQ(0, cache.disk_cache()->open_count());
5602   EXPECT_EQ(3, cache.disk_cache()->create_count());
5603 
5604   // Now, make sure that the second request asks for the entry not to be stored.
5605   request_handler.set_no_store(true);
5606 
5607   for (int i = 0; i < kNumTransactions; ++i) {
5608     Context* c = context_list[i].get();
5609     if (c->result == ERR_IO_PENDING)
5610       c->result = c->callback.WaitForResult();
5611     ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction);
5612     context_list[i].reset();
5613   }
5614 
5615   EXPECT_EQ(3, cache.network_layer()->transaction_count());
5616   EXPECT_EQ(0, cache.disk_cache()->open_count());
5617   EXPECT_EQ(3, cache.disk_cache()->create_count());
5618 
5619   RemoveMockTransaction(&kFastNoStoreGET_Transaction);
5620 }
5621 
TEST_F(HttpCacheTest,SimpleGET_ManyWriters_CancelFirst)5622 TEST_F(HttpCacheTest, SimpleGET_ManyWriters_CancelFirst) {
5623   MockHttpCache cache;
5624 
5625   MockHttpRequest request(kSimpleGET_Transaction);
5626 
5627   std::vector<std::unique_ptr<Context>> context_list;
5628   const int kNumTransactions = 2;
5629 
5630   for (int i = 0; i < kNumTransactions; ++i) {
5631     context_list.push_back(std::make_unique<Context>());
5632     Context* c = context_list[i].get();
5633 
5634     c->result = cache.CreateTransaction(&c->trans);
5635     ASSERT_THAT(c->result, IsOk());
5636 
5637     c->result =
5638         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5639   }
5640 
5641   // Allow all requests to move from the Create queue to the active entry.
5642   // All would have been added to writers.
5643   base::RunLoop().RunUntilIdle();
5644   std::string cache_key =
5645       *cache.http_cache()->GenerateCacheKeyForRequest(&request);
5646   EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
5647 
5648   // The second transaction skipped validation, thus only one network
5649   // transaction is created.
5650   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5651   EXPECT_EQ(0, cache.disk_cache()->open_count());
5652   EXPECT_EQ(1, cache.disk_cache()->create_count());
5653 
5654   for (int i = 0; i < kNumTransactions; ++i) {
5655     Context* c = context_list[i].get();
5656     if (c->result == ERR_IO_PENDING)
5657       c->result = c->callback.WaitForResult();
5658     // Destroy only the first transaction.
5659     // This should not impact the other writer transaction and the network
5660     // transaction will continue to be used by that transaction.
5661     if (i == 0) {
5662       context_list[i].reset();
5663     }
5664   }
5665 
5666   // Complete the rest of the transactions.
5667   for (int i = 1; i < kNumTransactions; ++i) {
5668     Context* c = context_list[i].get();
5669     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5670   }
5671 
5672   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5673   EXPECT_EQ(0, cache.disk_cache()->open_count());
5674   EXPECT_EQ(1, cache.disk_cache()->create_count());
5675 }
5676 
5677 // Tests that we can cancel requests that are queued waiting to open the disk
5678 // cache entry.
TEST_F(HttpCacheTest,SimpleGET_ManyWriters_CancelCreate)5679 TEST_F(HttpCacheTest, SimpleGET_ManyWriters_CancelCreate) {
5680   MockHttpCache cache;
5681 
5682   MockHttpRequest request(kSimpleGET_Transaction);
5683 
5684   std::vector<std::unique_ptr<Context>> context_list;
5685   const int kNumTransactions = 5;
5686 
5687   for (int i = 0; i < kNumTransactions; i++) {
5688     context_list.push_back(std::make_unique<Context>());
5689     Context* c = context_list[i].get();
5690 
5691     c->result = cache.CreateTransaction(&c->trans);
5692     ASSERT_THAT(c->result, IsOk());
5693 
5694     c->result =
5695         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5696   }
5697 
5698   // The first request should be creating the disk cache entry and the others
5699   // should be pending.
5700 
5701   EXPECT_EQ(0, cache.network_layer()->transaction_count());
5702   EXPECT_EQ(0, cache.disk_cache()->open_count());
5703   EXPECT_EQ(1, cache.disk_cache()->create_count());
5704 
5705   // Cancel a request from the pending queue.
5706   context_list[3].reset();
5707 
5708   // Cancel the request that is creating the entry. This will force the pending
5709   // operations to restart.
5710   context_list[0].reset();
5711 
5712   // Complete the rest of the transactions.
5713   for (int i = 1; i < kNumTransactions; i++) {
5714     Context* c = context_list[i].get();
5715     if (c) {
5716       c->result = c->callback.GetResult(c->result);
5717       ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5718     }
5719   }
5720 
5721   // We should have had to re-create the disk entry.
5722 
5723   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5724   EXPECT_EQ(0, cache.disk_cache()->open_count());
5725   EXPECT_EQ(2, cache.disk_cache()->create_count());
5726 }
5727 
5728 // Tests that we can cancel a single request to open a disk cache entry.
TEST_F(HttpCacheTest,SimpleGET_CancelCreate)5729 TEST_F(HttpCacheTest, SimpleGET_CancelCreate) {
5730   MockHttpCache cache;
5731 
5732   MockHttpRequest request(kSimpleGET_Transaction);
5733 
5734   auto c = std::make_unique<Context>();
5735 
5736   c->result = cache.CreateTransaction(&c->trans);
5737   ASSERT_THAT(c->result, IsOk());
5738 
5739   c->result =
5740       c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5741   EXPECT_THAT(c->result, IsError(ERR_IO_PENDING));
5742 
5743   // Release the reference that the mock disk cache keeps for this entry, so
5744   // that we test that the http cache handles the cancellation correctly.
5745   cache.disk_cache()->ReleaseAll();
5746   c.reset();
5747 
5748   base::RunLoop().RunUntilIdle();
5749   EXPECT_EQ(1, cache.disk_cache()->create_count());
5750 }
5751 
5752 // Tests that we delete/create entries even if multiple requests are queued.
TEST_F(HttpCacheTest,SimpleGET_ManyWriters_BypassCache)5753 TEST_F(HttpCacheTest, SimpleGET_ManyWriters_BypassCache) {
5754   MockHttpCache cache;
5755 
5756   MockHttpRequest request(kSimpleGET_Transaction);
5757   request.load_flags = LOAD_BYPASS_CACHE;
5758 
5759   std::vector<std::unique_ptr<Context>> context_list;
5760   const int kNumTransactions = 5;
5761 
5762   for (int i = 0; i < kNumTransactions; i++) {
5763     context_list.push_back(std::make_unique<Context>());
5764     Context* c = context_list[i].get();
5765 
5766     c->result = cache.CreateTransaction(&c->trans);
5767     ASSERT_THAT(c->result, IsOk());
5768 
5769     c->result =
5770         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5771   }
5772 
5773   // The first request should be deleting the disk cache entry and the others
5774   // should be pending.
5775 
5776   EXPECT_EQ(0, cache.network_layer()->transaction_count());
5777   EXPECT_EQ(0, cache.disk_cache()->open_count());
5778   EXPECT_EQ(0, cache.disk_cache()->create_count());
5779 
5780   // Complete the transactions.
5781   for (int i = 0; i < kNumTransactions; i++) {
5782     Context* c = context_list[i].get();
5783     c->result = c->callback.GetResult(c->result);
5784     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5785   }
5786 
5787   // We should have had to re-create the disk entry multiple times.
5788 
5789   EXPECT_EQ(5, cache.network_layer()->transaction_count());
5790   EXPECT_EQ(0, cache.disk_cache()->open_count());
5791   EXPECT_EQ(5, cache.disk_cache()->create_count());
5792 }
5793 
5794 // Tests that a (simulated) timeout allows transactions waiting on the cache
5795 // lock to continue.
TEST_F(HttpCacheTest,SimpleGET_WriterTimeout)5796 TEST_F(HttpCacheTest, SimpleGET_WriterTimeout) {
5797   MockHttpCache cache;
5798   cache.SimulateCacheLockTimeout();
5799 
5800   MockHttpRequest request(kSimpleGET_Transaction);
5801   Context c1, c2;
5802   ASSERT_THAT(cache.CreateTransaction(&c1.trans), IsOk());
5803   ASSERT_EQ(ERR_IO_PENDING, c1.trans->Start(&request, c1.callback.callback(),
5804                                             NetLogWithSource()));
5805   ASSERT_THAT(cache.CreateTransaction(&c2.trans), IsOk());
5806   ASSERT_EQ(ERR_IO_PENDING, c2.trans->Start(&request, c2.callback.callback(),
5807                                             NetLogWithSource()));
5808 
5809   // The second request is queued after the first one.
5810 
5811   c2.callback.WaitForResult();
5812   ReadAndVerifyTransaction(c2.trans.get(), kSimpleGET_Transaction);
5813 
5814   // Complete the first transaction.
5815   c1.callback.WaitForResult();
5816   ReadAndVerifyTransaction(c1.trans.get(), kSimpleGET_Transaction);
5817 }
5818 
5819 // Tests that a (simulated) timeout allows transactions waiting on the cache
5820 // lock to continue but read only transactions to error out.
TEST_F(HttpCacheTest,SimpleGET_WriterTimeoutReadOnlyError)5821 TEST_F(HttpCacheTest, SimpleGET_WriterTimeoutReadOnlyError) {
5822   MockHttpCache cache;
5823 
5824   // Simulate timeout.
5825   cache.SimulateCacheLockTimeout();
5826 
5827   MockHttpRequest request(kSimpleGET_Transaction);
5828   Context c1, c2;
5829   ASSERT_THAT(cache.CreateTransaction(&c1.trans), IsOk());
5830   ASSERT_EQ(ERR_IO_PENDING, c1.trans->Start(&request, c1.callback.callback(),
5831                                             NetLogWithSource()));
5832 
5833   request.load_flags = LOAD_ONLY_FROM_CACHE;
5834   ASSERT_THAT(cache.CreateTransaction(&c2.trans), IsOk());
5835   ASSERT_EQ(ERR_IO_PENDING, c2.trans->Start(&request, c2.callback.callback(),
5836                                             NetLogWithSource()));
5837 
5838   // The second request is queued after the first one.
5839   int res = c2.callback.WaitForResult();
5840   ASSERT_EQ(ERR_CACHE_MISS, res);
5841 
5842   // Complete the first transaction.
5843   c1.callback.WaitForResult();
5844   ReadAndVerifyTransaction(c1.trans.get(), kSimpleGET_Transaction);
5845 }
5846 
TEST_F(HttpCacheTest,SimpleGET_AbandonedCacheRead)5847 TEST_F(HttpCacheTest, SimpleGET_AbandonedCacheRead) {
5848   MockHttpCache cache;
5849 
5850   // write to the cache
5851   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5852 
5853   MockHttpRequest request(kSimpleGET_Transaction);
5854   TestCompletionCallback callback;
5855 
5856   std::unique_ptr<HttpTransaction> trans;
5857   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
5858   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5859   if (rv == ERR_IO_PENDING)
5860     rv = callback.WaitForResult();
5861   ASSERT_THAT(rv, IsOk());
5862 
5863   scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
5864   rv = trans->Read(buf.get(), 256, callback.callback());
5865   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5866 
5867   // Test that destroying the transaction while it is reading from the cache
5868   // works properly.
5869   trans.reset();
5870 
5871   // Make sure we pump any pending events, which should include a call to
5872   // HttpCache::Transaction::OnCacheReadCompleted.
5873   base::RunLoop().RunUntilIdle();
5874 }
5875 
5876 // Tests that we can delete the HttpCache and deal with queued transactions
5877 // ("waiting for the backend" as opposed to Active or Doomed entries).
TEST_F(HttpCacheTest,SimpleGET_ManyWriters_DeleteCache)5878 TEST_F(HttpCacheTest, SimpleGET_ManyWriters_DeleteCache) {
5879   auto cache = std::make_unique<MockHttpCache>(
5880       std::make_unique<MockBackendNoCbFactory>());
5881 
5882   MockHttpRequest request(kSimpleGET_Transaction);
5883 
5884   std::vector<std::unique_ptr<Context>> context_list;
5885   const int kNumTransactions = 5;
5886 
5887   for (int i = 0; i < kNumTransactions; i++) {
5888     context_list.push_back(std::make_unique<Context>());
5889     Context* c = context_list[i].get();
5890 
5891     c->result = cache->CreateTransaction(&c->trans);
5892     ASSERT_THAT(c->result, IsOk());
5893 
5894     c->result =
5895         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5896   }
5897 
5898   // The first request should be creating the disk cache entry and the others
5899   // should be pending.
5900 
5901   EXPECT_EQ(0, cache->network_layer()->transaction_count());
5902   EXPECT_EQ(0, cache->disk_cache()->open_count());
5903   EXPECT_EQ(0, cache->disk_cache()->create_count());
5904 
5905   cache.reset();
5906 }
5907 
5908 // Tests that we queue requests when initializing the backend.
TEST_F(HttpCacheTest,SimpleGET_WaitForBackend)5909 TEST_F(HttpCacheTest, SimpleGET_WaitForBackend) {
5910   auto factory = std::make_unique<MockBlockingBackendFactory>();
5911   MockBlockingBackendFactory* factory_ptr = factory.get();
5912   MockHttpCache cache(std::move(factory));
5913 
5914   MockHttpRequest request0(kSimpleGET_Transaction);
5915   MockHttpRequest request1(kTypicalGET_Transaction);
5916   MockHttpRequest request2(kETagGET_Transaction);
5917 
5918   std::vector<std::unique_ptr<Context>> context_list;
5919   const int kNumTransactions = 3;
5920 
5921   for (int i = 0; i < kNumTransactions; i++) {
5922     context_list.push_back(std::make_unique<Context>());
5923     Context* c = context_list[i].get();
5924 
5925     c->result = cache.CreateTransaction(&c->trans);
5926     ASSERT_THAT(c->result, IsOk());
5927   }
5928 
5929   context_list[0]->result = context_list[0]->trans->Start(
5930       &request0, context_list[0]->callback.callback(), NetLogWithSource());
5931   context_list[1]->result = context_list[1]->trans->Start(
5932       &request1, context_list[1]->callback.callback(), NetLogWithSource());
5933   context_list[2]->result = context_list[2]->trans->Start(
5934       &request2, context_list[2]->callback.callback(), NetLogWithSource());
5935 
5936   // Just to make sure that everything is still pending.
5937   base::RunLoop().RunUntilIdle();
5938 
5939   // The first request should be creating the disk cache.
5940   EXPECT_FALSE(context_list[0]->callback.have_result());
5941 
5942   factory_ptr->FinishCreation();
5943 
5944   base::RunLoop().RunUntilIdle();
5945   EXPECT_EQ(3, cache.network_layer()->transaction_count());
5946   EXPECT_EQ(3, cache.disk_cache()->create_count());
5947 
5948   for (int i = 0; i < kNumTransactions; ++i) {
5949     EXPECT_TRUE(context_list[i]->callback.have_result());
5950     context_list[i].reset();
5951   }
5952 }
5953 
5954 // Tests that we can cancel requests that are queued waiting for the backend
5955 // to be initialized.
TEST_F(HttpCacheTest,SimpleGET_WaitForBackend_CancelCreate)5956 TEST_F(HttpCacheTest, SimpleGET_WaitForBackend_CancelCreate) {
5957   auto factory = std::make_unique<MockBlockingBackendFactory>();
5958   MockBlockingBackendFactory* factory_ptr = factory.get();
5959   MockHttpCache cache(std::move(factory));
5960 
5961   MockHttpRequest request0(kSimpleGET_Transaction);
5962   MockHttpRequest request1(kTypicalGET_Transaction);
5963   MockHttpRequest request2(kETagGET_Transaction);
5964 
5965   std::vector<std::unique_ptr<Context>> context_list;
5966   const int kNumTransactions = 3;
5967 
5968   for (int i = 0; i < kNumTransactions; i++) {
5969     context_list.push_back(std::make_unique<Context>());
5970     Context* c = context_list[i].get();
5971 
5972     c->result = cache.CreateTransaction(&c->trans);
5973     ASSERT_THAT(c->result, IsOk());
5974   }
5975 
5976   context_list[0]->result = context_list[0]->trans->Start(
5977       &request0, context_list[0]->callback.callback(), NetLogWithSource());
5978   context_list[1]->result = context_list[1]->trans->Start(
5979       &request1, context_list[1]->callback.callback(), NetLogWithSource());
5980   context_list[2]->result = context_list[2]->trans->Start(
5981       &request2, context_list[2]->callback.callback(), NetLogWithSource());
5982 
5983   // Just to make sure that everything is still pending.
5984   base::RunLoop().RunUntilIdle();
5985 
5986   // The first request should be creating the disk cache.
5987   EXPECT_FALSE(context_list[0]->callback.have_result());
5988 
5989   // Cancel a request from the pending queue.
5990   context_list[1].reset();
5991 
5992   // Cancel the request that is creating the entry.
5993   context_list[0].reset();
5994 
5995   // Complete the last transaction.
5996   factory_ptr->FinishCreation();
5997 
5998   context_list[2]->result =
5999       context_list[2]->callback.GetResult(context_list[2]->result);
6000   ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction);
6001 
6002   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6003   EXPECT_EQ(1, cache.disk_cache()->create_count());
6004 }
6005 
6006 // Tests that we can delete the HttpCache while creating the backend.
TEST_F(HttpCacheTest,DeleteCacheWaitingForBackend)6007 TEST_F(HttpCacheTest, DeleteCacheWaitingForBackend) {
6008   auto factory = std::make_unique<MockBlockingBackendFactory>();
6009   MockBlockingBackendFactory* factory_ptr = factory.get();
6010   auto cache = std::make_unique<MockHttpCache>(std::move(factory));
6011 
6012   MockHttpRequest request(kSimpleGET_Transaction);
6013 
6014   auto c = std::make_unique<Context>();
6015   c->result = cache->CreateTransaction(&c->trans);
6016   ASSERT_THAT(c->result, IsOk());
6017 
6018   c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
6019 
6020   // Just to make sure that everything is still pending.
6021   base::RunLoop().RunUntilIdle();
6022 
6023   // The request should be creating the disk cache.
6024   EXPECT_FALSE(c->callback.have_result());
6025 
6026   // Manually arrange for completion to happen after ~HttpCache.
6027   // This can't be done via FinishCreation() since that's in `factory`, and
6028   // that's owned by `cache`.
6029   disk_cache::BackendResultCallback callback = factory_ptr->ReleaseCallback();
6030 
6031   cache.reset();
6032   base::RunLoop().RunUntilIdle();
6033 
6034   // Simulate the backend completion callback running now the HttpCache is gone.
6035   std::move(callback).Run(disk_cache::BackendResult::MakeError(ERR_ABORTED));
6036 }
6037 
6038 // Tests that we can delete the cache while creating the backend, from within
6039 // one of the callbacks.
TEST_F(HttpCacheTest,DeleteCacheWaitingForBackend2)6040 TEST_F(HttpCacheTest, DeleteCacheWaitingForBackend2) {
6041   auto factory = std::make_unique<MockBlockingBackendFactory>();
6042   MockBlockingBackendFactory* factory_ptr = factory.get();
6043   auto cache = std::make_unique<MockHttpCache>(std::move(factory));
6044   auto* cache_ptr = cache.get();
6045 
6046   DeleteCacheCompletionCallback cb(std::move(cache));
6047   disk_cache::Backend* backend;
6048   int rv = cache_ptr->http_cache()->GetBackend(&backend, cb.callback());
6049   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6050 
6051   // Now let's queue a regular transaction
6052   MockHttpRequest request(kSimpleGET_Transaction);
6053 
6054   auto c = std::make_unique<Context>();
6055   c->result = cache_ptr->CreateTransaction(&c->trans);
6056   ASSERT_THAT(c->result, IsOk());
6057 
6058   c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
6059 
6060   // And another direct backend request.
6061   TestCompletionCallback cb2;
6062   rv = cache_ptr->http_cache()->GetBackend(&backend, cb2.callback());
6063   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6064 
6065   // Just to make sure that everything is still pending.
6066   base::RunLoop().RunUntilIdle();
6067 
6068   // The request should be queued.
6069   EXPECT_FALSE(c->callback.have_result());
6070 
6071   // Generate the callback.
6072   factory_ptr->FinishCreation();
6073   rv = cb.WaitForResult();
6074 
6075   // The cache should be gone by now.
6076   base::RunLoop().RunUntilIdle();
6077   EXPECT_THAT(c->callback.GetResult(c->result), IsOk());
6078   EXPECT_FALSE(cb2.have_result());
6079 }
6080 
TEST_F(HttpCacheTest,TypicalGET_ConditionalRequest)6081 TEST_F(HttpCacheTest, TypicalGET_ConditionalRequest) {
6082   MockHttpCache cache;
6083 
6084   // write to the cache
6085   RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
6086 
6087   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6088   EXPECT_EQ(0, cache.disk_cache()->open_count());
6089   EXPECT_EQ(1, cache.disk_cache()->create_count());
6090 
6091   // Get the same URL again, but this time we expect it to result
6092   // in a conditional request.
6093   LoadTimingInfo load_timing_info;
6094   RunTransactionTestAndGetTiming(cache.http_cache(), kTypicalGET_Transaction,
6095                                  NetLogWithSource::Make(NetLogSourceType::NONE),
6096                                  &load_timing_info);
6097 
6098   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6099   EXPECT_EQ(1, cache.disk_cache()->open_count());
6100   EXPECT_EQ(1, cache.disk_cache()->create_count());
6101   TestLoadTimingNetworkRequest(load_timing_info);
6102 }
6103 
ETagGet_ConditionalRequest_Handler(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)6104 static void ETagGet_ConditionalRequest_Handler(const HttpRequestInfo* request,
6105                                                std::string* response_status,
6106                                                std::string* response_headers,
6107                                                std::string* response_data) {
6108   EXPECT_TRUE(
6109       request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
6110   response_status->assign("HTTP/1.1 304 Not Modified");
6111   response_headers->assign(kETagGET_Transaction.response_headers);
6112   response_data->clear();
6113 }
6114 
TEST_F(HttpCacheTest,ETagGET_ConditionalRequest_304)6115 TEST_F(HttpCacheTest, ETagGET_ConditionalRequest_304) {
6116   MockHttpCache cache;
6117 
6118   ScopedMockTransaction transaction(kETagGET_Transaction);
6119 
6120   // write to the cache
6121   RunTransactionTest(cache.http_cache(), transaction);
6122 
6123   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6124   EXPECT_EQ(0, cache.disk_cache()->open_count());
6125   EXPECT_EQ(1, cache.disk_cache()->create_count());
6126 
6127   // Get the same URL again, but this time we expect it to result
6128   // in a conditional request.
6129   transaction.load_flags = LOAD_VALIDATE_CACHE;
6130   transaction.handler = ETagGet_ConditionalRequest_Handler;
6131   LoadTimingInfo load_timing_info;
6132   IPEndPoint remote_endpoint;
6133   RunTransactionTestAndGetTimingAndConnectedSocketAddress(
6134       cache.http_cache(), transaction,
6135       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info,
6136       &remote_endpoint);
6137 
6138   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6139   EXPECT_EQ(1, cache.disk_cache()->open_count());
6140   EXPECT_EQ(1, cache.disk_cache()->create_count());
6141   TestLoadTimingNetworkRequest(load_timing_info);
6142 
6143   EXPECT_FALSE(remote_endpoint.address().empty());
6144 }
6145 
6146 class RevalidationServer {
6147  public:
RevalidationServer()6148   RevalidationServer() {
6149     s_etag_used_ = false;
6150     s_last_modified_used_ = false;
6151   }
6152 
EtagUsed()6153   bool EtagUsed() { return s_etag_used_; }
LastModifiedUsed()6154   bool LastModifiedUsed() { return s_last_modified_used_; }
6155 
6156   static void Handler(const HttpRequestInfo* request,
6157                       std::string* response_status,
6158                       std::string* response_headers,
6159                       std::string* response_data);
6160 
6161  private:
6162   static bool s_etag_used_;
6163   static bool s_last_modified_used_;
6164 };
6165 bool RevalidationServer::s_etag_used_ = false;
6166 bool RevalidationServer::s_last_modified_used_ = false;
6167 
Handler(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)6168 void RevalidationServer::Handler(const HttpRequestInfo* request,
6169                                  std::string* response_status,
6170                                  std::string* response_headers,
6171                                  std::string* response_data) {
6172   if (request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch))
6173       s_etag_used_ = true;
6174 
6175   if (request->extra_headers.HasHeader(HttpRequestHeaders::kIfModifiedSince)) {
6176       s_last_modified_used_ = true;
6177   }
6178 
6179   if (s_etag_used_ || s_last_modified_used_) {
6180     response_status->assign("HTTP/1.1 304 Not Modified");
6181     response_headers->assign(kTypicalGET_Transaction.response_headers);
6182     response_data->clear();
6183   } else {
6184     response_status->assign(kTypicalGET_Transaction.status);
6185     response_headers->assign(kTypicalGET_Transaction.response_headers);
6186     response_data->assign(kTypicalGET_Transaction.data);
6187   }
6188 }
6189 
6190 // Tests revalidation after a vary match.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMatch)6191 TEST_F(HttpCacheTest, GET_ValidateCache_VaryMatch) {
6192   MockHttpCache cache;
6193 
6194   // Write to the cache.
6195   MockTransaction transaction(kTypicalGET_Transaction);
6196   transaction.request_headers = "Foo: bar\r\n";
6197   transaction.response_headers =
6198       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6199       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6200       "Etag: \"foopy\"\n"
6201       "Cache-Control: max-age=0\n"
6202       "Vary: Foo\n";
6203   AddMockTransaction(&transaction);
6204   RunTransactionTest(cache.http_cache(), transaction);
6205 
6206   // Read from the cache.
6207   RevalidationServer server;
6208   transaction.handler = server.Handler;
6209   LoadTimingInfo load_timing_info;
6210   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
6211                                  NetLogWithSource::Make(NetLogSourceType::NONE),
6212                                  &load_timing_info);
6213 
6214   EXPECT_TRUE(server.EtagUsed());
6215   EXPECT_TRUE(server.LastModifiedUsed());
6216   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6217   EXPECT_EQ(1, cache.disk_cache()->open_count());
6218   EXPECT_EQ(1, cache.disk_cache()->create_count());
6219   TestLoadTimingNetworkRequest(load_timing_info);
6220   RemoveMockTransaction(&transaction);
6221 }
6222 
6223 // Tests revalidation after a vary mismatch if etag is present.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMismatch)6224 TEST_F(HttpCacheTest, GET_ValidateCache_VaryMismatch) {
6225   MockHttpCache cache;
6226 
6227   // Write to the cache.
6228   MockTransaction transaction(kTypicalGET_Transaction);
6229   transaction.request_headers = "Foo: bar\r\n";
6230   transaction.response_headers =
6231       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6232       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6233       "Etag: \"foopy\"\n"
6234       "Cache-Control: max-age=0\n"
6235       "Vary: Foo\n";
6236   AddMockTransaction(&transaction);
6237   RunTransactionTest(cache.http_cache(), transaction);
6238 
6239   // Read from the cache and revalidate the entry.
6240   RevalidationServer server;
6241   transaction.handler = server.Handler;
6242   transaction.request_headers = "Foo: none\r\n";
6243   LoadTimingInfo load_timing_info;
6244   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
6245                                  NetLogWithSource::Make(NetLogSourceType::NONE),
6246                                  &load_timing_info);
6247 
6248   EXPECT_TRUE(server.EtagUsed());
6249   EXPECT_FALSE(server.LastModifiedUsed());
6250   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6251   EXPECT_EQ(1, cache.disk_cache()->open_count());
6252   EXPECT_EQ(1, cache.disk_cache()->create_count());
6253   TestLoadTimingNetworkRequest(load_timing_info);
6254   RemoveMockTransaction(&transaction);
6255 }
6256 
6257 // Tests revalidation after a vary mismatch due to vary: * if etag is present.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMismatchStar)6258 TEST_F(HttpCacheTest, GET_ValidateCache_VaryMismatchStar) {
6259   MockHttpCache cache;
6260 
6261   // Write to the cache.
6262   MockTransaction transaction(kTypicalGET_Transaction);
6263   transaction.response_headers =
6264       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6265       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6266       "Etag: \"foopy\"\n"
6267       "Cache-Control: max-age=0\n"
6268       "Vary: *\n";
6269   AddMockTransaction(&transaction);
6270   RunTransactionTest(cache.http_cache(), transaction);
6271 
6272   // Read from the cache and revalidate the entry.
6273   RevalidationServer server;
6274   transaction.handler = server.Handler;
6275   LoadTimingInfo load_timing_info;
6276   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
6277                                  NetLogWithSource::Make(NetLogSourceType::NONE),
6278                                  &load_timing_info);
6279 
6280   EXPECT_TRUE(server.EtagUsed());
6281   EXPECT_FALSE(server.LastModifiedUsed());
6282   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6283   EXPECT_EQ(1, cache.disk_cache()->open_count());
6284   EXPECT_EQ(1, cache.disk_cache()->create_count());
6285   TestLoadTimingNetworkRequest(load_timing_info);
6286   RemoveMockTransaction(&transaction);
6287 }
6288 
6289 // Tests lack of revalidation after a vary mismatch and no etag.
TEST_F(HttpCacheTest,GET_DontValidateCache_VaryMismatch)6290 TEST_F(HttpCacheTest, GET_DontValidateCache_VaryMismatch) {
6291   MockHttpCache cache;
6292 
6293   // Write to the cache.
6294   MockTransaction transaction(kTypicalGET_Transaction);
6295   transaction.request_headers = "Foo: bar\r\n";
6296   transaction.response_headers =
6297       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6298       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6299       "Cache-Control: max-age=0\n"
6300       "Vary: Foo\n";
6301   AddMockTransaction(&transaction);
6302   RunTransactionTest(cache.http_cache(), transaction);
6303 
6304   // Read from the cache and don't revalidate the entry.
6305   RevalidationServer server;
6306   transaction.handler = server.Handler;
6307   transaction.request_headers = "Foo: none\r\n";
6308   LoadTimingInfo load_timing_info;
6309   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
6310                                  NetLogWithSource::Make(NetLogSourceType::NONE),
6311                                  &load_timing_info);
6312 
6313   EXPECT_FALSE(server.EtagUsed());
6314   EXPECT_FALSE(server.LastModifiedUsed());
6315   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6316   EXPECT_EQ(1, cache.disk_cache()->open_count());
6317   EXPECT_EQ(1, cache.disk_cache()->create_count());
6318   TestLoadTimingNetworkRequest(load_timing_info);
6319   RemoveMockTransaction(&transaction);
6320 }
6321 
6322 // Tests that a new vary header provided when revalidating an entry is saved.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMatch_UpdateVary)6323 TEST_F(HttpCacheTest, GET_ValidateCache_VaryMatch_UpdateVary) {
6324   MockHttpCache cache;
6325 
6326   // Write to the cache.
6327   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6328   transaction.request_headers = "Foo: bar\r\n Name: bar\r\n";
6329   transaction.response_headers =
6330       "Etag: \"foopy\"\n"
6331       "Cache-Control: max-age=0\n"
6332       "Vary: Foo\n";
6333   RunTransactionTest(cache.http_cache(), transaction);
6334 
6335   // Validate the entry and change the vary field in the response.
6336   transaction.request_headers = "Foo: bar\r\n Name: none\r\n";
6337   transaction.status = "HTTP/1.1 304 Not Modified";
6338   transaction.response_headers =
6339       "Etag: \"foopy\"\n"
6340       "Cache-Control: max-age=3600\n"
6341       "Vary: Name\n";
6342   RunTransactionTest(cache.http_cache(), transaction);
6343 
6344   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6345   EXPECT_EQ(1, cache.disk_cache()->open_count());
6346   EXPECT_EQ(1, cache.disk_cache()->create_count());
6347 
6348   // Make sure that the ActiveEntry is gone.
6349   base::RunLoop().RunUntilIdle();
6350 
6351   // Generate a vary mismatch.
6352   transaction.request_headers = "Foo: bar\r\n Name: bar\r\n";
6353   RunTransactionTest(cache.http_cache(), transaction);
6354 
6355   EXPECT_EQ(3, cache.network_layer()->transaction_count());
6356   EXPECT_EQ(2, cache.disk_cache()->open_count());
6357   EXPECT_EQ(1, cache.disk_cache()->create_count());
6358 }
6359 
6360 // Tests that new request headers causing a vary mismatch are paired with the
6361 // new response when the server says the old response can be used.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMismatch_UpdateRequestHeader)6362 TEST_F(HttpCacheTest, GET_ValidateCache_VaryMismatch_UpdateRequestHeader) {
6363   MockHttpCache cache;
6364 
6365   // Write to the cache.
6366   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6367   transaction.request_headers = "Foo: bar\r\n";
6368   transaction.response_headers =
6369       "Etag: \"foopy\"\n"
6370       "Cache-Control: max-age=3600\n"
6371       "Vary: Foo\n";
6372   RunTransactionTest(cache.http_cache(), transaction);
6373 
6374   // Vary-mismatch validation receives 304.
6375   transaction.request_headers = "Foo: none\r\n";
6376   transaction.status = "HTTP/1.1 304 Not Modified";
6377   RunTransactionTest(cache.http_cache(), transaction);
6378 
6379   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6380   EXPECT_EQ(1, cache.disk_cache()->open_count());
6381   EXPECT_EQ(1, cache.disk_cache()->create_count());
6382 
6383   // Make sure that the ActiveEntry is gone.
6384   base::RunLoop().RunUntilIdle();
6385 
6386   // Generate a vary mismatch.
6387   transaction.request_headers = "Foo: bar\r\n";
6388   RunTransactionTest(cache.http_cache(), transaction);
6389 
6390   EXPECT_EQ(3, cache.network_layer()->transaction_count());
6391   EXPECT_EQ(2, cache.disk_cache()->open_count());
6392   EXPECT_EQ(1, cache.disk_cache()->create_count());
6393 }
6394 
6395 // Tests that a 304 without vary headers doesn't delete the previously stored
6396 // vary data after a vary match revalidation.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMatch_DontDeleteVary)6397 TEST_F(HttpCacheTest, GET_ValidateCache_VaryMatch_DontDeleteVary) {
6398   MockHttpCache cache;
6399 
6400   // Write to the cache.
6401   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6402   transaction.request_headers = "Foo: bar\r\n";
6403   transaction.response_headers =
6404       "Etag: \"foopy\"\n"
6405       "Cache-Control: max-age=0\n"
6406       "Vary: Foo\n";
6407   RunTransactionTest(cache.http_cache(), transaction);
6408 
6409   // Validate the entry and remove the vary field in the response.
6410   transaction.status = "HTTP/1.1 304 Not Modified";
6411   transaction.response_headers =
6412       "Etag: \"foopy\"\n"
6413       "Cache-Control: max-age=3600\n";
6414   RunTransactionTest(cache.http_cache(), transaction);
6415 
6416   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6417   EXPECT_EQ(1, cache.disk_cache()->open_count());
6418   EXPECT_EQ(1, cache.disk_cache()->create_count());
6419 
6420   // Make sure that the ActiveEntry is gone.
6421   base::RunLoop().RunUntilIdle();
6422 
6423   // Generate a vary mismatch.
6424   transaction.request_headers = "Foo: none\r\n";
6425   RunTransactionTest(cache.http_cache(), transaction);
6426 
6427   EXPECT_EQ(3, cache.network_layer()->transaction_count());
6428   EXPECT_EQ(2, cache.disk_cache()->open_count());
6429   EXPECT_EQ(1, cache.disk_cache()->create_count());
6430 }
6431 
6432 // Tests that a 304 without vary headers doesn't delete the previously stored
6433 // vary data after a vary mismatch.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMismatch_DontDeleteVary)6434 TEST_F(HttpCacheTest, GET_ValidateCache_VaryMismatch_DontDeleteVary) {
6435   MockHttpCache cache;
6436 
6437   // Write to the cache.
6438   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6439   transaction.request_headers = "Foo: bar\r\n";
6440   transaction.response_headers =
6441       "Etag: \"foopy\"\n"
6442       "Cache-Control: max-age=3600\n"
6443       "Vary: Foo\n";
6444   RunTransactionTest(cache.http_cache(), transaction);
6445 
6446   // Vary-mismatch validation receives 304 and no vary header.
6447   transaction.request_headers = "Foo: none\r\n";
6448   transaction.status = "HTTP/1.1 304 Not Modified";
6449   transaction.response_headers =
6450       "Etag: \"foopy\"\n"
6451       "Cache-Control: max-age=3600\n";
6452   RunTransactionTest(cache.http_cache(), transaction);
6453 
6454   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6455   EXPECT_EQ(1, cache.disk_cache()->open_count());
6456   EXPECT_EQ(1, cache.disk_cache()->create_count());
6457 
6458   // Make sure that the ActiveEntry is gone.
6459   base::RunLoop().RunUntilIdle();
6460 
6461   // Generate a vary mismatch.
6462   transaction.request_headers = "Foo: bar\r\n";
6463   RunTransactionTest(cache.http_cache(), transaction);
6464 
6465   EXPECT_EQ(3, cache.network_layer()->transaction_count());
6466   EXPECT_EQ(2, cache.disk_cache()->open_count());
6467   EXPECT_EQ(1, cache.disk_cache()->create_count());
6468 }
6469 
ETagGet_UnconditionalRequest_Handler(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)6470 static void ETagGet_UnconditionalRequest_Handler(const HttpRequestInfo* request,
6471                                                  std::string* response_status,
6472                                                  std::string* response_headers,
6473                                                  std::string* response_data) {
6474   EXPECT_FALSE(
6475       request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
6476 }
6477 
TEST_F(HttpCacheTest,ETagGET_Http10)6478 TEST_F(HttpCacheTest, ETagGET_Http10) {
6479   MockHttpCache cache;
6480 
6481   ScopedMockTransaction transaction(kETagGET_Transaction);
6482   transaction.status = "HTTP/1.0 200 OK";
6483 
6484   // Write to the cache.
6485   RunTransactionTest(cache.http_cache(), transaction);
6486 
6487   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6488   EXPECT_EQ(0, cache.disk_cache()->open_count());
6489   EXPECT_EQ(1, cache.disk_cache()->create_count());
6490 
6491   // Get the same URL again, without generating a conditional request.
6492   transaction.load_flags = LOAD_VALIDATE_CACHE;
6493   transaction.handler = ETagGet_UnconditionalRequest_Handler;
6494   RunTransactionTest(cache.http_cache(), transaction);
6495 
6496   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6497   EXPECT_EQ(1, cache.disk_cache()->open_count());
6498   EXPECT_EQ(1, cache.disk_cache()->create_count());
6499 }
6500 
TEST_F(HttpCacheTest,ETagGET_Http10_Range)6501 TEST_F(HttpCacheTest, ETagGET_Http10_Range) {
6502   MockHttpCache cache;
6503 
6504   ScopedMockTransaction transaction(kETagGET_Transaction);
6505   transaction.status = "HTTP/1.0 200 OK";
6506 
6507   // Write to the cache.
6508   RunTransactionTest(cache.http_cache(), transaction);
6509 
6510   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6511   EXPECT_EQ(0, cache.disk_cache()->open_count());
6512   EXPECT_EQ(1, cache.disk_cache()->create_count());
6513 
6514   // Get the same URL again, but use a byte range request.
6515   transaction.load_flags = LOAD_VALIDATE_CACHE;
6516   transaction.handler = ETagGet_UnconditionalRequest_Handler;
6517   transaction.request_headers = "Range: bytes = 5-\r\n";
6518   RunTransactionTest(cache.http_cache(), transaction);
6519 
6520   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6521   EXPECT_EQ(1, cache.disk_cache()->open_count());
6522   EXPECT_EQ(2, cache.disk_cache()->create_count());
6523 }
6524 
ETagGet_ConditionalRequest_NoStore_Handler(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)6525 static void ETagGet_ConditionalRequest_NoStore_Handler(
6526     const HttpRequestInfo* request,
6527     std::string* response_status,
6528     std::string* response_headers,
6529     std::string* response_data) {
6530   EXPECT_TRUE(
6531       request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
6532   response_status->assign("HTTP/1.1 304 Not Modified");
6533   response_headers->assign("Cache-Control: no-store\n");
6534   response_data->clear();
6535 }
6536 
TEST_F(HttpCacheTest,ETagGET_ConditionalRequest_304_NoStore)6537 TEST_F(HttpCacheTest, ETagGET_ConditionalRequest_304_NoStore) {
6538   MockHttpCache cache;
6539 
6540   ScopedMockTransaction transaction(kETagGET_Transaction);
6541 
6542   // Write to the cache.
6543   RunTransactionTest(cache.http_cache(), transaction);
6544 
6545   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6546   EXPECT_EQ(0, cache.disk_cache()->open_count());
6547   EXPECT_EQ(1, cache.disk_cache()->create_count());
6548 
6549   // Get the same URL again, but this time we expect it to result
6550   // in a conditional request.
6551   transaction.load_flags = LOAD_VALIDATE_CACHE;
6552   transaction.handler = ETagGet_ConditionalRequest_NoStore_Handler;
6553   RunTransactionTest(cache.http_cache(), transaction);
6554 
6555   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6556   EXPECT_EQ(1, cache.disk_cache()->open_count());
6557   EXPECT_EQ(1, cache.disk_cache()->create_count());
6558 
6559   ScopedMockTransaction transaction2(kETagGET_Transaction);
6560 
6561   // Write to the cache again. This should create a new entry.
6562   RunTransactionTest(cache.http_cache(), transaction2);
6563 
6564   EXPECT_EQ(3, cache.network_layer()->transaction_count());
6565   EXPECT_EQ(1, cache.disk_cache()->open_count());
6566   EXPECT_EQ(2, cache.disk_cache()->create_count());
6567 }
6568 
6569 // Helper that does 4 requests using HttpCache:
6570 //
6571 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
6572 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
6573 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
6574 //     be returned.
6575 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
6576 //     returned.
6577 // The entry will be created once and will be opened for the 3 subsequent
6578 // requests.
ConditionalizedRequestUpdatesCacheHelper(const Response & net_response_1,const Response & net_response_2,const Response & cached_response_2,const char * extra_request_headers)6579 static void ConditionalizedRequestUpdatesCacheHelper(
6580     const Response& net_response_1,
6581     const Response& net_response_2,
6582     const Response& cached_response_2,
6583     const char* extra_request_headers) {
6584   MockHttpCache cache;
6585 
6586   // The URL we will be requesting.
6587   const char kUrl[] = "http://foobar.com/main.css";
6588 
6589   // Junk network response.
6590   static const Response kUnexpectedResponse = {
6591     "HTTP/1.1 500 Unexpected",
6592     "Server: unexpected_header",
6593     "unexpected body"
6594   };
6595 
6596   // We will control the network layer's responses for |kUrl| using
6597   // |mock_network_response|.
6598   MockTransaction mock_network_response = {nullptr};
6599   mock_network_response.url = kUrl;
6600   AddMockTransaction(&mock_network_response);
6601 
6602   // Request |kUrl| for the first time. It should hit the network and
6603   // receive |kNetResponse1|, which it saves into the HTTP cache.
6604 
6605   MockTransaction request = {nullptr};
6606   request.url = kUrl;
6607   request.method = "GET";
6608   request.request_headers = "";
6609 
6610   net_response_1.AssignTo(&mock_network_response);  // Network mock.
6611   net_response_1.AssignTo(&request);                // Expected result.
6612 
6613   std::string response_headers;
6614   RunTransactionTestWithResponse(
6615       cache.http_cache(), request, &response_headers);
6616 
6617   EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
6618   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6619   EXPECT_EQ(0, cache.disk_cache()->open_count());
6620   EXPECT_EQ(1, cache.disk_cache()->create_count());
6621 
6622   // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
6623   // cache, so we don't hit the network.
6624 
6625   request.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
6626 
6627   kUnexpectedResponse.AssignTo(&mock_network_response);  // Network mock.
6628   net_response_1.AssignTo(&request);                     // Expected result.
6629 
6630   RunTransactionTestWithResponse(
6631       cache.http_cache(), request, &response_headers);
6632 
6633   EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
6634   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6635   EXPECT_EQ(1, cache.disk_cache()->open_count());
6636   EXPECT_EQ(1, cache.disk_cache()->create_count());
6637 
6638   // Request |kUrl| yet again, but this time give the request an
6639   // "If-Modified-Since" header. This will cause the request to re-hit the
6640   // network. However now the network response is going to be
6641   // different -- this simulates a change made to the CSS file.
6642 
6643   request.request_headers = extra_request_headers;
6644   request.load_flags = LOAD_NORMAL;
6645 
6646   net_response_2.AssignTo(&mock_network_response);  // Network mock.
6647   net_response_2.AssignTo(&request);                // Expected result.
6648 
6649   RunTransactionTestWithResponse(
6650       cache.http_cache(), request, &response_headers);
6651 
6652   EXPECT_EQ(net_response_2.status_and_headers(), response_headers);
6653   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6654   EXPECT_EQ(1, cache.disk_cache()->open_count());
6655   EXPECT_EQ(1, cache.disk_cache()->create_count());
6656 
6657   // Finally, request |kUrl| again. This request should be serviced from
6658   // the cache. Moreover, the value in the cache should be |kNetResponse2|
6659   // and NOT |kNetResponse1|. The previous step should have replaced the
6660   // value in the cache with the modified response.
6661 
6662   request.request_headers = "";
6663   request.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
6664 
6665   kUnexpectedResponse.AssignTo(&mock_network_response);  // Network mock.
6666   cached_response_2.AssignTo(&request);                  // Expected result.
6667 
6668   RunTransactionTestWithResponse(
6669       cache.http_cache(), request, &response_headers);
6670 
6671   EXPECT_EQ(cached_response_2.status_and_headers(), response_headers);
6672   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6673   EXPECT_EQ(2, cache.disk_cache()->open_count());
6674   EXPECT_EQ(1, cache.disk_cache()->create_count());
6675 
6676   RemoveMockTransaction(&mock_network_response);
6677 }
6678 
6679 // Check that when an "if-modified-since" header is attached
6680 // to the request, the result still updates the cached entry.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache1)6681 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache1) {
6682   // First network response for |kUrl|.
6683   static const Response kNetResponse1 = {
6684     "HTTP/1.1 200 OK",
6685     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6686     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6687     "body1"
6688   };
6689 
6690   // Second network response for |kUrl|.
6691   static const Response kNetResponse2 = {
6692     "HTTP/1.1 200 OK",
6693     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6694     "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
6695     "body2"
6696   };
6697 
6698   const char extra_headers[] =
6699       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
6700 
6701   ConditionalizedRequestUpdatesCacheHelper(
6702       kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
6703 }
6704 
6705 // Check that when an "if-none-match" header is attached
6706 // to the request, the result updates the cached entry.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache2)6707 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache2) {
6708   // First network response for |kUrl|.
6709   static const Response kNetResponse1 = {
6710     "HTTP/1.1 200 OK",
6711     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6712     "Etag: \"ETAG1\"\n"
6713     "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n",  // Should never expire.
6714     "body1"
6715   };
6716 
6717   // Second network response for |kUrl|.
6718   static const Response kNetResponse2 = {
6719     "HTTP/1.1 200 OK",
6720     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6721     "Etag: \"ETAG2\"\n"
6722     "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n",  // Should never expire.
6723     "body2"
6724   };
6725 
6726   const char extra_headers[] = "If-None-Match: \"ETAG1\"\r\n";
6727 
6728   ConditionalizedRequestUpdatesCacheHelper(
6729       kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
6730 }
6731 
6732 // Check that when an "if-modified-since" header is attached
6733 // to a request, the 304 (not modified result) result updates the cached
6734 // headers, and the 304 response is returned rather than the cached response.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache3)6735 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache3) {
6736   // First network response for |kUrl|.
6737   static const Response kNetResponse1 = {
6738     "HTTP/1.1 200 OK",
6739     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6740     "Server: server1\n"
6741     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6742     "body1"
6743   };
6744 
6745   // Second network response for |kUrl|.
6746   static const Response kNetResponse2 = {
6747     "HTTP/1.1 304 Not Modified",
6748     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6749     "Server: server2\n"
6750     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6751     ""
6752   };
6753 
6754   static const Response kCachedResponse2 = {
6755     "HTTP/1.1 200 OK",
6756     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6757     "Server: server2\n"
6758     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6759     "body1"
6760   };
6761 
6762   const char extra_headers[] =
6763       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
6764 
6765   ConditionalizedRequestUpdatesCacheHelper(
6766       kNetResponse1, kNetResponse2, kCachedResponse2, extra_headers);
6767 }
6768 
6769 // Test that when doing an externally conditionalized if-modified-since
6770 // and there is no corresponding cache entry, a new cache entry is NOT
6771 // created (304 response).
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache4)6772 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache4) {
6773   MockHttpCache cache;
6774 
6775   const char kUrl[] = "http://foobar.com/main.css";
6776 
6777   static const Response kNetResponse = {
6778     "HTTP/1.1 304 Not Modified",
6779     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6780     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6781     ""
6782   };
6783 
6784   const char kExtraRequestHeaders[] =
6785       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
6786 
6787   // We will control the network layer's responses for |kUrl| using
6788   // |mock_network_response|.
6789   MockTransaction mock_network_response = {nullptr};
6790   mock_network_response.url = kUrl;
6791   AddMockTransaction(&mock_network_response);
6792 
6793   MockTransaction request = {nullptr};
6794   request.url = kUrl;
6795   request.method = "GET";
6796   request.request_headers = kExtraRequestHeaders;
6797 
6798   kNetResponse.AssignTo(&mock_network_response);  // Network mock.
6799   kNetResponse.AssignTo(&request);                // Expected result.
6800 
6801   std::string response_headers;
6802   RunTransactionTestWithResponse(
6803       cache.http_cache(), request, &response_headers);
6804 
6805   EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
6806   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6807   EXPECT_EQ(0, cache.disk_cache()->open_count());
6808   EXPECT_EQ(0, cache.disk_cache()->create_count());
6809 
6810   RemoveMockTransaction(&mock_network_response);
6811 }
6812 
6813 // Test that when doing an externally conditionalized if-modified-since
6814 // and there is no corresponding cache entry, a new cache entry is NOT
6815 // created (200 response).
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache5)6816 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache5) {
6817   MockHttpCache cache;
6818 
6819   const char kUrl[] = "http://foobar.com/main.css";
6820 
6821   static const Response kNetResponse = {
6822     "HTTP/1.1 200 OK",
6823     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6824     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6825     "foobar!!!"
6826   };
6827 
6828   const char kExtraRequestHeaders[] =
6829       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
6830 
6831   // We will control the network layer's responses for |kUrl| using
6832   // |mock_network_response|.
6833   MockTransaction mock_network_response = {nullptr};
6834   mock_network_response.url = kUrl;
6835   AddMockTransaction(&mock_network_response);
6836 
6837   MockTransaction request = {nullptr};
6838   request.url = kUrl;
6839   request.method = "GET";
6840   request.request_headers = kExtraRequestHeaders;
6841 
6842   kNetResponse.AssignTo(&mock_network_response);  // Network mock.
6843   kNetResponse.AssignTo(&request);                // Expected result.
6844 
6845   std::string response_headers;
6846   RunTransactionTestWithResponse(
6847       cache.http_cache(), request, &response_headers);
6848 
6849   EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
6850   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6851   EXPECT_EQ(0, cache.disk_cache()->open_count());
6852   EXPECT_EQ(0, cache.disk_cache()->create_count());
6853 
6854   RemoveMockTransaction(&mock_network_response);
6855 }
6856 
6857 // Test that when doing an externally conditionalized if-modified-since
6858 // if the date does not match the cache entry's last-modified date,
6859 // then we do NOT use the response (304) to update the cache.
6860 // (the if-modified-since date is 2 days AFTER the cache's modification date).
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache6)6861 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache6) {
6862   static const Response kNetResponse1 = {
6863     "HTTP/1.1 200 OK",
6864     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6865     "Server: server1\n"
6866     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6867     "body1"
6868   };
6869 
6870   // Second network response for |kUrl|.
6871   static const Response kNetResponse2 = {
6872     "HTTP/1.1 304 Not Modified",
6873     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6874     "Server: server2\n"
6875     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6876     ""
6877   };
6878 
6879   // This is two days in the future from the original response's last-modified
6880   // date!
6881   const char kExtraRequestHeaders[] =
6882       "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
6883 
6884   ConditionalizedRequestUpdatesCacheHelper(
6885       kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
6886 }
6887 
6888 // Test that when doing an externally conditionalized if-none-match
6889 // if the etag does not match the cache entry's etag, then we do not use the
6890 // response (304) to update the cache.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache7)6891 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache7) {
6892   static const Response kNetResponse1 = {
6893     "HTTP/1.1 200 OK",
6894     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6895     "Etag: \"Foo1\"\n"
6896     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6897     "body1"
6898   };
6899 
6900   // Second network response for |kUrl|.
6901   static const Response kNetResponse2 = {
6902     "HTTP/1.1 304 Not Modified",
6903     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6904     "Etag: \"Foo2\"\n"
6905     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6906     ""
6907   };
6908 
6909   // Different etag from original response.
6910   const char kExtraRequestHeaders[] = "If-None-Match: \"Foo2\"\r\n";
6911 
6912   ConditionalizedRequestUpdatesCacheHelper(
6913       kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
6914 }
6915 
6916 // Test that doing an externally conditionalized request with both if-none-match
6917 // and if-modified-since updates the cache.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache8)6918 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache8) {
6919   static const Response kNetResponse1 = {
6920     "HTTP/1.1 200 OK",
6921     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6922     "Etag: \"Foo1\"\n"
6923     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6924     "body1"
6925   };
6926 
6927   // Second network response for |kUrl|.
6928   static const Response kNetResponse2 = {
6929     "HTTP/1.1 200 OK",
6930     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6931     "Etag: \"Foo2\"\n"
6932     "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
6933     "body2"
6934   };
6935 
6936   const char kExtraRequestHeaders[] =
6937       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
6938       "If-None-Match: \"Foo1\"\r\n";
6939 
6940   ConditionalizedRequestUpdatesCacheHelper(
6941       kNetResponse1, kNetResponse2, kNetResponse2, kExtraRequestHeaders);
6942 }
6943 
6944 // Test that doing an externally conditionalized request with both if-none-match
6945 // and if-modified-since does not update the cache with only one match.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache9)6946 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache9) {
6947   static const Response kNetResponse1 = {
6948     "HTTP/1.1 200 OK",
6949     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6950     "Etag: \"Foo1\"\n"
6951     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6952     "body1"
6953   };
6954 
6955   // Second network response for |kUrl|.
6956   static const Response kNetResponse2 = {
6957     "HTTP/1.1 200 OK",
6958     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6959     "Etag: \"Foo2\"\n"
6960     "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
6961     "body2"
6962   };
6963 
6964   // The etag doesn't match what we have stored.
6965   const char kExtraRequestHeaders[] =
6966       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
6967       "If-None-Match: \"Foo2\"\r\n";
6968 
6969   ConditionalizedRequestUpdatesCacheHelper(
6970       kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
6971 }
6972 
6973 // Test that doing an externally conditionalized request with both if-none-match
6974 // and if-modified-since does not update the cache with only one match.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache10)6975 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache10) {
6976   static const Response kNetResponse1 = {
6977     "HTTP/1.1 200 OK",
6978     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6979     "Etag: \"Foo1\"\n"
6980     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6981     "body1"
6982   };
6983 
6984   // Second network response for |kUrl|.
6985   static const Response kNetResponse2 = {
6986     "HTTP/1.1 200 OK",
6987     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6988     "Etag: \"Foo2\"\n"
6989     "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
6990     "body2"
6991   };
6992 
6993   // The modification date doesn't match what we have stored.
6994   const char kExtraRequestHeaders[] =
6995       "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
6996       "If-None-Match: \"Foo1\"\r\n";
6997 
6998   ConditionalizedRequestUpdatesCacheHelper(
6999       kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
7000 }
7001 
TEST_F(HttpCacheTest,UrlContainingHash)7002 TEST_F(HttpCacheTest, UrlContainingHash) {
7003   MockHttpCache cache;
7004 
7005   // Do a typical GET request -- should write an entry into our cache.
7006   MockTransaction trans(kTypicalGET_Transaction);
7007   RunTransactionTest(cache.http_cache(), trans);
7008 
7009   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7010   EXPECT_EQ(0, cache.disk_cache()->open_count());
7011   EXPECT_EQ(1, cache.disk_cache()->create_count());
7012 
7013   // Request the same URL, but this time with a reference section (hash).
7014   // Since the cache key strips the hash sections, this should be a cache hit.
7015   std::string url_with_hash = std::string(trans.url) + "#multiple#hashes";
7016   trans.url = url_with_hash.c_str();
7017   trans.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7018 
7019   RunTransactionTest(cache.http_cache(), trans);
7020 
7021   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7022   EXPECT_EQ(1, cache.disk_cache()->open_count());
7023   EXPECT_EQ(1, cache.disk_cache()->create_count());
7024 }
7025 
7026 // Tests that we skip the cache for POST requests that do not have an upload
7027 // identifier.
TEST_F(HttpCacheTest,SimplePOST_SkipsCache)7028 TEST_F(HttpCacheTest, SimplePOST_SkipsCache) {
7029   MockHttpCache cache;
7030 
7031   RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
7032 
7033   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7034   EXPECT_EQ(0, cache.disk_cache()->open_count());
7035   EXPECT_EQ(0, cache.disk_cache()->create_count());
7036 }
7037 
7038 // Tests POST handling with a disabled cache (no DCHECK).
TEST_F(HttpCacheTest,SimplePOST_DisabledCache)7039 TEST_F(HttpCacheTest, SimplePOST_DisabledCache) {
7040   MockHttpCache cache;
7041   cache.http_cache()->set_mode(HttpCache::Mode::DISABLE);
7042 
7043   RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
7044 
7045   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7046   EXPECT_EQ(0, cache.disk_cache()->open_count());
7047   EXPECT_EQ(0, cache.disk_cache()->create_count());
7048 }
7049 
TEST_F(HttpCacheTest,SimplePOST_LoadOnlyFromCache_Miss)7050 TEST_F(HttpCacheTest, SimplePOST_LoadOnlyFromCache_Miss) {
7051   MockHttpCache cache;
7052 
7053   MockTransaction transaction(kSimplePOST_Transaction);
7054   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7055 
7056   MockHttpRequest request(transaction);
7057   TestCompletionCallback callback;
7058 
7059   std::unique_ptr<HttpTransaction> trans;
7060   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
7061   ASSERT_TRUE(trans.get());
7062 
7063   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
7064   ASSERT_THAT(callback.GetResult(rv), IsError(ERR_CACHE_MISS));
7065 
7066   trans.reset();
7067 
7068   EXPECT_EQ(0, cache.network_layer()->transaction_count());
7069   EXPECT_EQ(0, cache.disk_cache()->open_count());
7070   EXPECT_EQ(0, cache.disk_cache()->create_count());
7071 }
7072 
TEST_F(HttpCacheTest,SimplePOST_LoadOnlyFromCache_Hit)7073 TEST_F(HttpCacheTest, SimplePOST_LoadOnlyFromCache_Hit) {
7074   MockHttpCache cache;
7075 
7076   // Test that we hit the cache for POST requests.
7077 
7078   MockTransaction transaction(kSimplePOST_Transaction);
7079 
7080   const int64_t kUploadId = 1;  // Just a dummy value.
7081 
7082   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7083   element_readers.push_back(
7084       std::make_unique<UploadBytesElementReader>("hello", 5));
7085   ElementsUploadDataStream upload_data_stream(std::move(element_readers),
7086                                               kUploadId);
7087   MockHttpRequest request(transaction);
7088   request.upload_data_stream = &upload_data_stream;
7089 
7090   // Populate the cache.
7091   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
7092                                 nullptr);
7093 
7094   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7095   EXPECT_EQ(0, cache.disk_cache()->open_count());
7096   EXPECT_EQ(1, cache.disk_cache()->create_count());
7097 
7098   // Load from cache.
7099   request.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7100   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
7101                                 nullptr);
7102 
7103   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7104   EXPECT_EQ(1, cache.disk_cache()->open_count());
7105   EXPECT_EQ(1, cache.disk_cache()->create_count());
7106 }
7107 
7108 // Test that we don't hit the cache for POST requests if there is a byte range.
TEST_F(HttpCacheTest,SimplePOST_WithRanges)7109 TEST_F(HttpCacheTest, SimplePOST_WithRanges) {
7110   MockHttpCache cache;
7111 
7112   MockTransaction transaction(kSimplePOST_Transaction);
7113   transaction.request_headers = "Range: bytes = 0-4\r\n";
7114 
7115   const int64_t kUploadId = 1;  // Just a dummy value.
7116 
7117   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7118   element_readers.push_back(
7119       std::make_unique<UploadBytesElementReader>("hello", 5));
7120   ElementsUploadDataStream upload_data_stream(std::move(element_readers),
7121                                               kUploadId);
7122 
7123   MockHttpRequest request(transaction);
7124   request.upload_data_stream = &upload_data_stream;
7125 
7126   // Attempt to populate the cache.
7127   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
7128                                 nullptr);
7129 
7130   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7131   EXPECT_EQ(0, cache.disk_cache()->open_count());
7132   EXPECT_EQ(0, cache.disk_cache()->create_count());
7133 }
7134 
7135 // Tests that a POST is cached separately from a GET.
TEST_F(HttpCacheTest,SimplePOST_SeparateCache)7136 TEST_F(HttpCacheTest, SimplePOST_SeparateCache) {
7137   MockHttpCache cache;
7138 
7139   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7140   element_readers.push_back(
7141       std::make_unique<UploadBytesElementReader>("hello", 5));
7142   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 1);
7143 
7144   MockTransaction transaction(kSimplePOST_Transaction);
7145   MockHttpRequest req1(transaction);
7146   req1.upload_data_stream = &upload_data_stream;
7147 
7148   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7149 
7150   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7151   EXPECT_EQ(0, cache.disk_cache()->open_count());
7152   EXPECT_EQ(1, cache.disk_cache()->create_count());
7153 
7154   transaction.method = "GET";
7155   MockHttpRequest req2(transaction);
7156 
7157   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7158 
7159   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7160   EXPECT_EQ(0, cache.disk_cache()->open_count());
7161   EXPECT_EQ(2, cache.disk_cache()->create_count());
7162 }
7163 
7164 // Tests that a successful POST invalidates a previously cached GET.
TEST_F(HttpCacheTest,SimplePOST_Invalidate_205)7165 TEST_F(HttpCacheTest, SimplePOST_Invalidate_205) {
7166   MockHttpCache cache;
7167 
7168   MockTransaction transaction(kSimpleGET_Transaction);
7169   AddMockTransaction(&transaction);
7170   MockHttpRequest req1(transaction);
7171 
7172   // Attempt to populate the cache.
7173   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7174 
7175   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7176   EXPECT_EQ(0, cache.disk_cache()->open_count());
7177   EXPECT_EQ(1, cache.disk_cache()->create_count());
7178 
7179   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7180   element_readers.push_back(
7181       std::make_unique<UploadBytesElementReader>("hello", 5));
7182   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 1);
7183 
7184   transaction.method = "POST";
7185   transaction.status = "HTTP/1.1 205 No Content";
7186   MockHttpRequest req2(transaction);
7187   req2.upload_data_stream = &upload_data_stream;
7188 
7189   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7190 
7191   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7192   EXPECT_EQ(0, cache.disk_cache()->open_count());
7193   EXPECT_EQ(2, cache.disk_cache()->create_count());
7194 
7195   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7196 
7197   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7198   EXPECT_EQ(0, cache.disk_cache()->open_count());
7199   EXPECT_EQ(3, cache.disk_cache()->create_count());
7200   RemoveMockTransaction(&transaction);
7201 }
7202 
7203 // Tests that a successful POST invalidates a previously cached GET,
7204 // with cache split by top-frame origin.
TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,SimplePOST_Invalidate_205_SplitCache)7205 TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,
7206        SimplePOST_Invalidate_205_SplitCache) {
7207   SchemefulSite site_a(GURL("http://a.com"));
7208   SchemefulSite site_b(GURL("http://b.com"));
7209 
7210   MockHttpCache cache;
7211 
7212   MockTransaction transaction(kSimpleGET_Transaction);
7213   AddMockTransaction(&transaction);
7214   MockHttpRequest req1(transaction);
7215   req1.network_isolation_key = NetworkIsolationKey(site_a, site_a);
7216   req1.network_anonymization_key =
7217       net::NetworkAnonymizationKey::CreateSameSite(site_a);
7218 
7219   // Attempt to populate the cache.
7220   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7221 
7222   // Same for a different origin.
7223   MockHttpRequest req1b(transaction);
7224   req1b.network_isolation_key = NetworkIsolationKey(site_b, site_b);
7225   req1b.network_anonymization_key =
7226       net::NetworkAnonymizationKey::CreateSameSite(site_b);
7227   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1b,
7228                                 nullptr);
7229 
7230   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7231   EXPECT_EQ(0, cache.disk_cache()->open_count());
7232   EXPECT_EQ(2, cache.disk_cache()->create_count());
7233 
7234   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7235   element_readers.push_back(
7236       std::make_unique<UploadBytesElementReader>("hello", 5));
7237   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 1);
7238 
7239   transaction.method = "POST";
7240   transaction.status = "HTTP/1.1 205 No Content";
7241   MockHttpRequest req2(transaction);
7242   req2.upload_data_stream = &upload_data_stream;
7243   req2.network_isolation_key = NetworkIsolationKey(site_a, site_a);
7244   req2.network_anonymization_key =
7245       net::NetworkAnonymizationKey::CreateSameSite(site_a);
7246 
7247   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7248 
7249   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7250   EXPECT_EQ(0, cache.disk_cache()->open_count());
7251   EXPECT_EQ(3, cache.disk_cache()->create_count());
7252 
7253   // req1b should still be cached, since it has a different top-level frame
7254   // origin.
7255   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1b,
7256                                 nullptr);
7257   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7258   EXPECT_EQ(1, cache.disk_cache()->open_count());
7259   EXPECT_EQ(3, cache.disk_cache()->create_count());
7260 
7261   // req1 should not be cached after the POST.
7262   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7263   EXPECT_EQ(4, cache.network_layer()->transaction_count());
7264   EXPECT_EQ(1, cache.disk_cache()->open_count());
7265   EXPECT_EQ(4, cache.disk_cache()->create_count());
7266 
7267   RemoveMockTransaction(&transaction);
7268 }
7269 
7270 // Tests that a successful POST invalidates a previously cached GET, even when
7271 // there is no upload identifier.
TEST_F(HttpCacheTest,SimplePOST_NoUploadId_Invalidate_205)7272 TEST_F(HttpCacheTest, SimplePOST_NoUploadId_Invalidate_205) {
7273   MockHttpCache cache;
7274 
7275   MockTransaction transaction(kSimpleGET_Transaction);
7276   AddMockTransaction(&transaction);
7277   MockHttpRequest req1(transaction);
7278 
7279   // Attempt to populate the cache.
7280   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7281 
7282   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7283   EXPECT_EQ(0, cache.disk_cache()->open_count());
7284   EXPECT_EQ(1, cache.disk_cache()->create_count());
7285 
7286   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7287   element_readers.push_back(
7288       std::make_unique<UploadBytesElementReader>("hello", 5));
7289   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7290 
7291   transaction.method = "POST";
7292   transaction.status = "HTTP/1.1 205 No Content";
7293   MockHttpRequest req2(transaction);
7294   req2.upload_data_stream = &upload_data_stream;
7295 
7296   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7297 
7298   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7299   EXPECT_EQ(0, cache.disk_cache()->open_count());
7300   EXPECT_EQ(1, cache.disk_cache()->create_count());
7301 
7302   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7303 
7304   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7305   EXPECT_EQ(0, cache.disk_cache()->open_count());
7306   EXPECT_EQ(2, cache.disk_cache()->create_count());
7307   RemoveMockTransaction(&transaction);
7308 }
7309 
7310 // Tests that processing a POST before creating the backend doesn't crash.
TEST_F(HttpCacheTest,SimplePOST_NoUploadId_NoBackend)7311 TEST_F(HttpCacheTest, SimplePOST_NoUploadId_NoBackend) {
7312   // This will initialize a cache object with NULL backend.
7313   auto factory = std::make_unique<MockBlockingBackendFactory>();
7314   factory->set_fail(true);
7315   factory->FinishCreation();
7316   MockHttpCache cache(std::move(factory));
7317 
7318   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7319   element_readers.push_back(
7320       std::make_unique<UploadBytesElementReader>("hello", 5));
7321   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7322 
7323   MockTransaction transaction(kSimplePOST_Transaction);
7324   AddMockTransaction(&transaction);
7325   MockHttpRequest req(transaction);
7326   req.upload_data_stream = &upload_data_stream;
7327 
7328   RunTransactionTestWithRequest(cache.http_cache(), transaction, req, nullptr);
7329 
7330   RemoveMockTransaction(&transaction);
7331 }
7332 
7333 // Tests that we don't invalidate entries as a result of a failed POST.
TEST_F(HttpCacheTest,SimplePOST_DontInvalidate_100)7334 TEST_F(HttpCacheTest, SimplePOST_DontInvalidate_100) {
7335   MockHttpCache cache;
7336 
7337   MockTransaction transaction(kSimpleGET_Transaction);
7338   AddMockTransaction(&transaction);
7339   MockHttpRequest req1(transaction);
7340 
7341   // Attempt to populate the cache.
7342   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7343 
7344   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7345   EXPECT_EQ(0, cache.disk_cache()->open_count());
7346   EXPECT_EQ(1, cache.disk_cache()->create_count());
7347 
7348   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7349   element_readers.push_back(
7350       std::make_unique<UploadBytesElementReader>("hello", 5));
7351   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 1);
7352 
7353   transaction.method = "POST";
7354   transaction.status = "HTTP/1.1 100 Continue";
7355   MockHttpRequest req2(transaction);
7356   req2.upload_data_stream = &upload_data_stream;
7357 
7358   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7359 
7360   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7361   EXPECT_EQ(0, cache.disk_cache()->open_count());
7362   EXPECT_EQ(2, cache.disk_cache()->create_count());
7363 
7364   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7365 
7366   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7367   EXPECT_EQ(1, cache.disk_cache()->open_count());
7368   EXPECT_EQ(2, cache.disk_cache()->create_count());
7369   RemoveMockTransaction(&transaction);
7370 }
7371 
7372 // Tests that a HEAD request is not cached by itself.
TEST_F(HttpCacheTest,SimpleHEAD_LoadOnlyFromCache_Miss)7373 TEST_F(HttpCacheTest, SimpleHEAD_LoadOnlyFromCache_Miss) {
7374   MockHttpCache cache;
7375   MockTransaction transaction(kSimplePOST_Transaction);
7376   AddMockTransaction(&transaction);
7377   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7378   transaction.method = "HEAD";
7379 
7380   MockHttpRequest request(transaction);
7381   TestCompletionCallback callback;
7382 
7383   std::unique_ptr<HttpTransaction> trans;
7384   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
7385   ASSERT_TRUE(trans.get());
7386 
7387   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
7388   ASSERT_THAT(callback.GetResult(rv), IsError(ERR_CACHE_MISS));
7389 
7390   trans.reset();
7391 
7392   EXPECT_EQ(0, cache.network_layer()->transaction_count());
7393   EXPECT_EQ(0, cache.disk_cache()->open_count());
7394   EXPECT_EQ(0, cache.disk_cache()->create_count());
7395   RemoveMockTransaction(&transaction);
7396 }
7397 
7398 // Tests that a HEAD request is served from a cached GET.
TEST_F(HttpCacheTest,SimpleHEAD_LoadOnlyFromCache_Hit)7399 TEST_F(HttpCacheTest, SimpleHEAD_LoadOnlyFromCache_Hit) {
7400   MockHttpCache cache;
7401   MockTransaction transaction(kSimpleGET_Transaction);
7402   AddMockTransaction(&transaction);
7403 
7404   // Populate the cache.
7405   RunTransactionTest(cache.http_cache(), transaction);
7406 
7407   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7408   EXPECT_EQ(0, cache.disk_cache()->open_count());
7409   EXPECT_EQ(1, cache.disk_cache()->create_count());
7410 
7411   // Load from cache.
7412   transaction.method = "HEAD";
7413   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7414   transaction.data = "";
7415   RunTransactionTest(cache.http_cache(), transaction);
7416 
7417   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7418   EXPECT_EQ(1, cache.disk_cache()->open_count());
7419   EXPECT_EQ(1, cache.disk_cache()->create_count());
7420   RemoveMockTransaction(&transaction);
7421 }
7422 
7423 // Tests that a read-only request served from the cache preserves CL.
TEST_F(HttpCacheTest,SimpleHEAD_ContentLengthOnHit_Read)7424 TEST_F(HttpCacheTest, SimpleHEAD_ContentLengthOnHit_Read) {
7425   MockHttpCache cache;
7426   MockTransaction transaction(kSimpleGET_Transaction);
7427   AddMockTransaction(&transaction);
7428   transaction.response_headers = "Content-Length: 42\n";
7429 
7430   // Populate the cache.
7431   RunTransactionTest(cache.http_cache(), transaction);
7432 
7433   // Load from cache.
7434   transaction.method = "HEAD";
7435   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7436   transaction.data = "";
7437   std::string headers;
7438 
7439   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7440 
7441   EXPECT_EQ("HTTP/1.1 200 OK\nContent-Length: 42\n", headers);
7442   RemoveMockTransaction(&transaction);
7443 }
7444 
7445 // Tests that a read-write request served from the cache preserves CL.
TEST_F(HttpCacheTest,ETagHEAD_ContentLengthOnHit_ReadWrite)7446 TEST_F(HttpCacheTest, ETagHEAD_ContentLengthOnHit_ReadWrite) {
7447   MockHttpCache cache;
7448   MockTransaction transaction(kETagGET_Transaction);
7449   AddMockTransaction(&transaction);
7450   std::string server_headers(kETagGET_Transaction.response_headers);
7451   server_headers.append("Content-Length: 42\n");
7452   transaction.response_headers = server_headers.data();
7453 
7454   // Populate the cache.
7455   RunTransactionTest(cache.http_cache(), transaction);
7456 
7457   // Load from cache.
7458   transaction.method = "HEAD";
7459   transaction.data = "";
7460   std::string headers;
7461 
7462   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7463 
7464   EXPECT_NE(std::string::npos, headers.find("Content-Length: 42\n"));
7465   RemoveMockTransaction(&transaction);
7466 }
7467 
7468 // Tests that a HEAD request that includes byte ranges bypasses the cache.
TEST_F(HttpCacheTest,SimpleHEAD_WithRanges)7469 TEST_F(HttpCacheTest, SimpleHEAD_WithRanges) {
7470   MockHttpCache cache;
7471   MockTransaction transaction(kSimpleGET_Transaction);
7472   AddMockTransaction(&transaction);
7473 
7474   // Populate the cache.
7475   RunTransactionTest(cache.http_cache(), transaction);
7476 
7477   // Load from cache.
7478   transaction.method = "HEAD";
7479   transaction.request_headers = "Range: bytes = 0-4\r\n";
7480   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7481   transaction.start_return_code = ERR_CACHE_MISS;
7482   RunTransactionTest(cache.http_cache(), transaction);
7483 
7484   EXPECT_EQ(0, cache.disk_cache()->open_count());
7485   EXPECT_EQ(1, cache.disk_cache()->create_count());
7486   RemoveMockTransaction(&transaction);
7487 }
7488 
7489 // Tests that a HEAD request can be served from a partialy cached resource.
TEST_F(HttpCacheTest,SimpleHEAD_WithCachedRanges)7490 TEST_F(HttpCacheTest, SimpleHEAD_WithCachedRanges) {
7491   MockHttpCache cache;
7492   AddMockTransaction(&kRangeGET_TransactionOK);
7493 
7494   // Write to the cache (40-49).
7495   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
7496   RemoveMockTransaction(&kRangeGET_TransactionOK);
7497 
7498   MockTransaction transaction(kSimpleGET_Transaction);
7499 
7500   transaction.url = kRangeGET_TransactionOK.url;
7501   transaction.method = "HEAD";
7502   transaction.data = "";
7503   AddMockTransaction(&transaction);
7504   std::string headers;
7505 
7506   // Load from cache.
7507   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7508 
7509   EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
7510   EXPECT_NE(std::string::npos, headers.find("Content-Length: 80\n"));
7511   EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
7512   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7513   EXPECT_EQ(1, cache.disk_cache()->open_count());
7514   EXPECT_EQ(1, cache.disk_cache()->create_count());
7515   RemoveMockTransaction(&transaction);
7516 }
7517 
7518 // Tests that a HEAD request can be served from a truncated resource.
TEST_F(HttpCacheTest,SimpleHEAD_WithTruncatedEntry)7519 TEST_F(HttpCacheTest, SimpleHEAD_WithTruncatedEntry) {
7520   MockHttpCache cache;
7521   AddMockTransaction(&kRangeGET_TransactionOK);
7522 
7523   std::string raw_headers("HTTP/1.1 200 OK\n"
7524                           "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7525                           "ETag: \"foo\"\n"
7526                           "Accept-Ranges: bytes\n"
7527                           "Content-Length: 80\n");
7528   CreateTruncatedEntry(raw_headers, &cache);
7529   RemoveMockTransaction(&kRangeGET_TransactionOK);
7530 
7531   MockTransaction transaction(kSimpleGET_Transaction);
7532 
7533   transaction.url = kRangeGET_TransactionOK.url;
7534   transaction.method = "HEAD";
7535   transaction.data = "";
7536   AddMockTransaction(&transaction);
7537   std::string headers;
7538 
7539   // Load from cache.
7540   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7541 
7542   EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
7543   EXPECT_NE(std::string::npos, headers.find("Content-Length: 80\n"));
7544   EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
7545   EXPECT_EQ(0, cache.network_layer()->transaction_count());
7546   EXPECT_EQ(1, cache.disk_cache()->open_count());
7547   EXPECT_EQ(1, cache.disk_cache()->create_count());
7548   RemoveMockTransaction(&transaction);
7549 }
7550 
7551 // Tests that a HEAD request updates the cached response.
TEST_F(HttpCacheTest,TypicalHEAD_UpdatesResponse)7552 TEST_F(HttpCacheTest, TypicalHEAD_UpdatesResponse) {
7553   MockHttpCache cache;
7554   MockTransaction transaction(kTypicalGET_Transaction);
7555   AddMockTransaction(&transaction);
7556 
7557   // Populate the cache.
7558   RunTransactionTest(cache.http_cache(), transaction);
7559 
7560   // Update the cache.
7561   transaction.method = "HEAD";
7562   transaction.response_headers = "Foo: bar\n";
7563   transaction.data = "";
7564   transaction.status = "HTTP/1.1 304 Not Modified\n";
7565   std::string headers;
7566   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7567   RemoveMockTransaction(&transaction);
7568 
7569   EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
7570   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7571 
7572   MockTransaction transaction2(kTypicalGET_Transaction);
7573   AddMockTransaction(&transaction2);
7574 
7575   // Make sure we are done with the previous transaction.
7576   base::RunLoop().RunUntilIdle();
7577 
7578   // Load from the cache.
7579   transaction2.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7580   RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
7581 
7582   EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
7583   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7584   EXPECT_EQ(2, cache.disk_cache()->open_count());
7585   EXPECT_EQ(1, cache.disk_cache()->create_count());
7586   RemoveMockTransaction(&transaction2);
7587 }
7588 
7589 // Tests that an externally conditionalized HEAD request updates the cache.
TEST_F(HttpCacheTest,TypicalHEAD_ConditionalizedRequestUpdatesResponse)7590 TEST_F(HttpCacheTest, TypicalHEAD_ConditionalizedRequestUpdatesResponse) {
7591   MockHttpCache cache;
7592   MockTransaction transaction(kTypicalGET_Transaction);
7593   AddMockTransaction(&transaction);
7594 
7595   // Populate the cache.
7596   RunTransactionTest(cache.http_cache(), transaction);
7597 
7598   // Update the cache.
7599   transaction.method = "HEAD";
7600   transaction.request_headers =
7601       "If-Modified-Since: Wed, 28 Nov 2007 00:40:09 GMT\r\n";
7602   transaction.response_headers = "Foo: bar\n";
7603   transaction.data = "";
7604   transaction.status = "HTTP/1.1 304 Not Modified\n";
7605   std::string headers;
7606   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7607   RemoveMockTransaction(&transaction);
7608 
7609   EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 304 Not Modified\n"));
7610   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7611 
7612   MockTransaction transaction2(kTypicalGET_Transaction);
7613   AddMockTransaction(&transaction2);
7614 
7615   // Make sure we are done with the previous transaction.
7616   base::RunLoop().RunUntilIdle();
7617 
7618   // Load from the cache.
7619   transaction2.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7620   RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
7621 
7622   EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
7623   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7624   EXPECT_EQ(2, cache.disk_cache()->open_count());
7625   EXPECT_EQ(1, cache.disk_cache()->create_count());
7626   RemoveMockTransaction(&transaction2);
7627 }
7628 
7629 // Tests that a HEAD request invalidates an old cached entry.
TEST_F(HttpCacheTest,SimpleHEAD_InvalidatesEntry)7630 TEST_F(HttpCacheTest, SimpleHEAD_InvalidatesEntry) {
7631   MockHttpCache cache;
7632   MockTransaction transaction(kTypicalGET_Transaction);
7633   AddMockTransaction(&transaction);
7634 
7635   // Populate the cache.
7636   RunTransactionTest(cache.http_cache(), transaction);
7637 
7638   // Update the cache.
7639   transaction.method = "HEAD";
7640   transaction.data = "";
7641   RunTransactionTest(cache.http_cache(), transaction);
7642   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7643 
7644   // Load from the cache.
7645   transaction.method = "GET";
7646   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7647   transaction.start_return_code = ERR_CACHE_MISS;
7648   RunTransactionTest(cache.http_cache(), transaction);
7649 
7650   RemoveMockTransaction(&transaction);
7651 }
7652 
7653 // Tests that we do not cache the response of a PUT.
TEST_F(HttpCacheTest,SimplePUT_Miss)7654 TEST_F(HttpCacheTest, SimplePUT_Miss) {
7655   MockHttpCache cache;
7656 
7657   MockTransaction transaction(kSimplePOST_Transaction);
7658   transaction.method = "PUT";
7659 
7660   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7661   element_readers.push_back(
7662       std::make_unique<UploadBytesElementReader>("hello", 5));
7663   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7664 
7665   MockHttpRequest request(transaction);
7666   request.upload_data_stream = &upload_data_stream;
7667 
7668   // Attempt to populate the cache.
7669   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
7670                                 nullptr);
7671 
7672   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7673   EXPECT_EQ(0, cache.disk_cache()->open_count());
7674   EXPECT_EQ(0, cache.disk_cache()->create_count());
7675 }
7676 
7677 // Tests that we invalidate entries as a result of a PUT.
TEST_F(HttpCacheTest,SimplePUT_Invalidate)7678 TEST_F(HttpCacheTest, SimplePUT_Invalidate) {
7679   MockHttpCache cache;
7680 
7681   MockTransaction transaction(kSimpleGET_Transaction);
7682   MockHttpRequest req1(transaction);
7683 
7684   // Attempt to populate the cache.
7685   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7686 
7687   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7688   EXPECT_EQ(0, cache.disk_cache()->open_count());
7689   EXPECT_EQ(1, cache.disk_cache()->create_count());
7690 
7691   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7692   element_readers.push_back(
7693       std::make_unique<UploadBytesElementReader>("hello", 5));
7694   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7695 
7696   transaction.method = "PUT";
7697   MockHttpRequest req2(transaction);
7698   req2.upload_data_stream = &upload_data_stream;
7699 
7700   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7701 
7702   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7703   EXPECT_EQ(1, cache.disk_cache()->open_count());
7704   EXPECT_EQ(1, cache.disk_cache()->create_count());
7705 
7706   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7707 
7708   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7709   EXPECT_EQ(1, cache.disk_cache()->open_count());
7710   EXPECT_EQ(2, cache.disk_cache()->create_count());
7711 }
7712 
7713 // Tests that we invalidate entries as a result of a PUT.
TEST_F(HttpCacheTest,SimplePUT_Invalidate_305)7714 TEST_F(HttpCacheTest, SimplePUT_Invalidate_305) {
7715   MockHttpCache cache;
7716 
7717   MockTransaction transaction(kSimpleGET_Transaction);
7718   AddMockTransaction(&transaction);
7719   MockHttpRequest req1(transaction);
7720 
7721   // Attempt to populate the cache.
7722   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7723 
7724   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7725   EXPECT_EQ(0, cache.disk_cache()->open_count());
7726   EXPECT_EQ(1, cache.disk_cache()->create_count());
7727 
7728   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7729   element_readers.push_back(
7730       std::make_unique<UploadBytesElementReader>("hello", 5));
7731   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7732 
7733   transaction.method = "PUT";
7734   transaction.status = "HTTP/1.1 305 Use Proxy";
7735   MockHttpRequest req2(transaction);
7736   req2.upload_data_stream = &upload_data_stream;
7737 
7738   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7739 
7740   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7741   EXPECT_EQ(1, cache.disk_cache()->open_count());
7742   EXPECT_EQ(1, cache.disk_cache()->create_count());
7743 
7744   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7745 
7746   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7747   EXPECT_EQ(1, cache.disk_cache()->open_count());
7748   EXPECT_EQ(2, cache.disk_cache()->create_count());
7749   RemoveMockTransaction(&transaction);
7750 }
7751 
7752 // Tests that we don't invalidate entries as a result of a failed PUT.
TEST_F(HttpCacheTest,SimplePUT_DontInvalidate_404)7753 TEST_F(HttpCacheTest, SimplePUT_DontInvalidate_404) {
7754   MockHttpCache cache;
7755 
7756   MockTransaction transaction(kSimpleGET_Transaction);
7757   AddMockTransaction(&transaction);
7758   MockHttpRequest req1(transaction);
7759 
7760   // Attempt to populate the cache.
7761   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7762 
7763   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7764   EXPECT_EQ(0, cache.disk_cache()->open_count());
7765   EXPECT_EQ(1, cache.disk_cache()->create_count());
7766 
7767   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7768   element_readers.push_back(
7769       std::make_unique<UploadBytesElementReader>("hello", 5));
7770   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7771 
7772   transaction.method = "PUT";
7773   transaction.status = "HTTP/1.1 404 Not Found";
7774   MockHttpRequest req2(transaction);
7775   req2.upload_data_stream = &upload_data_stream;
7776 
7777   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7778 
7779   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7780   EXPECT_EQ(1, cache.disk_cache()->open_count());
7781   EXPECT_EQ(1, cache.disk_cache()->create_count());
7782 
7783   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7784 
7785   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7786   EXPECT_EQ(2, cache.disk_cache()->open_count());
7787   EXPECT_EQ(1, cache.disk_cache()->create_count());
7788   RemoveMockTransaction(&transaction);
7789 }
7790 
7791 // Tests that we do not cache the response of a DELETE.
TEST_F(HttpCacheTest,SimpleDELETE_Miss)7792 TEST_F(HttpCacheTest, SimpleDELETE_Miss) {
7793   MockHttpCache cache;
7794 
7795   MockTransaction transaction(kSimplePOST_Transaction);
7796   transaction.method = "DELETE";
7797 
7798   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7799   element_readers.push_back(
7800       std::make_unique<UploadBytesElementReader>("hello", 5));
7801   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7802 
7803   MockHttpRequest request(transaction);
7804   request.upload_data_stream = &upload_data_stream;
7805 
7806   // Attempt to populate the cache.
7807   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
7808                                 nullptr);
7809 
7810   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7811   EXPECT_EQ(0, cache.disk_cache()->open_count());
7812   EXPECT_EQ(0, cache.disk_cache()->create_count());
7813 }
7814 
7815 // Tests that we invalidate entries as a result of a DELETE.
TEST_F(HttpCacheTest,SimpleDELETE_Invalidate)7816 TEST_F(HttpCacheTest, SimpleDELETE_Invalidate) {
7817   MockHttpCache cache;
7818 
7819   MockTransaction transaction(kSimpleGET_Transaction);
7820   MockHttpRequest req1(transaction);
7821 
7822   // Attempt to populate the cache.
7823   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7824 
7825   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7826   EXPECT_EQ(0, cache.disk_cache()->open_count());
7827   EXPECT_EQ(1, cache.disk_cache()->create_count());
7828 
7829   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7830   element_readers.push_back(
7831       std::make_unique<UploadBytesElementReader>("hello", 5));
7832   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7833 
7834   transaction.method = "DELETE";
7835   MockHttpRequest req2(transaction);
7836   req2.upload_data_stream = &upload_data_stream;
7837 
7838   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7839 
7840   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7841   EXPECT_EQ(1, cache.disk_cache()->open_count());
7842   EXPECT_EQ(1, cache.disk_cache()->create_count());
7843 
7844   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7845 
7846   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7847   EXPECT_EQ(1, cache.disk_cache()->open_count());
7848   EXPECT_EQ(2, cache.disk_cache()->create_count());
7849 }
7850 
7851 // Tests that we invalidate entries as a result of a DELETE.
TEST_F(HttpCacheTest,SimpleDELETE_Invalidate_301)7852 TEST_F(HttpCacheTest, SimpleDELETE_Invalidate_301) {
7853   MockHttpCache cache;
7854 
7855   MockTransaction transaction(kSimpleGET_Transaction);
7856   AddMockTransaction(&transaction);
7857 
7858   // Attempt to populate the cache.
7859   RunTransactionTest(cache.http_cache(), transaction);
7860 
7861   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7862   EXPECT_EQ(0, cache.disk_cache()->open_count());
7863   EXPECT_EQ(1, cache.disk_cache()->create_count());
7864 
7865   transaction.method = "DELETE";
7866   transaction.status = "HTTP/1.1 301 Moved Permanently ";
7867 
7868   RunTransactionTest(cache.http_cache(), transaction);
7869 
7870   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7871   EXPECT_EQ(1, cache.disk_cache()->open_count());
7872   EXPECT_EQ(1, cache.disk_cache()->create_count());
7873 
7874   transaction.method = "GET";
7875   RunTransactionTest(cache.http_cache(), transaction);
7876 
7877   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7878   EXPECT_EQ(1, cache.disk_cache()->open_count());
7879   EXPECT_EQ(2, cache.disk_cache()->create_count());
7880   RemoveMockTransaction(&transaction);
7881 }
7882 
7883 // Tests that we don't invalidate entries as a result of a failed DELETE.
TEST_F(HttpCacheTest,SimpleDELETE_DontInvalidate_416)7884 TEST_F(HttpCacheTest, SimpleDELETE_DontInvalidate_416) {
7885   MockHttpCache cache;
7886 
7887   MockTransaction transaction(kSimpleGET_Transaction);
7888   AddMockTransaction(&transaction);
7889 
7890   // Attempt to populate the cache.
7891   RunTransactionTest(cache.http_cache(), transaction);
7892 
7893   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7894   EXPECT_EQ(0, cache.disk_cache()->open_count());
7895   EXPECT_EQ(1, cache.disk_cache()->create_count());
7896 
7897   transaction.method = "DELETE";
7898   transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
7899 
7900   RunTransactionTest(cache.http_cache(), transaction);
7901 
7902   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7903   EXPECT_EQ(1, cache.disk_cache()->open_count());
7904   EXPECT_EQ(1, cache.disk_cache()->create_count());
7905 
7906   transaction.method = "GET";
7907   transaction.status = "HTTP/1.1 200 OK";
7908   RunTransactionTest(cache.http_cache(), transaction);
7909 
7910   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7911   EXPECT_EQ(2, cache.disk_cache()->open_count());
7912   EXPECT_EQ(1, cache.disk_cache()->create_count());
7913   RemoveMockTransaction(&transaction);
7914 }
7915 
7916 // Tests that we invalidate entries as a result of a PATCH.
TEST_F(HttpCacheTest,SimplePATCH_Invalidate)7917 TEST_F(HttpCacheTest, SimplePATCH_Invalidate) {
7918   MockHttpCache cache;
7919 
7920   MockTransaction transaction(kSimpleGET_Transaction);
7921   MockHttpRequest req1(transaction);
7922 
7923   // Attempt to populate the cache.
7924   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7925 
7926   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7927   EXPECT_EQ(0, cache.disk_cache()->open_count());
7928   EXPECT_EQ(1, cache.disk_cache()->create_count());
7929 
7930   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7931   element_readers.push_back(
7932       std::make_unique<UploadBytesElementReader>("hello", 5));
7933   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7934 
7935   transaction.method = "PATCH";
7936   MockHttpRequest req2(transaction);
7937   req2.upload_data_stream = &upload_data_stream;
7938 
7939   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7940 
7941   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7942   EXPECT_EQ(1, cache.disk_cache()->open_count());
7943   EXPECT_EQ(1, cache.disk_cache()->create_count());
7944 
7945   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7946 
7947   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7948   EXPECT_EQ(1, cache.disk_cache()->open_count());
7949   EXPECT_EQ(2, cache.disk_cache()->create_count());
7950 }
7951 
7952 // Tests that we invalidate entries as a result of a PATCH.
TEST_F(HttpCacheTest,SimplePATCH_Invalidate_301)7953 TEST_F(HttpCacheTest, SimplePATCH_Invalidate_301) {
7954   MockHttpCache cache;
7955 
7956   MockTransaction transaction(kSimpleGET_Transaction);
7957   AddMockTransaction(&transaction);
7958 
7959   // Attempt to populate the cache.
7960   RunTransactionTest(cache.http_cache(), transaction);
7961 
7962   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7963   EXPECT_EQ(0, cache.disk_cache()->open_count());
7964   EXPECT_EQ(1, cache.disk_cache()->create_count());
7965 
7966   transaction.method = "PATCH";
7967   transaction.status = "HTTP/1.1 301 Moved Permanently ";
7968 
7969   RunTransactionTest(cache.http_cache(), transaction);
7970 
7971   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7972   EXPECT_EQ(1, cache.disk_cache()->open_count());
7973   EXPECT_EQ(1, cache.disk_cache()->create_count());
7974 
7975   transaction.method = "GET";
7976   RunTransactionTest(cache.http_cache(), transaction);
7977 
7978   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7979   EXPECT_EQ(1, cache.disk_cache()->open_count());
7980   EXPECT_EQ(2, cache.disk_cache()->create_count());
7981   RemoveMockTransaction(&transaction);
7982 }
7983 
7984 // Tests that we don't invalidate entries as a result of a failed PATCH.
TEST_F(HttpCacheTest,SimplePATCH_DontInvalidate_416)7985 TEST_F(HttpCacheTest, SimplePATCH_DontInvalidate_416) {
7986   MockHttpCache cache;
7987 
7988   MockTransaction transaction(kSimpleGET_Transaction);
7989   AddMockTransaction(&transaction);
7990 
7991   // Attempt to populate the cache.
7992   RunTransactionTest(cache.http_cache(), transaction);
7993 
7994   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7995   EXPECT_EQ(0, cache.disk_cache()->open_count());
7996   EXPECT_EQ(1, cache.disk_cache()->create_count());
7997 
7998   transaction.method = "PATCH";
7999   transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
8000 
8001   RunTransactionTest(cache.http_cache(), transaction);
8002 
8003   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8004   EXPECT_EQ(1, cache.disk_cache()->open_count());
8005   EXPECT_EQ(1, cache.disk_cache()->create_count());
8006 
8007   transaction.method = "GET";
8008   transaction.status = "HTTP/1.1 200 OK";
8009   RunTransactionTest(cache.http_cache(), transaction);
8010 
8011   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8012   EXPECT_EQ(2, cache.disk_cache()->open_count());
8013   EXPECT_EQ(1, cache.disk_cache()->create_count());
8014   RemoveMockTransaction(&transaction);
8015 }
8016 
8017 // Tests that we don't invalidate entries after a failed network transaction.
TEST_F(HttpCacheTest,SimpleGET_DontInvalidateOnFailure)8018 TEST_F(HttpCacheTest, SimpleGET_DontInvalidateOnFailure) {
8019   MockHttpCache cache;
8020 
8021   // Populate the cache.
8022   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
8023   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8024 
8025   // Fail the network request.
8026   MockTransaction transaction(kSimpleGET_Transaction);
8027   transaction.start_return_code = ERR_FAILED;
8028   transaction.load_flags |= LOAD_VALIDATE_CACHE;
8029 
8030   AddMockTransaction(&transaction);
8031   RunTransactionTest(cache.http_cache(), transaction);
8032   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8033   RemoveMockTransaction(&transaction);
8034 
8035   transaction.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
8036   transaction.start_return_code = OK;
8037   AddMockTransaction(&transaction);
8038   RunTransactionTest(cache.http_cache(), transaction);
8039 
8040   // Make sure the transaction didn't reach the network.
8041   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8042   RemoveMockTransaction(&transaction);
8043 }
8044 
TEST_F(HttpCacheTest,RangeGET_SkipsCache)8045 TEST_F(HttpCacheTest, RangeGET_SkipsCache) {
8046   MockHttpCache cache;
8047 
8048   // Test that we skip the cache for range GET requests.  Eventually, we will
8049   // want to cache these, but we'll still have cases where skipping the cache
8050   // makes sense, so we want to make sure that it works properly.
8051 
8052   RunTransactionTest(cache.http_cache(), kRangeGET_Transaction);
8053 
8054   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8055   EXPECT_EQ(0, cache.disk_cache()->open_count());
8056   EXPECT_EQ(0, cache.disk_cache()->create_count());
8057 
8058   MockTransaction transaction(kSimpleGET_Transaction);
8059   transaction.request_headers = "If-None-Match: foo\r\n";
8060   RunTransactionTest(cache.http_cache(), transaction);
8061 
8062   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8063   EXPECT_EQ(0, cache.disk_cache()->open_count());
8064   EXPECT_EQ(0, cache.disk_cache()->create_count());
8065 
8066   transaction.request_headers =
8067       "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
8068   RunTransactionTest(cache.http_cache(), transaction);
8069 
8070   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8071   EXPECT_EQ(0, cache.disk_cache()->open_count());
8072   EXPECT_EQ(0, cache.disk_cache()->create_count());
8073 }
8074 
8075 // Test that we skip the cache for range requests that include a validation
8076 // header.
TEST_F(HttpCacheTest,RangeGET_SkipsCache2)8077 TEST_F(HttpCacheTest, RangeGET_SkipsCache2) {
8078   MockHttpCache cache;
8079 
8080   MockTransaction transaction(kRangeGET_Transaction);
8081   transaction.request_headers = "If-None-Match: foo\r\n"
8082                                 EXTRA_HEADER
8083                                 "Range: bytes = 40-49\r\n";
8084   RunTransactionTest(cache.http_cache(), transaction);
8085 
8086   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8087   EXPECT_EQ(0, cache.disk_cache()->open_count());
8088   EXPECT_EQ(0, cache.disk_cache()->create_count());
8089 
8090   transaction.request_headers =
8091       "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
8092       EXTRA_HEADER
8093       "Range: bytes = 40-49\r\n";
8094   RunTransactionTest(cache.http_cache(), transaction);
8095 
8096   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8097   EXPECT_EQ(0, cache.disk_cache()->open_count());
8098   EXPECT_EQ(0, cache.disk_cache()->create_count());
8099 
8100   transaction.request_headers = "If-Range: bla\r\n"
8101                                 EXTRA_HEADER
8102                                 "Range: bytes = 40-49\r\n";
8103   RunTransactionTest(cache.http_cache(), transaction);
8104 
8105   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8106   EXPECT_EQ(0, cache.disk_cache()->open_count());
8107   EXPECT_EQ(0, cache.disk_cache()->create_count());
8108 }
8109 
TEST_F(HttpCacheTest,SimpleGET_DoesntLogHeaders)8110 TEST_F(HttpCacheTest, SimpleGET_DoesntLogHeaders) {
8111   MockHttpCache cache;
8112 
8113   RecordingNetLogObserver net_log_observer;
8114   RunTransactionTestWithLog(cache.http_cache(), kSimpleGET_Transaction,
8115                             NetLogWithSource::Make(NetLogSourceType::NONE));
8116 
8117   EXPECT_FALSE(LogContainsEventType(
8118       net_log_observer, NetLogEventType::HTTP_CACHE_CALLER_REQUEST_HEADERS));
8119 }
8120 
TEST_F(HttpCacheTest,RangeGET_LogsHeaders)8121 TEST_F(HttpCacheTest, RangeGET_LogsHeaders) {
8122   MockHttpCache cache;
8123 
8124   RecordingNetLogObserver net_log_observer;
8125   RunTransactionTestWithLog(cache.http_cache(), kRangeGET_Transaction,
8126                             NetLogWithSource::Make(NetLogSourceType::NONE));
8127 
8128   EXPECT_TRUE(LogContainsEventType(
8129       net_log_observer, NetLogEventType::HTTP_CACHE_CALLER_REQUEST_HEADERS));
8130 }
8131 
TEST_F(HttpCacheTest,ExternalValidation_LogsHeaders)8132 TEST_F(HttpCacheTest, ExternalValidation_LogsHeaders) {
8133   MockHttpCache cache;
8134 
8135   RecordingNetLogObserver net_log_observer;
8136   MockTransaction transaction(kSimpleGET_Transaction);
8137   transaction.request_headers = "If-None-Match: foo\r\n" EXTRA_HEADER;
8138   RunTransactionTestWithLog(cache.http_cache(), transaction,
8139                             NetLogWithSource::Make(NetLogSourceType::NONE));
8140 
8141   EXPECT_TRUE(LogContainsEventType(
8142       net_log_observer, NetLogEventType::HTTP_CACHE_CALLER_REQUEST_HEADERS));
8143 }
8144 
TEST_F(HttpCacheTest,SpecialHeaders_LogsHeaders)8145 TEST_F(HttpCacheTest, SpecialHeaders_LogsHeaders) {
8146   MockHttpCache cache;
8147 
8148   RecordingNetLogObserver net_log_observer;
8149   MockTransaction transaction(kSimpleGET_Transaction);
8150   transaction.request_headers = "cache-control: no-cache\r\n" EXTRA_HEADER;
8151   RunTransactionTestWithLog(cache.http_cache(), transaction,
8152                             NetLogWithSource::Make(NetLogSourceType::NONE));
8153 
8154   EXPECT_TRUE(LogContainsEventType(
8155       net_log_observer, NetLogEventType::HTTP_CACHE_CALLER_REQUEST_HEADERS));
8156 }
8157 
8158 // Tests that receiving 206 for a regular request is handled correctly.
TEST_F(HttpCacheTest,GET_Crazy206)8159 TEST_F(HttpCacheTest, GET_Crazy206) {
8160   MockHttpCache cache;
8161 
8162   // Write to the cache.
8163   MockTransaction transaction(kRangeGET_TransactionOK);
8164   AddMockTransaction(&transaction);
8165   transaction.request_headers = EXTRA_HEADER;
8166   transaction.handler = nullptr;
8167   RunTransactionTest(cache.http_cache(), transaction);
8168 
8169   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8170   EXPECT_EQ(0, cache.disk_cache()->open_count());
8171   EXPECT_EQ(1, cache.disk_cache()->create_count());
8172 
8173   // This should read again from the net.
8174   RunTransactionTest(cache.http_cache(), transaction);
8175 
8176   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8177   EXPECT_EQ(0, cache.disk_cache()->open_count());
8178   EXPECT_EQ(2, cache.disk_cache()->create_count());
8179   RemoveMockTransaction(&transaction);
8180 }
8181 
8182 // Tests that receiving 416 for a regular request is handled correctly.
TEST_F(HttpCacheTest,GET_Crazy416)8183 TEST_F(HttpCacheTest, GET_Crazy416) {
8184   MockHttpCache cache;
8185 
8186   // Write to the cache.
8187   MockTransaction transaction(kSimpleGET_Transaction);
8188   AddMockTransaction(&transaction);
8189   transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
8190   RunTransactionTest(cache.http_cache(), transaction);
8191 
8192   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8193   EXPECT_EQ(0, cache.disk_cache()->open_count());
8194   EXPECT_EQ(1, cache.disk_cache()->create_count());
8195 
8196   RemoveMockTransaction(&transaction);
8197 }
8198 
8199 // Tests that we don't store partial responses that can't be validated.
TEST_F(HttpCacheTest,RangeGET_NoStrongValidators)8200 TEST_F(HttpCacheTest, RangeGET_NoStrongValidators) {
8201   MockHttpCache cache;
8202   std::string headers;
8203 
8204   // Attempt to write to the cache (40-49).
8205   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8206   transaction.response_headers = "Content-Length: 10\n"
8207                                  "Cache-Control: max-age=3600\n"
8208                                  "ETag: w/\"foo\"\n";
8209   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8210 
8211   Verify206Response(headers, 40, 49);
8212   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8213   EXPECT_EQ(0, cache.disk_cache()->open_count());
8214   EXPECT_EQ(1, cache.disk_cache()->create_count());
8215 
8216   // Now verify that there's no cached data.
8217   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8218                                  &headers);
8219 
8220   Verify206Response(headers, 40, 49);
8221   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8222   EXPECT_EQ(0, cache.disk_cache()->open_count());
8223   EXPECT_EQ(2, cache.disk_cache()->create_count());
8224 }
8225 
8226 // Tests failures to conditionalize byte range requests.
TEST_F(HttpCacheTest,RangeGET_NoConditionalization)8227 TEST_F(HttpCacheTest, RangeGET_NoConditionalization) {
8228   MockHttpCache cache;
8229   cache.FailConditionalizations();
8230   std::string headers;
8231 
8232   // Write to the cache (40-49).
8233   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8234   transaction.response_headers = "Content-Length: 10\n"
8235                                  "ETag: \"foo\"\n";
8236   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8237 
8238   Verify206Response(headers, 40, 49);
8239   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8240   EXPECT_EQ(0, cache.disk_cache()->open_count());
8241   EXPECT_EQ(1, cache.disk_cache()->create_count());
8242 
8243   // Now verify that the cached data is not used.
8244   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8245                                  &headers);
8246 
8247   Verify206Response(headers, 40, 49);
8248   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8249   EXPECT_EQ(1, cache.disk_cache()->open_count());
8250   EXPECT_EQ(2, cache.disk_cache()->create_count());
8251 }
8252 
8253 // Tests that restarting a partial request when the cached data cannot be
8254 // revalidated logs an event.
TEST_F(HttpCacheTest,RangeGET_NoValidation_LogsRestart)8255 TEST_F(HttpCacheTest, RangeGET_NoValidation_LogsRestart) {
8256   MockHttpCache cache;
8257   cache.FailConditionalizations();
8258 
8259   // Write to the cache (40-49).
8260   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8261   transaction.response_headers = "Content-Length: 10\n"
8262                                  "ETag: \"foo\"\n";
8263   RunTransactionTest(cache.http_cache(), transaction);
8264 
8265   // Now verify that the cached data is not used.
8266   RecordingNetLogObserver net_log_observer;
8267   RunTransactionTestWithLog(cache.http_cache(), kRangeGET_TransactionOK,
8268                             NetLogWithSource::Make(NetLogSourceType::NONE));
8269 
8270   EXPECT_TRUE(LogContainsEventType(
8271       net_log_observer, NetLogEventType::HTTP_CACHE_RESTART_PARTIAL_REQUEST));
8272 }
8273 
8274 // Tests that a failure to conditionalize a regular request (no range) with a
8275 // sparse entry results in a full response.
TEST_F(HttpCacheTest,GET_NoConditionalization)8276 TEST_F(HttpCacheTest, GET_NoConditionalization) {
8277   for (bool use_memory_entry_data : {false, true}) {
8278     MockHttpCache cache;
8279     cache.disk_cache()->set_support_in_memory_entry_data(use_memory_entry_data);
8280     cache.FailConditionalizations();
8281     std::string headers;
8282 
8283     // Write to the cache (40-49).
8284     ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8285     transaction.response_headers =
8286         "Content-Length: 10\n"
8287         "ETag: \"foo\"\n";
8288     RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8289 
8290     Verify206Response(headers, 40, 49);
8291     EXPECT_EQ(1, cache.network_layer()->transaction_count());
8292     EXPECT_EQ(0, cache.disk_cache()->open_count());
8293     EXPECT_EQ(1, cache.disk_cache()->create_count());
8294 
8295     // Now verify that the cached data is not used.
8296     // Don't ask for a range. The cache will attempt to use the cached data but
8297     // should discard it as it cannot be validated. A regular request should go
8298     // to the server and a new entry should be created.
8299     transaction.request_headers = EXTRA_HEADER;
8300     transaction.data = "Not a range";
8301     RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8302 
8303     EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
8304     EXPECT_EQ(2, cache.network_layer()->transaction_count());
8305     EXPECT_EQ(1, cache.disk_cache()->open_count());
8306     EXPECT_EQ(2, cache.disk_cache()->create_count());
8307 
8308     // The last response was saved.
8309     RunTransactionTest(cache.http_cache(), transaction);
8310     EXPECT_EQ(3, cache.network_layer()->transaction_count());
8311     if (use_memory_entry_data) {
8312       // The cache entry isn't really useful, since when
8313       // &RangeTransactionServer::RangeHandler gets a non-range request,
8314       // (the network transaction #2) it returns headers without ETag,
8315       // Last-Modified or caching headers, with a Date in 2007 (so no heuristic
8316       // freshness), so it's both expired and not conditionalizable --- so in
8317       // this branch we avoid opening it.
8318       EXPECT_EQ(1, cache.disk_cache()->open_count());
8319       EXPECT_EQ(3, cache.disk_cache()->create_count());
8320     } else {
8321       EXPECT_EQ(2, cache.disk_cache()->open_count());
8322       EXPECT_EQ(2, cache.disk_cache()->create_count());
8323     }
8324   }
8325 }
8326 
8327 // Verifies that conditionalization failures when asking for a range that would
8328 // require the cache to modify the range to ask, result in a network request
8329 // that matches the user's one.
TEST_F(HttpCacheTest,RangeGET_NoConditionalization2)8330 TEST_F(HttpCacheTest, RangeGET_NoConditionalization2) {
8331   MockHttpCache cache;
8332   cache.FailConditionalizations();
8333   std::string headers;
8334 
8335   // Write to the cache (40-49).
8336   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8337   transaction.response_headers = "Content-Length: 10\n"
8338                                  "ETag: \"foo\"\n";
8339   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8340 
8341   Verify206Response(headers, 40, 49);
8342   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8343   EXPECT_EQ(0, cache.disk_cache()->open_count());
8344   EXPECT_EQ(1, cache.disk_cache()->create_count());
8345 
8346   // Now verify that the cached data is not used.
8347   // Ask for a range that extends before and after the cached data so that the
8348   // cache would normally mix data from three sources. After deleting the entry,
8349   // the response will come from a single network request.
8350   transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
8351   transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
8352   transaction.response_headers = kRangeGET_TransactionOK.response_headers;
8353   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8354 
8355   Verify206Response(headers, 20, 59);
8356   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8357   EXPECT_EQ(1, cache.disk_cache()->open_count());
8358   EXPECT_EQ(2, cache.disk_cache()->create_count());
8359 
8360   // The last response was saved.
8361   RunTransactionTest(cache.http_cache(), transaction);
8362   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8363   EXPECT_EQ(2, cache.disk_cache()->open_count());
8364   EXPECT_EQ(2, cache.disk_cache()->create_count());
8365 }
8366 
8367 // Tests that we cache partial responses that lack content-length.
TEST_F(HttpCacheTest,RangeGET_NoContentLength)8368 TEST_F(HttpCacheTest, RangeGET_NoContentLength) {
8369   MockHttpCache cache;
8370   std::string headers;
8371 
8372   // Attempt to write to the cache (40-49).
8373   MockTransaction transaction(kRangeGET_TransactionOK);
8374   AddMockTransaction(&transaction);
8375   transaction.response_headers = "ETag: \"foo\"\n"
8376                                  "Accept-Ranges: bytes\n"
8377                                  "Content-Range: bytes 40-49/80\n";
8378   transaction.handler = nullptr;
8379   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8380 
8381   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8382   EXPECT_EQ(0, cache.disk_cache()->open_count());
8383   EXPECT_EQ(1, cache.disk_cache()->create_count());
8384 
8385   // Now verify that there's no cached data.
8386   transaction.handler = &RangeTransactionServer::RangeHandler;
8387   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8388                                  &headers);
8389 
8390   Verify206Response(headers, 40, 49);
8391   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8392   EXPECT_EQ(1, cache.disk_cache()->open_count());
8393   EXPECT_EQ(1, cache.disk_cache()->create_count());
8394 
8395   RemoveMockTransaction(&transaction);
8396 }
8397 
8398 // Tests that we can cache range requests and fetch random blocks from the
8399 // cache and the network.
TEST_F(HttpCacheTest,RangeGET_OK)8400 TEST_F(HttpCacheTest, RangeGET_OK) {
8401   MockHttpCache cache;
8402   AddMockTransaction(&kRangeGET_TransactionOK);
8403   std::string headers;
8404 
8405   // Write to the cache (40-49).
8406   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8407                                  &headers);
8408 
8409   Verify206Response(headers, 40, 49);
8410   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8411   EXPECT_EQ(0, cache.disk_cache()->open_count());
8412   EXPECT_EQ(1, cache.disk_cache()->create_count());
8413 
8414   // Read from the cache (40-49).
8415   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8416                                  &headers);
8417 
8418   Verify206Response(headers, 40, 49);
8419   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8420   EXPECT_EQ(1, cache.disk_cache()->open_count());
8421   EXPECT_EQ(1, cache.disk_cache()->create_count());
8422 
8423   // Make sure we are done with the previous transaction.
8424   base::RunLoop().RunUntilIdle();
8425 
8426   // Write to the cache (30-39).
8427   MockTransaction transaction(kRangeGET_TransactionOK);
8428   transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
8429   transaction.data = "rg: 30-39 ";
8430   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8431 
8432   Verify206Response(headers, 30, 39);
8433   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8434   EXPECT_EQ(2, cache.disk_cache()->open_count());
8435   EXPECT_EQ(1, cache.disk_cache()->create_count());
8436 
8437   // Make sure we are done with the previous transaction.
8438   base::RunLoop().RunUntilIdle();
8439 
8440   // Write and read from the cache (20-59).
8441   transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
8442   transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
8443   LoadTimingInfo load_timing_info;
8444   RunTransactionTestWithResponseAndGetTiming(
8445       cache.http_cache(), transaction, &headers,
8446       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info);
8447 
8448   Verify206Response(headers, 20, 59);
8449   EXPECT_EQ(4, cache.network_layer()->transaction_count());
8450   EXPECT_EQ(3, cache.disk_cache()->open_count());
8451   EXPECT_EQ(1, cache.disk_cache()->create_count());
8452   TestLoadTimingNetworkRequest(load_timing_info);
8453 
8454   RemoveMockTransaction(&kRangeGET_TransactionOK);
8455 }
8456 
TEST_F(HttpCacheTest,RangeGET_CacheReadError)8457 TEST_F(HttpCacheTest, RangeGET_CacheReadError) {
8458   // Tests recovery on cache read error on range request.
8459   MockHttpCache cache;
8460   AddMockTransaction(&kRangeGET_TransactionOK);
8461   std::string headers;
8462 
8463   // Write to the cache (40-49).
8464   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8465                                  &headers);
8466 
8467   Verify206Response(headers, 40, 49);
8468   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8469   EXPECT_EQ(0, cache.disk_cache()->open_count());
8470   EXPECT_EQ(1, cache.disk_cache()->create_count());
8471 
8472   cache.disk_cache()->set_soft_failures_one_instance(MockDiskEntry::FAIL_ALL);
8473 
8474   // Try to read from the cache (40-49), which will fail quickly enough to
8475   // restart, due to the failure injected above.  This should still be a range
8476   // request. (https://crbug.com/891212)
8477   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8478                                  &headers);
8479 
8480   Verify206Response(headers, 40, 49);
8481   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8482   EXPECT_EQ(1, cache.disk_cache()->open_count());
8483   EXPECT_EQ(2, cache.disk_cache()->create_count());
8484 
8485   RemoveMockTransaction(&kRangeGET_TransactionOK);
8486 }
8487 
8488 // Tests that range requests with no-store get correct content-length
8489 // (https://crbug.com/700197).
TEST_F(HttpCacheTest,RangeGET_NoStore)8490 TEST_F(HttpCacheTest, RangeGET_NoStore) {
8491   MockHttpCache cache;
8492 
8493   MockTransaction transaction(kRangeGET_TransactionOK);
8494   std::string response_headers = base::StrCat(
8495       {kRangeGET_TransactionOK.response_headers, "Cache-Control: no-store\n"});
8496   transaction.response_headers = response_headers.c_str();
8497   AddMockTransaction(&transaction);
8498 
8499   std::string headers;
8500   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8501 
8502   Verify206Response(headers, 40, 49);
8503   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8504   EXPECT_EQ(0, cache.disk_cache()->open_count());
8505   EXPECT_EQ(1, cache.disk_cache()->create_count());
8506 
8507   RemoveMockTransaction(&transaction);
8508 }
8509 
8510 // Tests a 304 setting no-store on existing 206 entry.
TEST_F(HttpCacheTest,RangeGET_NoStore304)8511 TEST_F(HttpCacheTest, RangeGET_NoStore304) {
8512   MockHttpCache cache;
8513 
8514   MockTransaction transaction(kRangeGET_TransactionOK);
8515   std::string response_headers = base::StrCat(
8516       {kRangeGET_TransactionOK.response_headers, "Cache-Control: max-age=0\n"});
8517   transaction.response_headers = response_headers.c_str();
8518   AddMockTransaction(&transaction);
8519 
8520   std::string headers;
8521   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8522 
8523   Verify206Response(headers, 40, 49);
8524   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8525   EXPECT_EQ(0, cache.disk_cache()->open_count());
8526   EXPECT_EQ(1, cache.disk_cache()->create_count());
8527 
8528   response_headers = base::StrCat(
8529       {kRangeGET_TransactionOK.response_headers, "Cache-Control: no-store\n"});
8530   transaction.response_headers = response_headers.c_str();
8531   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8532   Verify206Response(headers, 40, 49);
8533 
8534   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8535   EXPECT_EQ(1, cache.disk_cache()->open_count());
8536   EXPECT_EQ(1, cache.disk_cache()->create_count());
8537 
8538   // Fetch again, this one should be from newly created cache entry, due to
8539   // earlier no-store.
8540   transaction.response_headers = kRangeGET_TransactionOK.response_headers;
8541   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8542   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8543   EXPECT_EQ(1, cache.disk_cache()->open_count());
8544   EXPECT_EQ(2, cache.disk_cache()->create_count());
8545   Verify206Response(headers, 40, 49);
8546 
8547   RemoveMockTransaction(&transaction);
8548 }
8549 
8550 // Tests that we can cache range requests and fetch random blocks from the
8551 // cache and the network, with synchronous responses.
TEST_F(HttpCacheTest,RangeGET_SyncOK)8552 TEST_F(HttpCacheTest, RangeGET_SyncOK) {
8553   MockHttpCache cache;
8554 
8555   MockTransaction transaction(kRangeGET_TransactionOK);
8556   transaction.test_mode = TEST_MODE_SYNC_ALL;
8557   AddMockTransaction(&transaction);
8558 
8559   // Write to the cache (40-49).
8560   std::string headers;
8561   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8562 
8563   Verify206Response(headers, 40, 49);
8564   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8565   EXPECT_EQ(0, cache.disk_cache()->open_count());
8566   EXPECT_EQ(1, cache.disk_cache()->create_count());
8567 
8568   // Read from the cache (40-49).
8569   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8570 
8571   Verify206Response(headers, 40, 49);
8572   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8573   EXPECT_EQ(0, cache.disk_cache()->open_count());
8574   EXPECT_EQ(1, cache.disk_cache()->create_count());
8575 
8576   // Make sure we are done with the previous transaction.
8577   base::RunLoop().RunUntilIdle();
8578 
8579   // Write to the cache (30-39).
8580   transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
8581   transaction.data = "rg: 30-39 ";
8582   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8583 
8584   Verify206Response(headers, 30, 39);
8585   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8586   EXPECT_EQ(1, cache.disk_cache()->open_count());
8587   EXPECT_EQ(1, cache.disk_cache()->create_count());
8588 
8589   // Make sure we are done with the previous transaction.
8590   base::RunLoop().RunUntilIdle();
8591 
8592   // Write and read from the cache (20-59).
8593   transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
8594   transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
8595   LoadTimingInfo load_timing_info;
8596   RunTransactionTestWithResponseAndGetTiming(
8597       cache.http_cache(), transaction, &headers,
8598       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info);
8599 
8600   Verify206Response(headers, 20, 59);
8601   EXPECT_EQ(4, cache.network_layer()->transaction_count());
8602   EXPECT_EQ(2, cache.disk_cache()->open_count());
8603   EXPECT_EQ(1, cache.disk_cache()->create_count());
8604   TestLoadTimingNetworkRequest(load_timing_info);
8605 
8606   RemoveMockTransaction(&transaction);
8607 }
8608 
8609 // Tests that if the previous transaction is cancelled while busy (doing sparse
8610 // IO), a new transaction (that reuses that same ActiveEntry) waits until the
8611 // entry is ready again.
TEST_F(HttpCacheTest,Sparse_WaitForEntry)8612 TEST_F(HttpCacheTest, Sparse_WaitForEntry) {
8613   MockHttpCache cache;
8614 
8615   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8616 
8617   // Create a sparse entry.
8618   RunTransactionTest(cache.http_cache(), transaction);
8619 
8620   // Simulate a previous transaction being cancelled.
8621   disk_cache::Entry* entry;
8622   MockHttpRequest request(transaction);
8623   std::string cache_key =
8624       *cache.http_cache()->GenerateCacheKeyForRequest(&request);
8625   ASSERT_TRUE(cache.OpenBackendEntry(cache_key, &entry));
8626   entry->CancelSparseIO();
8627 
8628   // Test with a range request.
8629   RunTransactionTest(cache.http_cache(), transaction);
8630 
8631   // Now test with a regular request.
8632   entry->CancelSparseIO();
8633   transaction.request_headers = EXTRA_HEADER;
8634   transaction.data = kFullRangeData;
8635   RunTransactionTest(cache.http_cache(), transaction);
8636 
8637   entry->Close();
8638 }
8639 
8640 // Tests that we don't revalidate an entry unless we are required to do so.
TEST_F(HttpCacheTest,RangeGET_Revalidate1)8641 TEST_F(HttpCacheTest, RangeGET_Revalidate1) {
8642   MockHttpCache cache;
8643   std::string headers;
8644 
8645   // Write to the cache (40-49).
8646   MockTransaction transaction(kRangeGET_TransactionOK);
8647   transaction.response_headers =
8648       "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
8649       "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n"  // Should never expire.
8650       "ETag: \"foo\"\n"
8651       "Accept-Ranges: bytes\n"
8652       "Content-Length: 10\n";
8653   AddMockTransaction(&transaction);
8654   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8655 
8656   Verify206Response(headers, 40, 49);
8657   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8658   EXPECT_EQ(0, cache.disk_cache()->open_count());
8659   EXPECT_EQ(1, cache.disk_cache()->create_count());
8660 
8661   // Read from the cache (40-49).
8662   NetLogWithSource net_log_with_source =
8663       NetLogWithSource::Make(NetLogSourceType::NONE);
8664   LoadTimingInfo load_timing_info;
8665   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
8666                                              &headers, net_log_with_source,
8667                                              &load_timing_info);
8668 
8669   Verify206Response(headers, 40, 49);
8670   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8671   EXPECT_EQ(1, cache.disk_cache()->open_count());
8672   EXPECT_EQ(1, cache.disk_cache()->create_count());
8673   TestLoadTimingCachedResponse(load_timing_info);
8674 
8675   // Read again forcing the revalidation.
8676   transaction.load_flags |= LOAD_VALIDATE_CACHE;
8677   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
8678                                              &headers, net_log_with_source,
8679                                              &load_timing_info);
8680 
8681   Verify206Response(headers, 40, 49);
8682   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8683   EXPECT_EQ(1, cache.disk_cache()->open_count());
8684   EXPECT_EQ(1, cache.disk_cache()->create_count());
8685   TestLoadTimingNetworkRequest(load_timing_info);
8686 
8687   RemoveMockTransaction(&transaction);
8688 }
8689 
8690 // Checks that we revalidate an entry when the headers say so.
TEST_F(HttpCacheTest,RangeGET_Revalidate2)8691 TEST_F(HttpCacheTest, RangeGET_Revalidate2) {
8692   MockHttpCache cache;
8693   std::string headers;
8694 
8695   // Write to the cache (40-49).
8696   MockTransaction transaction(kRangeGET_TransactionOK);
8697   transaction.response_headers =
8698       "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
8699       "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n"  // Expired.
8700       "ETag: \"foo\"\n"
8701       "Accept-Ranges: bytes\n"
8702       "Content-Length: 10\n";
8703   AddMockTransaction(&transaction);
8704   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8705 
8706   Verify206Response(headers, 40, 49);
8707   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8708   EXPECT_EQ(0, cache.disk_cache()->open_count());
8709   EXPECT_EQ(1, cache.disk_cache()->create_count());
8710 
8711   // Read from the cache (40-49).
8712   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8713   Verify206Response(headers, 40, 49);
8714 
8715   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8716   EXPECT_EQ(1, cache.disk_cache()->open_count());
8717   EXPECT_EQ(1, cache.disk_cache()->create_count());
8718 
8719   RemoveMockTransaction(&transaction);
8720 }
8721 
8722 // Tests that we deal with 304s for range requests.
TEST_F(HttpCacheTest,RangeGET_304)8723 TEST_F(HttpCacheTest, RangeGET_304) {
8724   MockHttpCache cache;
8725   AddMockTransaction(&kRangeGET_TransactionOK);
8726   std::string headers;
8727 
8728   // Write to the cache (40-49).
8729   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8730                                  &headers);
8731 
8732   Verify206Response(headers, 40, 49);
8733   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8734   EXPECT_EQ(0, cache.disk_cache()->open_count());
8735   EXPECT_EQ(1, cache.disk_cache()->create_count());
8736 
8737   // Read from the cache (40-49).
8738   RangeTransactionServer handler;
8739   handler.set_not_modified(true);
8740   MockTransaction transaction(kRangeGET_TransactionOK);
8741   transaction.load_flags |= LOAD_VALIDATE_CACHE;
8742   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8743 
8744   Verify206Response(headers, 40, 49);
8745   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8746   EXPECT_EQ(1, cache.disk_cache()->open_count());
8747   EXPECT_EQ(1, cache.disk_cache()->create_count());
8748 
8749   RemoveMockTransaction(&kRangeGET_TransactionOK);
8750 }
8751 
8752 // Tests that we deal with 206s when revalidating range requests.
TEST_F(HttpCacheTest,RangeGET_ModifiedResult)8753 TEST_F(HttpCacheTest, RangeGET_ModifiedResult) {
8754   MockHttpCache cache;
8755   AddMockTransaction(&kRangeGET_TransactionOK);
8756   std::string headers;
8757 
8758   // Write to the cache (40-49).
8759   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8760                                  &headers);
8761 
8762   Verify206Response(headers, 40, 49);
8763   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8764   EXPECT_EQ(0, cache.disk_cache()->open_count());
8765   EXPECT_EQ(1, cache.disk_cache()->create_count());
8766 
8767   // Attempt to read from the cache (40-49).
8768   RangeTransactionServer handler;
8769   handler.set_modified(true);
8770   MockTransaction transaction(kRangeGET_TransactionOK);
8771   transaction.load_flags |= LOAD_VALIDATE_CACHE;
8772   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8773 
8774   Verify206Response(headers, 40, 49);
8775   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8776   EXPECT_EQ(1, cache.disk_cache()->open_count());
8777   EXPECT_EQ(1, cache.disk_cache()->create_count());
8778 
8779   // And the entry should be gone.
8780   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
8781   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8782   EXPECT_EQ(1, cache.disk_cache()->open_count());
8783   EXPECT_EQ(2, cache.disk_cache()->create_count());
8784 
8785   RemoveMockTransaction(&kRangeGET_TransactionOK);
8786 }
8787 
8788 // Tests that when a server returns 206 with a sub-range of the requested range,
8789 // and there is nothing stored in the cache, the returned response is passed to
8790 // the caller as is. In this context, a subrange means a response that starts
8791 // with the same byte that was requested, but that is not the whole range that
8792 // was requested.
TEST_F(HttpCacheTest,RangeGET_206ReturnsSubrangeRange_NoCachedContent)8793 TEST_F(HttpCacheTest, RangeGET_206ReturnsSubrangeRange_NoCachedContent) {
8794   MockHttpCache cache;
8795   std::string headers;
8796 
8797   // Request a large range (40-59). The server sends 40-49.
8798   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8799   transaction.request_headers = "Range: bytes = 40-59\r\n" EXTRA_HEADER;
8800   transaction.response_headers =
8801       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
8802       "ETag: \"foo\"\n"
8803       "Accept-Ranges: bytes\n"
8804       "Content-Length: 10\n"
8805       "Content-Range: bytes 40-49/80\n";
8806   transaction.handler = nullptr;
8807   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8808 
8809   Verify206Response(headers, 40, 49);
8810   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8811   EXPECT_EQ(0, cache.disk_cache()->open_count());
8812   EXPECT_EQ(1, cache.disk_cache()->create_count());
8813 }
8814 
8815 // Tests that when a server returns 206 with a sub-range of the requested range,
8816 // and there was an entry stored in the cache, the cache gets out of the way.
TEST_F(HttpCacheTest,RangeGET_206ReturnsSubrangeRange_CachedContent)8817 TEST_F(HttpCacheTest, RangeGET_206ReturnsSubrangeRange_CachedContent) {
8818   MockHttpCache cache;
8819   std::string headers;
8820 
8821   // Write to the cache (70-79).
8822   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8823   transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
8824   transaction.data = "rg: 70-79 ";
8825   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8826   Verify206Response(headers, 70, 79);
8827 
8828   // Request a large range (40-79). The cache will ask the server for 40-59.
8829   // The server returns 40-49. The cache should consider the server confused and
8830   // abort caching, restarting the request without caching.
8831   transaction.request_headers = "Range: bytes = 40-79\r\n" EXTRA_HEADER;
8832   transaction.response_headers =
8833       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
8834       "ETag: \"foo\"\n"
8835       "Accept-Ranges: bytes\n"
8836       "Content-Length: 10\n"
8837       "Content-Range: bytes 40-49/80\n";
8838   transaction.handler = nullptr;
8839   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8840 
8841   // Two new network requests were issued, one from the cache and another after
8842   // deleting the entry.
8843   Verify206Response(headers, 40, 49);
8844   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8845   EXPECT_EQ(1, cache.disk_cache()->open_count());
8846   EXPECT_EQ(1, cache.disk_cache()->create_count());
8847 
8848   // The entry was deleted.
8849   RunTransactionTest(cache.http_cache(), transaction);
8850   EXPECT_EQ(4, cache.network_layer()->transaction_count());
8851   EXPECT_EQ(1, cache.disk_cache()->open_count());
8852   EXPECT_EQ(2, cache.disk_cache()->create_count());
8853 }
8854 
8855 // Tests that when a server returns 206 with a sub-range of the requested range,
8856 // and there was an entry stored in the cache, the cache gets out of the way,
8857 // when the caller is not using ranges.
TEST_F(HttpCacheTest,GET_206ReturnsSubrangeRange_CachedContent)8858 TEST_F(HttpCacheTest, GET_206ReturnsSubrangeRange_CachedContent) {
8859   MockHttpCache cache;
8860   std::string headers;
8861 
8862   // Write to the cache (70-79).
8863   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8864   transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
8865   transaction.data = "rg: 70-79 ";
8866   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8867   Verify206Response(headers, 70, 79);
8868 
8869   // Don't ask for a range. The cache will ask the server for 0-69.
8870   // The server returns 40-49. The cache should consider the server confused and
8871   // abort caching, restarting the request.
8872   // The second network request should not be a byte range request so the server
8873   // should return 200 + "Not a range"
8874   transaction.request_headers = "X-Return-Default-Range:\r\n" EXTRA_HEADER;
8875   transaction.data = "Not a range";
8876   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8877 
8878   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
8879   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8880   EXPECT_EQ(1, cache.disk_cache()->open_count());
8881   EXPECT_EQ(1, cache.disk_cache()->create_count());
8882 
8883   // The entry was deleted.
8884   RunTransactionTest(cache.http_cache(), transaction);
8885   EXPECT_EQ(4, cache.network_layer()->transaction_count());
8886   EXPECT_EQ(1, cache.disk_cache()->open_count());
8887   EXPECT_EQ(2, cache.disk_cache()->create_count());
8888 }
8889 
8890 // Tests that when a server returns 206 with a random range and there is
8891 // nothing stored in the cache, the returned response is passed to the caller
8892 // as is. In this context, a WrongRange means that the returned range may or may
8893 // not have any relationship with the requested range (may or may not be
8894 // contained). The important part is that the first byte doesn't match the first
8895 // requested byte.
TEST_F(HttpCacheTest,RangeGET_206ReturnsWrongRange_NoCachedContent)8896 TEST_F(HttpCacheTest, RangeGET_206ReturnsWrongRange_NoCachedContent) {
8897   MockHttpCache cache;
8898   std::string headers;
8899 
8900   // Request a large range (30-59). The server sends (40-49).
8901   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8902   transaction.request_headers = "Range: bytes = 30-59\r\n" EXTRA_HEADER;
8903   transaction.response_headers =
8904       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
8905       "ETag: \"foo\"\n"
8906       "Accept-Ranges: bytes\n"
8907       "Content-Length: 10\n"
8908       "Content-Range: bytes 40-49/80\n";
8909   transaction.handler = nullptr;
8910   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8911 
8912   Verify206Response(headers, 40, 49);
8913   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8914   EXPECT_EQ(0, cache.disk_cache()->open_count());
8915   EXPECT_EQ(1, cache.disk_cache()->create_count());
8916 
8917   // The entry was deleted.
8918   RunTransactionTest(cache.http_cache(), transaction);
8919   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8920   EXPECT_EQ(0, cache.disk_cache()->open_count());
8921   EXPECT_EQ(2, cache.disk_cache()->create_count());
8922 }
8923 
8924 // Tests that when a server returns 206 with a random range and there is
8925 // an entry stored in the cache, the cache gets out of the way.
TEST_F(HttpCacheTest,RangeGET_206ReturnsWrongRange_CachedContent)8926 TEST_F(HttpCacheTest, RangeGET_206ReturnsWrongRange_CachedContent) {
8927   MockHttpCache cache;
8928   std::string headers;
8929 
8930   // Write to the cache (70-79).
8931   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8932   transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
8933   transaction.data = "rg: 70-79 ";
8934   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8935   Verify206Response(headers, 70, 79);
8936 
8937   // Request a large range (30-79). The cache will ask the server for 30-69.
8938   // The server returns 40-49. The cache should consider the server confused and
8939   // abort caching, returning the weird range to the caller.
8940   transaction.request_headers = "Range: bytes = 30-79\r\n" EXTRA_HEADER;
8941   transaction.response_headers =
8942       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
8943       "ETag: \"foo\"\n"
8944       "Accept-Ranges: bytes\n"
8945       "Content-Length: 10\n"
8946       "Content-Range: bytes 40-49/80\n";
8947   transaction.handler = nullptr;
8948   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8949 
8950   Verify206Response(headers, 40, 49);
8951   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8952   EXPECT_EQ(1, cache.disk_cache()->open_count());
8953   EXPECT_EQ(1, cache.disk_cache()->create_count());
8954 
8955   // The entry was deleted.
8956   RunTransactionTest(cache.http_cache(), transaction);
8957   EXPECT_EQ(4, cache.network_layer()->transaction_count());
8958   EXPECT_EQ(1, cache.disk_cache()->open_count());
8959   EXPECT_EQ(2, cache.disk_cache()->create_count());
8960 }
8961 
8962 // Tests that when a caller asks for a range beyond EOF, with an empty cache,
8963 // the response matches the one provided by the server.
TEST_F(HttpCacheTest,RangeGET_206ReturnsSmallerFile_NoCachedContent)8964 TEST_F(HttpCacheTest, RangeGET_206ReturnsSmallerFile_NoCachedContent) {
8965   MockHttpCache cache;
8966   std::string headers;
8967 
8968   // Request a large range (70-99). The server sends 70-79.
8969   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8970   transaction.request_headers = "Range: bytes = 70-99\r\n" EXTRA_HEADER;
8971   transaction.data = "rg: 70-79 ";
8972   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8973 
8974   Verify206Response(headers, 70, 79);
8975   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8976   EXPECT_EQ(0, cache.disk_cache()->open_count());
8977   EXPECT_EQ(1, cache.disk_cache()->create_count());
8978 
8979   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
8980   EXPECT_EQ(1, cache.disk_cache()->open_count());
8981 }
8982 
8983 // Tests that when a caller asks for a range beyond EOF, with a cached entry,
8984 // the cache automatically fixes the request.
TEST_F(HttpCacheTest,RangeGET_206ReturnsSmallerFile_CachedContent)8985 TEST_F(HttpCacheTest, RangeGET_206ReturnsSmallerFile_CachedContent) {
8986   MockHttpCache cache;
8987   std::string headers;
8988 
8989   // Write to the cache (40-49).
8990   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8991   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8992 
8993   // Request a large range (70-99). The server sends 70-79.
8994   transaction.request_headers = "Range: bytes = 70-99\r\n" EXTRA_HEADER;
8995   transaction.data = "rg: 70-79 ";
8996   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8997 
8998   Verify206Response(headers, 70, 79);
8999   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9000   EXPECT_EQ(1, cache.disk_cache()->open_count());
9001   EXPECT_EQ(1, cache.disk_cache()->create_count());
9002 
9003   // The entry was not deleted (the range was automatically fixed).
9004   RunTransactionTest(cache.http_cache(), transaction);
9005   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9006   EXPECT_EQ(2, cache.disk_cache()->open_count());
9007   EXPECT_EQ(1, cache.disk_cache()->create_count());
9008 }
9009 
9010 // Tests that when a caller asks for a not-satisfiable range, the server's
9011 // response is forwarded to the caller.
TEST_F(HttpCacheTest,RangeGET_416_NoCachedContent)9012 TEST_F(HttpCacheTest, RangeGET_416_NoCachedContent) {
9013   MockHttpCache cache;
9014   std::string headers;
9015 
9016   // Request a range beyond EOF (80-99).
9017   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9018   transaction.request_headers = "Range: bytes = 80-99\r\n" EXTRA_HEADER;
9019   transaction.data = "";
9020   transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
9021   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9022 
9023   EXPECT_EQ(0U, headers.find(transaction.status));
9024   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9025   EXPECT_EQ(0, cache.disk_cache()->open_count());
9026   EXPECT_EQ(1, cache.disk_cache()->create_count());
9027 
9028   // The entry was deleted.
9029   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9030   EXPECT_EQ(2, cache.disk_cache()->create_count());
9031 }
9032 
9033 // Tests that we cache 301s for range requests.
TEST_F(HttpCacheTest,RangeGET_301)9034 TEST_F(HttpCacheTest, RangeGET_301) {
9035   MockHttpCache cache;
9036   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9037   transaction.status = "HTTP/1.1 301 Moved Permanently";
9038   transaction.response_headers = "Location: http://www.bar.com/\n";
9039   transaction.data = "";
9040   transaction.handler = nullptr;
9041 
9042   // Write to the cache.
9043   RunTransactionTest(cache.http_cache(), transaction);
9044   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9045   EXPECT_EQ(0, cache.disk_cache()->open_count());
9046   EXPECT_EQ(1, cache.disk_cache()->create_count());
9047 
9048   // Read from the cache.
9049   RunTransactionTest(cache.http_cache(), transaction);
9050   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9051   EXPECT_EQ(1, cache.disk_cache()->open_count());
9052   EXPECT_EQ(1, cache.disk_cache()->create_count());
9053 }
9054 
9055 // Tests that we can cache range requests when the start or end is unknown.
9056 // We start with one suffix request, followed by a request from a given point.
TEST_F(HttpCacheTest,UnknownRangeGET_1)9057 TEST_F(HttpCacheTest, UnknownRangeGET_1) {
9058   MockHttpCache cache;
9059   AddMockTransaction(&kRangeGET_TransactionOK);
9060   std::string headers;
9061 
9062   // Write to the cache (70-79).
9063   MockTransaction transaction(kRangeGET_TransactionOK);
9064   transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
9065   transaction.data = "rg: 70-79 ";
9066   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9067 
9068   Verify206Response(headers, 70, 79);
9069   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9070   EXPECT_EQ(0, cache.disk_cache()->open_count());
9071   EXPECT_EQ(1, cache.disk_cache()->create_count());
9072 
9073   // Make sure we are done with the previous transaction.
9074   base::RunLoop().RunUntilIdle();
9075 
9076   // Write and read from the cache (60-79).
9077   transaction.request_headers = "Range: bytes = 60-\r\n" EXTRA_HEADER;
9078   transaction.data = "rg: 60-69 rg: 70-79 ";
9079   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9080 
9081   Verify206Response(headers, 60, 79);
9082   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9083   EXPECT_EQ(1, cache.disk_cache()->open_count());
9084   EXPECT_EQ(1, cache.disk_cache()->create_count());
9085 
9086   RemoveMockTransaction(&kRangeGET_TransactionOK);
9087 }
9088 
9089 // Tests that we can cache range requests when the start or end is unknown.
9090 // We start with one request from a given point, followed by a suffix request.
9091 // We'll also verify that synchronous cache responses work as intended.
TEST_F(HttpCacheTest,UnknownRangeGET_2)9092 TEST_F(HttpCacheTest, UnknownRangeGET_2) {
9093   MockHttpCache cache;
9094   std::string headers;
9095 
9096   MockTransaction transaction(kRangeGET_TransactionOK);
9097   transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
9098                           TEST_MODE_SYNC_CACHE_READ |
9099                           TEST_MODE_SYNC_CACHE_WRITE;
9100   AddMockTransaction(&transaction);
9101 
9102   // Write to the cache (70-79).
9103   transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
9104   transaction.data = "rg: 70-79 ";
9105   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9106 
9107   Verify206Response(headers, 70, 79);
9108   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9109   EXPECT_EQ(0, cache.disk_cache()->open_count());
9110   EXPECT_EQ(1, cache.disk_cache()->create_count());
9111 
9112   // Make sure we are done with the previous transaction.
9113   base::RunLoop().RunUntilIdle();
9114 
9115   // Write and read from the cache (60-79).
9116   transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
9117   transaction.data = "rg: 60-69 rg: 70-79 ";
9118   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9119 
9120   Verify206Response(headers, 60, 79);
9121   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9122   EXPECT_EQ(1, cache.disk_cache()->open_count());
9123   EXPECT_EQ(1, cache.disk_cache()->create_count());
9124 
9125   RemoveMockTransaction(&transaction);
9126 }
9127 
9128 // Similar to UnknownRangeGET_2, except that the resource size is empty.
9129 // Regression test for crbug.com/813061, and probably https://crbug.com/1375128
TEST_F(HttpCacheTest,UnknownRangeGET_3)9130 TEST_F(HttpCacheTest, UnknownRangeGET_3) {
9131   MockHttpCache cache;
9132   std::string headers;
9133 
9134   ScopedMockTransaction transaction(kSimpleGET_Transaction);
9135   transaction.response_headers =
9136       "Cache-Control: max-age=10000\n"
9137       "Content-Length: 0\n",
9138   transaction.data = "";
9139   transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
9140                           TEST_MODE_SYNC_CACHE_READ |
9141                           TEST_MODE_SYNC_CACHE_WRITE;
9142 
9143   // Write the empty resource to the cache.
9144   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9145 
9146   EXPECT_EQ(
9147       "HTTP/1.1 200 OK\nCache-Control: max-age=10000\nContent-Length: 0\n",
9148       headers);
9149   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9150   EXPECT_EQ(0, cache.disk_cache()->open_count());
9151   EXPECT_EQ(1, cache.disk_cache()->create_count());
9152 
9153   // Make sure we are done with the previous transaction.
9154   base::RunLoop().RunUntilIdle();
9155 
9156   // Write and read from the cache. This used to trigger a DCHECK
9157   // (or loop infinitely with it off).
9158   transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
9159   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9160 
9161   EXPECT_EQ(
9162       "HTTP/1.1 200 OK\nCache-Control: max-age=10000\nContent-Length: 0\n",
9163       headers);
9164   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9165   EXPECT_EQ(1, cache.disk_cache()->open_count());
9166   EXPECT_EQ(1, cache.disk_cache()->create_count());
9167 }
9168 
9169 // Testcase for https://crbug.com/1433305, validation of range request to a
9170 // cache 302, which is notably bodiless.
TEST_F(HttpCacheTest,UnknownRangeGET_302)9171 TEST_F(HttpCacheTest, UnknownRangeGET_302) {
9172   MockHttpCache cache;
9173   std::string headers;
9174 
9175   ScopedMockTransaction transaction(kSimpleGET_Transaction);
9176   transaction.status = "HTTP/1.1 302 Found";
9177   transaction.response_headers =
9178       "Cache-Control: max-age=0\n"
9179       "Content-Length: 0\n"
9180       "Location: https://example.org/\n",
9181 
9182   transaction.data = "";
9183   transaction.request_headers = "Range: bytes = 0-\r\n" EXTRA_HEADER;
9184   transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
9185                           TEST_MODE_SYNC_CACHE_READ |
9186                           TEST_MODE_SYNC_CACHE_WRITE;
9187 
9188   // Write the empty resource to the cache.
9189   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9190 
9191   EXPECT_EQ(
9192       "HTTP/1.1 302 Found\n"
9193       "Cache-Control: max-age=0\n"
9194       "Content-Length: 0\n"
9195       "Location: https://example.org/\n",
9196       headers);
9197   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9198   EXPECT_EQ(0, cache.disk_cache()->open_count());
9199   EXPECT_EQ(1, cache.disk_cache()->create_count());
9200 
9201   // Make sure we are done with the previous transaction.
9202   base::RunLoop().RunUntilIdle();
9203 
9204   // Try to read from the cache. This should send a network request to
9205   // validate it, and get a different redirect.
9206   transaction.response_headers =
9207       "Cache-Control: max-age=0\n"
9208       "Content-Length: 0\n"
9209       "Location: https://example.com/\n",
9210   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9211 
9212   EXPECT_EQ(
9213       "HTTP/1.1 302 Found\n"
9214       "Cache-Control: max-age=0\n"
9215       "Content-Length: 0\n"
9216       "Location: https://example.com/\n",
9217       headers);
9218   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9219   EXPECT_EQ(1, cache.disk_cache()->open_count());
9220   // A new entry is created since this one isn't conditionalizable.
9221   EXPECT_EQ(2, cache.disk_cache()->create_count());
9222 }
9223 
9224 // Testcase for https://crbug.com/1433305, validation of range request to a
9225 // cache 302, which is notably bodiless, where the 302 is replaced with an
9226 // actual body.
TEST_F(HttpCacheTest,UnknownRangeGET_302_Replaced)9227 TEST_F(HttpCacheTest, UnknownRangeGET_302_Replaced) {
9228   MockHttpCache cache;
9229   std::string headers;
9230 
9231   ScopedMockTransaction transaction(kSimpleGET_Transaction);
9232   transaction.status = "HTTP/1.1 302 Found";
9233   transaction.response_headers =
9234       "Cache-Control: max-age=0\n"
9235       "Content-Length: 0\n"
9236       "Location: https://example.org/\n",
9237 
9238   transaction.data = "";
9239   transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
9240                           TEST_MODE_SYNC_CACHE_READ |
9241                           TEST_MODE_SYNC_CACHE_WRITE;
9242 
9243   // Write the empty resource to the cache.
9244   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9245 
9246   EXPECT_EQ(
9247       "HTTP/1.1 302 Found\n"
9248       "Cache-Control: max-age=0\n"
9249       "Content-Length: 0\n"
9250       "Location: https://example.org/\n",
9251       headers);
9252   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9253   EXPECT_EQ(0, cache.disk_cache()->open_count());
9254   EXPECT_EQ(1, cache.disk_cache()->create_count());
9255 
9256   // Make sure we are done with the previous transaction.
9257   base::RunLoop().RunUntilIdle();
9258 
9259   // Try to read from the cache. This should send a network request to
9260   // validate it, and get a different response.
9261   transaction.handler = &RangeTransactionServer::RangeHandler;
9262   transaction.request_headers = "Range: bytes = -30\r\n" EXTRA_HEADER;
9263   // Tail 30 bytes out of 80
9264   transaction.data = "rg: 50-59 rg: 60-69 rg: 70-79 ";
9265   transaction.status = "HTTP/1.1 206 Partial Content";
9266   transaction.response_headers = "Content-Length: 10\n";
9267   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9268 
9269   EXPECT_EQ(
9270       "HTTP/1.1 206 Partial Content\n"
9271       "Content-Range: bytes 50-79/80\n"
9272       "Content-Length: 30\n",
9273       headers);
9274   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9275   EXPECT_EQ(1, cache.disk_cache()->open_count());
9276   // A new entry is created since this one isn't conditionalizable.
9277   EXPECT_EQ(2, cache.disk_cache()->create_count());
9278 }
9279 
9280 // Tests that receiving Not Modified when asking for an open range doesn't mess
9281 // up things.
TEST_F(HttpCacheTest,UnknownRangeGET_304)9282 TEST_F(HttpCacheTest, UnknownRangeGET_304) {
9283   MockHttpCache cache;
9284   std::string headers;
9285 
9286   MockTransaction transaction(kRangeGET_TransactionOK);
9287   AddMockTransaction(&transaction);
9288 
9289   RangeTransactionServer handler;
9290   handler.set_not_modified(true);
9291 
9292   // Ask for the end of the file, without knowing the length.
9293   transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
9294   transaction.data = "";
9295   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9296 
9297   // We just bypass the cache.
9298   EXPECT_EQ(0U, headers.find("HTTP/1.1 304 Not Modified\n"));
9299   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9300   EXPECT_EQ(0, cache.disk_cache()->open_count());
9301   EXPECT_EQ(1, cache.disk_cache()->create_count());
9302 
9303   RunTransactionTest(cache.http_cache(), transaction);
9304   EXPECT_EQ(2, cache.disk_cache()->create_count());
9305 
9306   RemoveMockTransaction(&transaction);
9307 }
9308 
9309 // Tests that we can handle non-range requests when we have cached a range.
TEST_F(HttpCacheTest,GET_Previous206)9310 TEST_F(HttpCacheTest, GET_Previous206) {
9311   MockHttpCache cache;
9312   AddMockTransaction(&kRangeGET_TransactionOK);
9313   std::string headers;
9314   NetLogWithSource net_log_with_source =
9315       NetLogWithSource::Make(NetLogSourceType::NONE);
9316   LoadTimingInfo load_timing_info;
9317 
9318   // Write to the cache (40-49).
9319   RunTransactionTestWithResponseAndGetTiming(
9320       cache.http_cache(), kRangeGET_TransactionOK, &headers,
9321       net_log_with_source, &load_timing_info);
9322 
9323   Verify206Response(headers, 40, 49);
9324   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9325   EXPECT_EQ(0, cache.disk_cache()->open_count());
9326   EXPECT_EQ(1, cache.disk_cache()->create_count());
9327   TestLoadTimingNetworkRequest(load_timing_info);
9328 
9329   // Write and read from the cache (0-79), when not asked for a range.
9330   MockTransaction transaction(kRangeGET_TransactionOK);
9331   transaction.request_headers = EXTRA_HEADER;
9332   transaction.data = kFullRangeData;
9333   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
9334                                              &headers, net_log_with_source,
9335                                              &load_timing_info);
9336 
9337   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
9338   EXPECT_EQ(3, cache.network_layer()->transaction_count());
9339   EXPECT_EQ(1, cache.disk_cache()->open_count());
9340   EXPECT_EQ(1, cache.disk_cache()->create_count());
9341   TestLoadTimingNetworkRequest(load_timing_info);
9342 
9343   RemoveMockTransaction(&kRangeGET_TransactionOK);
9344 }
9345 
9346 // Tests that we can handle non-range requests when we have cached the first
9347 // part of the object and the server replies with 304 (Not Modified).
TEST_F(HttpCacheTest,GET_Previous206_NotModified)9348 TEST_F(HttpCacheTest, GET_Previous206_NotModified) {
9349   MockHttpCache cache;
9350 
9351   MockTransaction transaction(kRangeGET_TransactionOK);
9352   AddMockTransaction(&transaction);
9353   std::string headers;
9354   NetLogWithSource net_log_with_source =
9355       NetLogWithSource::Make(NetLogSourceType::NONE);
9356 
9357   LoadTimingInfo load_timing_info;
9358 
9359   // Write to the cache (0-9).
9360   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
9361   transaction.data = "rg: 00-09 ";
9362   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
9363                                              &headers, net_log_with_source,
9364                                              &load_timing_info);
9365   Verify206Response(headers, 0, 9);
9366   TestLoadTimingNetworkRequest(load_timing_info);
9367 
9368   // Write to the cache (70-79).
9369   transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
9370   transaction.data = "rg: 70-79 ";
9371   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
9372                                              &headers, net_log_with_source,
9373                                              &load_timing_info);
9374   Verify206Response(headers, 70, 79);
9375 
9376   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9377   EXPECT_EQ(1, cache.disk_cache()->open_count());
9378   EXPECT_EQ(1, cache.disk_cache()->create_count());
9379   TestLoadTimingNetworkRequest(load_timing_info);
9380 
9381   // Read from the cache (0-9), write and read from cache (10 - 79).
9382   transaction.load_flags |= LOAD_VALIDATE_CACHE;
9383   transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER;
9384   transaction.data = kFullRangeData;
9385   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
9386                                              &headers, net_log_with_source,
9387                                              &load_timing_info);
9388 
9389   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
9390   EXPECT_EQ(4, cache.network_layer()->transaction_count());
9391   EXPECT_EQ(2, cache.disk_cache()->open_count());
9392   EXPECT_EQ(1, cache.disk_cache()->create_count());
9393   TestLoadTimingNetworkRequest(load_timing_info);
9394 
9395   RemoveMockTransaction(&transaction);
9396 }
9397 
9398 // Tests that we can handle a regular request to a sparse entry, that results in
9399 // new content provided by the server (206).
TEST_F(HttpCacheTest,GET_Previous206_NewContent)9400 TEST_F(HttpCacheTest, GET_Previous206_NewContent) {
9401   MockHttpCache cache;
9402   AddMockTransaction(&kRangeGET_TransactionOK);
9403   std::string headers;
9404 
9405   // Write to the cache (0-9).
9406   MockTransaction transaction(kRangeGET_TransactionOK);
9407   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
9408   transaction.data = "rg: 00-09 ";
9409   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9410 
9411   Verify206Response(headers, 0, 9);
9412   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9413   EXPECT_EQ(0, cache.disk_cache()->open_count());
9414   EXPECT_EQ(1, cache.disk_cache()->create_count());
9415 
9416   // Now we'll issue a request without any range that should result first in a
9417   // 206 (when revalidating), and then in a weird standard answer: the test
9418   // server will not modify the response so we'll get the default range... a
9419   // real server will answer with 200.
9420   MockTransaction transaction2(kRangeGET_TransactionOK);
9421   transaction2.request_headers = EXTRA_HEADER;
9422   transaction2.load_flags |= LOAD_VALIDATE_CACHE;
9423   transaction2.data = "Not a range";
9424   RangeTransactionServer handler;
9425   handler.set_modified(true);
9426   LoadTimingInfo load_timing_info;
9427   RunTransactionTestWithResponseAndGetTiming(
9428       cache.http_cache(), transaction2, &headers,
9429       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info);
9430 
9431   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
9432   EXPECT_EQ(3, cache.network_layer()->transaction_count());
9433   EXPECT_EQ(1, cache.disk_cache()->open_count());
9434   EXPECT_EQ(1, cache.disk_cache()->create_count());
9435   TestLoadTimingNetworkRequest(load_timing_info);
9436 
9437   // Verify that the previous request deleted the entry.
9438   RunTransactionTest(cache.http_cache(), transaction);
9439   EXPECT_EQ(2, cache.disk_cache()->create_count());
9440 
9441   RemoveMockTransaction(&transaction);
9442 }
9443 
9444 // Tests that we can handle cached 206 responses that are not sparse.
TEST_F(HttpCacheTest,GET_Previous206_NotSparse)9445 TEST_F(HttpCacheTest, GET_Previous206_NotSparse) {
9446   MockHttpCache cache;
9447 
9448   MockHttpRequest request(kSimpleGET_Transaction);
9449   // Create a disk cache entry that stores 206 headers while not being sparse.
9450   disk_cache::Entry* entry;
9451   ASSERT_TRUE(cache.CreateBackendEntry(request.CacheKey(), &entry, nullptr));
9452 
9453   std::string raw_headers(kRangeGET_TransactionOK.status);
9454   raw_headers.append("\n");
9455   raw_headers.append(kRangeGET_TransactionOK.response_headers);
9456 
9457   HttpResponseInfo response;
9458   response.headers = base::MakeRefCounted<HttpResponseHeaders>(
9459       HttpUtil::AssembleRawHeaders(raw_headers));
9460   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
9461 
9462   scoped_refptr<IOBuffer> buf(base::MakeRefCounted<IOBuffer>(500));
9463   int len = static_cast<int>(base::strlcpy(buf->data(),
9464                                            kRangeGET_TransactionOK.data, 500));
9465   TestCompletionCallback cb;
9466   int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
9467   EXPECT_EQ(len, cb.GetResult(rv));
9468   entry->Close();
9469 
9470   // Now see that we don't use the stored entry.
9471   std::string headers;
9472   LoadTimingInfo load_timing_info;
9473   RunTransactionTestWithResponseAndGetTiming(
9474       cache.http_cache(), kSimpleGET_Transaction, &headers,
9475       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info);
9476 
9477   // We are expecting a 200.
9478   std::string expected_headers(kSimpleGET_Transaction.status);
9479   expected_headers.append("\n");
9480   expected_headers.append(kSimpleGET_Transaction.response_headers);
9481   EXPECT_EQ(expected_headers, headers);
9482   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9483   EXPECT_EQ(1, cache.disk_cache()->open_count());
9484   EXPECT_EQ(2, cache.disk_cache()->create_count());
9485   TestLoadTimingNetworkRequest(load_timing_info);
9486 }
9487 
9488 // Tests that we can handle cached 206 responses that are not sparse. This time
9489 // we issue a range request and expect to receive a range.
TEST_F(HttpCacheTest,RangeGET_Previous206_NotSparse_2)9490 TEST_F(HttpCacheTest, RangeGET_Previous206_NotSparse_2) {
9491   MockHttpCache cache;
9492   AddMockTransaction(&kRangeGET_TransactionOK);
9493 
9494   // Create a disk cache entry that stores 206 headers while not being sparse.
9495   MockHttpRequest request(kRangeGET_TransactionOK);
9496   disk_cache::Entry* entry;
9497   ASSERT_TRUE(cache.CreateBackendEntry(request.CacheKey(), &entry, nullptr));
9498 
9499   std::string raw_headers(kRangeGET_TransactionOK.status);
9500   raw_headers.append("\n");
9501   raw_headers.append(kRangeGET_TransactionOK.response_headers);
9502 
9503   HttpResponseInfo response;
9504   response.headers = base::MakeRefCounted<HttpResponseHeaders>(
9505       HttpUtil::AssembleRawHeaders(raw_headers));
9506   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
9507 
9508   scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(500);
9509   int len = static_cast<int>(base::strlcpy(buf->data(),
9510                                            kRangeGET_TransactionOK.data, 500));
9511   TestCompletionCallback cb;
9512   int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
9513   EXPECT_EQ(len, cb.GetResult(rv));
9514   entry->Close();
9515 
9516   // Now see that we don't use the stored entry.
9517   std::string headers;
9518   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
9519                                  &headers);
9520 
9521   // We are expecting a 206.
9522   Verify206Response(headers, 40, 49);
9523   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9524   EXPECT_EQ(1, cache.disk_cache()->open_count());
9525   EXPECT_EQ(2, cache.disk_cache()->create_count());
9526 
9527   RemoveMockTransaction(&kRangeGET_TransactionOK);
9528 }
9529 
9530 // Tests that we can handle cached 206 responses that can't be validated.
TEST_F(HttpCacheTest,GET_Previous206_NotValidation)9531 TEST_F(HttpCacheTest, GET_Previous206_NotValidation) {
9532   MockHttpCache cache;
9533 
9534   MockHttpRequest request(kSimpleGET_Transaction);
9535   // Create a disk cache entry that stores 206 headers.
9536   disk_cache::Entry* entry;
9537   ASSERT_TRUE(cache.CreateBackendEntry(request.CacheKey(), &entry, nullptr));
9538 
9539   // Make sure that the headers cannot be validated with the server.
9540   std::string raw_headers(kRangeGET_TransactionOK.status);
9541   raw_headers.append("\n");
9542   raw_headers.append("Content-Length: 80\n");
9543 
9544   HttpResponseInfo response;
9545   response.headers = base::MakeRefCounted<HttpResponseHeaders>(
9546       HttpUtil::AssembleRawHeaders(raw_headers));
9547   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
9548 
9549   scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(500);
9550   int len = static_cast<int>(base::strlcpy(buf->data(),
9551                                            kRangeGET_TransactionOK.data, 500));
9552   TestCompletionCallback cb;
9553   int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
9554   EXPECT_EQ(len, cb.GetResult(rv));
9555   entry->Close();
9556 
9557   // Now see that we don't use the stored entry.
9558   std::string headers;
9559   RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
9560                                  &headers);
9561 
9562   // We are expecting a 200.
9563   std::string expected_headers(kSimpleGET_Transaction.status);
9564   expected_headers.append("\n");
9565   expected_headers.append(kSimpleGET_Transaction.response_headers);
9566   EXPECT_EQ(expected_headers, headers);
9567   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9568   EXPECT_EQ(1, cache.disk_cache()->open_count());
9569   EXPECT_EQ(2, cache.disk_cache()->create_count());
9570 }
9571 
9572 // Tests that we can handle range requests with cached 200 responses.
TEST_F(HttpCacheTest,RangeGET_Previous200)9573 TEST_F(HttpCacheTest, RangeGET_Previous200) {
9574   MockHttpCache cache;
9575 
9576   // Store the whole thing with status 200.
9577   MockTransaction transaction(kTypicalGET_Transaction);
9578   transaction.url = kRangeGET_TransactionOK.url;
9579   transaction.data = kFullRangeData;
9580   AddMockTransaction(&transaction);
9581   RunTransactionTest(cache.http_cache(), transaction);
9582   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9583   EXPECT_EQ(0, cache.disk_cache()->open_count());
9584   EXPECT_EQ(1, cache.disk_cache()->create_count());
9585 
9586   RemoveMockTransaction(&transaction);
9587   AddMockTransaction(&kRangeGET_TransactionOK);
9588 
9589   // Now see that we use the stored entry.
9590   std::string headers;
9591   MockTransaction transaction2(kRangeGET_TransactionOK);
9592   RangeTransactionServer handler;
9593   handler.set_not_modified(true);
9594   RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
9595 
9596   // We are expecting a 206.
9597   Verify206Response(headers, 40, 49);
9598   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9599   EXPECT_EQ(1, cache.disk_cache()->open_count());
9600   EXPECT_EQ(1, cache.disk_cache()->create_count());
9601 
9602   // The last transaction has finished so make sure the entry is deactivated.
9603   base::RunLoop().RunUntilIdle();
9604 
9605   // Make a request for an invalid range.
9606   MockTransaction transaction3(kRangeGET_TransactionOK);
9607   transaction3.request_headers = "Range: bytes = 80-90\r\n" EXTRA_HEADER;
9608   transaction3.data = transaction.data;
9609   transaction3.load_flags = LOAD_SKIP_CACHE_VALIDATION;
9610   RunTransactionTestWithResponse(cache.http_cache(), transaction3, &headers);
9611   EXPECT_EQ(2, cache.disk_cache()->open_count());
9612   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 "));
9613   EXPECT_EQ(std::string::npos, headers.find("Content-Range:"));
9614   EXPECT_EQ(std::string::npos, headers.find("Content-Length: 80"));
9615 
9616   // Make sure the entry is deactivated.
9617   base::RunLoop().RunUntilIdle();
9618 
9619   // Even though the request was invalid, we should have the entry.
9620   RunTransactionTest(cache.http_cache(), transaction2);
9621   EXPECT_EQ(3, cache.disk_cache()->open_count());
9622 
9623   // Make sure the entry is deactivated.
9624   base::RunLoop().RunUntilIdle();
9625 
9626   // Now we should receive a range from the server and drop the stored entry.
9627   handler.set_not_modified(false);
9628   transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
9629   RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
9630   Verify206Response(headers, 40, 49);
9631   EXPECT_EQ(4, cache.network_layer()->transaction_count());
9632   EXPECT_EQ(4, cache.disk_cache()->open_count());
9633   EXPECT_EQ(1, cache.disk_cache()->create_count());
9634 
9635   RunTransactionTest(cache.http_cache(), transaction2);
9636   EXPECT_EQ(2, cache.disk_cache()->create_count());
9637 
9638   RemoveMockTransaction(&kRangeGET_TransactionOK);
9639 }
9640 
9641 // Tests that we can handle a 200 response when dealing with sparse entries.
TEST_F(HttpCacheTest,RangeRequestResultsIn200)9642 TEST_F(HttpCacheTest, RangeRequestResultsIn200) {
9643   MockHttpCache cache;
9644   AddMockTransaction(&kRangeGET_TransactionOK);
9645   std::string headers;
9646 
9647   // Write to the cache (70-79).
9648   MockTransaction transaction(kRangeGET_TransactionOK);
9649   transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
9650   transaction.data = "rg: 70-79 ";
9651   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9652 
9653   Verify206Response(headers, 70, 79);
9654   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9655   EXPECT_EQ(0, cache.disk_cache()->open_count());
9656   EXPECT_EQ(1, cache.disk_cache()->create_count());
9657 
9658   // Now we'll issue a request that results in a plain 200 response, but to
9659   // the to the same URL that we used to store sparse data, and making sure
9660   // that we ask for a range.
9661   RemoveMockTransaction(&kRangeGET_TransactionOK);
9662   MockTransaction transaction2(kSimpleGET_Transaction);
9663   transaction2.url = kRangeGET_TransactionOK.url;
9664   transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
9665   AddMockTransaction(&transaction2);
9666 
9667   RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
9668 
9669   std::string expected_headers(kSimpleGET_Transaction.status);
9670   expected_headers.append("\n");
9671   expected_headers.append(kSimpleGET_Transaction.response_headers);
9672   EXPECT_EQ(expected_headers, headers);
9673   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9674   EXPECT_EQ(1, cache.disk_cache()->open_count());
9675   EXPECT_EQ(1, cache.disk_cache()->create_count());
9676 
9677   RemoveMockTransaction(&transaction2);
9678 }
9679 
9680 // Tests that a range request that falls outside of the size that we know about
9681 // only deletes the entry if the resource has indeed changed.
TEST_F(HttpCacheTest,RangeGET_MoreThanCurrentSize)9682 TEST_F(HttpCacheTest, RangeGET_MoreThanCurrentSize) {
9683   MockHttpCache cache;
9684   AddMockTransaction(&kRangeGET_TransactionOK);
9685   std::string headers;
9686 
9687   // Write to the cache (40-49).
9688   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
9689                                  &headers);
9690 
9691   Verify206Response(headers, 40, 49);
9692   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9693   EXPECT_EQ(0, cache.disk_cache()->open_count());
9694   EXPECT_EQ(1, cache.disk_cache()->create_count());
9695 
9696   // A weird request should not delete this entry. Ask for bytes 120-.
9697   MockTransaction transaction(kRangeGET_TransactionOK);
9698   transaction.request_headers = "Range: bytes = 120-\r\n" EXTRA_HEADER;
9699   transaction.data = "";
9700   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9701 
9702   EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
9703   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9704   EXPECT_EQ(1, cache.disk_cache()->open_count());
9705   EXPECT_EQ(1, cache.disk_cache()->create_count());
9706 
9707   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9708   EXPECT_EQ(2, cache.disk_cache()->open_count());
9709   EXPECT_EQ(1, cache.disk_cache()->create_count());
9710 
9711   RemoveMockTransaction(&kRangeGET_TransactionOK);
9712 }
9713 
9714 // Tests that we don't delete a sparse entry when we cancel a request.
TEST_F(HttpCacheTest,RangeGET_Cancel)9715 TEST_F(HttpCacheTest, RangeGET_Cancel) {
9716   MockHttpCache cache;
9717   AddMockTransaction(&kRangeGET_TransactionOK);
9718 
9719   MockHttpRequest request(kRangeGET_TransactionOK);
9720 
9721   auto c = std::make_unique<Context>();
9722   int rv = cache.CreateTransaction(&c->trans);
9723   ASSERT_THAT(rv, IsOk());
9724 
9725   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
9726   if (rv == ERR_IO_PENDING)
9727     rv = c->callback.WaitForResult();
9728 
9729   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9730   EXPECT_EQ(0, cache.disk_cache()->open_count());
9731   EXPECT_EQ(1, cache.disk_cache()->create_count());
9732 
9733   // Make sure that the entry has some data stored.
9734   scoped_refptr<IOBufferWithSize> buf =
9735       base::MakeRefCounted<IOBufferWithSize>(10);
9736   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
9737   if (rv == ERR_IO_PENDING)
9738     rv = c->callback.WaitForResult();
9739   EXPECT_EQ(buf->size(), rv);
9740 
9741   // Destroy the transaction.
9742   c.reset();
9743 
9744   // Verify that the entry has not been deleted.
9745   disk_cache::Entry* entry;
9746   ASSERT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &entry));
9747   entry->Close();
9748   RemoveMockTransaction(&kRangeGET_TransactionOK);
9749 }
9750 
9751 // Tests that we don't mark an entry as truncated if it is partial and not
9752 // already truncated.
TEST_F(HttpCacheTest,RangeGET_CancelWhileReading)9753 TEST_F(HttpCacheTest, RangeGET_CancelWhileReading) {
9754   MockHttpCache cache;
9755   AddMockTransaction(&kRangeGET_TransactionOK);
9756 
9757   MockHttpRequest request(kRangeGET_TransactionOK);
9758 
9759   auto context = std::make_unique<Context>();
9760   int rv = cache.CreateTransaction(&context->trans);
9761   ASSERT_THAT(rv, IsOk());
9762 
9763   rv = context->trans->Start(&request, context->callback.callback(),
9764                              NetLogWithSource());
9765   if (rv == ERR_IO_PENDING)
9766     rv = context->callback.WaitForResult();
9767 
9768   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9769   EXPECT_EQ(0, cache.disk_cache()->open_count());
9770   EXPECT_EQ(1, cache.disk_cache()->create_count());
9771 
9772   // Start Read.
9773   scoped_refptr<IOBufferWithSize> buf =
9774       base::MakeRefCounted<IOBufferWithSize>(5);
9775   rv = context->trans->Read(buf.get(), buf->size(),
9776                             context->callback.callback());
9777   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9778 
9779   // Destroy the transaction.
9780   context.reset();
9781 
9782   // Complete Read.
9783   base::RunLoop().RunUntilIdle();
9784 
9785   // Verify that the entry has not been marked as truncated.
9786   VerifyTruncatedFlag(&cache, request.CacheKey(), false, 0);
9787   RemoveMockTransaction(&kRangeGET_TransactionOK);
9788 }
9789 
9790 // Tests that we don't delete a sparse entry when we start a new request after
9791 // cancelling the previous one.
TEST_F(HttpCacheTest,RangeGET_Cancel2)9792 TEST_F(HttpCacheTest, RangeGET_Cancel2) {
9793   MockHttpCache cache;
9794   AddMockTransaction(&kRangeGET_TransactionOK);
9795 
9796   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9797   MockHttpRequest request(kRangeGET_TransactionOK);
9798   request.load_flags |= LOAD_VALIDATE_CACHE;
9799 
9800   auto c = std::make_unique<Context>();
9801   int rv = cache.CreateTransaction(&c->trans);
9802   ASSERT_THAT(rv, IsOk());
9803 
9804   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
9805   if (rv == ERR_IO_PENDING)
9806     rv = c->callback.WaitForResult();
9807 
9808   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9809   EXPECT_EQ(1, cache.disk_cache()->open_count());
9810   EXPECT_EQ(1, cache.disk_cache()->create_count());
9811 
9812   // Make sure that we revalidate the entry and read from the cache (a single
9813   // read will return while waiting for the network).
9814   scoped_refptr<IOBufferWithSize> buf =
9815       base::MakeRefCounted<IOBufferWithSize>(5);
9816   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
9817   EXPECT_EQ(5, c->callback.GetResult(rv));
9818   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
9819   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9820 
9821   // Destroy the transaction before completing the read.
9822   c.reset();
9823 
9824   // We have the read and the delete (OnProcessPendingQueue) waiting on the
9825   // message loop. This means that a new transaction will just reuse the same
9826   // active entry (no open or create).
9827 
9828   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9829 
9830   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9831   EXPECT_EQ(1, cache.disk_cache()->open_count());
9832   EXPECT_EQ(1, cache.disk_cache()->create_count());
9833   RemoveMockTransaction(&kRangeGET_TransactionOK);
9834 }
9835 
9836 // A slight variation of the previous test, this time we cancel two requests in
9837 // a row, making sure that the second is waiting for the entry to be ready.
TEST_F(HttpCacheTest,RangeGET_Cancel3)9838 TEST_F(HttpCacheTest, RangeGET_Cancel3) {
9839   MockHttpCache cache;
9840   AddMockTransaction(&kRangeGET_TransactionOK);
9841 
9842   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9843   MockHttpRequest request(kRangeGET_TransactionOK);
9844   request.load_flags |= LOAD_VALIDATE_CACHE;
9845 
9846   auto c = std::make_unique<Context>();
9847   int rv = cache.CreateTransaction(&c->trans);
9848   ASSERT_THAT(rv, IsOk());
9849 
9850   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
9851   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9852   rv = c->callback.WaitForResult();
9853 
9854   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9855   EXPECT_EQ(1, cache.disk_cache()->open_count());
9856   EXPECT_EQ(1, cache.disk_cache()->create_count());
9857 
9858   // Make sure that we revalidate the entry and read from the cache (a single
9859   // read will return while waiting for the network).
9860   scoped_refptr<IOBufferWithSize> buf =
9861       base::MakeRefCounted<IOBufferWithSize>(5);
9862   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
9863   EXPECT_EQ(5, c->callback.GetResult(rv));
9864   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
9865   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9866 
9867   // Destroy the previous transaction before completing the read.
9868   c.reset();
9869 
9870   // We have the read and the delete (OnProcessPendingQueue) waiting on the
9871   // message loop. This means that a new transaction will just reuse the same
9872   // active entry (no open or create).
9873 
9874   c = std::make_unique<Context>();
9875   rv = cache.CreateTransaction(&c->trans);
9876   ASSERT_THAT(rv, IsOk());
9877 
9878   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
9879   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9880 
9881   MockDiskEntry::IgnoreCallbacks(true);
9882   base::RunLoop().RunUntilIdle();
9883   MockDiskEntry::IgnoreCallbacks(false);
9884 
9885   // The new transaction is waiting for the query range callback.
9886   c.reset();
9887 
9888   // And we should not crash when the callback is delivered.
9889   base::RunLoop().RunUntilIdle();
9890 
9891   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9892   EXPECT_EQ(1, cache.disk_cache()->open_count());
9893   EXPECT_EQ(1, cache.disk_cache()->create_count());
9894   RemoveMockTransaction(&kRangeGET_TransactionOK);
9895 }
9896 
9897 // Tests that an invalid range response results in no cached entry.
TEST_F(HttpCacheTest,RangeGET_InvalidResponse1)9898 TEST_F(HttpCacheTest, RangeGET_InvalidResponse1) {
9899   MockHttpCache cache;
9900   std::string headers;
9901 
9902   MockTransaction transaction(kRangeGET_TransactionOK);
9903   transaction.handler = nullptr;
9904   transaction.response_headers = "Content-Range: bytes 40-49/45\n"
9905                                  "Content-Length: 10\n";
9906   AddMockTransaction(&transaction);
9907   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9908 
9909   std::string expected(transaction.status);
9910   expected.append("\n");
9911   expected.append(transaction.response_headers);
9912   EXPECT_EQ(expected, headers);
9913 
9914   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9915   EXPECT_EQ(0, cache.disk_cache()->open_count());
9916   EXPECT_EQ(1, cache.disk_cache()->create_count());
9917 
9918   // Verify that we don't have a cached entry.
9919   disk_cache::Entry* entry;
9920   MockHttpRequest request(transaction);
9921   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
9922 
9923   RemoveMockTransaction(&kRangeGET_TransactionOK);
9924 }
9925 
9926 // Tests that we reject a range that doesn't match the content-length.
TEST_F(HttpCacheTest,RangeGET_InvalidResponse2)9927 TEST_F(HttpCacheTest, RangeGET_InvalidResponse2) {
9928   MockHttpCache cache;
9929   std::string headers;
9930 
9931   MockTransaction transaction(kRangeGET_TransactionOK);
9932   transaction.handler = nullptr;
9933   transaction.response_headers = "Content-Range: bytes 40-49/80\n"
9934                                  "Content-Length: 20\n";
9935   AddMockTransaction(&transaction);
9936   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9937 
9938   std::string expected(transaction.status);
9939   expected.append("\n");
9940   expected.append(transaction.response_headers);
9941   EXPECT_EQ(expected, headers);
9942 
9943   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9944   EXPECT_EQ(0, cache.disk_cache()->open_count());
9945   EXPECT_EQ(1, cache.disk_cache()->create_count());
9946 
9947   // Verify that we don't have a cached entry.
9948   disk_cache::Entry* entry;
9949   MockHttpRequest request(transaction);
9950   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
9951 
9952   RemoveMockTransaction(&kRangeGET_TransactionOK);
9953 }
9954 
9955 // Tests that if a server tells us conflicting information about a resource we
9956 // drop the entry.
TEST_F(HttpCacheTest,RangeGET_InvalidResponse3)9957 TEST_F(HttpCacheTest, RangeGET_InvalidResponse3) {
9958   MockHttpCache cache;
9959   std::string headers;
9960 
9961   MockTransaction transaction(kRangeGET_TransactionOK);
9962   transaction.handler = nullptr;
9963   transaction.request_headers = "Range: bytes = 50-59\r\n" EXTRA_HEADER;
9964   std::string response_headers(transaction.response_headers);
9965   response_headers.append("Content-Range: bytes 50-59/160\n");
9966   transaction.response_headers = response_headers.c_str();
9967   AddMockTransaction(&transaction);
9968   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9969 
9970   Verify206Response(headers, 50, 59);
9971   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9972   EXPECT_EQ(0, cache.disk_cache()->open_count());
9973   EXPECT_EQ(1, cache.disk_cache()->create_count());
9974 
9975   RemoveMockTransaction(&transaction);
9976   AddMockTransaction(&kRangeGET_TransactionOK);
9977 
9978   // This transaction will report a resource size of 80 bytes, and we think it's
9979   // 160 so we should ignore the response.
9980   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
9981                                  &headers);
9982 
9983   Verify206Response(headers, 40, 49);
9984   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9985   EXPECT_EQ(1, cache.disk_cache()->open_count());
9986   EXPECT_EQ(1, cache.disk_cache()->create_count());
9987 
9988   // Verify that the entry is gone.
9989   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9990   EXPECT_EQ(1, cache.disk_cache()->open_count());
9991   EXPECT_EQ(2, cache.disk_cache()->create_count());
9992   RemoveMockTransaction(&kRangeGET_TransactionOK);
9993 }
9994 
9995 // Tests that we handle large range values properly.
TEST_F(HttpCacheTest,RangeGET_LargeValues)9996 TEST_F(HttpCacheTest, RangeGET_LargeValues) {
9997   // We need a real sparse cache for this test.
9998   MockHttpCache cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
9999   std::string headers;
10000 
10001   MockTransaction transaction(kRangeGET_TransactionOK);
10002   transaction.handler = nullptr;
10003   transaction.request_headers = "Range: bytes = 4294967288-4294967297\r\n"
10004                                 EXTRA_HEADER;
10005   transaction.response_headers =
10006       "ETag: \"foo\"\n"
10007       "Content-Range: bytes 4294967288-4294967297/4294967299\n"
10008       "Content-Length: 10\n";
10009   AddMockTransaction(&transaction);
10010   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
10011 
10012   std::string expected(transaction.status);
10013   expected.append("\n");
10014   expected.append(transaction.response_headers);
10015   EXPECT_EQ(expected, headers);
10016 
10017   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10018 
10019   // Verify that we have a cached entry.
10020   disk_cache::Entry* en;
10021   MockHttpRequest request(transaction);
10022   ASSERT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &en));
10023   en->Close();
10024 
10025   RemoveMockTransaction(&kRangeGET_TransactionOK);
10026 }
10027 
10028 // Tests that we don't crash with a range request if the disk cache was not
10029 // initialized properly.
TEST_F(HttpCacheTest,RangeGET_NoDiskCache)10030 TEST_F(HttpCacheTest, RangeGET_NoDiskCache) {
10031   auto factory = std::make_unique<MockBlockingBackendFactory>();
10032   factory->set_fail(true);
10033   factory->FinishCreation();  // We'll complete synchronously.
10034   MockHttpCache cache(std::move(factory));
10035 
10036   AddMockTransaction(&kRangeGET_TransactionOK);
10037 
10038   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
10039   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10040 
10041   RemoveMockTransaction(&kRangeGET_TransactionOK);
10042 }
10043 
10044 // Tests that we handle byte range requests that skip the cache.
TEST_F(HttpCacheTest,RangeHEAD)10045 TEST_F(HttpCacheTest, RangeHEAD) {
10046   MockHttpCache cache;
10047   AddMockTransaction(&kRangeGET_TransactionOK);
10048 
10049   MockTransaction transaction(kRangeGET_TransactionOK);
10050   transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
10051   transaction.method = "HEAD";
10052   transaction.data = "rg: 70-79 ";
10053 
10054   std::string headers;
10055   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
10056 
10057   Verify206Response(headers, 70, 79);
10058   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10059   EXPECT_EQ(0, cache.disk_cache()->open_count());
10060   EXPECT_EQ(0, cache.disk_cache()->create_count());
10061 
10062   RemoveMockTransaction(&kRangeGET_TransactionOK);
10063 }
10064 
10065 // Tests that we don't crash when after reading from the cache we issue a
10066 // request for the next range and the server gives us a 200 synchronously.
TEST_F(HttpCacheTest,RangeGET_FastFlakyServer)10067 TEST_F(HttpCacheTest, RangeGET_FastFlakyServer) {
10068   MockHttpCache cache;
10069 
10070   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10071   transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER;
10072   transaction.test_mode = TEST_MODE_SYNC_NET_START;
10073   transaction.load_flags |= LOAD_VALIDATE_CACHE;
10074 
10075   // Write to the cache.
10076   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
10077 
10078   // And now read from the cache and the network.
10079   RangeTransactionServer handler;
10080   handler.set_bad_200(true);
10081   transaction.data = "Not a range";
10082   RecordingNetLogObserver net_log_observer;
10083   RunTransactionTestWithLog(cache.http_cache(), transaction,
10084                             NetLogWithSource::Make(NetLogSourceType::NONE));
10085 
10086   EXPECT_EQ(3, cache.network_layer()->transaction_count());
10087   EXPECT_EQ(1, cache.disk_cache()->open_count());
10088   EXPECT_EQ(1, cache.disk_cache()->create_count());
10089   EXPECT_TRUE(LogContainsEventType(
10090       net_log_observer, NetLogEventType::HTTP_CACHE_RE_SEND_PARTIAL_REQUEST));
10091 }
10092 
10093 // Tests that when the server gives us less data than expected, we don't keep
10094 // asking for more data.
TEST_F(HttpCacheTest,RangeGET_FastFlakyServer2)10095 TEST_F(HttpCacheTest, RangeGET_FastFlakyServer2) {
10096   MockHttpCache cache;
10097 
10098   // First, check with an empty cache (WRITE mode).
10099   MockTransaction transaction(kRangeGET_TransactionOK);
10100   transaction.request_headers = "Range: bytes = 40-49\r\n" EXTRA_HEADER;
10101   transaction.data = "rg: 40-";  // Less than expected.
10102   transaction.handler = nullptr;
10103   std::string headers(transaction.response_headers);
10104   headers.append("Content-Range: bytes 40-49/80\n");
10105   transaction.response_headers = headers.c_str();
10106 
10107   AddMockTransaction(&transaction);
10108 
10109   // Write to the cache.
10110   RunTransactionTest(cache.http_cache(), transaction);
10111 
10112   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10113   EXPECT_EQ(0, cache.disk_cache()->open_count());
10114   EXPECT_EQ(1, cache.disk_cache()->create_count());
10115 
10116   // Now verify that even in READ_WRITE mode, we forward the bad response to
10117   // the caller.
10118   transaction.request_headers = "Range: bytes = 60-69\r\n" EXTRA_HEADER;
10119   transaction.data = "rg: 60-";  // Less than expected.
10120   headers = kRangeGET_TransactionOK.response_headers;
10121   headers.append("Content-Range: bytes 60-69/80\n");
10122   transaction.response_headers = headers.c_str();
10123 
10124   RunTransactionTest(cache.http_cache(), transaction);
10125 
10126   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10127   EXPECT_EQ(1, cache.disk_cache()->open_count());
10128   EXPECT_EQ(1, cache.disk_cache()->create_count());
10129 
10130   RemoveMockTransaction(&transaction);
10131 }
10132 
TEST_F(HttpCacheTest,RangeGET_OK_LoadOnlyFromCache)10133 TEST_F(HttpCacheTest, RangeGET_OK_LoadOnlyFromCache) {
10134   MockHttpCache cache;
10135   AddMockTransaction(&kRangeGET_TransactionOK);
10136 
10137   // Write to the cache (40-49).
10138   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
10139   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10140   EXPECT_EQ(0, cache.disk_cache()->open_count());
10141   EXPECT_EQ(1, cache.disk_cache()->create_count());
10142 
10143   // Force this transaction to read from the cache.
10144   MockTransaction transaction(kRangeGET_TransactionOK);
10145   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
10146 
10147   MockHttpRequest request(transaction);
10148   TestCompletionCallback callback;
10149 
10150   std::unique_ptr<HttpTransaction> trans;
10151   int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
10152   EXPECT_THAT(rv, IsOk());
10153   ASSERT_TRUE(trans.get());
10154 
10155   rv = trans->Start(&request, callback.callback(), NetLogWithSource());
10156   if (rv == ERR_IO_PENDING)
10157     rv = callback.WaitForResult();
10158   ASSERT_THAT(rv, IsError(ERR_CACHE_MISS));
10159 
10160   trans.reset();
10161 
10162   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10163   EXPECT_EQ(1, cache.disk_cache()->open_count());
10164   EXPECT_EQ(1, cache.disk_cache()->create_count());
10165 
10166   RemoveMockTransaction(&kRangeGET_TransactionOK);
10167 }
10168 
10169 // Tests the handling of the "truncation" flag.
TEST_F(HttpCacheTest,WriteResponseInfo_Truncated)10170 TEST_F(HttpCacheTest, WriteResponseInfo_Truncated) {
10171   MockHttpCache cache;
10172   disk_cache::Entry* entry;
10173   ASSERT_TRUE(cache.CreateBackendEntry(
10174       GenerateCacheKey("http://www.google.com"), &entry, nullptr));
10175 
10176   HttpResponseInfo response;
10177   response.headers = base::MakeRefCounted<HttpResponseHeaders>(
10178       HttpUtil::AssembleRawHeaders("HTTP/1.1 200 OK"));
10179 
10180   // Set the last argument for this to be an incomplete request.
10181   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
10182   bool truncated = false;
10183   EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
10184   EXPECT_TRUE(truncated);
10185 
10186   // And now test the opposite case.
10187   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
10188   truncated = true;
10189   EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
10190   EXPECT_FALSE(truncated);
10191   entry->Close();
10192 }
10193 
10194 // Tests basic pickling/unpickling of HttpResponseInfo.
TEST_F(HttpCacheTest,PersistHttpResponseInfo)10195 TEST_F(HttpCacheTest, PersistHttpResponseInfo) {
10196   const IPEndPoint expected_endpoint = IPEndPoint(IPAddress(1, 2, 3, 4), 80);
10197   // Set some fields (add more if needed.)
10198   HttpResponseInfo response1;
10199   response1.was_cached = false;
10200   response1.remote_endpoint = expected_endpoint;
10201   response1.headers =
10202       base::MakeRefCounted<HttpResponseHeaders>("HTTP/1.1 200 OK");
10203 
10204   // Pickle.
10205   base::Pickle pickle;
10206   response1.Persist(&pickle, false, false);
10207 
10208   // Unpickle.
10209   HttpResponseInfo response2;
10210   bool response_truncated;
10211   EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated));
10212   EXPECT_FALSE(response_truncated);
10213 
10214   // Verify fields.
10215   EXPECT_TRUE(response2.was_cached);  // InitFromPickle sets this flag.
10216   EXPECT_EQ(expected_endpoint, response2.remote_endpoint);
10217   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
10218 }
10219 
10220 // Tests that we delete an entry when the request is cancelled before starting
10221 // to read from the network.
TEST_F(HttpCacheTest,DoomOnDestruction)10222 TEST_F(HttpCacheTest, DoomOnDestruction) {
10223   MockHttpCache cache;
10224 
10225   MockHttpRequest request(kSimpleGET_Transaction);
10226 
10227   auto c = std::make_unique<Context>();
10228   int rv = cache.CreateTransaction(&c->trans);
10229   ASSERT_THAT(rv, IsOk());
10230 
10231   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10232   if (rv == ERR_IO_PENDING)
10233     c->result = c->callback.WaitForResult();
10234 
10235   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10236   EXPECT_EQ(0, cache.disk_cache()->open_count());
10237   EXPECT_EQ(1, cache.disk_cache()->create_count());
10238 
10239   // Destroy the transaction. We only have the headers so we should delete this
10240   // entry.
10241   c.reset();
10242 
10243   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
10244 
10245   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10246   EXPECT_EQ(0, cache.disk_cache()->open_count());
10247   EXPECT_EQ(2, cache.disk_cache()->create_count());
10248 }
10249 
10250 // Tests that we delete an entry when the request is cancelled if the response
10251 // does not have content-length and strong validators.
TEST_F(HttpCacheTest,DoomOnDestruction2)10252 TEST_F(HttpCacheTest, DoomOnDestruction2) {
10253   MockHttpCache cache;
10254 
10255   MockHttpRequest request(kSimpleGET_Transaction);
10256 
10257   auto c = std::make_unique<Context>();
10258   int rv = cache.CreateTransaction(&c->trans);
10259   ASSERT_THAT(rv, IsOk());
10260 
10261   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10262   if (rv == ERR_IO_PENDING)
10263     rv = c->callback.WaitForResult();
10264 
10265   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10266   EXPECT_EQ(0, cache.disk_cache()->open_count());
10267   EXPECT_EQ(1, cache.disk_cache()->create_count());
10268 
10269   // Make sure that the entry has some data stored.
10270   scoped_refptr<IOBufferWithSize> buf =
10271       base::MakeRefCounted<IOBufferWithSize>(10);
10272   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10273   if (rv == ERR_IO_PENDING)
10274     rv = c->callback.WaitForResult();
10275   EXPECT_EQ(buf->size(), rv);
10276 
10277   // Destroy the transaction.
10278   c.reset();
10279 
10280   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
10281 
10282   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10283   EXPECT_EQ(0, cache.disk_cache()->open_count());
10284   EXPECT_EQ(2, cache.disk_cache()->create_count());
10285 }
10286 
10287 // Tests that we delete an entry when the request is cancelled if the response
10288 // has an "Accept-Ranges: none" header.
TEST_F(HttpCacheTest,DoomOnDestruction3)10289 TEST_F(HttpCacheTest, DoomOnDestruction3) {
10290   MockHttpCache cache;
10291 
10292   MockTransaction transaction(kSimpleGET_Transaction);
10293   transaction.response_headers =
10294       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
10295       "Content-Length: 22\n"
10296       "Accept-Ranges: none\n"
10297       "Etag: \"foopy\"\n";
10298   AddMockTransaction(&transaction);
10299   MockHttpRequest request(transaction);
10300 
10301   auto c = std::make_unique<Context>();
10302   int rv = cache.CreateTransaction(&c->trans);
10303   ASSERT_THAT(rv, IsOk());
10304 
10305   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10306   if (rv == ERR_IO_PENDING)
10307     rv = c->callback.WaitForResult();
10308 
10309   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10310   EXPECT_EQ(0, cache.disk_cache()->open_count());
10311   EXPECT_EQ(1, cache.disk_cache()->create_count());
10312 
10313   // Make sure that the entry has some data stored.
10314   scoped_refptr<IOBufferWithSize> buf =
10315       base::MakeRefCounted<IOBufferWithSize>(10);
10316   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10317   if (rv == ERR_IO_PENDING)
10318     rv = c->callback.WaitForResult();
10319   EXPECT_EQ(buf->size(), rv);
10320 
10321   // Destroy the transaction.
10322   c.reset();
10323 
10324   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
10325 
10326   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10327   EXPECT_EQ(0, cache.disk_cache()->open_count());
10328   EXPECT_EQ(2, cache.disk_cache()->create_count());
10329 
10330   RemoveMockTransaction(&transaction);
10331 }
10332 
10333 // Tests that we mark an entry as incomplete when the request is cancelled.
TEST_F(HttpCacheTest,SetTruncatedFlag)10334 TEST_F(HttpCacheTest, SetTruncatedFlag) {
10335   MockHttpCache cache;
10336 
10337   ScopedMockTransaction transaction(kSimpleGET_Transaction);
10338   transaction.response_headers =
10339       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
10340       "Content-Length: 22\n"
10341       "Etag: \"foopy\"\n";
10342   MockHttpRequest request(transaction);
10343 
10344   auto c = std::make_unique<Context>();
10345 
10346   int rv = cache.CreateTransaction(&c->trans);
10347   ASSERT_THAT(rv, IsOk());
10348 
10349   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10350   if (rv == ERR_IO_PENDING)
10351     rv = c->callback.WaitForResult();
10352 
10353   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10354   EXPECT_EQ(0, cache.disk_cache()->open_count());
10355   EXPECT_EQ(1, cache.disk_cache()->create_count());
10356 
10357   // Make sure that the entry has some data stored.
10358   scoped_refptr<IOBufferWithSize> buf =
10359       base::MakeRefCounted<IOBufferWithSize>(10);
10360   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10361   if (rv == ERR_IO_PENDING)
10362     rv = c->callback.WaitForResult();
10363   EXPECT_EQ(buf->size(), rv);
10364 
10365   // We want to cancel the request when the transaction is busy.
10366   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10367   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10368   EXPECT_FALSE(c->callback.have_result());
10369 
10370   // Destroy the transaction.
10371   c->trans.reset();
10372 
10373   // Make sure that we don't invoke the callback. We may have an issue if the
10374   // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
10375   // could end up with the transaction being deleted twice if we send any
10376   // notification from the transaction destructor (see http://crbug.com/31723).
10377   EXPECT_FALSE(c->callback.have_result());
10378 
10379   base::RunLoop().RunUntilIdle();
10380   VerifyTruncatedFlag(&cache, request.CacheKey(), true, 0);
10381 }
10382 
10383 // Tests that we do not mark an entry as truncated when the request is
10384 // cancelled.
TEST_F(HttpCacheTest,DontSetTruncatedFlagForGarbledResponseCode)10385 TEST_F(HttpCacheTest, DontSetTruncatedFlagForGarbledResponseCode) {
10386   MockHttpCache cache;
10387 
10388   ScopedMockTransaction transaction(kSimpleGET_Transaction);
10389   transaction.response_headers =
10390       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
10391       "Content-Length: 22\n"
10392       "Etag: \"foopy\"\n";
10393   transaction.status = "HTTP/1.1 2";
10394   MockHttpRequest request(transaction);
10395 
10396   auto c = std::make_unique<Context>();
10397 
10398   int rv = cache.CreateTransaction(&c->trans);
10399   ASSERT_THAT(rv, IsOk());
10400 
10401   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10402   if (rv == ERR_IO_PENDING)
10403     rv = c->callback.WaitForResult();
10404 
10405   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10406   EXPECT_EQ(0, cache.disk_cache()->open_count());
10407   EXPECT_EQ(1, cache.disk_cache()->create_count());
10408 
10409   // Make sure that the entry has some data stored.
10410   scoped_refptr<IOBufferWithSize> buf =
10411       base::MakeRefCounted<IOBufferWithSize>(10);
10412   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10413   if (rv == ERR_IO_PENDING)
10414     rv = c->callback.WaitForResult();
10415   EXPECT_EQ(buf->size(), rv);
10416 
10417   // We want to cancel the request when the transaction is busy.
10418   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10419   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10420   EXPECT_FALSE(c->callback.have_result());
10421 
10422   MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL);
10423 
10424   // Destroy the transaction.
10425   c->trans.reset();
10426   MockHttpCache::SetTestMode(0);
10427 
10428   // Make sure that we don't invoke the callback. We may have an issue if the
10429   // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
10430   // could end up with the transaction being deleted twice if we send any
10431   // notification from the transaction destructor (see http://crbug.com/31723).
10432   EXPECT_FALSE(c->callback.have_result());
10433 
10434   // Verify that the entry is deleted as well, since the response status is
10435   // garbled. Note that the entry will be deleted after the pending Read is
10436   // complete.
10437   base::RunLoop().RunUntilIdle();
10438   disk_cache::Entry* entry;
10439   ASSERT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
10440 }
10441 
10442 // Tests that we don't mark an entry as truncated when we read everything.
TEST_F(HttpCacheTest,DontSetTruncatedFlag)10443 TEST_F(HttpCacheTest, DontSetTruncatedFlag) {
10444   MockHttpCache cache;
10445 
10446   ScopedMockTransaction transaction(kSimpleGET_Transaction);
10447   transaction.response_headers =
10448       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
10449       "Content-Length: 22\n"
10450       "Etag: \"foopy\"\n";
10451   MockHttpRequest request(transaction);
10452 
10453   auto c = std::make_unique<Context>();
10454   int rv = cache.CreateTransaction(&c->trans);
10455   ASSERT_THAT(rv, IsOk());
10456 
10457   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10458   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10459 
10460   // Read everything.
10461   scoped_refptr<IOBufferWithSize> buf =
10462       base::MakeRefCounted<IOBufferWithSize>(22);
10463   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10464   EXPECT_EQ(buf->size(), c->callback.GetResult(rv));
10465 
10466   // Destroy the transaction.
10467   c->trans.reset();
10468 
10469   // Verify that the entry is not marked as truncated.
10470   VerifyTruncatedFlag(&cache, request.CacheKey(), false, 0);
10471 }
10472 
10473 // Tests that sparse entries don't set the truncate flag.
TEST_F(HttpCacheTest,RangeGET_DontTruncate)10474 TEST_F(HttpCacheTest, RangeGET_DontTruncate) {
10475   MockHttpCache cache;
10476 
10477   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10478   transaction.request_headers = "Range: bytes = 0-19\r\n" EXTRA_HEADER;
10479 
10480   auto request = std::make_unique<MockHttpRequest>(transaction);
10481   std::unique_ptr<HttpTransaction> trans;
10482 
10483   int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
10484   EXPECT_THAT(rv, IsOk());
10485 
10486   TestCompletionCallback cb;
10487   rv = trans->Start(request.get(), cb.callback(), NetLogWithSource());
10488   EXPECT_EQ(0, cb.GetResult(rv));
10489 
10490   scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(10);
10491   rv = trans->Read(buf.get(), 10, cb.callback());
10492   EXPECT_EQ(10, cb.GetResult(rv));
10493 
10494   // Should not trigger any DCHECK.
10495   trans.reset();
10496   VerifyTruncatedFlag(&cache, request->CacheKey(), false, 0);
10497 }
10498 
10499 // Tests that sparse entries don't set the truncate flag (when the byte range
10500 //  starts after 0).
TEST_F(HttpCacheTest,RangeGET_DontTruncate2)10501 TEST_F(HttpCacheTest, RangeGET_DontTruncate2) {
10502   MockHttpCache cache;
10503 
10504   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10505   transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
10506 
10507   auto request = std::make_unique<MockHttpRequest>(transaction);
10508   std::unique_ptr<HttpTransaction> trans;
10509 
10510   int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
10511   EXPECT_THAT(rv, IsOk());
10512 
10513   TestCompletionCallback cb;
10514   rv = trans->Start(request.get(), cb.callback(), NetLogWithSource());
10515   EXPECT_EQ(0, cb.GetResult(rv));
10516 
10517   scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(10);
10518   rv = trans->Read(buf.get(), 10, cb.callback());
10519   EXPECT_EQ(10, cb.GetResult(rv));
10520 
10521   // Should not trigger any DCHECK.
10522   trans.reset();
10523   VerifyTruncatedFlag(&cache, request->CacheKey(), false, 0);
10524 }
10525 
10526 // Tests that we can continue with a request that was interrupted.
TEST_F(HttpCacheTest,GET_IncompleteResource)10527 TEST_F(HttpCacheTest, GET_IncompleteResource) {
10528   MockHttpCache cache;
10529   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10530 
10531   std::string raw_headers("HTTP/1.1 200 OK\n"
10532                           "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10533                           "ETag: \"foo\"\n"
10534                           "Accept-Ranges: bytes\n"
10535                           "Content-Length: 80\n");
10536   CreateTruncatedEntry(raw_headers, &cache);
10537 
10538   // Now make a regular request.
10539   std::string headers;
10540   transaction.request_headers = EXTRA_HEADER;
10541   transaction.data = kFullRangeData;
10542   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
10543 
10544   // We update the headers with the ones received while revalidating.
10545   std::string expected_headers(
10546       "HTTP/1.1 200 OK\n"
10547       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10548       "Accept-Ranges: bytes\n"
10549       "ETag: \"foo\"\n"
10550       "Content-Length: 80\n");
10551 
10552   EXPECT_EQ(expected_headers, headers);
10553   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10554   EXPECT_EQ(1, cache.disk_cache()->open_count());
10555   EXPECT_EQ(1, cache.disk_cache()->create_count());
10556 
10557   // Verify that the disk entry was updated.
10558   MockHttpRequest request(transaction);
10559   VerifyTruncatedFlag(&cache, request.CacheKey(), false, 80);
10560 }
10561 
10562 // Tests the handling of no-store when revalidating a truncated entry.
TEST_F(HttpCacheTest,GET_IncompleteResource_NoStore)10563 TEST_F(HttpCacheTest, GET_IncompleteResource_NoStore) {
10564   MockHttpCache cache;
10565   AddMockTransaction(&kRangeGET_TransactionOK);
10566 
10567   std::string raw_headers("HTTP/1.1 200 OK\n"
10568                           "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10569                           "ETag: \"foo\"\n"
10570                           "Accept-Ranges: bytes\n"
10571                           "Content-Length: 80\n");
10572   CreateTruncatedEntry(raw_headers, &cache);
10573   RemoveMockTransaction(&kRangeGET_TransactionOK);
10574 
10575   // Now make a regular request.
10576   MockTransaction transaction(kRangeGET_TransactionOK);
10577   transaction.request_headers = EXTRA_HEADER;
10578   std::string response_headers(transaction.response_headers);
10579   response_headers += ("Cache-Control: no-store\n");
10580   transaction.response_headers = response_headers.c_str();
10581   transaction.data = kFullRangeData;
10582   AddMockTransaction(&transaction);
10583 
10584   std::string headers;
10585   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
10586 
10587   // We update the headers with the ones received while revalidating.
10588   std::string expected_headers(
10589       "HTTP/1.1 200 OK\n"
10590       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10591       "Accept-Ranges: bytes\n"
10592       "Cache-Control: no-store\n"
10593       "ETag: \"foo\"\n"
10594       "Content-Length: 80\n");
10595 
10596   EXPECT_EQ(expected_headers, headers);
10597   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10598   EXPECT_EQ(1, cache.disk_cache()->open_count());
10599   EXPECT_EQ(1, cache.disk_cache()->create_count());
10600 
10601   // Verify that the disk entry was deleted.
10602   disk_cache::Entry* entry;
10603   MockHttpRequest request(transaction);
10604   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
10605   RemoveMockTransaction(&transaction);
10606 }
10607 
10608 // Tests cancelling a request after the server sent no-store.
TEST_F(HttpCacheTest,GET_IncompleteResource_Cancel)10609 TEST_F(HttpCacheTest, GET_IncompleteResource_Cancel) {
10610   MockHttpCache cache;
10611   AddMockTransaction(&kRangeGET_TransactionOK);
10612 
10613   std::string raw_headers("HTTP/1.1 200 OK\n"
10614                           "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10615                           "ETag: \"foo\"\n"
10616                           "Accept-Ranges: bytes\n"
10617                           "Content-Length: 80\n");
10618   CreateTruncatedEntry(raw_headers, &cache);
10619   RemoveMockTransaction(&kRangeGET_TransactionOK);
10620 
10621   // Now make a regular request.
10622   MockTransaction transaction(kRangeGET_TransactionOK);
10623   transaction.request_headers = EXTRA_HEADER;
10624   std::string response_headers(transaction.response_headers);
10625   response_headers += ("Cache-Control: no-store\n");
10626   transaction.response_headers = response_headers.c_str();
10627   transaction.data = kFullRangeData;
10628   AddMockTransaction(&transaction);
10629 
10630   MockHttpRequest request(transaction);
10631   auto c = std::make_unique<Context>();
10632 
10633   int rv = cache.CreateTransaction(&c->trans);
10634   ASSERT_THAT(rv, IsOk());
10635 
10636   // Queue another request to this transaction. We have to start this request
10637   // before the first one gets the response from the server and dooms the entry,
10638   // otherwise it will just create a new entry without being queued to the first
10639   // request.
10640   auto pending = std::make_unique<Context>();
10641   ASSERT_THAT(cache.CreateTransaction(&pending->trans), IsOk());
10642 
10643   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10644   EXPECT_EQ(ERR_IO_PENDING,
10645             pending->trans->Start(&request, pending->callback.callback(),
10646                                   NetLogWithSource()));
10647   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10648 
10649   // Make sure that the entry has some data stored.
10650   scoped_refptr<IOBufferWithSize> buf =
10651       base::MakeRefCounted<IOBufferWithSize>(5);
10652   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10653   EXPECT_EQ(5, c->callback.GetResult(rv));
10654 
10655   // Since |pending| is currently validating the already written headers
10656   // it will be restarted as well.
10657   c.reset();
10658   pending.reset();
10659 
10660   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10661   EXPECT_EQ(1, cache.disk_cache()->open_count());
10662   EXPECT_EQ(1, cache.disk_cache()->create_count());
10663 
10664   base::RunLoop().RunUntilIdle();
10665   RemoveMockTransaction(&transaction);
10666 }
10667 
10668 // Tests that we delete truncated entries if the server changes its mind midway.
TEST_F(HttpCacheTest,GET_IncompleteResource2)10669 TEST_F(HttpCacheTest, GET_IncompleteResource2) {
10670   MockHttpCache cache;
10671   AddMockTransaction(&kRangeGET_TransactionOK);
10672 
10673   // Content-length will be intentionally bad.
10674   std::string raw_headers("HTTP/1.1 200 OK\n"
10675                           "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10676                           "ETag: \"foo\"\n"
10677                           "Accept-Ranges: bytes\n"
10678                           "Content-Length: 50\n");
10679   CreateTruncatedEntry(raw_headers, &cache);
10680 
10681   // Now make a regular request. We expect the code to fail the validation and
10682   // retry the request without using byte ranges.
10683   std::string headers;
10684   MockTransaction transaction(kRangeGET_TransactionOK);
10685   transaction.request_headers = EXTRA_HEADER;
10686   transaction.data = "Not a range";
10687   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
10688 
10689   // The server will return 200 instead of a byte range.
10690   std::string expected_headers(
10691       "HTTP/1.1 200 OK\n"
10692       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
10693 
10694   EXPECT_EQ(expected_headers, headers);
10695   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10696   EXPECT_EQ(1, cache.disk_cache()->open_count());
10697   EXPECT_EQ(1, cache.disk_cache()->create_count());
10698 
10699   // Verify that the disk entry was deleted.
10700   disk_cache::Entry* entry;
10701   MockHttpRequest request(transaction);
10702   ASSERT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
10703   RemoveMockTransaction(&kRangeGET_TransactionOK);
10704 }
10705 
10706 // Tests that we always validate a truncated request.
TEST_F(HttpCacheTest,GET_IncompleteResource3)10707 TEST_F(HttpCacheTest, GET_IncompleteResource3) {
10708   MockHttpCache cache;
10709   AddMockTransaction(&kRangeGET_TransactionOK);
10710 
10711   // This should not require validation for 10 hours.
10712   std::string raw_headers("HTTP/1.1 200 OK\n"
10713                           "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
10714                           "ETag: \"foo\"\n"
10715                           "Cache-Control: max-age= 36000\n"
10716                           "Accept-Ranges: bytes\n"
10717                           "Content-Length: 80\n");
10718   CreateTruncatedEntry(raw_headers, &cache);
10719 
10720   // Now make a regular request.
10721   std::string headers;
10722   MockTransaction transaction(kRangeGET_TransactionOK);
10723   transaction.request_headers = EXTRA_HEADER;
10724   transaction.data = kFullRangeData;
10725 
10726   auto c = std::make_unique<Context>();
10727   int rv = cache.CreateTransaction(&c->trans);
10728   ASSERT_THAT(rv, IsOk());
10729 
10730   MockHttpRequest request(transaction);
10731   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10732   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10733 
10734   // We should have checked with the server before finishing Start().
10735   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10736   EXPECT_EQ(1, cache.disk_cache()->open_count());
10737   EXPECT_EQ(1, cache.disk_cache()->create_count());
10738 
10739   RemoveMockTransaction(&kRangeGET_TransactionOK);
10740 }
10741 
10742 // Tests that we handle 401s for truncated resources.
TEST_F(HttpCacheTest,GET_IncompleteResourceWithAuth)10743 TEST_F(HttpCacheTest, GET_IncompleteResourceWithAuth) {
10744   MockHttpCache cache;
10745   AddMockTransaction(&kRangeGET_TransactionOK);
10746 
10747   std::string raw_headers("HTTP/1.1 200 OK\n"
10748                           "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10749                           "ETag: \"foo\"\n"
10750                           "Accept-Ranges: bytes\n"
10751                           "Content-Length: 80\n");
10752   CreateTruncatedEntry(raw_headers, &cache);
10753 
10754   // Now make a regular request.
10755   MockTransaction transaction(kRangeGET_TransactionOK);
10756   transaction.request_headers = "X-Require-Mock-Auth: dummy\r\n"
10757                                 EXTRA_HEADER;
10758   transaction.data = kFullRangeData;
10759   RangeTransactionServer handler;
10760 
10761   auto c = std::make_unique<Context>();
10762   int rv = cache.CreateTransaction(&c->trans);
10763   ASSERT_THAT(rv, IsOk());
10764 
10765   MockHttpRequest request(transaction);
10766   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10767   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10768 
10769   const HttpResponseInfo* response = c->trans->GetResponseInfo();
10770   ASSERT_TRUE(response);
10771   ASSERT_EQ(401, response->headers->response_code());
10772   rv = c->trans->RestartWithAuth(AuthCredentials(), c->callback.callback());
10773   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10774   response = c->trans->GetResponseInfo();
10775   ASSERT_TRUE(response);
10776   ASSERT_EQ(200, response->headers->response_code());
10777 
10778   ReadAndVerifyTransaction(c->trans.get(), transaction);
10779   c.reset();  // The destructor could delete the entry.
10780   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10781 
10782   // Verify that the entry was deleted.
10783   disk_cache::Entry* entry;
10784   ASSERT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &entry));
10785   entry->Close();
10786 
10787   RemoveMockTransaction(&kRangeGET_TransactionOK);
10788 }
10789 
10790 // Test that the transaction won't retry failed partial requests
10791 // after it starts reading data.  http://crbug.com/474835
TEST_F(HttpCacheTest,TransactionRetryLimit)10792 TEST_F(HttpCacheTest, TransactionRetryLimit) {
10793   MockHttpCache cache;
10794 
10795   // Cache 0-9, so that we have data to read before failing.
10796   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10797   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
10798   transaction.data = "rg: 00-09 ";
10799 
10800   // Write to the cache.
10801   RunTransactionTest(cache.http_cache(), transaction);
10802   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10803 
10804   // And now read from the cache and the network.  10-19 will get a
10805   // 401, but will have already returned 0-9.
10806   // We do not set X-Require-Mock-Auth because that causes the mock
10807   // network transaction to become IsReadyToRestartForAuth().
10808   transaction.request_headers =
10809       "Range: bytes = 0-79\r\n"
10810       "X-Require-Mock-Auth-Alt: dummy\r\n" EXTRA_HEADER;
10811 
10812   auto c = std::make_unique<Context>();
10813   int rv = cache.CreateTransaction(&c->trans);
10814   ASSERT_THAT(rv, IsOk());
10815 
10816   MockHttpRequest request(transaction);
10817 
10818   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10819   if (rv == ERR_IO_PENDING)
10820     rv = c->callback.WaitForResult();
10821   std::string content;
10822   rv = ReadTransaction(c->trans.get(), &content);
10823   EXPECT_THAT(rv, IsError(ERR_CACHE_AUTH_FAILURE_AFTER_READ));
10824 }
10825 
10826 // Tests that we cache a 200 response to the validation request.
TEST_F(HttpCacheTest,GET_IncompleteResource4)10827 TEST_F(HttpCacheTest, GET_IncompleteResource4) {
10828   MockHttpCache cache;
10829   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10830 
10831   std::string raw_headers("HTTP/1.1 200 OK\n"
10832                           "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
10833                           "ETag: \"foo\"\n"
10834                           "Accept-Ranges: bytes\n"
10835                           "Content-Length: 80\n");
10836   CreateTruncatedEntry(raw_headers, &cache);
10837 
10838   // Now make a regular request.
10839   std::string headers;
10840   transaction.request_headers = EXTRA_HEADER;
10841   transaction.data = "Not a range";
10842   RangeTransactionServer handler;
10843   handler.set_bad_200(true);
10844   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
10845 
10846   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10847   EXPECT_EQ(1, cache.disk_cache()->open_count());
10848   EXPECT_EQ(1, cache.disk_cache()->create_count());
10849 
10850   // Verify that the disk entry was updated.
10851   MockHttpRequest request(transaction);
10852   VerifyTruncatedFlag(&cache, request.CacheKey(), false, 11);
10853 }
10854 
10855 // Tests that when we cancel a request that was interrupted, we mark it again
10856 // as truncated.
TEST_F(HttpCacheTest,GET_CancelIncompleteResource)10857 TEST_F(HttpCacheTest, GET_CancelIncompleteResource) {
10858   MockHttpCache cache;
10859   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10860 
10861   std::string raw_headers("HTTP/1.1 200 OK\n"
10862                           "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
10863                           "ETag: \"foo\"\n"
10864                           "Accept-Ranges: bytes\n"
10865                           "Content-Length: 80\n");
10866   CreateTruncatedEntry(raw_headers, &cache);
10867 
10868   // Now make a regular request.
10869   transaction.request_headers = EXTRA_HEADER;
10870 
10871   MockHttpRequest request(transaction);
10872   auto c = std::make_unique<Context>();
10873   int rv = cache.CreateTransaction(&c->trans);
10874   ASSERT_THAT(rv, IsOk());
10875 
10876   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10877   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10878 
10879   // Read 20 bytes from the cache, and 10 from the net.
10880   scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(100);
10881   rv = c->trans->Read(buf.get(), 20, c->callback.callback());
10882   EXPECT_EQ(20, c->callback.GetResult(rv));
10883   rv = c->trans->Read(buf.get(), 10, c->callback.callback());
10884   EXPECT_EQ(10, c->callback.GetResult(rv));
10885 
10886   // At this point, we are already reading so canceling the request should leave
10887   // a truncated one.
10888   c.reset();
10889 
10890   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10891   EXPECT_EQ(1, cache.disk_cache()->open_count());
10892   EXPECT_EQ(1, cache.disk_cache()->create_count());
10893 
10894   // Verify that the disk entry was updated: now we have 30 bytes.
10895   VerifyTruncatedFlag(&cache, request.CacheKey(), true, 30);
10896 }
10897 
10898 // Tests that we can handle range requests when we have a truncated entry.
TEST_F(HttpCacheTest,RangeGET_IncompleteResource)10899 TEST_F(HttpCacheTest, RangeGET_IncompleteResource) {
10900   MockHttpCache cache;
10901   AddMockTransaction(&kRangeGET_TransactionOK);
10902 
10903   // Content-length will be intentionally bogus.
10904   std::string raw_headers("HTTP/1.1 200 OK\n"
10905                           "Last-Modified: something\n"
10906                           "ETag: \"foo\"\n"
10907                           "Accept-Ranges: bytes\n"
10908                           "Content-Length: 10\n");
10909   CreateTruncatedEntry(raw_headers, &cache);
10910 
10911   // Now make a range request.
10912   std::string headers;
10913   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
10914                                  &headers);
10915 
10916   Verify206Response(headers, 40, 49);
10917   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10918   EXPECT_EQ(1, cache.disk_cache()->open_count());
10919   EXPECT_EQ(2, cache.disk_cache()->create_count());
10920 
10921   RemoveMockTransaction(&kRangeGET_TransactionOK);
10922 }
10923 
TEST_F(HttpCacheTest,SyncRead)10924 TEST_F(HttpCacheTest, SyncRead) {
10925   MockHttpCache cache;
10926 
10927   // This test ensures that a read that completes synchronously does not cause
10928   // any problems.
10929 
10930   ScopedMockTransaction transaction(kSimpleGET_Transaction);
10931   transaction.test_mode |= (TEST_MODE_SYNC_CACHE_START |
10932                             TEST_MODE_SYNC_CACHE_READ |
10933                             TEST_MODE_SYNC_CACHE_WRITE);
10934 
10935   MockHttpRequest r1(transaction),
10936                   r2(transaction),
10937                   r3(transaction);
10938 
10939   TestTransactionConsumer c1(DEFAULT_PRIORITY, cache.http_cache()),
10940       c2(DEFAULT_PRIORITY, cache.http_cache()),
10941       c3(DEFAULT_PRIORITY, cache.http_cache());
10942 
10943   c1.Start(&r1, NetLogWithSource());
10944 
10945   r2.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
10946   c2.Start(&r2, NetLogWithSource());
10947 
10948   r3.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
10949   c3.Start(&r3, NetLogWithSource());
10950 
10951   base::RunLoop().Run();
10952 
10953   EXPECT_TRUE(c1.is_done());
10954   EXPECT_TRUE(c2.is_done());
10955   EXPECT_TRUE(c3.is_done());
10956 
10957   EXPECT_THAT(c1.error(), IsOk());
10958   EXPECT_THAT(c2.error(), IsOk());
10959   EXPECT_THAT(c3.error(), IsOk());
10960 }
10961 
TEST_F(HttpCacheTest,ValidationResultsIn200)10962 TEST_F(HttpCacheTest, ValidationResultsIn200) {
10963   MockHttpCache cache;
10964 
10965   // This test ensures that a conditional request, which results in a 200
10966   // instead of a 304, properly truncates the existing response data.
10967 
10968   // write to the cache
10969   RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
10970 
10971   // force this transaction to validate the cache
10972   MockTransaction transaction(kETagGET_Transaction);
10973   transaction.load_flags |= LOAD_VALIDATE_CACHE;
10974   RunTransactionTest(cache.http_cache(), transaction);
10975 
10976   // read from the cache
10977   RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
10978 }
10979 
TEST_F(HttpCacheTest,CachedRedirect)10980 TEST_F(HttpCacheTest, CachedRedirect) {
10981   MockHttpCache cache;
10982 
10983   ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction);
10984   kTestTransaction.status = "HTTP/1.1 301 Moved Permanently";
10985   kTestTransaction.response_headers = "Location: http://www.bar.com/\n";
10986 
10987   MockHttpRequest request(kTestTransaction);
10988   TestCompletionCallback callback;
10989 
10990   // Write to the cache.
10991   {
10992     std::unique_ptr<HttpTransaction> trans;
10993     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
10994 
10995     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
10996     if (rv == ERR_IO_PENDING)
10997       rv = callback.WaitForResult();
10998     ASSERT_THAT(rv, IsOk());
10999 
11000     const HttpResponseInfo* info = trans->GetResponseInfo();
11001     ASSERT_TRUE(info);
11002 
11003     EXPECT_EQ(info->headers->response_code(), 301);
11004 
11005     std::string location;
11006     info->headers->EnumerateHeader(nullptr, "Location", &location);
11007     EXPECT_EQ(location, "http://www.bar.com/");
11008 
11009     // Mark the transaction as completed so it is cached.
11010     trans->DoneReading();
11011 
11012     // Destroy transaction when going out of scope. We have not actually
11013     // read the response body -- want to test that it is still getting cached.
11014   }
11015   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11016   EXPECT_EQ(0, cache.disk_cache()->open_count());
11017   EXPECT_EQ(1, cache.disk_cache()->create_count());
11018 
11019   // Active entries in the cache are not retired synchronously. Make
11020   // sure the next run hits the MockHttpCache and open_count is
11021   // correct.
11022   base::RunLoop().RunUntilIdle();
11023 
11024   // Read from the cache.
11025   {
11026     std::unique_ptr<HttpTransaction> trans;
11027     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11028 
11029     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11030     if (rv == ERR_IO_PENDING)
11031       rv = callback.WaitForResult();
11032     ASSERT_THAT(rv, IsOk());
11033 
11034     const HttpResponseInfo* info = trans->GetResponseInfo();
11035     ASSERT_TRUE(info);
11036 
11037     EXPECT_EQ(info->headers->response_code(), 301);
11038 
11039     std::string location;
11040     info->headers->EnumerateHeader(nullptr, "Location", &location);
11041     EXPECT_EQ(location, "http://www.bar.com/");
11042 
11043     // Mark the transaction as completed so it is cached.
11044     trans->DoneReading();
11045 
11046     // Destroy transaction when going out of scope. We have not actually
11047     // read the response body -- want to test that it is still getting cached.
11048   }
11049   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11050   EXPECT_EQ(1, cache.disk_cache()->open_count());
11051   EXPECT_EQ(1, cache.disk_cache()->create_count());
11052 }
11053 
11054 // Verify that no-cache resources are stored in cache, but are not fetched from
11055 // cache during normal loads.
TEST_F(HttpCacheTest,CacheControlNoCacheNormalLoad)11056 TEST_F(HttpCacheTest, CacheControlNoCacheNormalLoad) {
11057   for (bool use_memory_entry_data : {false, true}) {
11058     MockHttpCache cache;
11059     cache.disk_cache()->set_support_in_memory_entry_data(use_memory_entry_data);
11060 
11061     ScopedMockTransaction transaction(kSimpleGET_Transaction);
11062     transaction.response_headers = "cache-control: no-cache\n";
11063 
11064     // Initial load.
11065     RunTransactionTest(cache.http_cache(), transaction);
11066 
11067     EXPECT_EQ(1, cache.network_layer()->transaction_count());
11068     EXPECT_EQ(0, cache.disk_cache()->open_count());
11069     EXPECT_EQ(1, cache.disk_cache()->create_count());
11070 
11071     // Try loading again; it should result in a network fetch.
11072     RunTransactionTest(cache.http_cache(), transaction);
11073 
11074     EXPECT_EQ(2, cache.network_layer()->transaction_count());
11075     if (use_memory_entry_data) {
11076       EXPECT_EQ(0, cache.disk_cache()->open_count());
11077       EXPECT_EQ(2, cache.disk_cache()->create_count());
11078     } else {
11079       EXPECT_EQ(1, cache.disk_cache()->open_count());
11080       EXPECT_EQ(1, cache.disk_cache()->create_count());
11081     }
11082 
11083     disk_cache::Entry* entry;
11084     MockHttpRequest request(transaction);
11085     EXPECT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &entry));
11086     entry->Close();
11087   }
11088 }
11089 
11090 // Verify that no-cache resources are stored in cache and fetched from cache
11091 // when the LOAD_SKIP_CACHE_VALIDATION flag is set.
TEST_F(HttpCacheTest,CacheControlNoCacheHistoryLoad)11092 TEST_F(HttpCacheTest, CacheControlNoCacheHistoryLoad) {
11093   MockHttpCache cache;
11094 
11095   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11096   transaction.response_headers = "cache-control: no-cache\n";
11097 
11098   // Initial load.
11099   RunTransactionTest(cache.http_cache(), transaction);
11100 
11101   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11102   EXPECT_EQ(0, cache.disk_cache()->open_count());
11103   EXPECT_EQ(1, cache.disk_cache()->create_count());
11104 
11105   // Try loading again with LOAD_SKIP_CACHE_VALIDATION.
11106   transaction.load_flags = LOAD_SKIP_CACHE_VALIDATION;
11107   RunTransactionTest(cache.http_cache(), transaction);
11108 
11109   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11110   EXPECT_EQ(1, cache.disk_cache()->open_count());
11111   EXPECT_EQ(1, cache.disk_cache()->create_count());
11112 
11113   disk_cache::Entry* entry;
11114   MockHttpRequest request(transaction);
11115   EXPECT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &entry));
11116   entry->Close();
11117 }
11118 
TEST_F(HttpCacheTest,CacheControlNoStore)11119 TEST_F(HttpCacheTest, CacheControlNoStore) {
11120   MockHttpCache cache;
11121 
11122   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11123   transaction.response_headers = "cache-control: no-store\n";
11124 
11125   // initial load
11126   RunTransactionTest(cache.http_cache(), transaction);
11127 
11128   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11129   EXPECT_EQ(0, cache.disk_cache()->open_count());
11130   EXPECT_EQ(1, cache.disk_cache()->create_count());
11131 
11132   // try loading again; it should result in a network fetch
11133   RunTransactionTest(cache.http_cache(), transaction);
11134 
11135   EXPECT_EQ(2, cache.network_layer()->transaction_count());
11136   EXPECT_EQ(0, cache.disk_cache()->open_count());
11137   EXPECT_EQ(2, cache.disk_cache()->create_count());
11138 
11139   disk_cache::Entry* entry;
11140   MockHttpRequest request(transaction);
11141   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
11142 }
11143 
TEST_F(HttpCacheTest,CacheControlNoStore2)11144 TEST_F(HttpCacheTest, CacheControlNoStore2) {
11145   // this test is similar to the above test, except that the initial response
11146   // is cachable, but when it is validated, no-store is received causing the
11147   // cached document to be deleted.
11148   MockHttpCache cache;
11149 
11150   ScopedMockTransaction transaction(kETagGET_Transaction);
11151 
11152   // initial load
11153   RunTransactionTest(cache.http_cache(), transaction);
11154 
11155   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11156   EXPECT_EQ(0, cache.disk_cache()->open_count());
11157   EXPECT_EQ(1, cache.disk_cache()->create_count());
11158 
11159   // try loading again; it should result in a network fetch
11160   transaction.load_flags = LOAD_VALIDATE_CACHE;
11161   transaction.response_headers = "cache-control: no-store\n";
11162   RunTransactionTest(cache.http_cache(), transaction);
11163 
11164   EXPECT_EQ(2, cache.network_layer()->transaction_count());
11165   EXPECT_EQ(1, cache.disk_cache()->open_count());
11166   EXPECT_EQ(1, cache.disk_cache()->create_count());
11167 
11168   disk_cache::Entry* entry;
11169   MockHttpRequest request(transaction);
11170   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
11171 }
11172 
TEST_F(HttpCacheTest,CacheControlNoStore3)11173 TEST_F(HttpCacheTest, CacheControlNoStore3) {
11174   // this test is similar to the above test, except that the response is a 304
11175   // instead of a 200.  this should never happen in practice, but it seems like
11176   // a good thing to verify that we still destroy the cache entry.
11177   MockHttpCache cache;
11178 
11179   ScopedMockTransaction transaction(kETagGET_Transaction);
11180 
11181   // initial load
11182   RunTransactionTest(cache.http_cache(), transaction);
11183 
11184   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11185   EXPECT_EQ(0, cache.disk_cache()->open_count());
11186   EXPECT_EQ(1, cache.disk_cache()->create_count());
11187 
11188   // try loading again; it should result in a network fetch
11189   transaction.load_flags = LOAD_VALIDATE_CACHE;
11190   transaction.response_headers = "cache-control: no-store\n";
11191   transaction.status = "HTTP/1.1 304 Not Modified";
11192   RunTransactionTest(cache.http_cache(), transaction);
11193 
11194   EXPECT_EQ(2, cache.network_layer()->transaction_count());
11195   EXPECT_EQ(1, cache.disk_cache()->open_count());
11196   EXPECT_EQ(1, cache.disk_cache()->create_count());
11197 
11198   disk_cache::Entry* entry;
11199   MockHttpRequest request(transaction);
11200   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
11201 }
11202 
11203 // Ensure that we don't cache requests served over bad HTTPS.
TEST_F(HttpCacheTest,SimpleGET_SSLError)11204 TEST_F(HttpCacheTest, SimpleGET_SSLError) {
11205   MockHttpCache cache;
11206 
11207   MockTransaction transaction = kSimpleGET_Transaction;
11208   transaction.cert_status = CERT_STATUS_REVOKED;
11209   ScopedMockTransaction scoped_transaction(transaction);
11210 
11211   // write to the cache
11212   RunTransactionTest(cache.http_cache(), transaction);
11213 
11214   // Test that it was not cached.
11215   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
11216 
11217   MockHttpRequest request(transaction);
11218   TestCompletionCallback callback;
11219 
11220   std::unique_ptr<HttpTransaction> trans;
11221   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11222 
11223   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11224   if (rv == ERR_IO_PENDING)
11225     rv = callback.WaitForResult();
11226   ASSERT_THAT(rv, IsError(ERR_CACHE_MISS));
11227 }
11228 
11229 // Ensure that we don't crash by if left-behind transactions.
TEST_F(HttpCacheTest,OutlivedTransactions)11230 TEST_F(HttpCacheTest, OutlivedTransactions) {
11231   auto cache = std::make_unique<MockHttpCache>();
11232 
11233   std::unique_ptr<HttpTransaction> trans;
11234   EXPECT_THAT(cache->CreateTransaction(&trans), IsOk());
11235 
11236   cache.reset();
11237   trans.reset();
11238 }
11239 
11240 // Test that the disabled mode works.
TEST_F(HttpCacheTest,CacheDisabledMode)11241 TEST_F(HttpCacheTest, CacheDisabledMode) {
11242   MockHttpCache cache;
11243 
11244   // write to the cache
11245   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
11246 
11247   // go into disabled mode
11248   cache.http_cache()->set_mode(HttpCache::DISABLE);
11249 
11250   // force this transaction to write to the cache again
11251   MockTransaction transaction(kSimpleGET_Transaction);
11252 
11253   RunTransactionTest(cache.http_cache(), transaction);
11254 
11255   EXPECT_EQ(2, cache.network_layer()->transaction_count());
11256   EXPECT_EQ(0, cache.disk_cache()->open_count());
11257   EXPECT_EQ(1, cache.disk_cache()->create_count());
11258 }
11259 
11260 // Other tests check that the response headers of the cached response
11261 // get updated on 304. Here we specifically check that the
11262 // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
11263 // fields also gets updated.
11264 // http://crbug.com/20594.
TEST_F(HttpCacheTest,UpdatesRequestResponseTimeOn304)11265 TEST_F(HttpCacheTest, UpdatesRequestResponseTimeOn304) {
11266   MockHttpCache cache;
11267 
11268   const char kUrl[] = "http://foobar";
11269   const char kData[] = "body";
11270 
11271   MockTransaction mock_network_response = {nullptr};
11272   mock_network_response.url = kUrl;
11273 
11274   AddMockTransaction(&mock_network_response);
11275 
11276   // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
11277 
11278   MockTransaction request = {nullptr};
11279   request.url = kUrl;
11280   request.method = "GET";
11281   request.request_headers = "\r\n";
11282   request.data = kData;
11283 
11284   static const Response kNetResponse1 = {
11285     "HTTP/1.1 200 OK",
11286     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
11287     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
11288     kData
11289   };
11290 
11291   kNetResponse1.AssignTo(&mock_network_response);
11292 
11293   RunTransactionTest(cache.http_cache(), request);
11294 
11295   // Request |kUrl| again, this time validating the cache and getting
11296   // a 304 back.
11297 
11298   request.load_flags = LOAD_VALIDATE_CACHE;
11299 
11300   static const Response kNetResponse2 = {
11301     "HTTP/1.1 304 Not Modified",
11302     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
11303     ""
11304   };
11305 
11306   kNetResponse2.AssignTo(&mock_network_response);
11307 
11308   base::Time request_time = base::Time() + base::Hours(1234);
11309   base::Time response_time = base::Time() + base::Hours(1235);
11310 
11311   mock_network_response.request_time = request_time;
11312   mock_network_response.response_time = response_time;
11313 
11314   HttpResponseInfo response;
11315   RunTransactionTestWithResponseInfo(cache.http_cache(), request, &response);
11316 
11317   // The request and response times should have been updated.
11318   EXPECT_EQ(request_time.ToInternalValue(),
11319             response.request_time.ToInternalValue());
11320   EXPECT_EQ(response_time.ToInternalValue(),
11321             response.response_time.ToInternalValue());
11322 
11323   EXPECT_EQ("HTTP/1.1 200 OK\n"
11324             "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
11325             "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
11326             ToSimpleString(response.headers));
11327 
11328   RemoveMockTransaction(&mock_network_response);
11329 }
11330 
TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,SplitCacheWithNetworkIsolationKey)11331 TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,
11332        SplitCacheWithNetworkIsolationKey) {
11333   MockHttpCache cache;
11334   HttpResponseInfo response;
11335 
11336   SchemefulSite site_a(GURL("http://a.com"));
11337   SchemefulSite site_b(GURL("http://b.com"));
11338   SchemefulSite site_data(GURL("data:text/html,<body>Hello World</body>"));
11339 
11340   MockHttpRequest trans_info = MockHttpRequest(kSimpleGET_Transaction);
11341   // Request with a.com as the top frame and subframe origins. This should
11342   // result in a cache miss.
11343   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11344   trans_info.network_anonymization_key =
11345       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11346   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11347                                 trans_info, &response);
11348   EXPECT_FALSE(response.was_cached);
11349 
11350   // The second request should result in a cache hit.
11351   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11352                                 trans_info, &response);
11353   EXPECT_TRUE(response.was_cached);
11354 
11355   // Now request with b.com as the subframe origin. It should result in a cache
11356   // miss.
11357   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_b);
11358   trans_info.network_anonymization_key =
11359       net::NetworkAnonymizationKey::CreateCrossSite(site_a);
11360   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11361                                 trans_info, &response);
11362   EXPECT_FALSE(response.was_cached);
11363 
11364   // The second request should result in a cache hit.
11365   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11366                                 trans_info, &response);
11367   EXPECT_TRUE(response.was_cached);
11368 
11369   // Another request with a.com as the top frame and subframe origin should
11370   // still result in a cache hit.
11371   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11372   trans_info.network_anonymization_key =
11373       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11374   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11375                                 trans_info, &response);
11376   EXPECT_TRUE(response.was_cached);
11377 
11378   // Now make a request with an opaque subframe site. It shouldn't cause
11379   // anything to be added to the cache when the NIK makes use of the frame site.
11380   // Note that we will use `site_b` as the top-level site so that this resource
11381   // won't be in the cache at first regardless of the NIK partitioning scheme.
11382   trans_info.network_isolation_key = NetworkIsolationKey(site_b, site_data);
11383   trans_info.network_anonymization_key =
11384       net::NetworkAnonymizationKey::CreateCrossSite(site_b);
11385   if (IsNikFrameSiteEnabled()) {
11386     EXPECT_EQ(absl::nullopt,
11387               trans_info.network_isolation_key.ToCacheKeyString());
11388   } else {
11389     EXPECT_EQ("http://b.com _1",
11390               trans_info.network_isolation_key.ToCacheKeyString().value());
11391   }
11392   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11393                                 trans_info, &response);
11394   EXPECT_FALSE(response.was_cached);
11395 
11396   // On the second request, expect a cache miss if the NIK uses the frame site.
11397   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11398                                 trans_info, &response);
11399   if (IsNikFrameSiteEnabled()) {
11400     EXPECT_FALSE(response.was_cached);
11401   } else {
11402     EXPECT_TRUE(response.was_cached);
11403   }
11404 
11405   // Verify that a post transaction with a data stream uses a separate key.
11406   const int64_t kUploadId = 1;  // Just a dummy value.
11407 
11408   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
11409   element_readers.push_back(
11410       std::make_unique<UploadBytesElementReader>("hello", 5));
11411   ElementsUploadDataStream upload_data_stream(std::move(element_readers),
11412                                               kUploadId);
11413 
11414   MockHttpRequest post_info = MockHttpRequest(kSimplePOST_Transaction);
11415   post_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11416   post_info.network_anonymization_key =
11417       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11418   post_info.upload_data_stream = &upload_data_stream;
11419 
11420   RunTransactionTestWithRequest(cache.http_cache(), kSimplePOST_Transaction,
11421                                 post_info, &response);
11422   EXPECT_FALSE(response.was_cached);
11423 }
11424 
TEST_F(HttpCacheTest,HttpCacheProfileThirdPartyCSS)11425 TEST_F(HttpCacheTest, HttpCacheProfileThirdPartyCSS) {
11426   base::HistogramTester histograms;
11427   MockHttpCache cache;
11428   HttpResponseInfo response;
11429 
11430   url::Origin origin_a = url::Origin::Create(GURL(kSimpleGET_Transaction.url));
11431   url::Origin origin_b = url::Origin::Create(GURL("http://b.com"));
11432   SchemefulSite site_a(origin_a);
11433   SchemefulSite site_b(origin_b);
11434 
11435   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11436   transaction.response_headers = "Content-Type: text/css\n";
11437 
11438   MockHttpRequest trans_info = MockHttpRequest(transaction);
11439 
11440   // Requesting with the same top-frame site should not count as third-party
11441   // but should still be recorded as CSS
11442   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11443   trans_info.network_anonymization_key =
11444       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11445   trans_info.possibly_top_frame_origin = origin_a;
11446 
11447   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11448                                 &response);
11449 
11450   histograms.ExpectTotalCount("HttpCache.Pattern", 1);
11451   histograms.ExpectTotalCount("HttpCache.Pattern.CSS", 1);
11452   histograms.ExpectTotalCount("HttpCache.Pattern.CSSThirdParty", 0);
11453 
11454   // Requesting with a different top-frame site should count as third-party
11455   // and recorded as CSS
11456   trans_info.network_isolation_key = NetworkIsolationKey(site_b, site_b);
11457   trans_info.network_anonymization_key =
11458       net::NetworkAnonymizationKey::CreateSameSite(site_b);
11459   trans_info.possibly_top_frame_origin = origin_b;
11460 
11461   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11462                                 &response);
11463   histograms.ExpectTotalCount("HttpCache.Pattern", 2);
11464   histograms.ExpectTotalCount("HttpCache.Pattern.CSS", 2);
11465   histograms.ExpectTotalCount("HttpCache.Pattern.CSSThirdParty", 1);
11466 }
11467 
TEST_F(HttpCacheTest,HttpCacheProfileThirdPartyJavaScript)11468 TEST_F(HttpCacheTest, HttpCacheProfileThirdPartyJavaScript) {
11469   base::HistogramTester histograms;
11470   MockHttpCache cache;
11471   HttpResponseInfo response;
11472 
11473   url::Origin origin_a = url::Origin::Create(GURL(kSimpleGET_Transaction.url));
11474   url::Origin origin_b = url::Origin::Create(GURL("http://b.com"));
11475   SchemefulSite site_a(origin_a);
11476   SchemefulSite site_b(origin_b);
11477 
11478   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11479   transaction.response_headers = "Content-Type: application/javascript\n";
11480 
11481   MockHttpRequest trans_info = MockHttpRequest(transaction);
11482 
11483   // Requesting with the same top-frame site should not count as third-party
11484   // but should still be recorded as JavaScript
11485   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11486   trans_info.network_anonymization_key =
11487       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11488   trans_info.possibly_top_frame_origin = origin_a;
11489 
11490   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11491                                 &response);
11492 
11493   histograms.ExpectTotalCount("HttpCache.Pattern", 1);
11494   histograms.ExpectTotalCount("HttpCache.Pattern.JavaScript", 1);
11495   histograms.ExpectTotalCount("HttpCache.Pattern.JavaScriptThirdParty", 0);
11496 
11497   // Requesting with a different top-frame site should count as third-party
11498   // and recorded as JavaScript
11499   trans_info.network_isolation_key = NetworkIsolationKey(site_b, site_b);
11500   trans_info.network_anonymization_key =
11501       net::NetworkAnonymizationKey::CreateSameSite(site_b);
11502   trans_info.possibly_top_frame_origin = origin_b;
11503 
11504   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11505                                 &response);
11506   histograms.ExpectTotalCount("HttpCache.Pattern", 2);
11507   histograms.ExpectTotalCount("HttpCache.Pattern.JavaScript", 2);
11508   histograms.ExpectTotalCount("HttpCache.Pattern.JavaScriptThirdParty", 1);
11509 }
11510 
TEST_F(HttpCacheTest,HttpCacheProfileThirdPartyFont)11511 TEST_F(HttpCacheTest, HttpCacheProfileThirdPartyFont) {
11512   base::HistogramTester histograms;
11513   MockHttpCache cache;
11514   HttpResponseInfo response;
11515 
11516   url::Origin origin_a = url::Origin::Create(GURL(kSimpleGET_Transaction.url));
11517   url::Origin origin_b = url::Origin::Create(GURL("http://b.com"));
11518   SchemefulSite site_a(origin_a);
11519   SchemefulSite site_b(origin_b);
11520 
11521   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11522   transaction.response_headers = "Content-Type: font/otf\n";
11523 
11524   MockHttpRequest trans_info = MockHttpRequest(transaction);
11525 
11526   // Requesting with the same top-frame site should not count as third-party
11527   // but should still be recorded as a font
11528   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11529   trans_info.network_anonymization_key =
11530       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11531   trans_info.possibly_top_frame_origin = origin_a;
11532 
11533   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11534                                 &response);
11535 
11536   histograms.ExpectTotalCount("HttpCache.Pattern", 1);
11537   histograms.ExpectTotalCount("HttpCache.Pattern.Font", 1);
11538   histograms.ExpectTotalCount("HttpCache.Pattern.FontThirdParty", 0);
11539 
11540   // Requesting with a different top-frame site should count as third-party
11541   // and recorded as a font
11542   trans_info.network_isolation_key = NetworkIsolationKey(site_b, site_b);
11543   trans_info.network_anonymization_key =
11544       net::NetworkAnonymizationKey::CreateSameSite(site_b);
11545   trans_info.possibly_top_frame_origin = origin_b;
11546 
11547   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11548                                 &response);
11549   histograms.ExpectTotalCount("HttpCache.Pattern", 2);
11550   histograms.ExpectTotalCount("HttpCache.Pattern.Font", 2);
11551   histograms.ExpectTotalCount("HttpCache.Pattern.FontThirdParty", 1);
11552 }
11553 
TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,SplitCache)11554 TEST_P(HttpCacheTest_SplitCacheFeatureEnabled, SplitCache) {
11555   MockHttpCache cache;
11556   HttpResponseInfo response;
11557 
11558   SchemefulSite site_a(GURL("http://a.com"));
11559   SchemefulSite site_b(GURL("http://b.com"));
11560   SchemefulSite site_data(GURL("data:text/html,<body>Hello World</body>"));
11561 
11562   // A request without a top frame origin shouldn't result in anything being
11563   // added to the cache.
11564   MockHttpRequest trans_info = MockHttpRequest(kSimpleGET_Transaction);
11565   trans_info.network_isolation_key = net::NetworkIsolationKey();
11566   trans_info.network_anonymization_key = net::NetworkAnonymizationKey();
11567   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11568                                 trans_info, &response);
11569   EXPECT_FALSE(response.was_cached);
11570 
11571   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11572                                 trans_info, &response);
11573   EXPECT_FALSE(response.was_cached);
11574 
11575   // Now request with a.com as the top frame origin. This should initially
11576   // result in a cache miss since the cached resource has a different top frame
11577   // origin.
11578   net::NetworkIsolationKey key_a(site_a, site_a);
11579   auto nak_a = net::NetworkAnonymizationKey::CreateSameSite(site_a);
11580   trans_info.network_isolation_key = key_a;
11581   trans_info.network_anonymization_key = nak_a;
11582   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11583                                 trans_info, &response);
11584   EXPECT_FALSE(response.was_cached);
11585 
11586   // The second request should result in a cache hit.
11587   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11588                                 trans_info, &response);
11589   EXPECT_TRUE(response.was_cached);
11590 
11591   // If the same resource with the same NIK is for a subframe document resource,
11592   // it should not be a cache hit.
11593   MockHttpRequest subframe_document_trans_info = trans_info;
11594   subframe_document_trans_info.is_subframe_document_resource = true;
11595   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11596                                 subframe_document_trans_info, &response);
11597   EXPECT_FALSE(response.was_cached);
11598 
11599   // Same request again should be a cache hit.
11600   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11601                                 subframe_document_trans_info, &response);
11602   EXPECT_TRUE(response.was_cached);
11603 
11604   // Now request with b.com as the top frame origin. It should be a cache miss.
11605   trans_info.network_isolation_key = NetworkIsolationKey(site_b, site_b);
11606   trans_info.network_anonymization_key =
11607       NetworkAnonymizationKey::CreateSameSite(site_b);
11608   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11609                                 trans_info, &response);
11610   EXPECT_FALSE(response.was_cached);
11611 
11612   // The second request should be a cache hit.
11613   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11614                                 trans_info, &response);
11615   EXPECT_TRUE(response.was_cached);
11616 
11617   // Another request for a.com should still result in a cache hit.
11618   trans_info.network_isolation_key = key_a;
11619   trans_info.network_anonymization_key = nak_a;
11620   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11621                                 trans_info, &response);
11622   EXPECT_TRUE(response.was_cached);
11623 
11624   // Now make a request with an opaque top frame origin. It shouldn't result in
11625   // a cache hit.
11626   trans_info.network_isolation_key = NetworkIsolationKey(site_data, site_data);
11627   trans_info.network_anonymization_key =
11628       NetworkAnonymizationKey::CreateSameSite(site_data);
11629   EXPECT_EQ(absl::nullopt, trans_info.network_isolation_key.ToCacheKeyString());
11630   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11631                                 trans_info, &response);
11632   EXPECT_FALSE(response.was_cached);
11633 
11634   // On the second request, it still shouldn't result in a cache hit.
11635   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11636                                 trans_info, &response);
11637   EXPECT_FALSE(response.was_cached);
11638 
11639   // Verify that a post transaction with a data stream uses a separate key.
11640   const int64_t kUploadId = 1;  // Just a dummy value.
11641 
11642   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
11643   element_readers.push_back(
11644       std::make_unique<UploadBytesElementReader>("hello", 5));
11645   ElementsUploadDataStream upload_data_stream(std::move(element_readers),
11646                                               kUploadId);
11647 
11648   MockHttpRequest post_info = MockHttpRequest(kSimplePOST_Transaction);
11649   post_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11650   post_info.network_anonymization_key =
11651       NetworkAnonymizationKey::CreateSameSite(site_a);
11652   post_info.upload_data_stream = &upload_data_stream;
11653 
11654   RunTransactionTestWithRequest(cache.http_cache(), kSimplePOST_Transaction,
11655                                 post_info, &response);
11656   EXPECT_FALSE(response.was_cached);
11657 }
11658 
TEST_F(HttpCacheTest,SplitCacheEnabledByDefault)11659 TEST_F(HttpCacheTest, SplitCacheEnabledByDefault) {
11660   HttpCache::ClearGlobalsForTesting();
11661   HttpCache::SplitCacheFeatureEnableByDefault();
11662   EXPECT_TRUE(HttpCache::IsSplitCacheEnabled());
11663 
11664   MockHttpCache cache;
11665   HttpResponseInfo response;
11666 
11667   SchemefulSite site_a(GURL("http://a.com"));
11668   SchemefulSite site_b(GURL("http://b.com"));
11669   MockHttpRequest trans_info = MockHttpRequest(kSimpleGET_Transaction);
11670   net::NetworkIsolationKey key_a(site_a, site_a);
11671   auto nak_a = net::NetworkAnonymizationKey::CreateSameSite(site_a);
11672   trans_info.network_isolation_key = key_a;
11673   trans_info.network_anonymization_key = nak_a;
11674   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11675                                 trans_info, &response);
11676   EXPECT_FALSE(response.was_cached);
11677 
11678   // Subsequent requests with the same NIK and different NIK will be a cache hit
11679   // and miss respectively.
11680   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11681                                 trans_info, &response);
11682   EXPECT_TRUE(response.was_cached);
11683 
11684   net::NetworkIsolationKey key_b(site_b, site_b);
11685   auto nak_b = net::NetworkAnonymizationKey::CreateSameSite(site_b);
11686   trans_info.network_isolation_key = key_b;
11687   trans_info.network_anonymization_key = nak_b;
11688   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11689                                 trans_info, &response);
11690   EXPECT_FALSE(response.was_cached);
11691 }
11692 
TEST_F(HttpCacheTest,SplitCacheEnabledByDefaultButOverridden)11693 TEST_F(HttpCacheTest, SplitCacheEnabledByDefaultButOverridden) {
11694   HttpCache::ClearGlobalsForTesting();
11695   base::test::ScopedFeatureList feature_list;
11696   feature_list.InitAndDisableFeature(
11697       net::features::kSplitCacheByNetworkIsolationKey);
11698 
11699   // Enabling it here should have no effect as it is already overridden.
11700   HttpCache::SplitCacheFeatureEnableByDefault();
11701   EXPECT_FALSE(HttpCache::IsSplitCacheEnabled());
11702 }
11703 
TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,SplitCacheUsesRegistrableDomain)11704 TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,
11705        SplitCacheUsesRegistrableDomain) {
11706   MockHttpCache cache;
11707   HttpResponseInfo response;
11708   MockHttpRequest trans_info = MockHttpRequest(kSimpleGET_Transaction);
11709 
11710   SchemefulSite site_a(GURL("http://a.foo.com"));
11711   SchemefulSite site_b(GURL("http://b.foo.com"));
11712 
11713   net::NetworkIsolationKey key_a(site_a, site_a);
11714   auto nak_a = net::NetworkAnonymizationKey::CreateSameSite(site_a);
11715   trans_info.network_isolation_key = key_a;
11716   trans_info.network_anonymization_key = nak_a;
11717   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11718                                 trans_info, &response);
11719   EXPECT_FALSE(response.was_cached);
11720 
11721   // The second request with a different origin but the same registrable domain
11722   // should be a cache hit.
11723   net::NetworkIsolationKey key_b(site_b, site_b);
11724   auto nak_b = net::NetworkAnonymizationKey::CreateSameSite(site_b);
11725   trans_info.network_isolation_key = key_b;
11726   trans_info.network_anonymization_key = nak_b;
11727   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11728                                 trans_info, &response);
11729   EXPECT_TRUE(response.was_cached);
11730 
11731   // Request with a different registrable domain. It should be a cache miss.
11732   SchemefulSite new_site_a(GURL("http://a.bar.com"));
11733   net::NetworkIsolationKey new_key_a(new_site_a, new_site_a);
11734   auto new_nak_a = net::NetworkAnonymizationKey::CreateSameSite(new_site_a);
11735   trans_info.network_isolation_key = new_key_a;
11736   trans_info.network_anonymization_key = new_nak_a;
11737   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11738                                 trans_info, &response);
11739   EXPECT_FALSE(response.was_cached);
11740 }
11741 
TEST_F(HttpCacheTest,NonSplitCache)11742 TEST_F(HttpCacheTest, NonSplitCache) {
11743   base::test::ScopedFeatureList feature_list;
11744   feature_list.InitAndDisableFeature(
11745       net::features::kSplitCacheByNetworkIsolationKey);
11746 
11747   MockHttpCache cache;
11748   HttpResponseInfo response;
11749 
11750   // A request without a top frame is added to the cache normally.
11751   MockHttpRequest trans_info = MockHttpRequest(kSimpleGET_Transaction);
11752   trans_info.network_isolation_key = NetworkIsolationKey();
11753   trans_info.network_anonymization_key = NetworkAnonymizationKey();
11754   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11755                                 trans_info, &response);
11756   EXPECT_FALSE(response.was_cached);
11757 
11758   // The second request should result in a cache hit.
11759   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11760                                 trans_info, &response);
11761   EXPECT_TRUE(response.was_cached);
11762 
11763   // Now request with a.com as the top frame origin. The same cached object
11764   // should be used.
11765   const SchemefulSite kSiteA(GURL("http://a.com/"));
11766   trans_info.network_isolation_key = NetworkIsolationKey(kSiteA, kSiteA);
11767   trans_info.network_anonymization_key =
11768       NetworkAnonymizationKey::CreateSameSite(kSiteA);
11769   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11770                                 trans_info, &response);
11771   EXPECT_TRUE(response.was_cached);
11772 }
11773 
TEST_F(HttpCacheTest,SkipVaryCheck)11774 TEST_F(HttpCacheTest, SkipVaryCheck) {
11775   MockHttpCache cache;
11776 
11777   // Write a simple vary transaction to the cache.
11778   HttpResponseInfo response;
11779   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11780   transaction.request_headers = "accept-encoding: gzip\r\n";
11781   transaction.response_headers =
11782       "Vary: accept-encoding\n"
11783       "Cache-Control: max-age=10000\n";
11784   RunTransactionTest(cache.http_cache(), transaction);
11785 
11786   // Change the request headers so that the request doesn't match due to vary.
11787   // The request should fail.
11788   transaction.load_flags = LOAD_ONLY_FROM_CACHE;
11789   transaction.request_headers = "accept-encoding: foo\r\n";
11790   transaction.start_return_code = ERR_CACHE_MISS;
11791   RunTransactionTest(cache.http_cache(), transaction);
11792 
11793   // Change the load flags to ignore vary checks, the request should now hit.
11794   transaction.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_VARY_CHECK;
11795   transaction.start_return_code = OK;
11796   RunTransactionTest(cache.http_cache(), transaction);
11797 }
11798 
TEST_F(HttpCacheTest,SkipVaryCheckStar)11799 TEST_F(HttpCacheTest, SkipVaryCheckStar) {
11800   MockHttpCache cache;
11801 
11802   // Write a simple vary:* transaction to the cache.
11803   HttpResponseInfo response;
11804   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11805   transaction.request_headers = "accept-encoding: gzip\r\n";
11806   transaction.response_headers =
11807       "Vary: *\n"
11808       "Cache-Control: max-age=10000\n";
11809   RunTransactionTest(cache.http_cache(), transaction);
11810 
11811   // The request shouldn't match even with the same request headers due to the
11812   // Vary: *. The request should fail.
11813   transaction.load_flags = LOAD_ONLY_FROM_CACHE;
11814   transaction.start_return_code = ERR_CACHE_MISS;
11815   RunTransactionTest(cache.http_cache(), transaction);
11816 
11817   // Change the load flags to ignore vary checks, the request should now hit.
11818   transaction.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_VARY_CHECK;
11819   transaction.start_return_code = OK;
11820   RunTransactionTest(cache.http_cache(), transaction);
11821 }
11822 
11823 // Tests that we only return valid entries with LOAD_ONLY_FROM_CACHE
11824 // transactions unless LOAD_SKIP_CACHE_VALIDATION is set.
TEST_F(HttpCacheTest,ValidLoadOnlyFromCache)11825 TEST_F(HttpCacheTest, ValidLoadOnlyFromCache) {
11826   MockHttpCache cache;
11827   base::SimpleTestClock clock;
11828   cache.http_cache()->SetClockForTesting(&clock);
11829   cache.network_layer()->SetClock(&clock);
11830 
11831   // Write a resource that will expire in 100 seconds.
11832   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11833   transaction.response_headers = "Cache-Control: max-age=100\n";
11834   RunTransactionTest(cache.http_cache(), transaction);
11835 
11836   // Move forward in time such that the cached response is no longer valid.
11837   clock.Advance(base::Seconds(101));
11838 
11839   // Skipping cache validation should still return a response.
11840   transaction.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
11841   RunTransactionTest(cache.http_cache(), transaction);
11842 
11843   // If the cache entry is checked for validitiy, it should fail.
11844   transaction.load_flags = LOAD_ONLY_FROM_CACHE;
11845   transaction.start_return_code = ERR_CACHE_MISS;
11846   RunTransactionTest(cache.http_cache(), transaction);
11847 }
11848 
TEST_F(HttpCacheTest,InvalidLoadFlagCombination)11849 TEST_F(HttpCacheTest, InvalidLoadFlagCombination) {
11850   MockHttpCache cache;
11851 
11852   // Put the resource in the cache.
11853   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
11854 
11855   // Now try to fetch it again, but with a flag combination disallowing both
11856   // cache and network access.
11857   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11858   // DevTools relies on this combination of flags for "disable cache" mode
11859   // when a resource is only supposed to be loaded from cache.
11860   transaction.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_BYPASS_CACHE;
11861   transaction.start_return_code = ERR_CACHE_MISS;
11862   RunTransactionTest(cache.http_cache(), transaction);
11863 }
11864 
11865 // Tests that we don't mark entries as truncated when a filter detects the end
11866 // of the stream.
TEST_F(HttpCacheTest,FilterCompletion)11867 TEST_F(HttpCacheTest, FilterCompletion) {
11868   MockHttpCache cache;
11869   TestCompletionCallback callback;
11870 
11871   {
11872     MockHttpRequest request(kSimpleGET_Transaction);
11873     std::unique_ptr<HttpTransaction> trans;
11874     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11875 
11876     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11877     EXPECT_THAT(callback.GetResult(rv), IsOk());
11878 
11879     scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
11880     rv = trans->Read(buf.get(), 256, callback.callback());
11881     EXPECT_GT(callback.GetResult(rv), 0);
11882 
11883     // Now make sure that the entry is preserved.
11884     trans->DoneReading();
11885   }
11886 
11887   // Make sure that the ActiveEntry is gone.
11888   base::RunLoop().RunUntilIdle();
11889 
11890   // Read from the cache.
11891   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
11892 
11893   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11894   EXPECT_EQ(1, cache.disk_cache()->open_count());
11895   EXPECT_EQ(1, cache.disk_cache()->create_count());
11896 }
11897 
11898 // Tests that we don't mark entries as truncated and release the cache
11899 // entry when DoneReading() is called before any Read() calls, such as
11900 // for a redirect.
TEST_F(HttpCacheTest,DoneReading)11901 TEST_F(HttpCacheTest, DoneReading) {
11902   MockHttpCache cache;
11903   TestCompletionCallback callback;
11904 
11905   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11906   transaction.data = "";
11907   MockHttpRequest request(transaction);
11908 
11909   std::unique_ptr<HttpTransaction> trans;
11910   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11911 
11912   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11913   EXPECT_THAT(callback.GetResult(rv), IsOk());
11914 
11915   trans->DoneReading();
11916   // Leave the transaction around.
11917 
11918   // Make sure that the ActiveEntry is gone.
11919   base::RunLoop().RunUntilIdle();
11920 
11921   // Read from the cache. This should not deadlock.
11922   RunTransactionTest(cache.http_cache(), transaction);
11923 
11924   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11925   EXPECT_EQ(1, cache.disk_cache()->open_count());
11926   EXPECT_EQ(1, cache.disk_cache()->create_count());
11927 }
11928 
11929 // Tests that we stop caching when told.
TEST_F(HttpCacheTest,StopCachingDeletesEntry)11930 TEST_F(HttpCacheTest, StopCachingDeletesEntry) {
11931   MockHttpCache cache;
11932   TestCompletionCallback callback;
11933   MockHttpRequest request(kSimpleGET_Transaction);
11934 
11935   {
11936     std::unique_ptr<HttpTransaction> trans;
11937     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11938 
11939     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11940     EXPECT_THAT(callback.GetResult(rv), IsOk());
11941 
11942     scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
11943     rv = trans->Read(buf.get(), 10, callback.callback());
11944     EXPECT_EQ(10, callback.GetResult(rv));
11945 
11946     trans->StopCaching();
11947 
11948     // We should be able to keep reading.
11949     rv = trans->Read(buf.get(), 256, callback.callback());
11950     EXPECT_GT(callback.GetResult(rv), 0);
11951     rv = trans->Read(buf.get(), 256, callback.callback());
11952     EXPECT_EQ(0, callback.GetResult(rv));
11953   }
11954 
11955   // Make sure that the ActiveEntry is gone.
11956   base::RunLoop().RunUntilIdle();
11957 
11958   // Verify that the entry is gone.
11959   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
11960 
11961   EXPECT_EQ(2, cache.network_layer()->transaction_count());
11962   EXPECT_EQ(0, cache.disk_cache()->open_count());
11963   EXPECT_EQ(2, cache.disk_cache()->create_count());
11964 }
11965 
11966 // Tests that we stop caching when told, even if DoneReading is called
11967 // after StopCaching.
TEST_F(HttpCacheTest,StopCachingThenDoneReadingDeletesEntry)11968 TEST_F(HttpCacheTest, StopCachingThenDoneReadingDeletesEntry) {
11969   MockHttpCache cache;
11970   TestCompletionCallback callback;
11971   MockHttpRequest request(kSimpleGET_Transaction);
11972 
11973   {
11974     std::unique_ptr<HttpTransaction> trans;
11975     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11976 
11977     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11978     EXPECT_THAT(callback.GetResult(rv), IsOk());
11979 
11980     scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
11981     rv = trans->Read(buf.get(), 10, callback.callback());
11982     EXPECT_EQ(10, callback.GetResult(rv));
11983 
11984     trans->StopCaching();
11985 
11986     // We should be able to keep reading.
11987     rv = trans->Read(buf.get(), 256, callback.callback());
11988     EXPECT_GT(callback.GetResult(rv), 0);
11989     rv = trans->Read(buf.get(), 256, callback.callback());
11990     EXPECT_EQ(0, callback.GetResult(rv));
11991 
11992     // We should be able to call DoneReading.
11993     trans->DoneReading();
11994   }
11995 
11996   // Make sure that the ActiveEntry is gone.
11997   base::RunLoop().RunUntilIdle();
11998 
11999   // Verify that the entry is gone.
12000   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
12001 
12002   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12003   EXPECT_EQ(0, cache.disk_cache()->open_count());
12004   EXPECT_EQ(2, cache.disk_cache()->create_count());
12005 }
12006 
12007 // Tests that we stop caching when told, when using auth.
TEST_F(HttpCacheTest,StopCachingWithAuthDeletesEntry)12008 TEST_F(HttpCacheTest, StopCachingWithAuthDeletesEntry) {
12009   MockHttpCache cache;
12010   TestCompletionCallback callback;
12011   MockTransaction mock_transaction(kSimpleGET_Transaction);
12012   mock_transaction.status = "HTTP/1.1 401 Unauthorized";
12013   AddMockTransaction(&mock_transaction);
12014   MockHttpRequest request(mock_transaction);
12015 
12016   {
12017     std::unique_ptr<HttpTransaction> trans;
12018     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
12019 
12020     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
12021     EXPECT_THAT(callback.GetResult(rv), IsOk());
12022 
12023     trans->StopCaching();
12024   }
12025   RemoveMockTransaction(&mock_transaction);
12026 
12027   // Make sure that the ActiveEntry is gone.
12028   base::RunLoop().RunUntilIdle();
12029 
12030   // Verify that the entry is gone.
12031   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
12032 
12033   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12034   EXPECT_EQ(0, cache.disk_cache()->open_count());
12035   EXPECT_EQ(2, cache.disk_cache()->create_count());
12036 }
12037 
12038 // Tests that when we are told to stop caching we don't throw away valid data.
TEST_F(HttpCacheTest,StopCachingSavesEntry)12039 TEST_F(HttpCacheTest, StopCachingSavesEntry) {
12040   MockHttpCache cache;
12041   TestCompletionCallback callback;
12042   MockHttpRequest request(kSimpleGET_Transaction);
12043 
12044   {
12045     std::unique_ptr<HttpTransaction> trans;
12046     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
12047 
12048     // Force a response that can be resumed.
12049     ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
12050     AddMockTransaction(&mock_transaction);
12051     mock_transaction.response_headers = "Cache-Control: max-age=10000\n"
12052                                         "Content-Length: 42\n"
12053                                         "Etag: \"foo\"\n";
12054 
12055     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
12056     EXPECT_THAT(callback.GetResult(rv), IsOk());
12057 
12058     scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
12059     rv = trans->Read(buf.get(), 10, callback.callback());
12060     EXPECT_EQ(callback.GetResult(rv), 10);
12061 
12062     trans->StopCaching();
12063 
12064     // We should be able to keep reading.
12065     rv = trans->Read(buf.get(), 256, callback.callback());
12066     EXPECT_GT(callback.GetResult(rv), 0);
12067     rv = trans->Read(buf.get(), 256, callback.callback());
12068     EXPECT_EQ(callback.GetResult(rv), 0);
12069   }
12070 
12071   // Verify that the entry is marked as incomplete.
12072   // VerifyTruncatedFlag(&cache, kSimpleGET_Transaction.url, true, 0);
12073   // Verify that the entry is doomed.
12074   cache.disk_cache()->IsDiskEntryDoomed(request.CacheKey());
12075 }
12076 
12077 // Tests that we handle truncated enries when StopCaching is called.
TEST_F(HttpCacheTest,StopCachingTruncatedEntry)12078 TEST_F(HttpCacheTest, StopCachingTruncatedEntry) {
12079   MockHttpCache cache;
12080   TestCompletionCallback callback;
12081   MockHttpRequest request(kRangeGET_TransactionOK);
12082   request.extra_headers.Clear();
12083   request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE);
12084   AddMockTransaction(&kRangeGET_TransactionOK);
12085 
12086   std::string raw_headers("HTTP/1.1 200 OK\n"
12087                           "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12088                           "ETag: \"foo\"\n"
12089                           "Accept-Ranges: bytes\n"
12090                           "Content-Length: 80\n");
12091   CreateTruncatedEntry(raw_headers, &cache);
12092 
12093   {
12094     // Now make a regular request.
12095     std::unique_ptr<HttpTransaction> trans;
12096     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
12097 
12098     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
12099     EXPECT_THAT(callback.GetResult(rv), IsOk());
12100 
12101     scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
12102     rv = trans->Read(buf.get(), 10, callback.callback());
12103     EXPECT_EQ(callback.GetResult(rv), 10);
12104 
12105     // This is actually going to do nothing.
12106     trans->StopCaching();
12107 
12108     // We should be able to keep reading.
12109     rv = trans->Read(buf.get(), 256, callback.callback());
12110     EXPECT_GT(callback.GetResult(rv), 0);
12111     rv = trans->Read(buf.get(), 256, callback.callback());
12112     EXPECT_GT(callback.GetResult(rv), 0);
12113     rv = trans->Read(buf.get(), 256, callback.callback());
12114     EXPECT_EQ(callback.GetResult(rv), 0);
12115   }
12116 
12117   // Verify that the disk entry was updated.
12118   VerifyTruncatedFlag(&cache, request.CacheKey(), false, 80);
12119   RemoveMockTransaction(&kRangeGET_TransactionOK);
12120 }
12121 
12122 namespace {
12123 
12124 enum class TransactionPhase {
12125   BEFORE_FIRST_READ,
12126   AFTER_FIRST_READ,
12127   AFTER_NETWORK_READ
12128 };
12129 
12130 using CacheInitializer = void (*)(MockHttpCache*);
12131 using HugeCacheTestConfiguration =
12132     std::pair<TransactionPhase, CacheInitializer>;
12133 
12134 class HttpCacheHugeResourceTest
12135     : public ::testing::TestWithParam<HugeCacheTestConfiguration>,
12136       public WithTaskEnvironment {
12137  public:
12138   static std::list<HugeCacheTestConfiguration> GetTestModes();
12139   static std::list<HugeCacheTestConfiguration> kTestModes;
12140 
12141   // CacheInitializer callbacks. These are used to initialize the cache
12142   // depending on the test run configuration.
12143 
12144   // Initializes a cache containing a truncated entry containing the first 20
12145   // bytes of the reponse body.
12146   static void SetupTruncatedCacheEntry(MockHttpCache* cache);
12147 
12148   // Initializes a cache containing a sparse entry. The first 10 bytes are
12149   // present in the cache.
12150   static void SetupPrefixSparseCacheEntry(MockHttpCache* cache);
12151 
12152   // Initializes a cache containing a sparse entry. The 10 bytes at offset
12153   // 99990 are present in the cache.
12154   static void SetupInfixSparseCacheEntry(MockHttpCache* cache);
12155 
12156  protected:
12157   static void LargeResourceTransactionHandler(
12158       const net::HttpRequestInfo* request,
12159       std::string* response_status,
12160       std::string* response_headers,
12161       std::string* response_data);
12162   static int LargeBufferReader(int64_t content_length,
12163                                int64_t offset,
12164                                net::IOBuffer* buf,
12165                                int buf_len);
12166 
12167   static void SetFlagOnBeforeNetworkStart(bool* started, bool* /* defer */);
12168 
12169   // Size of resource to be tested.
12170   static const int64_t kTotalSize = 5000LL * 1000 * 1000;
12171 };
12172 
12173 const int64_t HttpCacheHugeResourceTest::kTotalSize;
12174 
12175 // static
LargeResourceTransactionHandler(const net::HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)12176 void HttpCacheHugeResourceTest::LargeResourceTransactionHandler(
12177     const net::HttpRequestInfo* request,
12178     std::string* response_status,
12179     std::string* response_headers,
12180     std::string* response_data) {
12181   std::string if_range;
12182   if (!request->extra_headers.GetHeader(net::HttpRequestHeaders::kIfRange,
12183                                         &if_range)) {
12184     // If there were no range headers in the request, we are going to just
12185     // return the entire response body.
12186     *response_status = "HTTP/1.1 200 Success";
12187     *response_headers = base::StringPrintf("Content-Length: %" PRId64
12188                                            "\n"
12189                                            "ETag: \"foo\"\n"
12190                                            "Accept-Ranges: bytes\n",
12191                                            kTotalSize);
12192     return;
12193   }
12194 
12195   // From this point on, we should be processing a valid byte-range request.
12196   EXPECT_EQ("\"foo\"", if_range);
12197 
12198   std::string range_header;
12199   EXPECT_TRUE(request->extra_headers.GetHeader(net::HttpRequestHeaders::kRange,
12200                                                &range_header));
12201   std::vector<net::HttpByteRange> ranges;
12202 
12203   EXPECT_TRUE(net::HttpUtil::ParseRangeHeader(range_header, &ranges));
12204   ASSERT_EQ(1u, ranges.size());
12205 
12206   net::HttpByteRange range = ranges[0];
12207   EXPECT_TRUE(range.HasFirstBytePosition());
12208   int64_t last_byte_position =
12209       range.HasLastBytePosition() ? range.last_byte_position() : kTotalSize - 1;
12210 
12211   *response_status = "HTTP/1.1 206 Partial";
12212   *response_headers = base::StringPrintf(
12213       "Content-Range: bytes %" PRId64 "-%" PRId64 "/%" PRId64
12214       "\n"
12215       "Content-Length: %" PRId64 "\n",
12216       range.first_byte_position(), last_byte_position, kTotalSize,
12217       last_byte_position - range.first_byte_position() + 1);
12218 }
12219 
12220 // static
LargeBufferReader(int64_t content_length,int64_t offset,net::IOBuffer * buf,int buf_len)12221 int HttpCacheHugeResourceTest::LargeBufferReader(int64_t content_length,
12222                                                  int64_t offset,
12223                                                  net::IOBuffer* buf,
12224                                                  int buf_len) {
12225   // This test involves reading multiple gigabytes of data. To make it run in a
12226   // reasonable amount of time, we are going to skip filling the buffer with
12227   // data. Instead the test relies on verifying that the count of bytes expected
12228   // at the end is correct.
12229   EXPECT_LT(0, content_length);
12230   EXPECT_LE(offset, content_length);
12231   int num = std::min(static_cast<int64_t>(buf_len), content_length - offset);
12232   return num;
12233 }
12234 
12235 // static
SetFlagOnBeforeNetworkStart(bool * started,bool *)12236 void HttpCacheHugeResourceTest::SetFlagOnBeforeNetworkStart(bool* started,
12237                                                             bool* /* defer */) {
12238   *started = true;
12239 }
12240 
12241 // static
SetupTruncatedCacheEntry(MockHttpCache * cache)12242 void HttpCacheHugeResourceTest::SetupTruncatedCacheEntry(MockHttpCache* cache) {
12243   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
12244   std::string cached_headers = base::StringPrintf(
12245       "HTTP/1.1 200 OK\n"
12246       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12247       "ETag: \"foo\"\n"
12248       "Accept-Ranges: bytes\n"
12249       "Content-Length: %" PRId64 "\n",
12250       kTotalSize);
12251   CreateTruncatedEntry(cached_headers, cache);
12252 }
12253 
12254 // static
SetupPrefixSparseCacheEntry(MockHttpCache * cache)12255 void HttpCacheHugeResourceTest::SetupPrefixSparseCacheEntry(
12256     MockHttpCache* cache) {
12257   MockTransaction transaction(kRangeGET_TransactionOK);
12258   transaction.handler = nullptr;
12259   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
12260   transaction.response_headers =
12261       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12262       "ETag: \"foo\"\n"
12263       "Accept-Ranges: bytes\n"
12264       "Content-Range: bytes 0-9/5000000000\n"
12265       "Content-Length: 10\n";
12266   AddMockTransaction(&transaction);
12267   std::string headers;
12268   RunTransactionTestWithResponse(cache->http_cache(), transaction, &headers);
12269   RemoveMockTransaction(&transaction);
12270 }
12271 
12272 // static
SetupInfixSparseCacheEntry(MockHttpCache * cache)12273 void HttpCacheHugeResourceTest::SetupInfixSparseCacheEntry(
12274     MockHttpCache* cache) {
12275   MockTransaction transaction(kRangeGET_TransactionOK);
12276   transaction.handler = nullptr;
12277   transaction.request_headers = "Range: bytes = 99990-99999\r\n" EXTRA_HEADER;
12278   transaction.response_headers =
12279       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12280       "ETag: \"foo\"\n"
12281       "Accept-Ranges: bytes\n"
12282       "Content-Range: bytes 99990-99999/5000000000\n"
12283       "Content-Length: 10\n";
12284   AddMockTransaction(&transaction);
12285   std::string headers;
12286   RunTransactionTestWithResponse(cache->http_cache(), transaction, &headers);
12287   RemoveMockTransaction(&transaction);
12288 }
12289 
12290 // static
12291 std::list<HugeCacheTestConfiguration>
GetTestModes()12292 HttpCacheHugeResourceTest::GetTestModes() {
12293   std::list<HugeCacheTestConfiguration> test_modes;
12294   const TransactionPhase kTransactionPhases[] = {
12295       TransactionPhase::BEFORE_FIRST_READ, TransactionPhase::AFTER_FIRST_READ,
12296       TransactionPhase::AFTER_NETWORK_READ};
12297   const CacheInitializer kInitializers[] = {&SetupTruncatedCacheEntry,
12298                                             &SetupPrefixSparseCacheEntry,
12299                                             &SetupInfixSparseCacheEntry};
12300 
12301   for (const auto phase : kTransactionPhases)
12302     for (const auto initializer : kInitializers)
12303       test_modes.emplace_back(phase, initializer);
12304 
12305   return test_modes;
12306 }
12307 
12308 // static
12309 std::list<HugeCacheTestConfiguration> HttpCacheHugeResourceTest::kTestModes =
12310     HttpCacheHugeResourceTest::GetTestModes();
12311 
12312 INSTANTIATE_TEST_SUITE_P(
12313     _,
12314     HttpCacheHugeResourceTest,
12315     ::testing::ValuesIn(HttpCacheHugeResourceTest::kTestModes));
12316 
12317 }  // namespace
12318 
12319 // Test what happens when StopCaching() is called while reading a huge resource
12320 // fetched via GET. Various combinations of cache state and when StopCaching()
12321 // is called is controlled by the parameter passed into the test via the
12322 // INSTANTIATE_TEST_SUITE_P invocation above.
TEST_P(HttpCacheHugeResourceTest,StopCachingFollowedByReadForHugeTruncatedResource)12323 TEST_P(HttpCacheHugeResourceTest,
12324        StopCachingFollowedByReadForHugeTruncatedResource) {
12325   // This test is going to be repeated for all combinations of TransactionPhase
12326   // and CacheInitializers returned by GetTestModes().
12327   const TransactionPhase stop_caching_phase = GetParam().first;
12328   const CacheInitializer cache_initializer = GetParam().second;
12329 
12330   MockHttpCache cache;
12331   (*cache_initializer)(&cache);
12332 
12333   MockTransaction transaction(kSimpleGET_Transaction);
12334   transaction.url = kRangeGET_TransactionOK.url;
12335   transaction.handler = &LargeResourceTransactionHandler;
12336   transaction.read_handler = &LargeBufferReader;
12337   ScopedMockTransaction scoped_transaction(transaction);
12338 
12339   MockHttpRequest request(transaction);
12340   net::TestCompletionCallback callback;
12341   std::unique_ptr<net::HttpTransaction> http_transaction;
12342   int rv = cache.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY,
12343                                                  &http_transaction);
12344   ASSERT_EQ(net::OK, rv);
12345   ASSERT_TRUE(http_transaction.get());
12346 
12347   bool network_transaction_started = false;
12348   if (stop_caching_phase == TransactionPhase::AFTER_NETWORK_READ) {
12349     http_transaction->SetBeforeNetworkStartCallback(base::BindOnce(
12350         &SetFlagOnBeforeNetworkStart, &network_transaction_started));
12351   }
12352 
12353   rv = http_transaction->Start(&request, callback.callback(),
12354                                NetLogWithSource());
12355   rv = callback.GetResult(rv);
12356   ASSERT_EQ(net::OK, rv);
12357 
12358   if (stop_caching_phase == TransactionPhase::BEFORE_FIRST_READ)
12359     http_transaction->StopCaching();
12360 
12361   int64_t total_bytes_received = 0;
12362 
12363   EXPECT_EQ(kTotalSize,
12364             http_transaction->GetResponseInfo()->headers->GetContentLength());
12365   do {
12366     // This test simulates reading gigabytes of data. Buffer size is set to 10MB
12367     // to reduce the number of reads and speed up the test.
12368     const int kBufferSize = 1024 * 1024 * 10;
12369     scoped_refptr<net::IOBuffer> buf =
12370         base::MakeRefCounted<net::IOBuffer>(kBufferSize);
12371     rv = http_transaction->Read(buf.get(), kBufferSize, callback.callback());
12372     rv = callback.GetResult(rv);
12373 
12374     if (stop_caching_phase == TransactionPhase::AFTER_FIRST_READ &&
12375         total_bytes_received == 0) {
12376       http_transaction->StopCaching();
12377     }
12378 
12379     if (rv > 0)
12380       total_bytes_received += rv;
12381 
12382     if (network_transaction_started &&
12383         stop_caching_phase == TransactionPhase::AFTER_NETWORK_READ) {
12384       http_transaction->StopCaching();
12385       network_transaction_started = false;
12386     }
12387   } while (rv > 0);
12388 
12389   // The only verification we are going to do is that the received resource has
12390   // the correct size. This is sufficient to verify that the state machine
12391   // didn't terminate abruptly due to the StopCaching() call.
12392   EXPECT_EQ(kTotalSize, total_bytes_received);
12393 }
12394 
12395 // Tests that we detect truncated resources from the net when there is
12396 // a Content-Length header.
TEST_F(HttpCacheTest,TruncatedByContentLength)12397 TEST_F(HttpCacheTest, TruncatedByContentLength) {
12398   MockHttpCache cache;
12399   TestCompletionCallback callback;
12400 
12401   MockTransaction transaction(kSimpleGET_Transaction);
12402   AddMockTransaction(&transaction);
12403   transaction.response_headers = "Cache-Control: max-age=10000\n"
12404                                  "Content-Length: 100\n";
12405   RunTransactionTest(cache.http_cache(), transaction);
12406   RemoveMockTransaction(&transaction);
12407 
12408   // Read from the cache.
12409   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
12410 
12411   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12412   EXPECT_EQ(0, cache.disk_cache()->open_count());
12413   EXPECT_EQ(2, cache.disk_cache()->create_count());
12414 }
12415 
12416 // Tests that we actually flag entries as truncated when we detect an error
12417 // from the net.
TEST_F(HttpCacheTest,TruncatedByContentLength2)12418 TEST_F(HttpCacheTest, TruncatedByContentLength2) {
12419   MockHttpCache cache;
12420   TestCompletionCallback callback;
12421 
12422   MockTransaction transaction(kSimpleGET_Transaction);
12423   AddMockTransaction(&transaction);
12424   transaction.response_headers = "Cache-Control: max-age=10000\n"
12425                                  "Content-Length: 100\n"
12426                                  "Etag: \"foo\"\n";
12427   RunTransactionTest(cache.http_cache(), transaction);
12428   RemoveMockTransaction(&transaction);
12429 
12430   // Verify that the entry is marked as incomplete.
12431   MockHttpRequest request(transaction);
12432   VerifyTruncatedFlag(&cache, request.CacheKey(), true, 0);
12433 }
12434 
12435 // Make sure that calling SetPriority on a cache transaction passes on
12436 // its priority updates to its underlying network transaction.
TEST_F(HttpCacheTest,SetPriority)12437 TEST_F(HttpCacheTest, SetPriority) {
12438   MockHttpCache cache;
12439 
12440   HttpRequestInfo info;
12441   std::unique_ptr<HttpTransaction> trans;
12442   ASSERT_THAT(cache.http_cache()->CreateTransaction(IDLE, &trans), IsOk());
12443 
12444   // Shouldn't crash, but doesn't do anything either.
12445   trans->SetPriority(LOW);
12446 
12447   EXPECT_FALSE(cache.network_layer()->last_transaction());
12448   EXPECT_EQ(DEFAULT_PRIORITY,
12449             cache.network_layer()->last_create_transaction_priority());
12450 
12451   info.url = GURL(kSimpleGET_Transaction.url);
12452   TestCompletionCallback callback;
12453   EXPECT_EQ(ERR_IO_PENDING,
12454             trans->Start(&info, callback.callback(), NetLogWithSource()));
12455 
12456   EXPECT_TRUE(cache.network_layer()->last_transaction());
12457   if (cache.network_layer()->last_transaction()) {
12458     EXPECT_EQ(LOW, cache.network_layer()->last_create_transaction_priority());
12459     EXPECT_EQ(LOW, cache.network_layer()->last_transaction()->priority());
12460   }
12461 
12462   trans->SetPriority(HIGHEST);
12463 
12464   if (cache.network_layer()->last_transaction()) {
12465     EXPECT_EQ(LOW, cache.network_layer()->last_create_transaction_priority());
12466     EXPECT_EQ(HIGHEST, cache.network_layer()->last_transaction()->priority());
12467   }
12468 
12469   EXPECT_THAT(callback.WaitForResult(), IsOk());
12470 }
12471 
12472 // Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
12473 // transaction passes on its argument to the underlying network transaction.
TEST_F(HttpCacheTest,SetWebSocketHandshakeStreamCreateHelper)12474 TEST_F(HttpCacheTest, SetWebSocketHandshakeStreamCreateHelper) {
12475   MockHttpCache cache;
12476   HttpRequestInfo info;
12477 
12478   FakeWebSocketHandshakeStreamCreateHelper create_helper;
12479   std::unique_ptr<HttpTransaction> trans;
12480   ASSERT_THAT(cache.http_cache()->CreateTransaction(IDLE, &trans), IsOk());
12481 
12482   EXPECT_FALSE(cache.network_layer()->last_transaction());
12483 
12484   info.url = GURL(kSimpleGET_Transaction.url);
12485   TestCompletionCallback callback;
12486   EXPECT_EQ(ERR_IO_PENDING,
12487             trans->Start(&info, callback.callback(), NetLogWithSource()));
12488 
12489   ASSERT_TRUE(cache.network_layer()->last_transaction());
12490   EXPECT_FALSE(cache.network_layer()->last_transaction()->
12491                websocket_handshake_stream_create_helper());
12492   trans->SetWebSocketHandshakeStreamCreateHelper(&create_helper);
12493   EXPECT_EQ(&create_helper,
12494             cache.network_layer()->last_transaction()->
12495             websocket_handshake_stream_create_helper());
12496   EXPECT_THAT(callback.WaitForResult(), IsOk());
12497 }
12498 
12499 // Make sure that a cache transaction passes on its priority to
12500 // newly-created network transactions.
TEST_F(HttpCacheTest,SetPriorityNewTransaction)12501 TEST_F(HttpCacheTest, SetPriorityNewTransaction) {
12502   MockHttpCache cache;
12503   AddMockTransaction(&kRangeGET_TransactionOK);
12504 
12505   std::string raw_headers("HTTP/1.1 200 OK\n"
12506                           "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12507                           "ETag: \"foo\"\n"
12508                           "Accept-Ranges: bytes\n"
12509                           "Content-Length: 80\n");
12510   CreateTruncatedEntry(raw_headers, &cache);
12511 
12512   // Now make a regular request.
12513   std::string headers;
12514   MockTransaction transaction(kRangeGET_TransactionOK);
12515   transaction.request_headers = EXTRA_HEADER;
12516   transaction.data = kFullRangeData;
12517 
12518   std::unique_ptr<HttpTransaction> trans;
12519   ASSERT_THAT(cache.http_cache()->CreateTransaction(MEDIUM, &trans), IsOk());
12520   EXPECT_EQ(DEFAULT_PRIORITY,
12521             cache.network_layer()->last_create_transaction_priority());
12522 
12523   MockHttpRequest info(transaction);
12524   TestCompletionCallback callback;
12525   EXPECT_EQ(ERR_IO_PENDING,
12526             trans->Start(&info, callback.callback(), NetLogWithSource()));
12527   EXPECT_THAT(callback.WaitForResult(), IsOk());
12528 
12529   EXPECT_EQ(MEDIUM, cache.network_layer()->last_create_transaction_priority());
12530 
12531   trans->SetPriority(HIGHEST);
12532   // Should trigger a new network transaction and pick up the new
12533   // priority.
12534   ReadAndVerifyTransaction(trans.get(), transaction);
12535 
12536   EXPECT_EQ(HIGHEST, cache.network_layer()->last_create_transaction_priority());
12537 
12538   RemoveMockTransaction(&kRangeGET_TransactionOK);
12539 }
12540 
12541 namespace {
12542 
RunTransactionAndGetNetworkBytes(MockHttpCache * cache,const MockTransaction & trans_info,int64_t * sent_bytes,int64_t * received_bytes)12543 void RunTransactionAndGetNetworkBytes(MockHttpCache* cache,
12544                                       const MockTransaction& trans_info,
12545                                       int64_t* sent_bytes,
12546                                       int64_t* received_bytes) {
12547   RunTransactionTestBase(
12548       cache->http_cache(), trans_info, MockHttpRequest(trans_info), nullptr,
12549       NetLogWithSource(), nullptr, sent_bytes, received_bytes, nullptr);
12550 }
12551 
12552 }  // namespace
12553 
TEST_F(HttpCacheTest,NetworkBytesCacheMissAndThenHit)12554 TEST_F(HttpCacheTest, NetworkBytesCacheMissAndThenHit) {
12555   MockHttpCache cache;
12556 
12557   MockTransaction transaction(kSimpleGET_Transaction);
12558   int64_t sent, received;
12559   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12560   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12561   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12562 
12563   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12564   EXPECT_EQ(0, sent);
12565   EXPECT_EQ(0, received);
12566 }
12567 
TEST_F(HttpCacheTest,NetworkBytesConditionalRequest304)12568 TEST_F(HttpCacheTest, NetworkBytesConditionalRequest304) {
12569   MockHttpCache cache;
12570 
12571   ScopedMockTransaction transaction(kETagGET_Transaction);
12572   int64_t sent, received;
12573   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12574   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12575   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12576 
12577   transaction.load_flags = LOAD_VALIDATE_CACHE;
12578   transaction.handler = ETagGet_ConditionalRequest_Handler;
12579   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12580   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12581   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12582 }
12583 
TEST_F(HttpCacheTest,NetworkBytesConditionalRequest200)12584 TEST_F(HttpCacheTest, NetworkBytesConditionalRequest200) {
12585   MockHttpCache cache;
12586 
12587   MockTransaction transaction(kTypicalGET_Transaction);
12588   transaction.request_headers = "Foo: bar\r\n";
12589   transaction.response_headers =
12590       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
12591       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
12592       "Etag: \"foopy\"\n"
12593       "Cache-Control: max-age=0\n"
12594       "Vary: Foo\n";
12595   AddMockTransaction(&transaction);
12596   int64_t sent, received;
12597   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12598   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12599   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12600 
12601   RevalidationServer server;
12602   transaction.handler = server.Handler;
12603   transaction.request_headers = "Foo: none\r\n";
12604   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12605   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12606   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12607 
12608   RemoveMockTransaction(&transaction);
12609 }
12610 
TEST_F(HttpCacheTest,NetworkBytesRange)12611 TEST_F(HttpCacheTest, NetworkBytesRange) {
12612   MockHttpCache cache;
12613   AddMockTransaction(&kRangeGET_TransactionOK);
12614   MockTransaction transaction(kRangeGET_TransactionOK);
12615 
12616   // Read bytes 40-49 from the network.
12617   int64_t sent, received;
12618   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12619   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12620   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12621 
12622   // Read bytes 40-49 from the cache.
12623   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12624   EXPECT_EQ(0, sent);
12625   EXPECT_EQ(0, received);
12626   base::RunLoop().RunUntilIdle();
12627 
12628   // Read bytes 30-39 from the network.
12629   transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
12630   transaction.data = "rg: 30-39 ";
12631   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12632   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12633   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12634   base::RunLoop().RunUntilIdle();
12635 
12636   // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
12637   transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
12638   transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
12639   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12640   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes * 2, sent);
12641   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes * 2, received);
12642 
12643   RemoveMockTransaction(&kRangeGET_TransactionOK);
12644 }
12645 
12646 class HttpCachePrefetchValidationTest : public TestWithTaskEnvironment {
12647  protected:
12648   static const int kNumSecondsPerMinute = 60;
12649   static const int kMaxAgeSecs = 100;
12650   static const int kRequireValidationSecs = kMaxAgeSecs + 1;
12651 
HttpCachePrefetchValidationTest()12652   HttpCachePrefetchValidationTest() : transaction_(kSimpleGET_Transaction) {
12653     DCHECK_LT(kMaxAgeSecs, prefetch_reuse_mins() * kNumSecondsPerMinute);
12654 
12655     cache_.http_cache()->SetClockForTesting(&clock_);
12656     cache_.network_layer()->SetClock(&clock_);
12657 
12658     transaction_.response_headers = "Cache-Control: max-age=100\n";
12659   }
12660 
TransactionRequiredNetwork(int load_flags)12661   bool TransactionRequiredNetwork(int load_flags) {
12662     int pre_transaction_count = transaction_count();
12663     transaction_.load_flags = load_flags;
12664     RunTransactionTest(cache_.http_cache(), transaction_);
12665     return pre_transaction_count != transaction_count();
12666   }
12667 
AdvanceTime(int seconds)12668   void AdvanceTime(int seconds) { clock_.Advance(base::Seconds(seconds)); }
12669 
prefetch_reuse_mins()12670   int prefetch_reuse_mins() { return HttpCache::kPrefetchReuseMins; }
12671 
12672   // How many times this test has sent requests to the (fake) origin
12673   // server. Every test case needs to make at least one request to initialise
12674   // the cache.
transaction_count()12675   int transaction_count() {
12676     return cache_.network_layer()->transaction_count();
12677   }
12678 
12679   MockHttpCache cache_;
12680   ScopedMockTransaction transaction_;
12681   std::string response_headers_;
12682   base::SimpleTestClock clock_;
12683 };
12684 
TEST_F(HttpCachePrefetchValidationTest,SkipValidationShortlyAfterPrefetch)12685 TEST_F(HttpCachePrefetchValidationTest, SkipValidationShortlyAfterPrefetch) {
12686   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12687   AdvanceTime(kRequireValidationSecs);
12688   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12689 }
12690 
TEST_F(HttpCachePrefetchValidationTest,ValidateLongAfterPrefetch)12691 TEST_F(HttpCachePrefetchValidationTest, ValidateLongAfterPrefetch) {
12692   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12693   AdvanceTime(prefetch_reuse_mins() * kNumSecondsPerMinute);
12694   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12695 }
12696 
TEST_F(HttpCachePrefetchValidationTest,SkipValidationOnceOnly)12697 TEST_F(HttpCachePrefetchValidationTest, SkipValidationOnceOnly) {
12698   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12699   AdvanceTime(kRequireValidationSecs);
12700   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12701   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12702 }
12703 
TEST_F(HttpCachePrefetchValidationTest,SkipValidationOnceReadOnly)12704 TEST_F(HttpCachePrefetchValidationTest, SkipValidationOnceReadOnly) {
12705   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12706   AdvanceTime(kRequireValidationSecs);
12707   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_ONLY_FROM_CACHE |
12708                                           LOAD_SKIP_CACHE_VALIDATION));
12709   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12710 }
12711 
TEST_F(HttpCachePrefetchValidationTest,BypassCacheOverwritesPrefetch)12712 TEST_F(HttpCachePrefetchValidationTest, BypassCacheOverwritesPrefetch) {
12713   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12714   AdvanceTime(kRequireValidationSecs);
12715   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_BYPASS_CACHE));
12716   AdvanceTime(kRequireValidationSecs);
12717   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12718 }
12719 
TEST_F(HttpCachePrefetchValidationTest,SkipValidationOnExistingEntryThatNeedsValidation)12720 TEST_F(HttpCachePrefetchValidationTest,
12721        SkipValidationOnExistingEntryThatNeedsValidation) {
12722   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12723   AdvanceTime(kRequireValidationSecs);
12724   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12725   AdvanceTime(kRequireValidationSecs);
12726   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12727   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12728 }
12729 
TEST_F(HttpCachePrefetchValidationTest,SkipValidationOnExistingEntryThatDoesNotNeedValidation)12730 TEST_F(HttpCachePrefetchValidationTest,
12731        SkipValidationOnExistingEntryThatDoesNotNeedValidation) {
12732   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12733   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH));
12734   AdvanceTime(kRequireValidationSecs);
12735   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12736   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12737 }
12738 
TEST_F(HttpCachePrefetchValidationTest,PrefetchMultipleTimes)12739 TEST_F(HttpCachePrefetchValidationTest, PrefetchMultipleTimes) {
12740   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12741   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH));
12742   AdvanceTime(kRequireValidationSecs);
12743   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12744 }
12745 
TEST_F(HttpCachePrefetchValidationTest,ValidateOnDelayedSecondPrefetch)12746 TEST_F(HttpCachePrefetchValidationTest, ValidateOnDelayedSecondPrefetch) {
12747   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12748   AdvanceTime(kRequireValidationSecs);
12749   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12750   AdvanceTime(kRequireValidationSecs);
12751   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12752 }
12753 
TEST_F(HttpCacheTest,StaleContentNotUsedWhenLoadFlagNotSet)12754 TEST_F(HttpCacheTest, StaleContentNotUsedWhenLoadFlagNotSet) {
12755   MockHttpCache cache;
12756 
12757   ScopedMockTransaction stale_while_revalidate_transaction(
12758       kSimpleGET_Transaction);
12759 
12760   stale_while_revalidate_transaction.response_headers =
12761       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12762       "Age: 10801\n"
12763       "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
12764 
12765   // Write to the cache.
12766   RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
12767 
12768   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12769 
12770   // Send the request again and check that it is sent to the network again.
12771   HttpResponseInfo response_info;
12772   RunTransactionTestWithResponseInfo(
12773       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12774 
12775   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12776   EXPECT_FALSE(response_info.async_revalidation_requested);
12777 }
12778 
TEST_F(HttpCacheTest,StaleContentUsedWhenLoadFlagSetAndUsableThenTimesout)12779 TEST_F(HttpCacheTest, StaleContentUsedWhenLoadFlagSetAndUsableThenTimesout) {
12780   MockHttpCache cache;
12781   base::SimpleTestClock clock;
12782   cache.http_cache()->SetClockForTesting(&clock);
12783   cache.network_layer()->SetClock(&clock);
12784   clock.Advance(base::Seconds(10));
12785 
12786   ScopedMockTransaction stale_while_revalidate_transaction(
12787       kSimpleGET_Transaction);
12788   stale_while_revalidate_transaction.load_flags |=
12789       LOAD_SUPPORT_ASYNC_REVALIDATION;
12790   stale_while_revalidate_transaction.response_headers =
12791       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12792       "Age: 10801\n"
12793       "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
12794 
12795   // Write to the cache.
12796   RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
12797 
12798   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12799 
12800   // Send the request again and check that it is not sent to the network again.
12801   HttpResponseInfo response_info;
12802   RunTransactionTestWithResponseInfo(
12803       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12804 
12805   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12806   EXPECT_TRUE(response_info.async_revalidation_requested);
12807   EXPECT_FALSE(response_info.stale_revalidate_timeout.is_null());
12808 
12809   // Move forward in time such that the stale response is no longer valid.
12810   clock.SetNow(response_info.stale_revalidate_timeout);
12811   clock.Advance(base::Seconds(1));
12812 
12813   RunTransactionTestWithResponseInfo(
12814       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12815 
12816   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12817   EXPECT_FALSE(response_info.async_revalidation_requested);
12818 }
12819 
TEST_F(HttpCacheTest,StaleContentUsedWhenLoadFlagSetAndUsable)12820 TEST_F(HttpCacheTest, StaleContentUsedWhenLoadFlagSetAndUsable) {
12821   MockHttpCache cache;
12822   base::SimpleTestClock clock;
12823   cache.http_cache()->SetClockForTesting(&clock);
12824   cache.network_layer()->SetClock(&clock);
12825   clock.Advance(base::Seconds(10));
12826 
12827   ScopedMockTransaction stale_while_revalidate_transaction(
12828       kSimpleGET_Transaction);
12829   stale_while_revalidate_transaction.load_flags |=
12830       LOAD_SUPPORT_ASYNC_REVALIDATION;
12831   stale_while_revalidate_transaction.response_headers =
12832       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12833       "Age: 10801\n"
12834       "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
12835 
12836   // Write to the cache.
12837   RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
12838 
12839   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12840 
12841   // Send the request again and check that it is not sent to the network again.
12842   HttpResponseInfo response_info;
12843   RunTransactionTestWithResponseInfo(
12844       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12845 
12846   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12847   EXPECT_TRUE(response_info.async_revalidation_requested);
12848   EXPECT_FALSE(response_info.stale_revalidate_timeout.is_null());
12849   base::Time revalidation_timeout = response_info.stale_revalidate_timeout;
12850   clock.Advance(base::Seconds(1));
12851   EXPECT_TRUE(clock.Now() < revalidation_timeout);
12852 
12853   // Fetch the resource again inside the revalidation timeout window.
12854   RunTransactionTestWithResponseInfo(
12855       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12856 
12857   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12858   EXPECT_TRUE(response_info.async_revalidation_requested);
12859   EXPECT_FALSE(response_info.stale_revalidate_timeout.is_null());
12860   // Expect that the original revalidation timeout hasn't changed.
12861   EXPECT_TRUE(revalidation_timeout == response_info.stale_revalidate_timeout);
12862 
12863   // mask of async revalidation flag.
12864   stale_while_revalidate_transaction.load_flags &=
12865       ~LOAD_SUPPORT_ASYNC_REVALIDATION;
12866   stale_while_revalidate_transaction.status = "HTTP/1.1 304 Not Modified";
12867   // Write 304 to the cache.
12868   RunTransactionTestWithResponseInfo(
12869       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12870 
12871   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12872   EXPECT_FALSE(response_info.async_revalidation_requested);
12873   EXPECT_TRUE(response_info.stale_revalidate_timeout.is_null());
12874 }
12875 
TEST_F(HttpCacheTest,StaleContentNotUsedWhenUnusable)12876 TEST_F(HttpCacheTest, StaleContentNotUsedWhenUnusable) {
12877   MockHttpCache cache;
12878 
12879   ScopedMockTransaction stale_while_revalidate_transaction(
12880       kSimpleGET_Transaction);
12881   stale_while_revalidate_transaction.load_flags |=
12882       LOAD_SUPPORT_ASYNC_REVALIDATION;
12883   stale_while_revalidate_transaction.response_headers =
12884       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12885       "Age: 10801\n"
12886       "Cache-Control: max-age=0,stale-while-revalidate=1800\n";
12887 
12888   // Write to the cache.
12889   RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
12890 
12891   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12892 
12893   // Send the request again and check that it is sent to the network again.
12894   HttpResponseInfo response_info;
12895   RunTransactionTestWithResponseInfo(
12896       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12897 
12898   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12899   EXPECT_FALSE(response_info.async_revalidation_requested);
12900 }
12901 
TEST_F(HttpCacheTest,StaleContentWriteError)12902 TEST_F(HttpCacheTest, StaleContentWriteError) {
12903   MockHttpCache cache;
12904   base::SimpleTestClock clock;
12905   cache.http_cache()->SetClockForTesting(&clock);
12906   cache.network_layer()->SetClock(&clock);
12907   clock.Advance(base::Seconds(10));
12908 
12909   ScopedMockTransaction stale_while_revalidate_transaction(
12910       kSimpleGET_Transaction);
12911   stale_while_revalidate_transaction.load_flags |=
12912       LOAD_SUPPORT_ASYNC_REVALIDATION;
12913   stale_while_revalidate_transaction.response_headers =
12914       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12915       "Age: 10801\n"
12916       "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
12917 
12918   // Write to the cache.
12919   RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
12920 
12921   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12922 
12923   // Send the request again but inject a write fault. Should still work
12924   // (and not dereference any null pointers).
12925   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_WRITE);
12926   HttpResponseInfo response_info;
12927   RunTransactionTestWithResponseInfo(
12928       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12929 
12930   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12931 }
12932 
12933 // Tests that we allow multiple simultaneous, non-overlapping transactions to
12934 // take place on a sparse entry.
TEST_F(HttpCacheTest,RangeGET_MultipleRequests)12935 TEST_F(HttpCacheTest, RangeGET_MultipleRequests) {
12936   MockHttpCache cache;
12937 
12938   // Create a transaction for bytes 0-9.
12939   MockHttpRequest request(kRangeGET_TransactionOK);
12940   MockTransaction transaction(kRangeGET_TransactionOK);
12941   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
12942   transaction.data = "rg: 00-09 ";
12943   AddMockTransaction(&transaction);
12944 
12945   TestCompletionCallback callback;
12946   std::unique_ptr<HttpTransaction> trans;
12947   int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
12948   EXPECT_THAT(rv, IsOk());
12949   ASSERT_TRUE(trans.get());
12950 
12951   // Start our transaction.
12952   trans->Start(&request, callback.callback(), NetLogWithSource());
12953 
12954   // A second transaction on a different part of the file (the default
12955   // kRangeGET_TransactionOK requests 40-49) should not be blocked by
12956   // the already pending transaction.
12957   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
12958 
12959   // Let the first transaction complete.
12960   callback.WaitForResult();
12961 
12962   RemoveMockTransaction(&transaction);
12963 }
12964 
12965 // Verify that a range request can be satisfied from a completely cached
12966 // resource with the LOAD_ONLY_FROM_CACHE flag set. Currently it's not
12967 // implemented so it returns ERR_CACHE_MISS. See also
12968 // HttpCacheTest.RangeGET_OK_LoadOnlyFromCache.
12969 // TODO(ricea): Update this test if it is implemented in future.
TEST_F(HttpCacheTest,RangeGET_Previous200_LoadOnlyFromCache)12970 TEST_F(HttpCacheTest, RangeGET_Previous200_LoadOnlyFromCache) {
12971   MockHttpCache cache;
12972 
12973   // Store the whole thing with status 200.
12974   MockTransaction transaction(kETagGET_Transaction);
12975   transaction.url = kRangeGET_TransactionOK.url;
12976   transaction.data = kFullRangeData;
12977   AddMockTransaction(&transaction);
12978   RunTransactionTest(cache.http_cache(), transaction);
12979   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12980   EXPECT_EQ(0, cache.disk_cache()->open_count());
12981   EXPECT_EQ(1, cache.disk_cache()->create_count());
12982 
12983   RemoveMockTransaction(&transaction);
12984   AddMockTransaction(&kRangeGET_TransactionOK);
12985 
12986   // Now see that we use the stored entry.
12987   MockTransaction transaction2(kRangeGET_TransactionOK);
12988   transaction2.load_flags |= LOAD_ONLY_FROM_CACHE;
12989   MockHttpRequest request(transaction2);
12990   TestCompletionCallback callback;
12991 
12992   std::unique_ptr<HttpTransaction> trans;
12993   int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
12994   EXPECT_THAT(rv, IsOk());
12995   ASSERT_TRUE(trans);
12996 
12997   rv = trans->Start(&request, callback.callback(), NetLogWithSource());
12998   if (rv == ERR_IO_PENDING) {
12999     rv = callback.WaitForResult();
13000   }
13001   EXPECT_THAT(rv, IsError(ERR_CACHE_MISS));
13002 
13003   EXPECT_EQ(1, cache.network_layer()->transaction_count());
13004   EXPECT_EQ(1, cache.disk_cache()->open_count());
13005   EXPECT_EQ(1, cache.disk_cache()->create_count());
13006 }
13007 
13008 // Makes sure that a request stops using the cache when the response headers
13009 // with "Cache-Control: no-store" arrives. That means that another request for
13010 // the same URL can be processed before the response body of the original
13011 // request arrives.
TEST_F(HttpCacheTest,NoStoreResponseShouldNotBlockFollowingRequests)13012 TEST_F(HttpCacheTest, NoStoreResponseShouldNotBlockFollowingRequests) {
13013   MockHttpCache cache;
13014   ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
13015   mock_transaction.response_headers = "Cache-Control: no-store\n";
13016   MockHttpRequest request(mock_transaction);
13017 
13018   auto first = std::make_unique<Context>();
13019   first->result = cache.CreateTransaction(&first->trans);
13020   ASSERT_THAT(first->result, IsOk());
13021   EXPECT_EQ(LOAD_STATE_IDLE, first->trans->GetLoadState());
13022   first->result = first->trans->Start(&request, first->callback.callback(),
13023                                       NetLogWithSource());
13024   EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, first->trans->GetLoadState());
13025 
13026   base::RunLoop().RunUntilIdle();
13027   EXPECT_EQ(LOAD_STATE_IDLE, first->trans->GetLoadState());
13028   ASSERT_TRUE(first->trans->GetResponseInfo());
13029   EXPECT_TRUE(first->trans->GetResponseInfo()->headers->HasHeaderValue(
13030       "Cache-Control", "no-store"));
13031   // Here we have read the response header but not read the response body yet.
13032 
13033   // Let us create the second (read) transaction.
13034   auto second = std::make_unique<Context>();
13035   second->result = cache.CreateTransaction(&second->trans);
13036   ASSERT_THAT(second->result, IsOk());
13037   EXPECT_EQ(LOAD_STATE_IDLE, second->trans->GetLoadState());
13038   second->result = second->trans->Start(&request, second->callback.callback(),
13039                                         NetLogWithSource());
13040 
13041   // Here the second transaction proceeds without reading the first body.
13042   EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, second->trans->GetLoadState());
13043   base::RunLoop().RunUntilIdle();
13044   EXPECT_EQ(LOAD_STATE_IDLE, second->trans->GetLoadState());
13045   ASSERT_TRUE(second->trans->GetResponseInfo());
13046   EXPECT_TRUE(second->trans->GetResponseInfo()->headers->HasHeaderValue(
13047       "Cache-Control", "no-store"));
13048   ReadAndVerifyTransaction(second->trans.get(), kSimpleGET_Transaction);
13049 }
13050 
13051 // Tests that serving a response entirely from cache replays the previous
13052 // SSLInfo.
TEST_F(HttpCacheTest,CachePreservesSSLInfo)13053 TEST_F(HttpCacheTest, CachePreservesSSLInfo) {
13054   static const uint16_t kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xc02f;
13055   int status = 0;
13056   SSLConnectionStatusSetCipherSuite(kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
13057                                     &status);
13058   SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2, &status);
13059 
13060   scoped_refptr<X509Certificate> cert =
13061       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
13062 
13063   MockHttpCache cache;
13064 
13065   ScopedMockTransaction transaction(kSimpleGET_Transaction);
13066   transaction.cert = cert;
13067   transaction.ssl_connection_status = status;
13068 
13069   // Fetch the resource.
13070   HttpResponseInfo response_info;
13071   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13072                                      &response_info);
13073 
13074   // The request should have hit the network and a cache entry created.
13075   EXPECT_EQ(1, cache.network_layer()->transaction_count());
13076   EXPECT_EQ(0, cache.disk_cache()->open_count());
13077   EXPECT_EQ(1, cache.disk_cache()->create_count());
13078 
13079   // The expected SSL state was reported.
13080   EXPECT_EQ(transaction.ssl_connection_status,
13081             response_info.ssl_info.connection_status);
13082   EXPECT_TRUE(cert->EqualsIncludingChain(response_info.ssl_info.cert.get()));
13083 
13084   // Fetch the resource again.
13085   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13086                                      &response_info);
13087 
13088   // The request should have been reused without hitting the network.
13089   EXPECT_EQ(1, cache.network_layer()->transaction_count());
13090   EXPECT_EQ(1, cache.disk_cache()->open_count());
13091   EXPECT_EQ(1, cache.disk_cache()->create_count());
13092 
13093   // The SSL state was preserved.
13094   EXPECT_EQ(status, response_info.ssl_info.connection_status);
13095   EXPECT_TRUE(cert->EqualsIncludingChain(response_info.ssl_info.cert.get()));
13096 }
13097 
13098 // Tests that SSLInfo gets updated when revalidating a cached response.
TEST_F(HttpCacheTest,RevalidationUpdatesSSLInfo)13099 TEST_F(HttpCacheTest, RevalidationUpdatesSSLInfo) {
13100   static const uint16_t kTLS_RSA_WITH_RC4_128_MD5 = 0x0004;
13101   static const uint16_t kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xc02f;
13102 
13103   int status1 = 0;
13104   SSLConnectionStatusSetCipherSuite(kTLS_RSA_WITH_RC4_128_MD5, &status1);
13105   SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1, &status1);
13106   int status2 = 0;
13107   SSLConnectionStatusSetCipherSuite(kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
13108                                     &status2);
13109   SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2, &status2);
13110 
13111   scoped_refptr<X509Certificate> cert1 =
13112       ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
13113   scoped_refptr<X509Certificate> cert2 =
13114       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
13115 
13116   MockHttpCache cache;
13117 
13118   ScopedMockTransaction transaction(kTypicalGET_Transaction);
13119   transaction.cert = cert1;
13120   transaction.ssl_connection_status = status1;
13121 
13122   // Fetch the resource.
13123   HttpResponseInfo response_info;
13124   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13125                                      &response_info);
13126 
13127   // The request should have hit the network and a cache entry created.
13128   EXPECT_EQ(1, cache.network_layer()->transaction_count());
13129   EXPECT_EQ(0, cache.disk_cache()->open_count());
13130   EXPECT_EQ(1, cache.disk_cache()->create_count());
13131   EXPECT_FALSE(response_info.was_cached);
13132 
13133   // The expected SSL state was reported.
13134   EXPECT_EQ(status1, response_info.ssl_info.connection_status);
13135   EXPECT_TRUE(cert1->EqualsIncludingChain(response_info.ssl_info.cert.get()));
13136 
13137   // The server deploys a more modern configuration but reports 304 on the
13138   // revalidation attempt.
13139   transaction.status = "HTTP/1.1 304 Not Modified";
13140   transaction.cert = cert2;
13141   transaction.ssl_connection_status = status2;
13142 
13143   // Fetch the resource again, forcing a revalidation.
13144   transaction.request_headers = "Cache-Control: max-age=0\r\n";
13145   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13146                                      &response_info);
13147 
13148   // The request should have been successfully revalidated.
13149   EXPECT_EQ(2, cache.network_layer()->transaction_count());
13150   EXPECT_EQ(1, cache.disk_cache()->open_count());
13151   EXPECT_EQ(1, cache.disk_cache()->create_count());
13152   EXPECT_TRUE(response_info.was_cached);
13153 
13154   // The new SSL state is reported.
13155   EXPECT_EQ(status2, response_info.ssl_info.connection_status);
13156   EXPECT_TRUE(cert2->EqualsIncludingChain(response_info.ssl_info.cert.get()));
13157 }
13158 
TEST_F(HttpCacheTest,CacheEntryStatusOther)13159 TEST_F(HttpCacheTest, CacheEntryStatusOther) {
13160   MockHttpCache cache;
13161 
13162   HttpResponseInfo response_info;
13163   RunTransactionTestWithResponseInfo(cache.http_cache(), kRangeGET_Transaction,
13164                                      &response_info);
13165 
13166   EXPECT_FALSE(response_info.was_cached);
13167   EXPECT_TRUE(response_info.network_accessed);
13168   EXPECT_EQ(CacheEntryStatus::ENTRY_OTHER, response_info.cache_entry_status);
13169 }
13170 
TEST_F(HttpCacheTest,CacheEntryStatusNotInCache)13171 TEST_F(HttpCacheTest, CacheEntryStatusNotInCache) {
13172   MockHttpCache cache;
13173 
13174   HttpResponseInfo response_info;
13175   RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
13176                                      &response_info);
13177 
13178   EXPECT_FALSE(response_info.was_cached);
13179   EXPECT_TRUE(response_info.network_accessed);
13180   EXPECT_EQ(CacheEntryStatus::ENTRY_NOT_IN_CACHE,
13181             response_info.cache_entry_status);
13182 }
13183 
TEST_F(HttpCacheTest,CacheEntryStatusUsed)13184 TEST_F(HttpCacheTest, CacheEntryStatusUsed) {
13185   MockHttpCache cache;
13186   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
13187 
13188   HttpResponseInfo response_info;
13189   RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
13190                                      &response_info);
13191 
13192   EXPECT_TRUE(response_info.was_cached);
13193   EXPECT_FALSE(response_info.network_accessed);
13194   EXPECT_EQ(CacheEntryStatus::ENTRY_USED, response_info.cache_entry_status);
13195 }
13196 
TEST_F(HttpCacheTest,CacheEntryStatusValidated)13197 TEST_F(HttpCacheTest, CacheEntryStatusValidated) {
13198   MockHttpCache cache;
13199   RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
13200 
13201   ScopedMockTransaction still_valid(kETagGET_Transaction);
13202   still_valid.load_flags = LOAD_VALIDATE_CACHE;  // Force a validation.
13203   still_valid.handler = ETagGet_ConditionalRequest_Handler;
13204 
13205   HttpResponseInfo response_info;
13206   RunTransactionTestWithResponseInfo(cache.http_cache(), still_valid,
13207                                      &response_info);
13208 
13209   EXPECT_TRUE(response_info.was_cached);
13210   EXPECT_TRUE(response_info.network_accessed);
13211   EXPECT_EQ(CacheEntryStatus::ENTRY_VALIDATED,
13212             response_info.cache_entry_status);
13213 }
13214 
TEST_F(HttpCacheTest,CacheEntryStatusUpdated)13215 TEST_F(HttpCacheTest, CacheEntryStatusUpdated) {
13216   MockHttpCache cache;
13217   RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
13218 
13219   ScopedMockTransaction update(kETagGET_Transaction);
13220   update.load_flags = LOAD_VALIDATE_CACHE;  // Force a validation.
13221 
13222   HttpResponseInfo response_info;
13223   RunTransactionTestWithResponseInfo(cache.http_cache(), update,
13224                                      &response_info);
13225 
13226   EXPECT_FALSE(response_info.was_cached);
13227   EXPECT_TRUE(response_info.network_accessed);
13228   EXPECT_EQ(CacheEntryStatus::ENTRY_UPDATED, response_info.cache_entry_status);
13229 }
13230 
TEST_F(HttpCacheTest,CacheEntryStatusCantConditionalize)13231 TEST_F(HttpCacheTest, CacheEntryStatusCantConditionalize) {
13232   MockHttpCache cache;
13233   cache.FailConditionalizations();
13234   RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
13235 
13236   HttpResponseInfo response_info;
13237   RunTransactionTestWithResponseInfo(cache.http_cache(),
13238                                      kTypicalGET_Transaction, &response_info);
13239 
13240   EXPECT_FALSE(response_info.was_cached);
13241   EXPECT_TRUE(response_info.network_accessed);
13242   EXPECT_EQ(CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE,
13243             response_info.cache_entry_status);
13244 }
13245 
TEST_F(HttpSplitCacheKeyTest,GetResourceURLFromHttpCacheKey)13246 TEST_F(HttpSplitCacheKeyTest, GetResourceURLFromHttpCacheKey) {
13247   base::test::ScopedFeatureList feature_list;
13248   feature_list.InitAndEnableFeature(
13249       net::features::kSplitCacheByNetworkIsolationKey);
13250   MockHttpCache cache;
13251   std::string urls[] = {"http://www.a.com/", "https://b.com/example.html",
13252                         "http://example.com/Some Path/Some Leaf?some query"};
13253 
13254   for (const std::string& url : urls) {
13255     std::string key = ComputeCacheKey(url);
13256     EXPECT_EQ(GURL(url).spec(), HttpCache::GetResourceURLFromHttpCacheKey(key));
13257   }
13258 }
13259 
TEST_F(HttpCacheTest,GetResourceURLFromHttpCacheKey)13260 TEST_F(HttpCacheTest, GetResourceURLFromHttpCacheKey) {
13261   const struct {
13262     std::string input;
13263     std::string output;
13264   } kTestCase[] = {
13265       // Valid input:
13266       {"0/0/https://a.com/", "https://a.com/"},
13267       {"0/0/https://a.com/path", "https://a.com/path"},
13268       {"0/0/https://a.com/?query", "https://a.com/?query"},
13269       {"0/0/https://a.com/#fragment", "https://a.com/#fragment"},
13270       {"0/0/_dk_s_ https://a.com/", "https://a.com/"},
13271       {"0/0/_dk_https://a.com https://b.com https://c.com/", "https://c.com/"},
13272       {"0/0/_dk_shttps://a.com https://b.com https://c.com/", "https://c.com/"},
13273 
13274       // Invalid input, producing garbage, without crashing.
13275       {"", ""},
13276       {"0/a.com", "0/a.com"},
13277       {"https://a.com/", "a.com/"},
13278       {"0/https://a.com/", "/a.com/"},
13279   };
13280 
13281   for (const auto& test : kTestCase) {
13282     EXPECT_EQ(test.output,
13283               HttpCache::GetResourceURLFromHttpCacheKey(test.input));
13284   }
13285 }
13286 
13287 class TestCompletionCallbackForHttpCache : public TestCompletionCallbackBase {
13288  public:
13289   TestCompletionCallbackForHttpCache() = default;
13290   ~TestCompletionCallbackForHttpCache() override = default;
13291 
callback()13292   CompletionRepeatingCallback callback() {
13293     return base::BindRepeating(&TestCompletionCallbackForHttpCache::SetResult,
13294                                base::Unretained(this));
13295   }
13296 
results()13297   const std::vector<int>& results() { return results_; }
13298 
13299  private:
13300   std::vector<int> results_;
13301 
13302  protected:
SetResult(int result)13303   void SetResult(int result) override {
13304     results_.push_back(result);
13305     DidSetResult();
13306   }
13307 };
13308 
TEST_F(HttpCacheIOCallbackTest,FailedDoomFollowedByOpen)13309 TEST_F(HttpCacheIOCallbackTest, FailedDoomFollowedByOpen) {
13310   MockHttpCache cache;
13311   TestCompletionCallbackForHttpCache cb;
13312   std::unique_ptr<Transaction> transaction =
13313       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13314 
13315   transaction->SetIOCallBackForTest(cb.callback());
13316 
13317   // Create the backend here as our direct calls to DoomEntry and OpenEntry
13318   // below require that it exists.
13319   cache.backend();
13320 
13321   // Need a mock transaction in order to use some of MockHttpCache's
13322   // functions.
13323   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13324 
13325   ActiveEntry* entry1 = nullptr;
13326 
13327   cache.disk_cache()->set_force_fail_callback_later(true);
13328 
13329   // Queue up our operations.
13330   int rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get());
13331   ASSERT_EQ(rv, ERR_IO_PENDING);
13332   cache.disk_cache()->set_force_fail_callback_later(false);
13333   rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry1,
13334                  transaction.get());
13335   ASSERT_EQ(rv, ERR_IO_PENDING);
13336 
13337   // Wait for all the results to arrive.
13338   cb.GetResult(rv);
13339   ASSERT_EQ(cb.results().size(), 2u);
13340 
13341   // Verify that DoomEntry failed correctly.
13342   ASSERT_EQ(cb.results()[0], ERR_CACHE_DOOM_FAILURE);
13343   // Verify that OpenEntry fails with the same code.
13344   ASSERT_EQ(cb.results()[1], ERR_CACHE_DOOM_FAILURE);
13345   ASSERT_EQ(entry1, nullptr);
13346 }
13347 
TEST_F(HttpCacheIOCallbackTest,FailedDoomFollowedByCreate)13348 TEST_F(HttpCacheIOCallbackTest, FailedDoomFollowedByCreate) {
13349   MockHttpCache cache;
13350   TestCompletionCallbackForHttpCache cb;
13351   std::unique_ptr<Transaction> transaction =
13352       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13353 
13354   transaction->SetIOCallBackForTest(cb.callback());
13355 
13356   // Create the backend here as our direct calls to DoomEntry and CreateEntry
13357   // below require that it exists.
13358   cache.backend();
13359 
13360   // Need a mock transaction in order to use some of MockHttpCache's
13361   // functions.
13362   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13363 
13364   ActiveEntry* entry1 = nullptr;
13365 
13366   cache.disk_cache()->set_force_fail_callback_later(true);
13367 
13368   // Queue up our operations.
13369   int rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get());
13370   ASSERT_EQ(rv, ERR_IO_PENDING);
13371   cache.disk_cache()->set_force_fail_callback_later(false);
13372   rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13373                    transaction.get());
13374   ASSERT_EQ(rv, ERR_IO_PENDING);
13375 
13376   // Wait for all the results to arrive.
13377   cb.GetResult(rv);
13378   ASSERT_EQ(cb.results().size(), 2u);
13379 
13380   // Verify that DoomEntry failed correctly.
13381   ASSERT_EQ(cb.results()[0], ERR_CACHE_DOOM_FAILURE);
13382   // Verify that CreateEntry requests a restart (CACHE_RACE).
13383   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13384   ASSERT_EQ(entry1, nullptr);
13385 }
13386 
TEST_F(HttpCacheIOCallbackTest,FailedDoomFollowedByDoom)13387 TEST_F(HttpCacheIOCallbackTest, FailedDoomFollowedByDoom) {
13388   MockHttpCache cache;
13389   TestCompletionCallbackForHttpCache cb;
13390   std::unique_ptr<Transaction> transaction =
13391       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13392 
13393   transaction->SetIOCallBackForTest(cb.callback());
13394 
13395   // Create the backend here as our direct calls to DoomEntry below require that
13396   // it exists.
13397   cache.backend();
13398 
13399   // Need a mock transaction in order to use some of MockHttpCache's
13400   // functions.
13401   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13402 
13403   cache.disk_cache()->set_force_fail_callback_later(true);
13404 
13405   // Queue up our operations.
13406   int rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get());
13407   ASSERT_EQ(rv, ERR_IO_PENDING);
13408   cache.disk_cache()->set_force_fail_callback_later(false);
13409   rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get());
13410   ASSERT_EQ(rv, ERR_IO_PENDING);
13411 
13412   // Wait for all the results to arrive.
13413   cb.GetResult(rv);
13414   ASSERT_EQ(cb.results().size(), 2u);
13415 
13416   // Verify that DoomEntry failed correctly.
13417   ASSERT_EQ(cb.results()[0], ERR_CACHE_DOOM_FAILURE);
13418   // Verify that the second DoomEntry requests a restart (CACHE_RACE).
13419   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13420 }
13421 
TEST_F(HttpCacheIOCallbackTest,FailedOpenFollowedByCreate)13422 TEST_F(HttpCacheIOCallbackTest, FailedOpenFollowedByCreate) {
13423   MockHttpCache cache;
13424   TestCompletionCallbackForHttpCache cb;
13425   std::unique_ptr<Transaction> transaction =
13426       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13427 
13428   transaction->SetIOCallBackForTest(cb.callback());
13429 
13430   // Create the backend here as our direct calls to OpenEntry and CreateEntry
13431   // below require that it exists.
13432   cache.backend();
13433 
13434   // Need a mock transaction in order to use some of MockHttpCache's
13435   // functions.
13436   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13437 
13438   ActiveEntry* entry1 = nullptr;
13439   ActiveEntry* entry2 = nullptr;
13440 
13441   cache.disk_cache()->set_force_fail_callback_later(true);
13442 
13443   // Queue up our operations.
13444   int rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry1,
13445                      transaction.get());
13446   ASSERT_EQ(rv, ERR_IO_PENDING);
13447   cache.disk_cache()->set_force_fail_callback_later(false);
13448   rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13449                    transaction.get());
13450   ASSERT_EQ(rv, ERR_IO_PENDING);
13451 
13452   // Wait for all the results to arrive.
13453   cb.GetResult(rv);
13454   ASSERT_EQ(cb.results().size(), 2u);
13455 
13456   // Verify that OpenEntry failed correctly.
13457   ASSERT_EQ(cb.results()[0], ERR_CACHE_OPEN_FAILURE);
13458   ASSERT_EQ(entry1, nullptr);
13459   // Verify that the CreateEntry requests a restart (CACHE_RACE).
13460   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13461   ASSERT_EQ(entry2, nullptr);
13462 }
13463 
TEST_F(HttpCacheIOCallbackTest,FailedCreateFollowedByOpen)13464 TEST_F(HttpCacheIOCallbackTest, FailedCreateFollowedByOpen) {
13465   MockHttpCache cache;
13466   TestCompletionCallbackForHttpCache cb;
13467   std::unique_ptr<Transaction> transaction =
13468       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13469 
13470   transaction->SetIOCallBackForTest(cb.callback());
13471 
13472   // Create the backend here as our direct calls to CreateEntry and OpenEntry
13473   // below require that it exists.
13474   cache.backend();
13475 
13476   // Need a mock transaction in order to use some of MockHttpCache's
13477   // functions.
13478   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13479 
13480   ActiveEntry* entry1 = nullptr;
13481   ActiveEntry* entry2 = nullptr;
13482 
13483   cache.disk_cache()->set_force_fail_callback_later(true);
13484 
13485   // Queue up our operations.
13486   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13487                        transaction.get());
13488   ASSERT_EQ(rv, ERR_IO_PENDING);
13489   cache.disk_cache()->set_force_fail_callback_later(false);
13490   rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry2,
13491                  transaction.get());
13492   ASSERT_EQ(rv, ERR_IO_PENDING);
13493 
13494   // Wait for all the results to arrive.
13495   cb.GetResult(rv);
13496   ASSERT_EQ(cb.results().size(), 2u);
13497 
13498   // Verify that CreateEntry failed correctly.
13499   ASSERT_EQ(cb.results()[0], ERR_CACHE_CREATE_FAILURE);
13500   ASSERT_EQ(entry1, nullptr);
13501   // Verify that the OpenEntry requests a restart (CACHE_RACE).
13502   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13503   ASSERT_EQ(entry2, nullptr);
13504 }
13505 
TEST_F(HttpCacheIOCallbackTest,FailedCreateFollowedByCreate)13506 TEST_F(HttpCacheIOCallbackTest, FailedCreateFollowedByCreate) {
13507   MockHttpCache cache;
13508   TestCompletionCallbackForHttpCache cb;
13509   std::unique_ptr<Transaction> transaction =
13510       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13511 
13512   transaction->SetIOCallBackForTest(cb.callback());
13513 
13514   // Create the backend here as our direct calls to CreateEntry below require
13515   // that it exists.
13516   cache.backend();
13517 
13518   // Need a mock transaction in order to use some of MockHttpCache's
13519   // functions.
13520   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13521 
13522   ActiveEntry* entry1 = nullptr;
13523   ActiveEntry* entry2 = nullptr;
13524 
13525   cache.disk_cache()->set_force_fail_callback_later(true);
13526 
13527   // Queue up our operations.
13528   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13529                        transaction.get());
13530   ASSERT_EQ(rv, ERR_IO_PENDING);
13531   cache.disk_cache()->set_force_fail_callback_later(false);
13532   rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13533                    transaction.get());
13534   ASSERT_EQ(rv, ERR_IO_PENDING);
13535 
13536   // Wait for all the results to arrive.
13537   cb.GetResult(rv);
13538   ASSERT_EQ(cb.results().size(), 2u);
13539 
13540   // Verify the CreateEntry(s) failed.
13541   ASSERT_EQ(cb.results()[0], ERR_CACHE_CREATE_FAILURE);
13542   ASSERT_EQ(entry1, nullptr);
13543   ASSERT_EQ(cb.results()[1], ERR_CACHE_CREATE_FAILURE);
13544   ASSERT_EQ(entry2, nullptr);
13545 }
13546 
TEST_F(HttpCacheIOCallbackTest,CreateFollowedByCreate)13547 TEST_F(HttpCacheIOCallbackTest, CreateFollowedByCreate) {
13548   MockHttpCache cache;
13549   TestCompletionCallbackForHttpCache cb;
13550   std::unique_ptr<Transaction> transaction =
13551       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13552 
13553   transaction->SetIOCallBackForTest(cb.callback());
13554 
13555   // Create the backend here as our direct calls to CreateEntry below require
13556   // that it exists.
13557   cache.backend();
13558 
13559   // Need a mock transaction in order to use some of MockHttpCache's
13560   // functions.
13561   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13562 
13563   ActiveEntry* entry1 = nullptr;
13564   ActiveEntry* entry2 = nullptr;
13565 
13566   // Queue up our operations.
13567   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13568                        transaction.get());
13569   ASSERT_EQ(rv, ERR_IO_PENDING);
13570   rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13571                    transaction.get());
13572   ASSERT_EQ(rv, ERR_IO_PENDING);
13573 
13574   // Wait for all the results to arrive.
13575   cb.GetResult(rv);
13576   ASSERT_EQ(cb.results().size(), 2u);
13577 
13578   // Verify that the first CreateEntry succeeded.
13579   ASSERT_EQ(cb.results()[0], OK);
13580   ASSERT_NE(entry1, nullptr);
13581   // Verify that the second CreateEntry failed.
13582   ASSERT_EQ(cb.results()[1], ERR_CACHE_CREATE_FAILURE);
13583   ASSERT_EQ(entry2, nullptr);
13584 }
13585 
TEST_F(HttpCacheIOCallbackTest,OperationFollowedByDoom)13586 TEST_F(HttpCacheIOCallbackTest, OperationFollowedByDoom) {
13587   MockHttpCache cache;
13588   TestCompletionCallbackForHttpCache cb;
13589   std::unique_ptr<Transaction> transaction =
13590       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13591 
13592   transaction->SetIOCallBackForTest(cb.callback());
13593 
13594   // Create the backend here as our direct calls to CreateEntry and DoomEntry
13595   // below require that it exists.
13596   cache.backend();
13597 
13598   // Need a mock transaction in order to use some of MockHttpCache's
13599   // functions.
13600   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13601 
13602   ActiveEntry* entry1 = nullptr;
13603 
13604   // Queue up our operations.
13605   // For this test all we need is some operation followed by a doom, a create
13606   // fulfills that requirement.
13607   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13608                        transaction.get());
13609   ASSERT_EQ(rv, ERR_IO_PENDING);
13610   rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get());
13611   ASSERT_EQ(rv, ERR_IO_PENDING);
13612 
13613   // Wait for all the results to arrive.
13614   cb.GetResult(rv);
13615   ASSERT_EQ(cb.results().size(), 2u);
13616 
13617   // Verify that the CreateEntry succeeded.
13618   ASSERT_EQ(cb.results()[0], OK);
13619   // Verify that the DoomEntry requests a restart (CACHE_RACE).
13620   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13621 }
13622 
TEST_F(HttpCacheIOCallbackTest,CreateFollowedByOpenOrCreate)13623 TEST_F(HttpCacheIOCallbackTest, CreateFollowedByOpenOrCreate) {
13624   MockHttpCache cache;
13625   TestCompletionCallbackForHttpCache cb;
13626   std::unique_ptr<Transaction> transaction =
13627       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13628 
13629   transaction->SetIOCallBackForTest(cb.callback());
13630 
13631   // Create the backend here as our direct calls to CreateEntry and
13632   // OpenOrCreateEntry below require that it exists.
13633   cache.backend();
13634 
13635   // Need a mock transaction in order to use some of MockHttpCache's
13636   // functions.
13637   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13638 
13639   ActiveEntry* entry1 = nullptr;
13640   ActiveEntry* entry2 = nullptr;
13641 
13642   // Queue up our operations.
13643   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13644                        transaction.get());
13645   ASSERT_EQ(rv, ERR_IO_PENDING);
13646   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13647                          transaction.get());
13648   ASSERT_EQ(rv, ERR_IO_PENDING);
13649 
13650   // Wait for all the results to arrive.
13651   cb.GetResult(rv);
13652   ASSERT_EQ(cb.results().size(), 2u);
13653 
13654   // Verify that the CreateEntry succeeded.
13655   ASSERT_EQ(cb.results()[0], OK);
13656   ASSERT_NE(entry1, nullptr);
13657   // Verify that OpenOrCreateEntry succeeded.
13658   ASSERT_EQ(cb.results()[1], OK);
13659   ASSERT_NE(entry2, nullptr);
13660   ASSERT_EQ(entry1->disk_entry, entry2->disk_entry);
13661 }
13662 
TEST_F(HttpCacheIOCallbackTest,FailedCreateFollowedByOpenOrCreate)13663 TEST_F(HttpCacheIOCallbackTest, FailedCreateFollowedByOpenOrCreate) {
13664   MockHttpCache cache;
13665   TestCompletionCallbackForHttpCache cb;
13666   std::unique_ptr<Transaction> transaction =
13667       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13668 
13669   transaction->SetIOCallBackForTest(cb.callback());
13670 
13671   // Create the backend here as our direct calls to CreateEntry and
13672   // OpenOrCreateEntry below require that it exists.
13673   cache.backend();
13674 
13675   // Need a mock transaction in order to use some of MockHttpCache's
13676   // functions.
13677   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13678 
13679   ActiveEntry* entry1 = nullptr;
13680   ActiveEntry* entry2 = nullptr;
13681 
13682   cache.disk_cache()->set_force_fail_callback_later(true);
13683 
13684   // Queue up our operations.
13685   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13686                        transaction.get());
13687   ASSERT_EQ(rv, ERR_IO_PENDING);
13688   cache.disk_cache()->set_force_fail_callback_later(false);
13689   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13690                          transaction.get());
13691   ASSERT_EQ(rv, ERR_IO_PENDING);
13692 
13693   // Wait for all the results to arrive.
13694   cb.GetResult(rv);
13695   ASSERT_EQ(cb.results().size(), 2u);
13696 
13697   // Verify that CreateEntry failed correctly.
13698   ASSERT_EQ(cb.results()[0], ERR_CACHE_CREATE_FAILURE);
13699   ASSERT_EQ(entry1, nullptr);
13700   // Verify that the OpenOrCreateEntry requests a restart (CACHE_RACE).
13701   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13702   ASSERT_EQ(entry2, nullptr);
13703 }
13704 
TEST_F(HttpCacheIOCallbackTest,OpenFollowedByOpenOrCreate)13705 TEST_F(HttpCacheIOCallbackTest, OpenFollowedByOpenOrCreate) {
13706   MockHttpCache cache;
13707   TestCompletionCallbackForHttpCache cb;
13708   std::unique_ptr<Transaction> transaction =
13709       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13710 
13711   transaction->SetIOCallBackForTest(cb.callback());
13712 
13713   // Create the backend here as our direct calls to OpenEntry and
13714   // OpenOrCreateEntry below require that it exists.
13715   cache.backend();
13716 
13717   // Need a mock transaction in order to use some of MockHttpCache's
13718   // functions.
13719   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13720 
13721   ActiveEntry* entry0 = nullptr;
13722   ActiveEntry* entry1 = nullptr;
13723   ActiveEntry* entry2 = nullptr;
13724 
13725   // First need to create and entry so we can open it.
13726   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry0,
13727                        transaction.get());
13728   ASSERT_EQ(rv, ERR_IO_PENDING);
13729   cb.GetResult(rv);
13730   ASSERT_EQ(cb.results().size(), static_cast<size_t>(1));
13731   ASSERT_EQ(cb.results()[0], OK);
13732   ASSERT_NE(entry0, nullptr);
13733   // Manually DeactivateEntry() because OpenEntry() fails if there is an
13734   // existing active entry.
13735   DeactivateEntry(cache.http_cache(), entry0);
13736 
13737   // Queue up our operations.
13738   rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry1,
13739                  transaction.get());
13740   ASSERT_EQ(rv, ERR_IO_PENDING);
13741   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13742                          transaction.get());
13743   ASSERT_EQ(rv, ERR_IO_PENDING);
13744 
13745   // Wait for all the results to arrive.
13746   cb.GetResult(rv);
13747   ASSERT_EQ(cb.results().size(), 3u);
13748 
13749   // Verify that the OpenEntry succeeded.
13750   ASSERT_EQ(cb.results()[1], OK);
13751   ASSERT_NE(entry1, nullptr);
13752   // Verify that OpenOrCreateEntry succeeded.
13753   ASSERT_EQ(cb.results()[2], OK);
13754   ASSERT_NE(entry2, nullptr);
13755   ASSERT_EQ(entry1->disk_entry, entry2->disk_entry);
13756 }
13757 
TEST_F(HttpCacheIOCallbackTest,FailedOpenFollowedByOpenOrCreate)13758 TEST_F(HttpCacheIOCallbackTest, FailedOpenFollowedByOpenOrCreate) {
13759   MockHttpCache cache;
13760   TestCompletionCallbackForHttpCache cb;
13761   std::unique_ptr<Transaction> transaction =
13762       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13763 
13764   transaction->SetIOCallBackForTest(cb.callback());
13765 
13766   // Create the backend here as our direct calls to OpenEntry and
13767   // OpenOrCreateEntry below require that it exists.
13768   cache.backend();
13769 
13770   // Need a mock transaction in order to use some of MockHttpCache's
13771   // functions.
13772   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13773 
13774   ActiveEntry* entry1 = nullptr;
13775   ActiveEntry* entry2 = nullptr;
13776 
13777   cache.disk_cache()->set_force_fail_callback_later(true);
13778 
13779   // Queue up our operations.
13780   int rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry1,
13781                      transaction.get());
13782   ASSERT_EQ(rv, ERR_IO_PENDING);
13783   cache.disk_cache()->set_force_fail_callback_later(false);
13784   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13785                          transaction.get());
13786   ASSERT_EQ(rv, ERR_IO_PENDING);
13787 
13788   // Wait for all the results to arrive.
13789   cb.GetResult(rv);
13790   ASSERT_EQ(cb.results().size(), 2u);
13791 
13792   // Verify that OpenEntry failed correctly.
13793   ASSERT_EQ(cb.results()[0], ERR_CACHE_OPEN_FAILURE);
13794   ASSERT_EQ(entry1, nullptr);
13795   // Verify that the OpenOrCreateEntry requests a restart (CACHE_RACE).
13796   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13797   ASSERT_EQ(entry2, nullptr);
13798 }
13799 
TEST_F(HttpCacheIOCallbackTest,OpenOrCreateFollowedByCreate)13800 TEST_F(HttpCacheIOCallbackTest, OpenOrCreateFollowedByCreate) {
13801   MockHttpCache cache;
13802   TestCompletionCallbackForHttpCache cb;
13803   std::unique_ptr<Transaction> transaction =
13804       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13805 
13806   transaction->SetIOCallBackForTest(cb.callback());
13807 
13808   // Create the backend here as our direct calls to OpenOrCreateEntry and
13809   // CreateEntry below require that it exists.
13810   cache.backend();
13811 
13812   // Need a mock transaction in order to use some of MockHttpCache's
13813   // functions.
13814   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13815 
13816   ActiveEntry* entry1 = nullptr;
13817   ActiveEntry* entry2 = nullptr;
13818 
13819   // Queue up our operations.
13820   int rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13821                              transaction.get());
13822   ASSERT_EQ(rv, ERR_IO_PENDING);
13823   rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13824                    transaction.get());
13825   ASSERT_EQ(rv, ERR_IO_PENDING);
13826 
13827   // Wait for all the results to arrive.
13828   cb.GetResult(rv);
13829   ASSERT_EQ(cb.results().size(), 2u);
13830 
13831   // Verify that the OpenOrCreateEntry succeeded.
13832   ASSERT_EQ(cb.results()[0], OK);
13833   ASSERT_NE(entry1, nullptr);
13834   // Verify that CreateEntry failed.
13835   ASSERT_EQ(cb.results()[1], ERR_CACHE_CREATE_FAILURE);
13836   ASSERT_EQ(entry2, nullptr);
13837 }
13838 
TEST_F(HttpCacheIOCallbackTest,OpenOrCreateFollowedByOpenOrCreate)13839 TEST_F(HttpCacheIOCallbackTest, OpenOrCreateFollowedByOpenOrCreate) {
13840   MockHttpCache cache;
13841   TestCompletionCallbackForHttpCache cb;
13842   std::unique_ptr<Transaction> transaction =
13843       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13844 
13845   transaction->SetIOCallBackForTest(cb.callback());
13846 
13847   // Create the backend here as our direct calls to OpenOrCreateEntry below
13848   // require that it exists.
13849   cache.backend();
13850 
13851   // Need a mock transaction in order to use some of MockHttpCache's
13852   // functions.
13853   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13854 
13855   ActiveEntry* entry1 = nullptr;
13856   ActiveEntry* entry2 = nullptr;
13857 
13858   // Queue up our operations.
13859   int rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13860                              transaction.get());
13861   ASSERT_EQ(rv, ERR_IO_PENDING);
13862   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13863                          transaction.get());
13864   ASSERT_EQ(rv, ERR_IO_PENDING);
13865 
13866   // Wait for all the results to arrive.
13867   cb.GetResult(rv);
13868   ASSERT_EQ(cb.results().size(), 2u);
13869 
13870   // Verify that the OpenOrCreateEntry succeeded.
13871   ASSERT_EQ(cb.results()[0], OK);
13872   ASSERT_NE(entry1, nullptr);
13873   // Verify that the other succeeded.
13874   ASSERT_EQ(cb.results()[1], OK);
13875   ASSERT_NE(entry2, nullptr);
13876 }
13877 
TEST_F(HttpCacheIOCallbackTest,FailedOpenOrCreateFollowedByOpenOrCreate)13878 TEST_F(HttpCacheIOCallbackTest, FailedOpenOrCreateFollowedByOpenOrCreate) {
13879   MockHttpCache cache;
13880   TestCompletionCallbackForHttpCache cb;
13881   std::unique_ptr<Transaction> transaction =
13882       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13883 
13884   transaction->SetIOCallBackForTest(cb.callback());
13885 
13886   // Create the backend here as our direct calls to OpenOrCreateEntry below
13887   // require that it exists.
13888   cache.backend();
13889 
13890   // Need a mock transaction in order to use some of MockHttpCache's
13891   // functions.
13892   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13893 
13894   ActiveEntry* entry1 = nullptr;
13895   ActiveEntry* entry2 = nullptr;
13896 
13897   cache.disk_cache()->set_force_fail_callback_later(true);
13898 
13899   // Queue up our operations.
13900   int rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13901                              transaction.get());
13902   ASSERT_EQ(rv, ERR_IO_PENDING);
13903   cache.disk_cache()->set_force_fail_callback_later(false);
13904   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13905                          transaction.get());
13906   ASSERT_EQ(rv, ERR_IO_PENDING);
13907 
13908   // Wait for all the results to arrive.
13909   cb.GetResult(rv);
13910   ASSERT_EQ(cb.results().size(), 2u);
13911 
13912   // Verify that the OpenOrCreateEntry failed.
13913   ASSERT_EQ(cb.results()[0], ERR_CACHE_OPEN_OR_CREATE_FAILURE);
13914   ASSERT_EQ(entry1, nullptr);
13915   // Verify that the other failed.
13916   ASSERT_EQ(cb.results()[1], ERR_CACHE_OPEN_OR_CREATE_FAILURE);
13917   ASSERT_EQ(entry2, nullptr);
13918 }
13919 
TEST_F(HttpCacheTest,DnsAliasesNoRevalidation)13920 TEST_F(HttpCacheTest, DnsAliasesNoRevalidation) {
13921   MockHttpCache cache;
13922   HttpResponseInfo response;
13923   ScopedMockTransaction transaction(kSimpleGET_Transaction);
13924   transaction.dns_aliases = {"alias1", "alias2"};
13925 
13926   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13927                                      &response);
13928   EXPECT_FALSE(response.was_cached);
13929   EXPECT_THAT(response.dns_aliases, testing::ElementsAre("alias1", "alias2"));
13930 
13931   // The second request result in a cache hit and the response used without
13932   // revalidation. Set the transaction alias list to empty to verify that the
13933   // cached aliases are being used.
13934   transaction.dns_aliases = {};
13935   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13936                                      &response);
13937   EXPECT_TRUE(response.was_cached);
13938   EXPECT_THAT(response.dns_aliases, testing::ElementsAre("alias1", "alias2"));
13939 }
13940 
TEST_F(HttpCacheTest,NoDnsAliasesNoRevalidation)13941 TEST_F(HttpCacheTest, NoDnsAliasesNoRevalidation) {
13942   MockHttpCache cache;
13943   HttpResponseInfo response;
13944   ScopedMockTransaction transaction(kSimpleGET_Transaction);
13945   transaction.dns_aliases = {};
13946 
13947   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13948                                      &response);
13949   EXPECT_FALSE(response.was_cached);
13950   EXPECT_TRUE(response.dns_aliases.empty());
13951 
13952   // The second request should result in a cache hit and the response used
13953   // without revalidation. Set the transaction alias list to nonempty to verify
13954   // that the cached aliases are being used.
13955   transaction.dns_aliases = {"alias"};
13956   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13957                                      &response);
13958   EXPECT_TRUE(response.was_cached);
13959   EXPECT_TRUE(response.dns_aliases.empty());
13960 }
13961 
TEST_F(HttpCacheTest,DnsAliasesRevalidation)13962 TEST_F(HttpCacheTest, DnsAliasesRevalidation) {
13963   MockHttpCache cache;
13964   HttpResponseInfo response;
13965   ScopedMockTransaction transaction(kTypicalGET_Transaction);
13966   transaction.response_headers =
13967       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
13968       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
13969       "Cache-Control: max-age=0\n";
13970   transaction.dns_aliases = {"alias1", "alias2"};
13971 
13972   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13973                                      &response);
13974   EXPECT_FALSE(response.was_cached);
13975   EXPECT_THAT(response.dns_aliases, testing::ElementsAre("alias1", "alias2"));
13976 
13977   // On the second request, the cache should be revalidated. Change the aliases
13978   // to be sure that the new aliases are being used, and have the response be
13979   // cached for next time.
13980   transaction.response_headers = "Cache-Control: max-age=10000\n";
13981   transaction.dns_aliases = {"alias3", "alias4"};
13982   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13983                                      &response);
13984   EXPECT_FALSE(response.was_cached);
13985   EXPECT_THAT(response.dns_aliases, testing::ElementsAre("alias3", "alias4"));
13986 
13987   transaction.dns_aliases = {"alias5", "alias6"};
13988   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13989                                      &response);
13990   EXPECT_TRUE(response.was_cached);
13991   EXPECT_THAT(response.dns_aliases, testing::ElementsAre("alias3", "alias4"));
13992 }
13993 
TEST_F(HttpCacheTest,FirstPartySetsBypassCache_ShouldBypass_NoId)13994 TEST_F(HttpCacheTest, FirstPartySetsBypassCache_ShouldBypass_NoId) {
13995   MockHttpCache cache;
13996   HttpResponseInfo response;
13997   ScopedMockTransaction transaction(kSimpleGET_Transaction);
13998 
13999   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
14000                                      &response);
14001   EXPECT_FALSE(response.was_cached);
14002 
14003   transaction.fps_cache_filter = {5};
14004   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
14005                                      &response);
14006   EXPECT_FALSE(response.was_cached);
14007 }
14008 
TEST_F(HttpCacheTest,FirstPartySetsBypassCache_ShouldBypass_IdTooSmall)14009 TEST_F(HttpCacheTest, FirstPartySetsBypassCache_ShouldBypass_IdTooSmall) {
14010   MockHttpCache cache;
14011   HttpResponseInfo response;
14012   ScopedMockTransaction transaction(kSimpleGET_Transaction);
14013   const int64_t kBrowserRunId = 4;
14014   transaction.browser_run_id = {kBrowserRunId};
14015   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
14016                                      &response);
14017   EXPECT_FALSE(response.was_cached);
14018   EXPECT_TRUE(response.browser_run_id.has_value());
14019   EXPECT_EQ(kBrowserRunId, response.browser_run_id.value());
14020 
14021   transaction.fps_cache_filter = {5};
14022   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
14023                                      &response);
14024   EXPECT_FALSE(response.was_cached);
14025 }
14026 
TEST_F(HttpCacheTest,FirstPartySetsBypassCache_ShouldNotBypass)14027 TEST_F(HttpCacheTest, FirstPartySetsBypassCache_ShouldNotBypass) {
14028   MockHttpCache cache;
14029   HttpResponseInfo response;
14030   ScopedMockTransaction transaction(kSimpleGET_Transaction);
14031   const int64_t kBrowserRunId = 5;
14032   transaction.browser_run_id = {kBrowserRunId};
14033   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
14034                                      &response);
14035   EXPECT_FALSE(response.was_cached);
14036   EXPECT_TRUE(response.browser_run_id.has_value());
14037   EXPECT_EQ(kBrowserRunId, response.browser_run_id.value());
14038 
14039   transaction.fps_cache_filter = {5};
14040   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
14041                                      &response);
14042   EXPECT_TRUE(response.was_cached);
14043 }
14044 
TEST_F(HttpCacheTest,FirstPartySetsBypassCache_ShouldNotBypass_NoFilter)14045 TEST_F(HttpCacheTest, FirstPartySetsBypassCache_ShouldNotBypass_NoFilter) {
14046   MockHttpCache cache;
14047   HttpResponseInfo response;
14048   ScopedMockTransaction transaction(kSimpleGET_Transaction);
14049 
14050   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
14051                                      &response);
14052   EXPECT_FALSE(response.was_cached);
14053 
14054   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
14055                                      &response);
14056   EXPECT_TRUE(response.was_cached);
14057 }
14058 
TEST_F(HttpCacheTest,SecurityHeadersAreCopiedToConditionalizedResponse)14059 TEST_F(HttpCacheTest, SecurityHeadersAreCopiedToConditionalizedResponse) {
14060   MockHttpCache cache;
14061   HttpResponseInfo response;
14062   ScopedMockTransaction transaction(kSimpleGET_Transaction);
14063 
14064   static const Response kNetResponse1 = {
14065       "HTTP/1.1 200 OK",
14066       "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
14067       "Server: server1\n"
14068       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n"
14069       "Cross-Origin-Resource-Policy: cross-origin\n",
14070       "body1"};
14071 
14072   static const Response kNetResponse2 = {
14073       "HTTP/1.1 304 Not Modified",
14074       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
14075       "Server: server2\n"
14076       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
14077       ""};
14078 
14079   kNetResponse1.AssignTo(&transaction);
14080   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
14081                                      &response);
14082 
14083   // On the second request, the cache is revalidated.
14084   const char kExtraRequestHeaders[] =
14085       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
14086   transaction.request_headers = kExtraRequestHeaders;
14087   kNetResponse2.AssignTo(&transaction);
14088   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
14089                                      &response);
14090 
14091   // Verify that the CORP header was carried over to the response.
14092   std::string response_corp_header;
14093   response.headers->GetNormalizedHeader("Cross-Origin-Resource-Policy",
14094                                         &response_corp_header);
14095 
14096   EXPECT_EQ(304, response.headers->response_code());
14097   EXPECT_EQ("cross-origin", response_corp_header);
14098 }
14099 class CacheTransparencyHttpCacheTest
14100     : public HttpCacheTest_SplitCacheFeatureEnabled {
14101  public:
CacheTransparencyHttpCacheTest()14102   CacheTransparencyHttpCacheTest() {
14103     // The single-keyed cache feature is meaningless when the split cache is not
14104     // enabled. The //net layer doesn't care whether or not the
14105     // "CacheTransparency" feature is enabled.
14106     CHECK(base::FeatureList::IsEnabled(
14107         net::features::kSplitCacheByNetworkIsolationKey));
14108   }
14109 
RunTransactionTestForSingleKeyedCache(HttpCache * cache,const MockTransaction & trans_info,const NetworkIsolationKey & network_isolation_key,const std::string & checksum)14110   void RunTransactionTestForSingleKeyedCache(
14111       HttpCache* cache,
14112       const MockTransaction& trans_info,
14113       const NetworkIsolationKey& network_isolation_key,
14114       const std::string& checksum) {
14115     ScopedMockTransaction transaction(trans_info);
14116 
14117     MockHttpRequest request(transaction);
14118     request.network_isolation_key = network_isolation_key;
14119     request.network_anonymization_key =
14120         net::NetworkAnonymizationKey::CreateFromNetworkIsolationKey(
14121             network_isolation_key);
14122     request.checksum = checksum;
14123 
14124     HttpResponseInfo response_info;
14125     RunTransactionTestWithRequest(cache, transaction, request, &response_info);
14126   }
14127 
RunSimpleTransactionTestForSingleKeyedCache(HttpCache * cache,const NetworkIsolationKey & network_isolation_key,const std::string & checksum)14128   void RunSimpleTransactionTestForSingleKeyedCache(
14129       HttpCache* cache,
14130       const NetworkIsolationKey& network_isolation_key,
14131       const std::string& checksum) {
14132     RunTransactionTestForSingleKeyedCache(cache, kSimpleGET_Transaction,
14133                                           network_isolation_key, checksum);
14134   }
14135 };
14136 
14137 INSTANTIATE_TEST_SUITE_P(
14138     All,
14139     CacheTransparencyHttpCacheTest,
14140     testing::ValuesIn({SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled,
14141                        SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled}),
__anonc87d1e5b0a02(const testing::TestParamInfo<SplitCacheTestCase>& info) 14142     [](const testing::TestParamInfo<SplitCacheTestCase>& info) {
14143       switch (info.param) {
14144         case (SplitCacheTestCase::kSplitCacheDisabled):
14145           return "NotUsedForThisTestSuite";
14146         case (SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled):
14147           return "SplitCacheNikFrameSiteEnabled";
14148         case (SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled):
14149           return "SplitCacheNikCrossSiteFlagEnabled";
14150       }
14151     });
14152 
14153 constexpr char kChecksumForSimpleGET[] =
14154     "80B4C37CEF5CFE69B4A90830282AA2BB772DC4CBC00491A219CE5F2AD75C7B58";
14155 
TEST_P(CacheTransparencyHttpCacheTest,SuccessfulGET)14156 TEST_P(CacheTransparencyHttpCacheTest, SuccessfulGET) {
14157   MockHttpCache cache;
14158   // The first request adds the item to the cache.
14159   {
14160     const auto site_a = SchemefulSite(GURL("https://a.com/"));
14161     RunSimpleTransactionTestForSingleKeyedCache(
14162         cache.http_cache(), NetworkIsolationKey(site_a, site_a),
14163         kChecksumForSimpleGET);
14164 
14165     EXPECT_EQ(1, cache.network_layer()->transaction_count());
14166     EXPECT_EQ(0, cache.disk_cache()->open_count());
14167     EXPECT_EQ(1, cache.disk_cache()->create_count());
14168   }
14169 
14170   // The second request verifies that the same cache entry is used with a
14171   // different NetworkIsolationKey
14172   {
14173     const auto site_b = SchemefulSite(GURL("https://b.com/"));
14174     RunSimpleTransactionTestForSingleKeyedCache(
14175         cache.http_cache(), NetworkIsolationKey(site_b, site_b),
14176         kChecksumForSimpleGET);
14177 
14178     EXPECT_EQ(1, cache.network_layer()->transaction_count());
14179     EXPECT_EQ(1, cache.disk_cache()->open_count());
14180     EXPECT_EQ(1, cache.disk_cache()->create_count());
14181   }
14182 }
14183 
TEST_P(CacheTransparencyHttpCacheTest,GETWithChecksumMismatch)14184 TEST_P(CacheTransparencyHttpCacheTest, GETWithChecksumMismatch) {
14185   MockHttpCache cache;
14186   const auto site_a = SchemefulSite(GURL("https://a.com/"));
14187   // The first request adds the item to the cache.
14188   {
14189     RunSimpleTransactionTestForSingleKeyedCache(
14190         cache.http_cache(), NetworkIsolationKey(site_a, site_a),
14191         "000000000000000000000000000000000000000000000000000000000000000");
14192 
14193     EXPECT_EQ(1, cache.network_layer()->transaction_count());
14194     EXPECT_EQ(0, cache.disk_cache()->open_count());
14195     EXPECT_EQ(1, cache.disk_cache()->create_count());
14196   }
14197 
14198   // The second request doesn't use the item that was added to the single-keyed
14199   // cache, but adds it to the split cache instead.
14200   {
14201     RunSimpleTransactionTestForSingleKeyedCache(
14202         cache.http_cache(), NetworkIsolationKey(site_a, site_a),
14203         "000000000000000000000000000000000000000000000000000000000000000");
14204 
14205     // Fetches from the network again, this time into the split cache.
14206     EXPECT_EQ(2, cache.network_layer()->transaction_count());
14207     EXPECT_EQ(1, cache.disk_cache()->open_count());
14208     EXPECT_EQ(2, cache.disk_cache()->create_count());
14209   }
14210 
14211   // The third request uses the split cache.
14212   {
14213     RunSimpleTransactionTestForSingleKeyedCache(
14214         cache.http_cache(), NetworkIsolationKey(site_a, site_a),
14215         "000000000000000000000000000000000000000000000000000000000000000");
14216 
14217     // Fetches from the split cache.
14218     EXPECT_EQ(2, cache.network_layer()->transaction_count());
14219     EXPECT_EQ(3, cache.disk_cache()->open_count());  // opens both cache entries
14220     EXPECT_EQ(2, cache.disk_cache()->create_count());
14221   }
14222 }
14223 
TEST_P(CacheTransparencyHttpCacheTest,GETWithBadResponseCode)14224 TEST_P(CacheTransparencyHttpCacheTest, GETWithBadResponseCode) {
14225   MockHttpCache cache;
14226   MockTransaction transaction = kSimpleGET_Transaction;
14227   transaction.status = "HTTP/1.1 404 Not Found";
14228   const auto site_a = SchemefulSite(GURL("https://a.com/"));
14229   // The first request adds the item to the single-keyed cache.
14230   {
14231     RunTransactionTestForSingleKeyedCache(cache.http_cache(), transaction,
14232                                           NetworkIsolationKey(site_a, site_a),
14233                                           kChecksumForSimpleGET);
14234 
14235     EXPECT_EQ(1, cache.network_layer()->transaction_count());
14236     EXPECT_EQ(0, cache.disk_cache()->open_count());
14237     EXPECT_EQ(1, cache.disk_cache()->create_count());
14238   }
14239 
14240   // The second request verifies that the cache entry is not re-used
14241   // but a new one is created in the split cache.
14242   {
14243     RunTransactionTestForSingleKeyedCache(cache.http_cache(), transaction,
14244                                           NetworkIsolationKey(site_a, site_a),
14245                                           kChecksumForSimpleGET);
14246 
14247     EXPECT_EQ(2, cache.network_layer()->transaction_count());
14248     EXPECT_EQ(1, cache.disk_cache()->open_count());
14249     EXPECT_EQ(2, cache.disk_cache()->create_count());
14250   }
14251 }
14252 
14253 // This is identical to GETWithBadResponseCode but with a different response
14254 // code. It's not very realistic as it doesn't call DoneReading(), but it covers
14255 // the relevant code path.
TEST_P(CacheTransparencyHttpCacheTest,RedirectUnusable)14256 TEST_P(CacheTransparencyHttpCacheTest, RedirectUnusable) {
14257   MockHttpCache cache;
14258   MockTransaction transaction = kSimpleGET_Transaction;
14259   transaction.status = "HTTP/1.1 301 Moved Permanently";
14260   const auto site_a = SchemefulSite(GURL("https://a.com/"));
14261   // The first request adds the item to the single-keyed cache.
14262   {
14263     RunTransactionTestForSingleKeyedCache(cache.http_cache(), transaction,
14264                                           NetworkIsolationKey(site_a, site_a),
14265                                           kChecksumForSimpleGET);
14266 
14267     EXPECT_EQ(1, cache.network_layer()->transaction_count());
14268     EXPECT_EQ(0, cache.disk_cache()->open_count());
14269     EXPECT_EQ(1, cache.disk_cache()->create_count());
14270   }
14271 
14272   // The second request verifies that the cache entry is not re-used
14273   // but a new one is created in the split cache.
14274   {
14275     RunTransactionTestForSingleKeyedCache(cache.http_cache(), transaction,
14276                                           NetworkIsolationKey(site_a, site_a),
14277                                           kChecksumForSimpleGET);
14278 
14279     EXPECT_EQ(2, cache.network_layer()->transaction_count());
14280     EXPECT_EQ(1, cache.disk_cache()->open_count());
14281     EXPECT_EQ(2, cache.disk_cache()->create_count());
14282   }
14283 }
14284 
TEST_P(CacheTransparencyHttpCacheTest,GETWith206ResponseCode)14285 TEST_P(CacheTransparencyHttpCacheTest, GETWith206ResponseCode) {
14286   MockHttpCache cache;
14287   MockTransaction transaction = kSimpleGET_Transaction;
14288   // We should never get a partial response since we never send a range request,
14289   // but it behaves differently from other bad response codes.
14290   transaction.status = "HTTP/1.1 206 Partial";
14291   const auto site_a = SchemefulSite(GURL("https://a.com/"));
14292   // The response is not cached.
14293   {
14294     RunTransactionTestForSingleKeyedCache(cache.http_cache(), transaction,
14295                                           NetworkIsolationKey(site_a, site_a),
14296                                           kChecksumForSimpleGET);
14297 
14298     EXPECT_EQ(1, cache.network_layer()->transaction_count());
14299     EXPECT_EQ(0, cache.disk_cache()->open_count());
14300     EXPECT_EQ(1, cache.disk_cache()->create_count());
14301   }
14302 
14303   // It is fetched from the network again.
14304   {
14305     RunTransactionTestForSingleKeyedCache(cache.http_cache(), transaction,
14306                                           NetworkIsolationKey(site_a, site_a),
14307                                           kChecksumForSimpleGET);
14308 
14309     EXPECT_EQ(2, cache.network_layer()->transaction_count());
14310     EXPECT_EQ(0, cache.disk_cache()->open_count());
14311     EXPECT_EQ(2, cache.disk_cache()->create_count());
14312   }
14313 }
14314 
TEST_P(CacheTransparencyHttpCacheTest,SuccessfulRevalidation)14315 TEST_P(CacheTransparencyHttpCacheTest, SuccessfulRevalidation) {
14316   MockHttpCache cache;
14317   MockTransaction transaction = kSimpleGET_Transaction;
14318   // Add a cache control header to permit the entry to be cached, with max-age 0
14319   // to force relatidation next time. Add Etag to permit it to be revalidated.
14320   transaction.response_headers =
14321       "Etag: \"foo\"\n"
14322       "Cache-Control: max-age=0\n";
14323   {
14324     const auto site_a = SchemefulSite(GURL("https://a.com/"));
14325     RunTransactionTestForSingleKeyedCache(cache.http_cache(), transaction,
14326                                           NetworkIsolationKey(site_a, site_a),
14327                                           kChecksumForSimpleGET);
14328 
14329     EXPECT_EQ(1, cache.network_layer()->transaction_count());
14330     EXPECT_EQ(0, cache.disk_cache()->open_count());
14331     EXPECT_EQ(1, cache.disk_cache()->create_count());
14332   }
14333 
14334   // The second request revalidates the existing entry.
14335   {
14336     const auto site_b = SchemefulSite(GURL("https://b.com/"));
14337     transaction.status = "HTTP/1.1 304 Not Modified";
14338     // Allow it to be reused without validation next time by increasing max-age.
14339     transaction.response_headers =
14340         "Etag: \"foo\"\n"
14341         "Cache-Control: max-age=10000\n";
14342     RunTransactionTestForSingleKeyedCache(cache.http_cache(), transaction,
14343                                           NetworkIsolationKey(site_b, site_b),
14344                                           kChecksumForSimpleGET);
14345 
14346     EXPECT_EQ(2, cache.network_layer()->transaction_count());
14347     EXPECT_EQ(1, cache.disk_cache()->open_count());
14348     EXPECT_EQ(1, cache.disk_cache()->create_count());
14349   }
14350 
14351   // The third request re-uses the entry.
14352   {
14353     const auto site_c = SchemefulSite(GURL("https://c.com/"));
14354     // Load from cache again.
14355     RunTransactionTestForSingleKeyedCache(cache.http_cache(), transaction,
14356                                           NetworkIsolationKey(site_c, site_c),
14357                                           kChecksumForSimpleGET);
14358 
14359     EXPECT_EQ(2, cache.network_layer()->transaction_count());
14360     EXPECT_EQ(1, cache.disk_cache()->open_count());
14361     EXPECT_EQ(1, cache.disk_cache()->create_count());
14362   }
14363 }
14364 
TEST_P(CacheTransparencyHttpCacheTest,RevalidationChangingUncheckedHeader)14365 TEST_P(CacheTransparencyHttpCacheTest, RevalidationChangingUncheckedHeader) {
14366   MockHttpCache cache;
14367   MockTransaction transaction = kSimpleGET_Transaction;
14368   // Add a cache control header to permit the entry to be cached, with max-age 0
14369   // to force relatidation next time. Add Etag to permit it to be revalidated.
14370   transaction.response_headers =
14371       "Etag: \"foo\"\n"
14372       "Cache-Control: max-age=0\n";
14373   {
14374     const auto site_a = SchemefulSite(GURL("https://a.com/"));
14375     RunTransactionTestForSingleKeyedCache(cache.http_cache(), transaction,
14376                                           NetworkIsolationKey(site_a, site_a),
14377                                           kChecksumForSimpleGET);
14378 
14379     EXPECT_EQ(1, cache.network_layer()->transaction_count());
14380     EXPECT_EQ(0, cache.disk_cache()->open_count());
14381     EXPECT_EQ(1, cache.disk_cache()->create_count());
14382   }
14383 
14384   // The second request revalidates the existing entry.
14385   {
14386     const auto site_b = SchemefulSite(GURL("https://b.com/"));
14387     transaction.status = "HTTP/1.1 304 Not Modified";
14388     // Add a response header. This is the only difference from the
14389     // SuccessfulRevalidation test.
14390     transaction.response_headers =
14391         "Etag: \"foo\"\n"
14392         "Cache-Control: max-age=10000\n"
14393         "X-Unchecked-Header: 1\n";
14394     RunTransactionTestForSingleKeyedCache(cache.http_cache(), transaction,
14395                                           NetworkIsolationKey(site_b, site_b),
14396                                           kChecksumForSimpleGET);
14397 
14398     EXPECT_EQ(2, cache.network_layer()->transaction_count());
14399     EXPECT_EQ(1, cache.disk_cache()->open_count());
14400     EXPECT_EQ(1, cache.disk_cache()->create_count());
14401   }
14402 
14403   // The third request re-uses the entry.
14404   {
14405     const auto site_c = SchemefulSite(GURL("https://c.com/"));
14406     // Load from cache again.
14407     RunTransactionTestForSingleKeyedCache(cache.http_cache(), transaction,
14408                                           NetworkIsolationKey(site_c, site_c),
14409                                           kChecksumForSimpleGET);
14410 
14411     EXPECT_EQ(2, cache.network_layer()->transaction_count());
14412     EXPECT_EQ(1, cache.disk_cache()->open_count());
14413     EXPECT_EQ(1, cache.disk_cache()->create_count());
14414   }
14415 }
14416 
TEST_P(CacheTransparencyHttpCacheTest,RevalidationChangingCheckedHeader)14417 TEST_P(CacheTransparencyHttpCacheTest, RevalidationChangingCheckedHeader) {
14418   MockHttpCache cache;
14419   MockTransaction transaction = kSimpleGET_Transaction;
14420   // Add a cache control header to permit the entry to be cached, with max-age 0
14421   // to force relatidation next time. Add Etag to permit it to be revalidated.
14422   transaction.response_headers =
14423       "Etag: \"foo\"\n"
14424       "Cache-Control: max-age=0\n";
14425   {
14426     const auto site_a = SchemefulSite(GURL("https://a.com/"));
14427     RunTransactionTestForSingleKeyedCache(cache.http_cache(), transaction,
14428                                           NetworkIsolationKey(site_a, site_a),
14429                                           kChecksumForSimpleGET);
14430 
14431     EXPECT_EQ(1, cache.network_layer()->transaction_count());
14432     EXPECT_EQ(0, cache.disk_cache()->open_count());
14433     EXPECT_EQ(1, cache.disk_cache()->create_count());
14434   }
14435 
14436   // The second request marks the single-keyed cache entry unusable because the
14437   // checksum no longer matches.
14438   {
14439     const auto site_b = SchemefulSite(GURL("https://b.com/"));
14440     transaction.status = "HTTP/1.1 304 Not Modified";
14441     // Add the "Vary" response header.
14442     transaction.response_headers =
14443         "Etag: \"foo\"\n"
14444         "Cache-Control: max-age=10000\n"
14445         "Vary: Cookie\n";
14446     RunTransactionTestForSingleKeyedCache(cache.http_cache(), transaction,
14447                                           NetworkIsolationKey(site_b, site_b),
14448                                           kChecksumForSimpleGET);
14449 
14450     EXPECT_EQ(2, cache.network_layer()->transaction_count());
14451     EXPECT_EQ(1, cache.disk_cache()->open_count());
14452     EXPECT_EQ(1, cache.disk_cache()->create_count());
14453   }
14454 
14455   // The third request has to go to the network because the single-keyed cache
14456   // entry is unusable. It writes a new entry to the split cache.
14457   {
14458     const auto site_c = SchemefulSite(GURL("https://c.com/"));
14459     RunTransactionTestForSingleKeyedCache(cache.http_cache(), transaction,
14460                                           NetworkIsolationKey(site_c, site_c),
14461                                           kChecksumForSimpleGET);
14462 
14463     EXPECT_EQ(3, cache.network_layer()->transaction_count());
14464     EXPECT_EQ(2, cache.disk_cache()->open_count());
14465     EXPECT_EQ(2, cache.disk_cache()->create_count());
14466   }
14467 }
14468 
TEST_P(CacheTransparencyHttpCacheTest,SuccessfulGETManyWriters)14469 TEST_P(CacheTransparencyHttpCacheTest, SuccessfulGETManyWriters) {
14470   MockHttpCache cache;
14471 
14472   MockHttpRequest request(kSimpleGET_Transaction);
14473   request.checksum = kChecksumForSimpleGET;
14474 
14475   constexpr int kNumTransactions = 2;
14476   std::vector<Context> context_list(kNumTransactions);
14477 
14478   for (Context& c : context_list) {
14479     c.result = cache.CreateTransaction(&c.trans);
14480     ASSERT_THAT(c.result, IsOk());
14481 
14482     c.result =
14483         c.trans->Start(&request, c.callback.callback(), NetLogWithSource());
14484   }
14485 
14486   // Allow all requests to move from the Create queue to the active entry.
14487   // All would have been added to writers.
14488   base::RunLoop().RunUntilIdle();
14489   std::string cache_key = cache.http_cache()
14490                               ->GenerateCacheKeyForRequest(
14491                                   &request, /*use_single_keyed_cache=*/true)
14492                               .value();
14493   EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
14494 
14495   // The second transaction skipped validation, thus only one network
14496   // transaction is created.
14497   EXPECT_EQ(1, cache.network_layer()->transaction_count());
14498   EXPECT_EQ(0, cache.disk_cache()->open_count());
14499   EXPECT_EQ(1, cache.disk_cache()->create_count());
14500 
14501   // Complete the transactions.
14502   for (Context& c : context_list) {
14503     ReadAndVerifyTransaction(c.trans.get(), kSimpleGET_Transaction);
14504   }
14505 
14506   EXPECT_EQ(1, cache.network_layer()->transaction_count());
14507   EXPECT_EQ(0, cache.disk_cache()->open_count());
14508   EXPECT_EQ(1, cache.disk_cache()->create_count());
14509 }
14510 
TEST_P(CacheTransparencyHttpCacheTest,BadChecksumManyWriters)14511 TEST_P(CacheTransparencyHttpCacheTest, BadChecksumManyWriters) {
14512   MockHttpCache cache;
14513 
14514   MockHttpRequest request(kSimpleGET_Transaction);
14515   request.checksum =
14516       "0000000000000000000000000000000000000000000000000000000000000000";
14517 
14518   constexpr int kNumTransactions = 2;
14519   std::vector<Context> context_list(kNumTransactions);
14520 
14521   for (Context& c : context_list) {
14522     c.result = cache.CreateTransaction(&c.trans);
14523     ASSERT_THAT(c.result, IsOk());
14524 
14525     c.result =
14526         c.trans->Start(&request, c.callback.callback(), NetLogWithSource());
14527   }
14528 
14529   // Allow all requests to move from the Create queue to the active entry.
14530   // All would have been added to writers.
14531   base::RunLoop().RunUntilIdle();
14532   std::string cache_key = cache.http_cache()
14533                               ->GenerateCacheKeyForRequest(
14534                                   &request, /*use_single_keyed_cache=*/true)
14535                               .value();
14536   EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
14537 
14538   // The second transaction skipped validation, thus only one network
14539   // transaction is created.
14540   EXPECT_EQ(1, cache.network_layer()->transaction_count());
14541   EXPECT_EQ(0, cache.disk_cache()->open_count());
14542   EXPECT_EQ(1, cache.disk_cache()->create_count());
14543 
14544   // Complete the transactions.
14545   for (Context& c : context_list) {
14546     ReadAndVerifyTransaction(c.trans.get(), kSimpleGET_Transaction);
14547   }
14548 
14549   EXPECT_EQ(1, cache.network_layer()->transaction_count());
14550   EXPECT_EQ(0, cache.disk_cache()->open_count());
14551   EXPECT_EQ(1, cache.disk_cache()->create_count());
14552 }
14553 
14554 }  // namespace net
14555