• 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/bind.h"
28 #include "base/test/metrics/histogram_tester.h"
29 #include "base/test/scoped_feature_list.h"
30 #include "base/test/simple_test_clock.h"
31 #include "base/time/time.h"
32 #include "base/trace_event/memory_allocator_dump.h"
33 #include "base/trace_event/memory_dump_request_args.h"
34 #include "base/trace_event/process_memory_dump.h"
35 #include "net/base/cache_type.h"
36 #include "net/base/completion_repeating_callback.h"
37 #include "net/base/elements_upload_data_stream.h"
38 #include "net/base/features.h"
39 #include "net/base/host_port_pair.h"
40 #include "net/base/ip_address.h"
41 #include "net/base/ip_endpoint.h"
42 #include "net/base/load_flags.h"
43 #include "net/base/load_timing_info.h"
44 #include "net/base/load_timing_info_test_util.h"
45 #include "net/base/net_errors.h"
46 #include "net/base/schemeful_site.h"
47 #include "net/base/tracing.h"
48 #include "net/base/upload_bytes_element_reader.h"
49 #include "net/cert/cert_status_flags.h"
50 #include "net/cert/x509_certificate.h"
51 #include "net/disk_cache/disk_cache.h"
52 #include "net/http/http_byte_range.h"
53 #include "net/http/http_cache_transaction.h"
54 #include "net/http/http_request_headers.h"
55 #include "net/http/http_request_info.h"
56 #include "net/http/http_response_headers.h"
57 #include "net/http/http_response_headers_test_util.h"
58 #include "net/http/http_response_info.h"
59 #include "net/http/http_transaction.h"
60 #include "net/http/http_transaction_test_util.h"
61 #include "net/http/http_util.h"
62 #include "net/http/mock_http_cache.h"
63 #include "net/log/net_log_event_type.h"
64 #include "net/log/net_log_source.h"
65 #include "net/log/net_log_with_source.h"
66 #include "net/log/test_net_log.h"
67 #include "net/log/test_net_log_util.h"
68 #include "net/socket/client_socket_handle.h"
69 #include "net/ssl/ssl_cert_request_info.h"
70 #include "net/ssl/ssl_connection_status_flags.h"
71 #include "net/test/cert_test_util.h"
72 #include "net/test/gtest_util.h"
73 #include "net/test/test_data_directory.h"
74 #include "net/test/test_with_task_environment.h"
75 #include "net/websockets/websocket_handshake_stream_base.h"
76 #include "testing/gmock/include/gmock/gmock.h"
77 #include "testing/gtest/include/gtest/gtest.h"
78 #include "third_party/abseil-cpp/absl/types/optional.h"
79 #include "url/origin.h"
80 
81 using net::test::IsError;
82 using net::test::IsOk;
83 using testing::AllOf;
84 using testing::ByRef;
85 using testing::Contains;
86 using testing::ElementsAre;
87 using testing::Eq;
88 using testing::Field;
89 using testing::Gt;
90 using testing::IsEmpty;
91 using testing::NotNull;
92 
93 using base::Time;
94 
95 namespace net {
96 
97 using CacheEntryStatus = HttpResponseInfo::CacheEntryStatus;
98 
99 class WebSocketEndpointLockManager;
100 
101 namespace {
102 
103 constexpr auto ToSimpleString = test::HttpResponseHeadersToSimpleString;
104 
105 // Tests the load timing values of a request that goes through a
106 // MockNetworkTransaction.
TestLoadTimingNetworkRequest(const LoadTimingInfo & load_timing_info)107 void TestLoadTimingNetworkRequest(const LoadTimingInfo& load_timing_info) {
108   EXPECT_FALSE(load_timing_info.socket_reused);
109   EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
110 
111   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
112   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
113 
114   ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
115                               CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
116   EXPECT_LE(load_timing_info.connect_timing.connect_end,
117             load_timing_info.send_start);
118 
119   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
120 
121   // Set by URLRequest / URLRequestHttpJob, at a higher level.
122   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
123   EXPECT_TRUE(load_timing_info.request_start.is_null());
124   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
125 }
126 
127 // Tests the load timing values of a request that receives a cached response.
TestLoadTimingCachedResponse(const LoadTimingInfo & load_timing_info)128 void TestLoadTimingCachedResponse(const LoadTimingInfo& load_timing_info) {
129   EXPECT_FALSE(load_timing_info.socket_reused);
130   EXPECT_EQ(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
131 
132   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
133   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
134 
135   ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
136 
137   // Only the send start / end times should be sent, and they should have the
138   // same value.
139   EXPECT_FALSE(load_timing_info.send_start.is_null());
140   EXPECT_EQ(load_timing_info.send_start, load_timing_info.send_end);
141 
142   // Set by URLRequest / URLRequestHttpJob, at a higher level.
143   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
144   EXPECT_TRUE(load_timing_info.request_start.is_null());
145   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
146 }
147 
DeferCallback(bool * defer)148 void DeferCallback(bool* defer) {
149   *defer = true;
150 }
151 
152 class DeleteCacheCompletionCallback : public TestCompletionCallbackBase {
153  public:
DeleteCacheCompletionCallback(std::unique_ptr<MockHttpCache> cache)154   explicit DeleteCacheCompletionCallback(std::unique_ptr<MockHttpCache> cache)
155       : cache_(std::move(cache)) {}
156 
157   DeleteCacheCompletionCallback(const DeleteCacheCompletionCallback&) = delete;
158   DeleteCacheCompletionCallback& operator=(
159       const DeleteCacheCompletionCallback&) = delete;
160 
callback()161   CompletionOnceCallback callback() {
162     return base::BindOnce(&DeleteCacheCompletionCallback::OnComplete,
163                           base::Unretained(this));
164   }
165 
166  private:
OnComplete(int result)167   void OnComplete(int result) {
168     cache_.reset();
169     SetResult(result);
170   }
171 
172   std::unique_ptr<MockHttpCache> cache_;
173 };
174 
175 //-----------------------------------------------------------------------------
176 // helpers
177 
ReadAndVerifyTransaction(HttpTransaction * trans,const MockTransaction & trans_info)178 void ReadAndVerifyTransaction(HttpTransaction* trans,
179                               const MockTransaction& trans_info) {
180   std::string content;
181   int rv = ReadTransaction(trans, &content);
182 
183   EXPECT_THAT(rv, IsOk());
184   std::string expected(trans_info.data);
185   EXPECT_EQ(expected, content);
186 }
187 
ReadRemainingAndVerifyTransaction(HttpTransaction * trans,const std::string & already_read,const MockTransaction & trans_info)188 void ReadRemainingAndVerifyTransaction(HttpTransaction* trans,
189                                        const std::string& already_read,
190                                        const MockTransaction& trans_info) {
191   std::string content;
192   int rv = ReadTransaction(trans, &content);
193   EXPECT_THAT(rv, IsOk());
194 
195   std::string expected(trans_info.data);
196   EXPECT_EQ(expected, already_read + content);
197 }
198 
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)199 void RunTransactionTestBase(HttpCache* cache,
200                             const MockTransaction& trans_info,
201                             const MockHttpRequest& request,
202                             HttpResponseInfo* response_info,
203                             const NetLogWithSource& net_log,
204                             LoadTimingInfo* load_timing_info,
205                             int64_t* sent_bytes,
206                             int64_t* received_bytes,
207                             IPEndPoint* remote_endpoint) {
208   TestCompletionCallback callback;
209 
210   // write to the cache
211 
212   std::unique_ptr<HttpTransaction> trans;
213   int rv = cache->CreateTransaction(DEFAULT_PRIORITY, &trans);
214   EXPECT_THAT(rv, IsOk());
215   ASSERT_TRUE(trans.get());
216 
217   rv = trans->Start(&request, callback.callback(), net_log);
218   if (rv == ERR_IO_PENDING)
219     rv = callback.WaitForResult();
220   ASSERT_EQ(trans_info.start_return_code, rv);
221 
222   if (OK != rv)
223     return;
224 
225   const HttpResponseInfo* response = trans->GetResponseInfo();
226   ASSERT_TRUE(response);
227 
228   if (response_info)
229     *response_info = *response;
230 
231   if (load_timing_info) {
232     // If a fake network connection is used, need a NetLog to get a fake socket
233     // ID.
234     EXPECT_TRUE(net_log.net_log());
235     *load_timing_info = LoadTimingInfo();
236     trans->GetLoadTimingInfo(load_timing_info);
237   }
238 
239   if (remote_endpoint)
240     ASSERT_TRUE(trans->GetRemoteEndpoint(remote_endpoint));
241 
242   ReadAndVerifyTransaction(trans.get(), trans_info);
243 
244   if (sent_bytes)
245     *sent_bytes = trans->GetTotalSentBytes();
246   if (received_bytes)
247     *received_bytes = trans->GetTotalReceivedBytes();
248 }
249 
RunTransactionTestWithRequest(HttpCache * cache,const MockTransaction & trans_info,const MockHttpRequest & request,HttpResponseInfo * response_info)250 void RunTransactionTestWithRequest(HttpCache* cache,
251                                    const MockTransaction& trans_info,
252                                    const MockHttpRequest& request,
253                                    HttpResponseInfo* response_info) {
254   RunTransactionTestBase(cache, trans_info, request, response_info,
255                          NetLogWithSource(), nullptr, nullptr, nullptr,
256                          nullptr);
257 }
258 
RunTransactionTestAndGetTiming(HttpCache * cache,const MockTransaction & trans_info,const NetLogWithSource & log,LoadTimingInfo * load_timing_info)259 void RunTransactionTestAndGetTiming(HttpCache* cache,
260                                     const MockTransaction& trans_info,
261                                     const NetLogWithSource& log,
262                                     LoadTimingInfo* load_timing_info) {
263   RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
264                          nullptr, log, load_timing_info, nullptr, nullptr,
265                          nullptr);
266 }
267 
RunTransactionTestAndGetTimingAndConnectedSocketAddress(HttpCache * cache,const MockTransaction & trans_info,const NetLogWithSource & log,LoadTimingInfo * load_timing_info,IPEndPoint * remote_endpoint)268 void RunTransactionTestAndGetTimingAndConnectedSocketAddress(
269     HttpCache* cache,
270     const MockTransaction& trans_info,
271     const NetLogWithSource& log,
272     LoadTimingInfo* load_timing_info,
273     IPEndPoint* remote_endpoint) {
274   RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
275                          nullptr, log, load_timing_info, nullptr, nullptr,
276                          remote_endpoint);
277 }
278 
RunTransactionTest(HttpCache * cache,const MockTransaction & trans_info)279 void RunTransactionTest(HttpCache* cache, const MockTransaction& trans_info) {
280   RunTransactionTestAndGetTiming(cache, trans_info, NetLogWithSource(),
281                                  nullptr);
282 }
283 
RunTransactionTestWithLog(HttpCache * cache,const MockTransaction & trans_info,const NetLogWithSource & log)284 void RunTransactionTestWithLog(HttpCache* cache,
285                                const MockTransaction& trans_info,
286                                const NetLogWithSource& log) {
287   RunTransactionTestAndGetTiming(cache, trans_info, log, nullptr);
288 }
289 
RunTransactionTestWithResponseInfo(HttpCache * cache,const MockTransaction & trans_info,HttpResponseInfo * response)290 void RunTransactionTestWithResponseInfo(HttpCache* cache,
291                                         const MockTransaction& trans_info,
292                                         HttpResponseInfo* response) {
293   RunTransactionTestWithRequest(cache, trans_info, MockHttpRequest(trans_info),
294                                 response);
295 }
296 
RunTransactionTestWithResponseInfoAndGetTiming(HttpCache * cache,const MockTransaction & trans_info,HttpResponseInfo * response,const NetLogWithSource & log,LoadTimingInfo * load_timing_info)297 void RunTransactionTestWithResponseInfoAndGetTiming(
298     HttpCache* cache,
299     const MockTransaction& trans_info,
300     HttpResponseInfo* response,
301     const NetLogWithSource& log,
302     LoadTimingInfo* load_timing_info) {
303   RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
304                          response, log, load_timing_info, nullptr, nullptr,
305                          nullptr);
306 }
307 
RunTransactionTestWithResponse(HttpCache * cache,const MockTransaction & trans_info,std::string * response_headers)308 void RunTransactionTestWithResponse(HttpCache* cache,
309                                     const MockTransaction& trans_info,
310                                     std::string* response_headers) {
311   HttpResponseInfo response;
312   RunTransactionTestWithResponseInfo(cache, trans_info, &response);
313   *response_headers = ToSimpleString(response.headers);
314 }
315 
RunTransactionTestWithResponseAndGetTiming(HttpCache * cache,const MockTransaction & trans_info,std::string * response_headers,const NetLogWithSource & log,LoadTimingInfo * load_timing_info)316 void RunTransactionTestWithResponseAndGetTiming(
317     HttpCache* cache,
318     const MockTransaction& trans_info,
319     std::string* response_headers,
320     const NetLogWithSource& log,
321     LoadTimingInfo* load_timing_info) {
322   HttpResponseInfo response;
323   RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
324                          &response, log, load_timing_info, nullptr, nullptr,
325                          nullptr);
326   *response_headers = ToSimpleString(response.headers);
327 }
328 
329 // This class provides a handler for kFastNoStoreGET_Transaction so that the
330 // no-store header can be included on demand.
331 class FastTransactionServer {
332  public:
FastTransactionServer()333   FastTransactionServer() {
334     no_store = false;
335   }
336 
337   FastTransactionServer(const FastTransactionServer&) = delete;
338   FastTransactionServer& operator=(const FastTransactionServer&) = delete;
339 
340   ~FastTransactionServer() = default;
341 
set_no_store(bool value)342   void set_no_store(bool value) { no_store = value; }
343 
FastNoStoreHandler(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)344   static void FastNoStoreHandler(const HttpRequestInfo* request,
345                                  std::string* response_status,
346                                  std::string* response_headers,
347                                  std::string* response_data) {
348     if (no_store)
349       *response_headers = "Cache-Control: no-store\n";
350   }
351 
352  private:
353   static bool no_store;
354 };
355 bool FastTransactionServer::no_store;
356 
357 const MockTransaction kFastNoStoreGET_Transaction = {
358     "http://www.google.com/nostore",
359     "GET",
360     base::Time(),
361     "",
362     LOAD_VALIDATE_CACHE,
363     DefaultTransportInfo(),
364     "HTTP/1.1 200 OK",
365     "Cache-Control: max-age=10000\n",
366     base::Time(),
367     "<html><body>Google Blah Blah</body></html>",
368     {},
369     absl::nullopt,
370     absl::nullopt,
371     TEST_MODE_SYNC_NET_START,
372     base::BindRepeating(&FastTransactionServer::FastNoStoreHandler),
373     MockTransactionReadHandler(),
374     nullptr,
375     0,
376     0,
377     OK,
378 };
379 
380 // This class provides a handler for kRangeGET_TransactionOK so that the range
381 // request can be served on demand.
382 class RangeTransactionServer {
383  public:
RangeTransactionServer()384   RangeTransactionServer() {
385     not_modified_ = false;
386     modified_ = false;
387     bad_200_ = false;
388     redirect_ = false;
389     length_ = 80;
390   }
391 
392   RangeTransactionServer(const RangeTransactionServer&) = delete;
393   RangeTransactionServer& operator=(const RangeTransactionServer&) = delete;
394 
~RangeTransactionServer()395   ~RangeTransactionServer() {
396     not_modified_ = false;
397     modified_ = false;
398     bad_200_ = false;
399     redirect_ = false;
400     length_ = 80;
401   }
402 
403   // Returns only 416 or 304 when set.
set_not_modified(bool value)404   void set_not_modified(bool value) { not_modified_ = value; }
405 
406   // Returns 206 when revalidating a range (instead of 304).
set_modified(bool value)407   void set_modified(bool value) { modified_ = value; }
408 
409   // Returns 200 instead of 206 (a malformed response overall).
set_bad_200(bool value)410   void set_bad_200(bool value) { bad_200_ = value; }
411 
412   // Sets how long the resource is. (Default is 80)
set_length(int64_t length)413   void set_length(int64_t length) { length_ = length; }
414 
415   // Sets whether to return a 301 instead of normal return.
set_redirect(bool redirect)416   void set_redirect(bool redirect) { redirect_ = redirect; }
417 
418   // Other than regular range related behavior (and the flags mentioned above),
419   // the server reacts to requests headers like so:
420   //   X-Require-Mock-Auth -> return 401.
421   //   X-Require-Mock-Auth-Alt -> return 401.
422   //   X-Return-Default-Range -> assume 40-49 was requested.
423   // The -Alt variant doesn't cause the MockNetworkTransaction to
424   // report that it IsReadyToRestartForAuth().
425   static void RangeHandler(const HttpRequestInfo* request,
426                            std::string* response_status,
427                            std::string* response_headers,
428                            std::string* response_data);
429 
430  private:
431   static bool not_modified_;
432   static bool modified_;
433   static bool bad_200_;
434   static bool redirect_;
435   static int64_t length_;
436 };
437 bool RangeTransactionServer::not_modified_ = false;
438 bool RangeTransactionServer::modified_ = false;
439 bool RangeTransactionServer::bad_200_ = false;
440 bool RangeTransactionServer::redirect_ = false;
441 int64_t RangeTransactionServer::length_ = 80;
442 
443 // A dummy extra header that must be preserved on a given request.
444 
445 // EXTRA_HEADER_LINE doesn't include a line terminator because it
446 // will be passed to AddHeaderFromString() which doesn't accept them.
447 #define EXTRA_HEADER_LINE "Extra: header"
448 
449 // EXTRA_HEADER contains a line terminator, as expected by
450 // AddHeadersFromString() (_not_ AddHeaderFromString()).
451 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
452 
453 static const char kExtraHeaderKey[] = "Extra";
454 
455 // Static.
RangeHandler(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)456 void RangeTransactionServer::RangeHandler(const HttpRequestInfo* request,
457                                           std::string* response_status,
458                                           std::string* response_headers,
459                                           std::string* response_data) {
460   if (request->extra_headers.IsEmpty()) {
461     response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
462     response_data->clear();
463     return;
464   }
465 
466   // We want to make sure we don't delete extra headers.
467   EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
468 
469   bool require_auth =
470       request->extra_headers.HasHeader("X-Require-Mock-Auth") ||
471       request->extra_headers.HasHeader("X-Require-Mock-Auth-Alt");
472 
473   if (require_auth && !request->extra_headers.HasHeader("Authorization")) {
474     response_status->assign("HTTP/1.1 401 Unauthorized");
475     response_data->assign("WWW-Authenticate: Foo\n");
476     return;
477   }
478 
479   if (redirect_) {
480     response_status->assign("HTTP/1.1 301 Moved Permanently");
481     response_headers->assign("Location: /elsewhere\nContent-Length: 5");
482     response_data->assign("12345");
483     return;
484   }
485 
486   if (not_modified_) {
487     response_status->assign("HTTP/1.1 304 Not Modified");
488     response_data->clear();
489     return;
490   }
491 
492   std::vector<HttpByteRange> ranges;
493   std::string range_header;
494   if (!request->extra_headers.GetHeader(HttpRequestHeaders::kRange,
495                                         &range_header) ||
496       !HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ ||
497       ranges.size() != 1 ||
498       (modified_ && request->extra_headers.HasHeader("If-Range"))) {
499     // This is not a byte range request, or a failed If-Range. We return 200.
500     response_status->assign("HTTP/1.1 200 OK");
501     response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
502     response_data->assign("Not a range");
503     return;
504   }
505 
506   // We can handle this range request.
507   HttpByteRange byte_range = ranges[0];
508 
509   if (request->extra_headers.HasHeader("X-Return-Default-Range")) {
510     byte_range.set_first_byte_position(40);
511     byte_range.set_last_byte_position(49);
512   }
513 
514   if (byte_range.first_byte_position() >= length_) {
515     response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
516     response_data->clear();
517     return;
518   }
519 
520   EXPECT_TRUE(byte_range.ComputeBounds(length_));
521   int64_t start = byte_range.first_byte_position();
522   int64_t end = byte_range.last_byte_position();
523 
524   EXPECT_LT(end, length_);
525 
526   std::string content_range = base::StringPrintf("Content-Range: bytes %" PRId64
527                                                  "-%" PRId64 "/%" PRId64 "\n",
528                                                  start, end, length_);
529   response_headers->append(content_range);
530 
531   if (!request->extra_headers.HasHeader("If-None-Match") || modified_) {
532     std::string data;
533     if (end == start) {
534       EXPECT_EQ(0, end % 10);
535       data = "r";
536     } else {
537       EXPECT_EQ(9, (end - start) % 10);
538       for (int64_t block_start = start; block_start < end; block_start += 10) {
539         base::StringAppendF(&data, "rg: %02" PRId64 "-%02" PRId64 " ",
540                             block_start % 100, (block_start + 9) % 100);
541       }
542     }
543     *response_data = data;
544 
545     if (end - start != 9) {
546       // We also have to fix content-length.
547       int64_t len = end - start + 1;
548       std::string content_length =
549           base::StringPrintf("Content-Length: %" PRId64 "\n", len);
550       response_headers->replace(response_headers->find("Content-Length:"),
551                                 content_length.size(), content_length);
552     }
553   } else {
554     response_status->assign("HTTP/1.1 304 Not Modified");
555     response_data->clear();
556   }
557 }
558 
559 const MockTransaction kRangeGET_TransactionOK = {
560     "http://www.google.com/range",
561     "GET",
562     base::Time(),
563     "Range: bytes = 40-49\r\n" EXTRA_HEADER,
564     LOAD_NORMAL,
565     DefaultTransportInfo(),
566     "HTTP/1.1 206 Partial Content",
567     "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
568     "ETag: \"foo\"\n"
569     "Accept-Ranges: bytes\n"
570     "Content-Length: 10\n",
571     base::Time(),
572     "rg: 40-49 ",
573     {},
574     absl::nullopt,
575     absl::nullopt,
576     TEST_MODE_NORMAL,
577     base::BindRepeating(&RangeTransactionServer::RangeHandler),
578     MockTransactionReadHandler(),
579     nullptr,
580     0,
581     0,
582     OK,
583 };
584 
585 const char kFullRangeData[] =
586     "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 "
587     "rg: 40-49 rg: 50-59 rg: 60-69 rg: 70-79 ";
588 
589 // Verifies the response headers (|response|) match a partial content
590 // response for the range starting at |start| and ending at |end|.
Verify206Response(const std::string & response,int start,int end)591 void Verify206Response(const std::string& response, int start, int end) {
592   auto headers = base::MakeRefCounted<HttpResponseHeaders>(
593       HttpUtil::AssembleRawHeaders(response));
594 
595   ASSERT_EQ(206, headers->response_code());
596 
597   int64_t range_start, range_end, object_size;
598   ASSERT_TRUE(
599       headers->GetContentRangeFor206(&range_start, &range_end, &object_size));
600   int64_t content_length = headers->GetContentLength();
601 
602   int length = end - start + 1;
603   ASSERT_EQ(length, content_length);
604   ASSERT_EQ(start, range_start);
605   ASSERT_EQ(end, range_end);
606 }
607 
608 // Creates a truncated entry that can be resumed using byte ranges.
CreateTruncatedEntry(std::string raw_headers,MockHttpCache * cache)609 void CreateTruncatedEntry(std::string raw_headers, MockHttpCache* cache) {
610   // Create a disk cache entry that stores an incomplete resource.
611   disk_cache::Entry* entry;
612   MockHttpRequest request(kRangeGET_TransactionOK);
613   ASSERT_TRUE(cache->CreateBackendEntry(request.CacheKey(), &entry, nullptr));
614 
615   HttpResponseInfo response;
616   response.response_time = base::Time::Now();
617   response.request_time = base::Time::Now();
618   response.headers = base::MakeRefCounted<HttpResponseHeaders>(
619       HttpUtil::AssembleRawHeaders(raw_headers));
620   // Set the last argument for this to be an incomplete request.
621   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
622 
623   auto buf = base::MakeRefCounted<IOBufferWithSize>(100);
624   int len = static_cast<int>(base::strlcpy(buf->data(),
625                                            "rg: 00-09 rg: 10-19 ", 100));
626   TestCompletionCallback cb;
627   int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
628   EXPECT_EQ(len, cb.GetResult(rv));
629   entry->Close();
630 }
631 
632 // Verifies that there's an entry with this |key| with the truncated flag set to
633 // |flag_value|, and with an optional |data_size| (if not zero).
VerifyTruncatedFlag(MockHttpCache * cache,const std::string & key,bool flag_value,int data_size)634 void VerifyTruncatedFlag(MockHttpCache* cache,
635                          const std::string& key,
636                          bool flag_value,
637                          int data_size) {
638   disk_cache::Entry* entry;
639   ASSERT_TRUE(cache->OpenBackendEntry(key, &entry));
640   disk_cache::ScopedEntryPtr closer(entry);
641 
642   HttpResponseInfo response;
643   bool truncated = !flag_value;
644   EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
645   EXPECT_EQ(flag_value, truncated);
646   if (data_size)
647     EXPECT_EQ(data_size, entry->GetDataSize(1));
648 }
649 
650 // Helper to represent a network HTTP response.
651 struct Response {
652   // Set this response into |trans|.
AssignTonet::__anond56f448a0111::Response653   void AssignTo(MockTransaction* trans) const {
654     trans->status = status;
655     trans->response_headers = headers;
656     trans->data = body;
657   }
658 
status_and_headersnet::__anond56f448a0111::Response659   std::string status_and_headers() const {
660     return std::string(status) + "\n" + std::string(headers);
661   }
662 
663   const char* status;
664   const char* headers;
665   const char* body;
666 };
667 
668 struct Context {
669   Context() = default;
670 
671   int result = ERR_IO_PENDING;
672   TestCompletionCallback callback;
673   std::unique_ptr<HttpTransaction> trans;
674 };
675 
676 class FakeWebSocketHandshakeStreamCreateHelper
677     : public WebSocketHandshakeStreamBase::CreateHelper {
678  public:
679   ~FakeWebSocketHandshakeStreamCreateHelper() override = default;
CreateBasicStream(std::unique_ptr<ClientSocketHandle> connect,bool using_proxy,WebSocketEndpointLockManager * websocket_endpoint_lock_manager)680   std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
681       std::unique_ptr<ClientSocketHandle> connect,
682       bool using_proxy,
683       WebSocketEndpointLockManager* websocket_endpoint_lock_manager) override {
684     return nullptr;
685   }
CreateHttp2Stream(base::WeakPtr<SpdySession> session,std::set<std::string> dns_aliases)686   std::unique_ptr<WebSocketHandshakeStreamBase> CreateHttp2Stream(
687       base::WeakPtr<SpdySession> session,
688       std::set<std::string> dns_aliases) override {
689     NOTREACHED();
690     return nullptr;
691   }
CreateHttp3Stream(std::unique_ptr<QuicChromiumClientSession::Handle> session,std::set<std::string> dns_aliases)692   std::unique_ptr<WebSocketHandshakeStreamBase> CreateHttp3Stream(
693       std::unique_ptr<QuicChromiumClientSession::Handle> session,
694       std::set<std::string> dns_aliases) override {
695     NOTREACHED();
696     return nullptr;
697   }
698 };
699 
700 // Returns true if |entry| is not one of the log types paid attention to in this
701 // test. Note that HTTP_CACHE_WRITE_INFO and HTTP_CACHE_*_DATA are
702 // ignored.
ShouldIgnoreLogEntry(const NetLogEntry & entry)703 bool ShouldIgnoreLogEntry(const NetLogEntry& entry) {
704   switch (entry.type) {
705     case NetLogEventType::HTTP_CACHE_GET_BACKEND:
706     case NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY:
707     case NetLogEventType::HTTP_CACHE_OPEN_ENTRY:
708     case NetLogEventType::HTTP_CACHE_CREATE_ENTRY:
709     case NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY:
710     case NetLogEventType::HTTP_CACHE_DOOM_ENTRY:
711     case NetLogEventType::HTTP_CACHE_READ_INFO:
712       return false;
713     default:
714       return true;
715   }
716 }
717 
718 // Gets the entries from |net_log| created by the cache layer and asserted on in
719 // these tests.
GetFilteredNetLogEntries(const RecordingNetLogObserver & net_log_observer)720 std::vector<NetLogEntry> GetFilteredNetLogEntries(
721     const RecordingNetLogObserver& net_log_observer) {
722   auto entries = net_log_observer.GetEntries();
723   base::EraseIf(entries, ShouldIgnoreLogEntry);
724   return entries;
725 }
726 
LogContainsEventType(const RecordingNetLogObserver & net_log_observer,NetLogEventType expected)727 bool LogContainsEventType(const RecordingNetLogObserver& net_log_observer,
728                           NetLogEventType expected) {
729   return !net_log_observer.GetEntriesWithType(expected).empty();
730 }
731 
732 // Returns a TransportInfo distinct from the default for mock transactions,
733 // with the given port number.
TestTransportInfoWithPort(uint16_t port)734 TransportInfo TestTransportInfoWithPort(uint16_t port) {
735   TransportInfo result;
736   result.endpoint = IPEndPoint(IPAddress(42, 0, 1, 2), port);
737   return result;
738 }
739 
740 // Returns a TransportInfo distinct from the default for mock transactions.
TestTransportInfo()741 TransportInfo TestTransportInfo() {
742   return TestTransportInfoWithPort(1337);
743 }
744 
CachedTestTransportInfo()745 TransportInfo CachedTestTransportInfo() {
746   TransportInfo result = TestTransportInfo();
747   result.type = TransportType::kCached;
748   return result;
749 }
750 
751 // Helper function, generating valid HTTP cache key from `url`.
752 // See also: HttpCache::GenerateCacheKey(..)
GenerateCacheKey(const std::string & url)753 std::string GenerateCacheKey(const std::string& url) {
754   return "1/0/" + url;
755 }
756 
757 }  // namespace
758 
759 using HttpCacheTest = TestWithTaskEnvironment;
760 
761 class HttpCacheIOCallbackTest : public HttpCacheTest {
762  public:
763   HttpCacheIOCallbackTest() = default;
764   ~HttpCacheIOCallbackTest() override = default;
765 
766   // HttpCache::ActiveEntry is private, doing this allows tests to use it
767   using ActiveEntry = HttpCache::ActiveEntry;
768   using Transaction = HttpCache::Transaction;
769 
770   // The below functions are forwarding calls to the HttpCache class.
OpenEntry(HttpCache * cache,const std::string & url,HttpCache::ActiveEntry ** entry,HttpCache::Transaction * trans)771   int OpenEntry(HttpCache* cache,
772                 const std::string& url,
773                 HttpCache::ActiveEntry** entry,
774                 HttpCache::Transaction* trans) {
775     return cache->OpenEntry(GenerateCacheKey(url), entry, trans);
776   }
777 
OpenOrCreateEntry(HttpCache * cache,const std::string & url,HttpCache::ActiveEntry ** entry,HttpCache::Transaction * trans)778   int OpenOrCreateEntry(HttpCache* cache,
779                         const std::string& url,
780                         HttpCache::ActiveEntry** entry,
781                         HttpCache::Transaction* trans) {
782     return cache->OpenOrCreateEntry(GenerateCacheKey(url), entry, trans);
783   }
784 
CreateEntry(HttpCache * cache,const std::string & url,HttpCache::ActiveEntry ** entry,HttpCache::Transaction * trans)785   int CreateEntry(HttpCache* cache,
786                   const std::string& url,
787                   HttpCache::ActiveEntry** entry,
788                   HttpCache::Transaction* trans) {
789     return cache->CreateEntry(GenerateCacheKey(url), entry, trans);
790   }
791 
DoomEntry(HttpCache * cache,const std::string & url,HttpCache::Transaction * trans)792   int DoomEntry(HttpCache* cache,
793                 const std::string& url,
794                 HttpCache::Transaction* trans) {
795     return cache->DoomEntry(GenerateCacheKey(url), trans);
796   }
797 
DeactivateEntry(HttpCache * cache,ActiveEntry * entry)798   void DeactivateEntry(HttpCache* cache, ActiveEntry* entry) {
799     cache->DeactivateEntry(entry);
800   }
801 };
802 
803 class HttpSplitCacheKeyTest : public HttpCacheTest {
804  public:
805   HttpSplitCacheKeyTest() = default;
806   ~HttpSplitCacheKeyTest() override = default;
807 
ComputeCacheKey(const std::string & url_string)808   std::string ComputeCacheKey(const std::string& url_string) {
809     GURL url(url_string);
810     SchemefulSite site(url);
811     net::HttpRequestInfo request_info;
812     request_info.url = url;
813     request_info.method = "GET";
814     request_info.network_isolation_key = net::NetworkIsolationKey(site, site);
815     request_info.network_anonymization_key =
816         net::NetworkAnonymizationKey::CreateSameSite(site);
817     MockHttpCache cache;
818     return *cache.http_cache()->GenerateCacheKeyForRequest(&request_info);
819   }
820 };
821 
822 //-----------------------------------------------------------------------------
823 // Tests.
824 
TEST_F(HttpCacheTest,CreateThenDestroy)825 TEST_F(HttpCacheTest, CreateThenDestroy) {
826   MockHttpCache cache;
827 
828   std::unique_ptr<HttpTransaction> trans;
829   EXPECT_THAT(cache.CreateTransaction(&trans), IsOk());
830   ASSERT_TRUE(trans.get());
831 }
832 
TEST_F(HttpCacheTest,GetBackend)833 TEST_F(HttpCacheTest, GetBackend) {
834   MockHttpCache cache(HttpCache::DefaultBackend::InMemory(0));
835 
836   disk_cache::Backend* backend;
837   TestCompletionCallback cb;
838   // This will lazily initialize the backend.
839   int rv = cache.http_cache()->GetBackend(&backend, cb.callback());
840   EXPECT_THAT(cb.GetResult(rv), IsOk());
841 }
842 
TEST_F(HttpCacheTest,SimpleGET)843 TEST_F(HttpCacheTest, SimpleGET) {
844   MockHttpCache cache;
845   LoadTimingInfo load_timing_info;
846 
847   // Write to the cache.
848   RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
849                                  NetLogWithSource::Make(NetLogSourceType::NONE),
850                                  &load_timing_info);
851 
852   EXPECT_EQ(1, cache.network_layer()->transaction_count());
853   EXPECT_EQ(0, cache.disk_cache()->open_count());
854   EXPECT_EQ(1, cache.disk_cache()->create_count());
855   TestLoadTimingNetworkRequest(load_timing_info);
856 }
857 
858 // This test verifies that the callback passed to SetConnectedCallback() is
859 // called once for simple GET calls that traverse the cache.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallback)860 TEST_F(HttpCacheTest, SimpleGET_ConnectedCallback) {
861   MockHttpCache cache;
862 
863   ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
864   mock_transaction.transport_info = TestTransportInfo();
865   MockHttpRequest request(mock_transaction);
866 
867   ConnectedHandler connected_handler;
868 
869   std::unique_ptr<HttpTransaction> transaction;
870   EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
871   ASSERT_THAT(transaction, NotNull());
872 
873   transaction->SetConnectedCallback(connected_handler.Callback());
874 
875   TestCompletionCallback callback;
876   ASSERT_THAT(
877       transaction->Start(&request, callback.callback(), NetLogWithSource()),
878       IsError(ERR_IO_PENDING));
879   EXPECT_THAT(callback.WaitForResult(), IsOk());
880 
881   EXPECT_THAT(connected_handler.transports(), ElementsAre(TestTransportInfo()));
882 }
883 
884 // This test verifies that when the callback passed to SetConnectedCallback()
885 // returns an error, the transaction fails with that error.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackReturnError)886 TEST_F(HttpCacheTest, SimpleGET_ConnectedCallbackReturnError) {
887   MockHttpCache cache;
888   MockHttpRequest request(kSimpleGET_Transaction);
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   // The exact error code does not matter. We only care that it is passed to
896   // the transaction's completion callback unmodified.
897   connected_handler.set_result(ERR_NOT_IMPLEMENTED);
898   transaction->SetConnectedCallback(connected_handler.Callback());
899 
900   TestCompletionCallback callback;
901   ASSERT_THAT(
902       transaction->Start(&request, callback.callback(), NetLogWithSource()),
903       IsError(ERR_IO_PENDING));
904   EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NOT_IMPLEMENTED));
905 }
906 
907 // This test verifies that the callback passed to SetConnectedCallback() is
908 // called once for requests that hit the cache.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackOnCacheHit)909 TEST_F(HttpCacheTest, SimpleGET_ConnectedCallbackOnCacheHit) {
910   MockHttpCache cache;
911 
912   {
913     // Populate the cache.
914     ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
915     mock_transaction.transport_info = TestTransportInfo();
916     RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
917   }
918 
919   // Establish a baseline.
920   EXPECT_EQ(1, cache.network_layer()->transaction_count());
921 
922   // Load from the cache (only), observe the callback being called.
923 
924   ConnectedHandler connected_handler;
925   MockHttpRequest request(kSimpleGET_Transaction);
926 
927   std::unique_ptr<HttpTransaction> transaction;
928   EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
929   ASSERT_THAT(transaction, NotNull());
930 
931   transaction->SetConnectedCallback(connected_handler.Callback());
932 
933   TestCompletionCallback callback;
934   ASSERT_THAT(
935       transaction->Start(&request, callback.callback(), NetLogWithSource()),
936       IsError(ERR_IO_PENDING));
937   EXPECT_THAT(callback.WaitForResult(), IsOk());
938 
939   // Still only 1 transaction for the previous request. The connected callback
940   // was not called by a second network transaction.
941   EXPECT_EQ(1, cache.network_layer()->transaction_count());
942 
943   EXPECT_THAT(connected_handler.transports(),
944               ElementsAre(CachedTestTransportInfo()));
945 }
946 
947 // This test verifies that when the callback passed to SetConnectedCallback()
948 // is called for a request that hit the cache and returns an error, the cache
949 // entry is reusable.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackOnCacheHitReturnError)950 TEST_F(HttpCacheTest, SimpleGET_ConnectedCallbackOnCacheHitReturnError) {
951   MockHttpCache cache;
952 
953   {
954     // Populate the cache.
955     ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
956     mock_transaction.transport_info = TestTransportInfo();
957     RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
958   }
959 
960   MockHttpRequest request(kSimpleGET_Transaction);
961 
962   {
963     // Attempt to read from cache entry, but abort transaction due to a
964     // connected callback error.
965     ConnectedHandler connected_handler;
966     connected_handler.set_result(ERR_FAILED);
967 
968     std::unique_ptr<HttpTransaction> transaction;
969     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
970     ASSERT_THAT(transaction, NotNull());
971 
972     transaction->SetConnectedCallback(connected_handler.Callback());
973 
974     TestCompletionCallback callback;
975     ASSERT_THAT(
976         transaction->Start(&request, callback.callback(), NetLogWithSource()),
977         IsError(ERR_IO_PENDING));
978     EXPECT_THAT(callback.WaitForResult(), IsError(ERR_FAILED));
979 
980     // Used the cache entry only.
981     EXPECT_THAT(connected_handler.transports(),
982                 ElementsAre(CachedTestTransportInfo()));
983   }
984 
985   {
986     // Request the same resource once more, observe that it is read from cache.
987     ConnectedHandler connected_handler;
988 
989     std::unique_ptr<HttpTransaction> transaction;
990     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
991     ASSERT_THAT(transaction, NotNull());
992 
993     transaction->SetConnectedCallback(connected_handler.Callback());
994 
995     TestCompletionCallback callback;
996     ASSERT_THAT(
997         transaction->Start(&request, callback.callback(), NetLogWithSource()),
998         IsError(ERR_IO_PENDING));
999     EXPECT_THAT(callback.WaitForResult(), IsOk());
1000 
1001     // Used the cache entry only.
1002     EXPECT_THAT(connected_handler.transports(),
1003                 ElementsAre(CachedTestTransportInfo()));
1004   }
1005 }
1006 
1007 // This test verifies that when the callback passed to SetConnectedCallback()
1008 // returns `ERR_INCONSISTENT_IP_ADDRESS_SPACE`, the cache entry is invalidated.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackOnCacheHitReturnInconsistentIpError)1009 TEST_F(HttpCacheTest,
1010        SimpleGET_ConnectedCallbackOnCacheHitReturnInconsistentIpError) {
1011   MockHttpCache cache;
1012 
1013   ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
1014   mock_transaction.transport_info = TestTransportInfo();
1015 
1016   // Populate the cache.
1017   RunTransactionTest(cache.http_cache(), mock_transaction);
1018 
1019   MockHttpRequest request(kSimpleGET_Transaction);
1020 
1021   {
1022     // Attempt to read from cache entry, but abort transaction due to a
1023     // connected callback error.
1024     ConnectedHandler connected_handler;
1025     connected_handler.set_result(ERR_INCONSISTENT_IP_ADDRESS_SPACE);
1026 
1027     std::unique_ptr<HttpTransaction> transaction;
1028     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
1029     ASSERT_THAT(transaction, NotNull());
1030 
1031     transaction->SetConnectedCallback(connected_handler.Callback());
1032 
1033     TestCompletionCallback callback;
1034     ASSERT_THAT(
1035         transaction->Start(&request, callback.callback(), NetLogWithSource()),
1036         IsError(ERR_IO_PENDING));
1037     EXPECT_THAT(callback.WaitForResult(),
1038                 IsError(ERR_INCONSISTENT_IP_ADDRESS_SPACE));
1039 
1040     // Used the cache entry only.
1041     EXPECT_THAT(connected_handler.transports(),
1042                 ElementsAre(CachedTestTransportInfo()));
1043   }
1044 
1045   {
1046     // Request the same resource once more, observe that it is not read from
1047     // cache.
1048     ConnectedHandler connected_handler;
1049 
1050     std::unique_ptr<HttpTransaction> transaction;
1051     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
1052     ASSERT_THAT(transaction, NotNull());
1053 
1054     transaction->SetConnectedCallback(connected_handler.Callback());
1055 
1056     TestCompletionCallback callback;
1057     ASSERT_THAT(
1058         transaction->Start(&request, callback.callback(), NetLogWithSource()),
1059         IsError(ERR_IO_PENDING));
1060     EXPECT_THAT(callback.WaitForResult(), IsOk());
1061 
1062     // Used the network only.
1063     EXPECT_THAT(connected_handler.transports(),
1064                 ElementsAre(TestTransportInfo()));
1065   }
1066 }
1067 
1068 // This test verifies that when the callback passed to SetConnectedCallback()
1069 // returns
1070 // `ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_PRIVATE_NETWORK_ACCESS_POLICY`, the
1071 // cache entry is invalidated, and we'll retry the connection from the network.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackOnCacheHitReturnPrivateNetworkAccessBlockedError)1072 TEST_F(
1073     HttpCacheTest,
1074     SimpleGET_ConnectedCallbackOnCacheHitReturnPrivateNetworkAccessBlockedError) {
1075   MockHttpCache cache;
1076 
1077   ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
1078   mock_transaction.transport_info = TestTransportInfo();
1079 
1080   // Populate the cache.
1081   RunTransactionTest(cache.http_cache(), mock_transaction);
1082 
1083   MockHttpRequest request(kSimpleGET_Transaction);
1084 
1085   {
1086     // Attempt to read from cache entry, but abort transaction due to a
1087     // connected callback error.
1088     ConnectedHandler connected_handler;
1089     connected_handler.set_result(
1090         ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_PRIVATE_NETWORK_ACCESS_POLICY);
1091 
1092     std::unique_ptr<HttpTransaction> transaction;
1093     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
1094     ASSERT_THAT(transaction, NotNull());
1095 
1096     transaction->SetConnectedCallback(connected_handler.Callback());
1097 
1098     TestCompletionCallback callback;
1099     ASSERT_THAT(
1100         transaction->Start(&request, callback.callback(), NetLogWithSource()),
1101         IsError(ERR_IO_PENDING));
1102     EXPECT_THAT(
1103         callback.WaitForResult(),
1104         IsError(
1105             ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_PRIVATE_NETWORK_ACCESS_POLICY));
1106 
1107     // Used the cache entry only.
1108     EXPECT_THAT(connected_handler.transports(),
1109                 ElementsAre(CachedTestTransportInfo(), TestTransportInfo()));
1110   }
1111 
1112   {
1113     // Request the same resource once more, observe that it is not read from
1114     // cache.
1115     ConnectedHandler connected_handler;
1116 
1117     std::unique_ptr<HttpTransaction> transaction;
1118     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
1119     ASSERT_THAT(transaction, NotNull());
1120 
1121     transaction->SetConnectedCallback(connected_handler.Callback());
1122 
1123     TestCompletionCallback callback;
1124     ASSERT_THAT(
1125         transaction->Start(&request, callback.callback(), NetLogWithSource()),
1126         IsError(ERR_IO_PENDING));
1127     EXPECT_THAT(callback.WaitForResult(), IsOk());
1128 
1129     // Used the network only.
1130     EXPECT_THAT(connected_handler.transports(),
1131                 ElementsAre(TestTransportInfo()));
1132   }
1133 }
1134 
1135 // This test verifies that the callback passed to SetConnectedCallback() is
1136 // called with the right transport type when the cached entry was originally
1137 // fetched via proxy.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackOnCacheHitFromProxy)1138 TEST_F(HttpCacheTest, SimpleGET_ConnectedCallbackOnCacheHitFromProxy) {
1139   MockHttpCache cache;
1140 
1141   TransportInfo proxied_transport_info = TestTransportInfo();
1142   proxied_transport_info.type = TransportType::kProxied;
1143 
1144   {
1145     // Populate the cache.
1146     ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
1147     mock_transaction.transport_info = proxied_transport_info;
1148     RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1149   }
1150 
1151   // Establish a baseline.
1152   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1153 
1154   // Load from the cache (only), observe the callback being called.
1155 
1156   ConnectedHandler connected_handler;
1157   MockHttpRequest request(kSimpleGET_Transaction);
1158 
1159   std::unique_ptr<HttpTransaction> transaction;
1160   EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
1161   ASSERT_THAT(transaction, NotNull());
1162 
1163   transaction->SetConnectedCallback(connected_handler.Callback());
1164 
1165   TestCompletionCallback callback;
1166   ASSERT_THAT(
1167       transaction->Start(&request, callback.callback(), NetLogWithSource()),
1168       IsError(ERR_IO_PENDING));
1169   EXPECT_THAT(callback.WaitForResult(), IsOk());
1170 
1171   // Still only 1 transaction for the previous request. The connected callback
1172   // was not called by a second network transaction.
1173   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1174 
1175   // The transport info mentions both the cache and the original proxy.
1176   TransportInfo expected_transport_info = TestTransportInfo();
1177   expected_transport_info.type = TransportType::kCachedFromProxy;
1178 
1179   EXPECT_THAT(connected_handler.transports(),
1180               ElementsAre(expected_transport_info));
1181 }
1182 
TEST_F(HttpCacheTest,SimpleGET_DelayedCacheLock)1183 TEST_F(HttpCacheTest, SimpleGET_DelayedCacheLock) {
1184   MockHttpCache cache;
1185   LoadTimingInfo load_timing_info;
1186 
1187   // Configure the cache to delay the response for AddTransactionToEntry so it
1188   // gets sequenced behind any other tasks that get generated when starting the
1189   // transaction (i.e. network activity when run in parallel with the cache
1190   // lock).
1191   cache.http_cache()->DelayAddTransactionToEntryForTesting();
1192 
1193   // Write to the cache.
1194   RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
1195                                  NetLogWithSource::Make(NetLogSourceType::NONE),
1196                                  &load_timing_info);
1197 
1198   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1199   EXPECT_EQ(0, cache.disk_cache()->open_count());
1200   EXPECT_EQ(1, cache.disk_cache()->create_count());
1201   TestLoadTimingNetworkRequest(load_timing_info);
1202 }
1203 
1204 enum class SplitCacheTestCase {
1205   kSplitCacheDisabled,
1206   kSplitCacheNikFrameSiteEnabled,
1207   kSplitCacheNikCrossSiteFlagEnabled,
1208   kSplitCacheNikFrameSiteSharedOpaqueEnabled,
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 
1232   if (test_case ==
1233       SplitCacheTestCase::kSplitCacheNikFrameSiteSharedOpaqueEnabled) {
1234     enabled_features.push_back(
1235         net::features::kEnableFrameSiteSharedOpaqueNetworkIsolationKey);
1236   } else {
1237     disabled_features.push_back(
1238         net::features::kEnableFrameSiteSharedOpaqueNetworkIsolationKey);
1239   }
1240   scoped_feature_list.InitWithFeatures(enabled_features, disabled_features);
1241 }
1242 
1243 class HttpCacheTest_SplitCacheFeature
1244     : public HttpCacheTest,
1245       public ::testing::WithParamInterface<SplitCacheTestCase> {
1246  public:
HttpCacheTest_SplitCacheFeature()1247   HttpCacheTest_SplitCacheFeature() {
1248     InitializeSplitCacheScopedFeatureList(feature_list_, GetParam());
1249   }
1250 
IsSplitCacheEnabled() const1251   bool IsSplitCacheEnabled() const {
1252     return GetParam() != SplitCacheTestCase::kSplitCacheDisabled;
1253   }
1254 
1255  private:
1256   base::test::ScopedFeatureList feature_list_;
1257 };
1258 
TEST_P(HttpCacheTest_SplitCacheFeature,SimpleGETVerifyGoogleFontMetrics)1259 TEST_P(HttpCacheTest_SplitCacheFeature, SimpleGETVerifyGoogleFontMetrics) {
1260   SchemefulSite site_a(GURL("http://www.a.com"));
1261 
1262   MockHttpCache cache;
1263 
1264   MockTransaction transaction(kSimpleGET_Transaction);
1265   transaction.url = "http://themes.googleusercontent.com/static/fonts/roboto";
1266   AddMockTransaction(&transaction);
1267   MockHttpRequest request(transaction);
1268   request.network_isolation_key = NetworkIsolationKey(site_a, site_a);
1269   request.network_anonymization_key =
1270       net::NetworkAnonymizationKey::CreateSameSite(site_a);
1271 
1272   // Attempt to populate the cache.
1273   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
1274                                 nullptr);
1275 
1276   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
1277                                 nullptr);
1278 }
1279 
1280 INSTANTIATE_TEST_SUITE_P(
1281     All,
1282     HttpCacheTest_SplitCacheFeature,
1283     testing::ValuesIn(
1284         {SplitCacheTestCase::kSplitCacheDisabled,
1285          SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled,
1286          SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled,
1287          SplitCacheTestCase::kSplitCacheNikFrameSiteSharedOpaqueEnabled}),
__anond56f448a0202(const testing::TestParamInfo<SplitCacheTestCase>& info) 1288     [](const testing::TestParamInfo<SplitCacheTestCase>& info) {
1289       switch (info.param) {
1290         case (SplitCacheTestCase::kSplitCacheDisabled):
1291           return "SplitCacheDisabled";
1292         case (SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled):
1293           return "SplitCacheNikFrameSiteEnabled";
1294         case (SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled):
1295           return "SplitCacheNikCrossSiteFlagEnabled";
1296         case (SplitCacheTestCase::kSplitCacheNikFrameSiteSharedOpaqueEnabled):
1297           return "SplitCacheNikFrameSiteSharedOpaqueEnabled";
1298       }
1299     });
1300 
1301 class HttpCacheTest_SplitCacheFeatureEnabled
1302     : public HttpCacheTest_SplitCacheFeature {
1303  public:
HttpCacheTest_SplitCacheFeatureEnabled()1304   HttpCacheTest_SplitCacheFeatureEnabled() {
1305     CHECK(base::FeatureList::IsEnabled(
1306         net::features::kSplitCacheByNetworkIsolationKey));
1307   }
1308 };
1309 
1310 INSTANTIATE_TEST_SUITE_P(
1311     All,
1312     HttpCacheTest_SplitCacheFeatureEnabled,
1313     testing::ValuesIn(
1314         {SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled,
1315          SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled,
1316          SplitCacheTestCase::kSplitCacheNikFrameSiteSharedOpaqueEnabled}),
__anond56f448a0302(const testing::TestParamInfo<SplitCacheTestCase>& info) 1317     [](const testing::TestParamInfo<SplitCacheTestCase>& info) {
1318       switch (info.param) {
1319         case (SplitCacheTestCase::kSplitCacheDisabled):
1320           return "NotUsedForThisTestSuite";
1321         case (SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled):
1322           return "SplitCacheNikFrameSiteEnabled";
1323         case (SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled):
1324           return "SplitCacheNikCrossSiteFlagEnabled";
1325         case (SplitCacheTestCase::kSplitCacheNikFrameSiteSharedOpaqueEnabled):
1326           return "SplitCacheNikFrameSiteSharedOpaqueEnabled";
1327       }
1328     });
1329 
TEST_F(HttpCacheTest,SimpleGETNoDiskCache)1330 TEST_F(HttpCacheTest, SimpleGETNoDiskCache) {
1331   MockHttpCache cache;
1332 
1333   cache.disk_cache()->set_fail_requests(true);
1334 
1335   RecordingNetLogObserver net_log_observer;
1336   LoadTimingInfo load_timing_info;
1337 
1338   // Read from the network, and don't use the cache.
1339   RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
1340                                  NetLogWithSource::Make(NetLogSourceType::NONE),
1341                                  &load_timing_info);
1342 
1343   // Check that the NetLog was filled as expected.
1344   // (We attempted to OpenOrCreate entries, but fail).
1345   auto entries = GetFilteredNetLogEntries(net_log_observer);
1346 
1347   EXPECT_EQ(4u, entries.size());
1348   EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
1349                                     NetLogEventType::HTTP_CACHE_GET_BACKEND));
1350   EXPECT_TRUE(
1351       LogContainsEndEvent(entries, 1, NetLogEventType::HTTP_CACHE_GET_BACKEND));
1352   EXPECT_TRUE(LogContainsBeginEvent(
1353       entries, 2, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1354   EXPECT_TRUE(LogContainsEndEvent(
1355       entries, 3, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1356 
1357   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1358   EXPECT_EQ(0, cache.disk_cache()->open_count());
1359   EXPECT_EQ(0, cache.disk_cache()->create_count());
1360   TestLoadTimingNetworkRequest(load_timing_info);
1361 }
1362 
TEST_F(HttpCacheTest,SimpleGETNoDiskCache2)1363 TEST_F(HttpCacheTest, SimpleGETNoDiskCache2) {
1364   // This will initialize a cache object with NULL backend.
1365   auto factory = std::make_unique<MockBlockingBackendFactory>();
1366   factory->set_fail(true);
1367   factory->FinishCreation();  // We'll complete synchronously.
1368   MockHttpCache cache(std::move(factory));
1369 
1370   // Read from the network, and don't use the cache.
1371   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1372 
1373   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1374   EXPECT_FALSE(cache.http_cache()->GetCurrentBackend());
1375 }
1376 
1377 // Tests that IOBuffers are not referenced after IO completes.
TEST_F(HttpCacheTest,ReleaseBuffer)1378 TEST_F(HttpCacheTest, ReleaseBuffer) {
1379   MockHttpCache cache;
1380 
1381   // Write to the cache.
1382   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1383 
1384   MockHttpRequest request(kSimpleGET_Transaction);
1385   std::unique_ptr<HttpTransaction> trans;
1386   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
1387 
1388   const int kBufferSize = 10;
1389   auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
1390   ReleaseBufferCompletionCallback cb(buffer.get());
1391 
1392   int rv = trans->Start(&request, cb.callback(), NetLogWithSource());
1393   EXPECT_THAT(cb.GetResult(rv), IsOk());
1394 
1395   rv = trans->Read(buffer.get(), kBufferSize, cb.callback());
1396   EXPECT_EQ(kBufferSize, cb.GetResult(rv));
1397 }
1398 
TEST_F(HttpCacheTest,SimpleGETWithDiskFailures)1399 TEST_F(HttpCacheTest, SimpleGETWithDiskFailures) {
1400   MockHttpCache cache;
1401 
1402   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_ALL);
1403 
1404   // Read from the network, and fail to write to the cache.
1405   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1406 
1407   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1408   EXPECT_EQ(0, cache.disk_cache()->open_count());
1409   EXPECT_EQ(1, cache.disk_cache()->create_count());
1410 
1411   // This one should see an empty cache again.
1412   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1413 
1414   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1415   EXPECT_EQ(0, cache.disk_cache()->open_count());
1416   EXPECT_EQ(2, cache.disk_cache()->create_count());
1417 }
1418 
1419 // Tests that disk failures after the transaction has started don't cause the
1420 // request to fail.
TEST_F(HttpCacheTest,SimpleGETWithDiskFailures2)1421 TEST_F(HttpCacheTest, SimpleGETWithDiskFailures2) {
1422   MockHttpCache cache;
1423 
1424   MockHttpRequest request(kSimpleGET_Transaction);
1425 
1426   auto c = std::make_unique<Context>();
1427   int rv = cache.CreateTransaction(&c->trans);
1428   ASSERT_THAT(rv, IsOk());
1429 
1430   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1431   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1432   rv = c->callback.WaitForResult();
1433 
1434   // Start failing request now.
1435   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_ALL);
1436 
1437   // We have to open the entry again to propagate the failure flag.
1438   disk_cache::Entry* en;
1439   ASSERT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &en));
1440   en->Close();
1441 
1442   ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1443   c.reset();
1444 
1445   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1446   EXPECT_EQ(1, cache.disk_cache()->open_count());
1447   EXPECT_EQ(1, cache.disk_cache()->create_count());
1448 
1449   // This one should see an empty cache again.
1450   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1451 
1452   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1453   EXPECT_EQ(1, cache.disk_cache()->open_count());
1454   EXPECT_EQ(2, cache.disk_cache()->create_count());
1455 }
1456 
1457 // Tests that we handle failures to read from the cache.
TEST_F(HttpCacheTest,SimpleGETWithDiskFailures3)1458 TEST_F(HttpCacheTest, SimpleGETWithDiskFailures3) {
1459   MockHttpCache cache;
1460 
1461   // Read from the network, and write to the cache.
1462   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1463 
1464   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1465   EXPECT_EQ(0, cache.disk_cache()->open_count());
1466   EXPECT_EQ(1, cache.disk_cache()->create_count());
1467 
1468   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_ALL);
1469 
1470   MockHttpRequest request(kSimpleGET_Transaction);
1471 
1472   // Now fail to read from the cache.
1473   auto c = std::make_unique<Context>();
1474   int rv = cache.CreateTransaction(&c->trans);
1475   ASSERT_THAT(rv, IsOk());
1476 
1477   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1478   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
1479 
1480   // Now verify that the entry was removed from the cache.
1481   cache.disk_cache()->set_soft_failures_mask(0);
1482 
1483   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1484   EXPECT_EQ(1, cache.disk_cache()->open_count());
1485   EXPECT_EQ(2, cache.disk_cache()->create_count());
1486 
1487   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1488 
1489   EXPECT_EQ(3, cache.network_layer()->transaction_count());
1490   EXPECT_EQ(1, cache.disk_cache()->open_count());
1491   EXPECT_EQ(3, cache.disk_cache()->create_count());
1492 }
1493 
TEST_F(HttpCacheTest,SimpleGET_LoadOnlyFromCache_Hit)1494 TEST_F(HttpCacheTest, SimpleGET_LoadOnlyFromCache_Hit) {
1495   MockHttpCache cache;
1496 
1497   RecordingNetLogObserver net_log_observer;
1498   NetLogWithSource net_log_with_source =
1499       NetLogWithSource::Make(NetLogSourceType::NONE);
1500   LoadTimingInfo load_timing_info;
1501 
1502   // Write to the cache.
1503   RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
1504                                  net_log_with_source, &load_timing_info);
1505 
1506   // Check that the NetLog was filled as expected.
1507   auto entries = GetFilteredNetLogEntries(net_log_observer);
1508 
1509   EXPECT_EQ(6u, entries.size());
1510   EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
1511                                     NetLogEventType::HTTP_CACHE_GET_BACKEND));
1512   EXPECT_TRUE(
1513       LogContainsEndEvent(entries, 1, NetLogEventType::HTTP_CACHE_GET_BACKEND));
1514   EXPECT_TRUE(LogContainsBeginEvent(
1515       entries, 2, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1516   EXPECT_TRUE(LogContainsEndEvent(
1517       entries, 3, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1518   EXPECT_TRUE(LogContainsBeginEvent(entries, 4,
1519                                     NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1520   EXPECT_TRUE(LogContainsEndEvent(entries, 5,
1521                                   NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1522 
1523   TestLoadTimingNetworkRequest(load_timing_info);
1524 
1525   // Force this transaction to read from the cache.
1526   MockTransaction transaction(kSimpleGET_Transaction);
1527   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
1528 
1529   net_log_observer.Clear();
1530 
1531   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
1532                                  net_log_with_source, &load_timing_info);
1533 
1534   // Check that the NetLog was filled as expected.
1535   entries = GetFilteredNetLogEntries(net_log_observer);
1536 
1537   EXPECT_EQ(8u, entries.size());
1538   EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
1539                                     NetLogEventType::HTTP_CACHE_GET_BACKEND));
1540   EXPECT_TRUE(
1541       LogContainsEndEvent(entries, 1, NetLogEventType::HTTP_CACHE_GET_BACKEND));
1542   EXPECT_TRUE(LogContainsBeginEvent(
1543       entries, 2, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1544   EXPECT_TRUE(LogContainsEndEvent(
1545       entries, 3, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1546   EXPECT_TRUE(LogContainsBeginEvent(entries, 4,
1547                                     NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1548   EXPECT_TRUE(LogContainsEndEvent(entries, 5,
1549                                   NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1550   EXPECT_TRUE(
1551       LogContainsBeginEvent(entries, 6, NetLogEventType::HTTP_CACHE_READ_INFO));
1552   EXPECT_TRUE(
1553       LogContainsEndEvent(entries, 7, NetLogEventType::HTTP_CACHE_READ_INFO));
1554 
1555   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1556   EXPECT_EQ(1, cache.disk_cache()->open_count());
1557   EXPECT_EQ(1, cache.disk_cache()->create_count());
1558   TestLoadTimingCachedResponse(load_timing_info);
1559 }
1560 
TEST_F(HttpCacheTest,SimpleGET_LoadOnlyFromCache_Miss)1561 TEST_F(HttpCacheTest, SimpleGET_LoadOnlyFromCache_Miss) {
1562   MockHttpCache cache;
1563 
1564   // force this transaction to read from the cache
1565   MockTransaction transaction(kSimpleGET_Transaction);
1566   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
1567 
1568   MockHttpRequest request(transaction);
1569   TestCompletionCallback callback;
1570 
1571   std::unique_ptr<HttpTransaction> trans;
1572   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
1573 
1574   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
1575   if (rv == ERR_IO_PENDING)
1576     rv = callback.WaitForResult();
1577   ASSERT_THAT(rv, IsError(ERR_CACHE_MISS));
1578 
1579   trans.reset();
1580 
1581   EXPECT_EQ(0, cache.network_layer()->transaction_count());
1582   EXPECT_EQ(0, cache.disk_cache()->open_count());
1583   EXPECT_EQ(0, cache.disk_cache()->create_count());
1584 }
1585 
TEST_F(HttpCacheTest,SimpleGET_LoadPreferringCache_Hit)1586 TEST_F(HttpCacheTest, SimpleGET_LoadPreferringCache_Hit) {
1587   MockHttpCache cache;
1588 
1589   // write to the cache
1590   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1591 
1592   // force this transaction to read from the cache if valid
1593   MockTransaction transaction(kSimpleGET_Transaction);
1594   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
1595 
1596   RunTransactionTest(cache.http_cache(), transaction);
1597 
1598   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1599   EXPECT_EQ(1, cache.disk_cache()->open_count());
1600   EXPECT_EQ(1, cache.disk_cache()->create_count());
1601 }
1602 
TEST_F(HttpCacheTest,SimpleGET_LoadPreferringCache_Miss)1603 TEST_F(HttpCacheTest, SimpleGET_LoadPreferringCache_Miss) {
1604   MockHttpCache cache;
1605 
1606   // force this transaction to read from the cache if valid
1607   MockTransaction transaction(kSimpleGET_Transaction);
1608   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
1609 
1610   RunTransactionTest(cache.http_cache(), transaction);
1611 
1612   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1613   EXPECT_EQ(0, cache.disk_cache()->open_count());
1614   EXPECT_EQ(1, cache.disk_cache()->create_count());
1615 }
1616 
1617 // Tests LOAD_SKIP_CACHE_VALIDATION in the presence of vary headers.
TEST_F(HttpCacheTest,SimpleGET_LoadPreferringCache_VaryMatch)1618 TEST_F(HttpCacheTest, SimpleGET_LoadPreferringCache_VaryMatch) {
1619   MockHttpCache cache;
1620 
1621   // Write to the cache.
1622   MockTransaction transaction(kSimpleGET_Transaction);
1623   transaction.request_headers = "Foo: bar\r\n";
1624   transaction.response_headers = "Cache-Control: max-age=10000\n"
1625                                  "Vary: Foo\n";
1626   AddMockTransaction(&transaction);
1627   RunTransactionTest(cache.http_cache(), transaction);
1628 
1629   // Read from the cache.
1630   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
1631   RunTransactionTest(cache.http_cache(), transaction);
1632 
1633   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1634   EXPECT_EQ(1, cache.disk_cache()->open_count());
1635   EXPECT_EQ(1, cache.disk_cache()->create_count());
1636   RemoveMockTransaction(&transaction);
1637 }
1638 
1639 // Tests LOAD_SKIP_CACHE_VALIDATION in the presence of vary headers.
TEST_F(HttpCacheTest,SimpleGET_LoadPreferringCache_VaryMismatch)1640 TEST_F(HttpCacheTest, SimpleGET_LoadPreferringCache_VaryMismatch) {
1641   MockHttpCache cache;
1642 
1643   // Write to the cache.
1644   MockTransaction transaction(kSimpleGET_Transaction);
1645   transaction.request_headers = "Foo: bar\r\n";
1646   transaction.response_headers = "Cache-Control: max-age=10000\n"
1647                                  "Vary: Foo\n";
1648   AddMockTransaction(&transaction);
1649   RunTransactionTest(cache.http_cache(), transaction);
1650 
1651   // Attempt to read from the cache... this is a vary mismatch that must reach
1652   // the network again.
1653   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
1654   transaction.request_headers = "Foo: none\r\n";
1655   LoadTimingInfo load_timing_info;
1656   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
1657                                  NetLogWithSource::Make(NetLogSourceType::NONE),
1658                                  &load_timing_info);
1659 
1660   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1661   EXPECT_EQ(1, cache.disk_cache()->open_count());
1662   EXPECT_EQ(1, cache.disk_cache()->create_count());
1663   TestLoadTimingNetworkRequest(load_timing_info);
1664   RemoveMockTransaction(&transaction);
1665 }
1666 
1667 // Tests that we honor Vary: * with LOAD_SKIP_CACHE_VALIDATION (crbug/778681)
TEST_F(HttpCacheTest,SimpleGET_LoadSkipCacheValidation_VaryStar)1668 TEST_F(HttpCacheTest, SimpleGET_LoadSkipCacheValidation_VaryStar) {
1669   MockHttpCache cache;
1670 
1671   // Write to the cache.
1672   MockTransaction transaction(kSimpleGET_Transaction);
1673   transaction.response_headers =
1674       "Cache-Control: max-age=10000\n"
1675       "Vary: *\n";
1676   AddMockTransaction(&transaction);
1677   RunTransactionTest(cache.http_cache(), transaction);
1678 
1679   // Attempt to read from the cache... we will still load it from network,
1680   // since Vary: * doesn't match.
1681   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
1682   LoadTimingInfo load_timing_info;
1683   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
1684                                  NetLogWithSource::Make(NetLogSourceType::NONE),
1685                                  &load_timing_info);
1686 
1687   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1688   EXPECT_EQ(1, cache.disk_cache()->open_count());
1689   EXPECT_EQ(1, cache.disk_cache()->create_count());
1690   RemoveMockTransaction(&transaction);
1691 }
1692 
1693 // Tests that was_cached was set properly on a failure, even if the cached
1694 // response wasn't returned.
TEST_F(HttpCacheTest,SimpleGET_CacheSignal_Failure)1695 TEST_F(HttpCacheTest, SimpleGET_CacheSignal_Failure) {
1696   for (bool use_memory_entry_data : {false, true}) {
1697     MockHttpCache cache;
1698     cache.disk_cache()->set_support_in_memory_entry_data(use_memory_entry_data);
1699 
1700     // Prime cache.
1701     MockTransaction transaction(kSimpleGET_Transaction);
1702     transaction.response_headers = "Cache-Control: no-cache\n";
1703 
1704     AddMockTransaction(&transaction);
1705     RunTransactionTest(cache.http_cache(), transaction);
1706     EXPECT_EQ(1, cache.network_layer()->transaction_count());
1707     EXPECT_EQ(1, cache.disk_cache()->create_count());
1708     EXPECT_EQ(0, cache.disk_cache()->open_count());
1709     RemoveMockTransaction(&transaction);
1710 
1711     // Network failure with error; should fail but have was_cached set.
1712     transaction.start_return_code = ERR_FAILED;
1713     AddMockTransaction(&transaction);
1714 
1715     MockHttpRequest request(transaction);
1716     TestCompletionCallback callback;
1717     std::unique_ptr<HttpTransaction> trans;
1718     int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
1719     EXPECT_THAT(rv, IsOk());
1720     ASSERT_TRUE(trans.get());
1721     rv = trans->Start(&request, callback.callback(), NetLogWithSource());
1722     EXPECT_THAT(callback.GetResult(rv), IsError(ERR_FAILED));
1723 
1724     const HttpResponseInfo* response_info = trans->GetResponseInfo();
1725     ASSERT_TRUE(response_info);
1726     // If use_memory_entry_data is true, we will not bother opening the entry,
1727     // and just kick it out, so was_cached will end up false.
1728     EXPECT_EQ(2, cache.network_layer()->transaction_count());
1729     if (use_memory_entry_data) {
1730       EXPECT_EQ(false, response_info->was_cached);
1731       EXPECT_EQ(2, cache.disk_cache()->create_count());
1732       EXPECT_EQ(0, cache.disk_cache()->open_count());
1733     } else {
1734       EXPECT_EQ(true, response_info->was_cached);
1735       EXPECT_EQ(1, cache.disk_cache()->create_count());
1736       EXPECT_EQ(1, cache.disk_cache()->open_count());
1737     }
1738 
1739     RemoveMockTransaction(&transaction);
1740   }
1741 }
1742 
1743 // Tests that if the transaction is destroyed right after setting the
1744 // cache_entry_status_ as CANT_CONDITIONALIZE, then RecordHistograms should not
1745 // hit a dcheck.
TEST_F(HttpCacheTest,RecordHistogramsCantConditionalize)1746 TEST_F(HttpCacheTest, RecordHistogramsCantConditionalize) {
1747   MockHttpCache cache;
1748   cache.disk_cache()->set_support_in_memory_entry_data(true);
1749 
1750   {
1751     // Prime cache.
1752     ScopedMockTransaction transaction(kSimpleGET_Transaction);
1753     transaction.response_headers = "Cache-Control: no-cache\n";
1754     RunTransactionTest(cache.http_cache(), transaction);
1755     EXPECT_EQ(1, cache.network_layer()->transaction_count());
1756     EXPECT_EQ(1, cache.disk_cache()->create_count());
1757     EXPECT_EQ(0, cache.disk_cache()->open_count());
1758   }
1759 
1760   {
1761     ScopedMockTransaction transaction(kSimpleGET_Transaction);
1762     MockHttpRequest request(transaction);
1763     TestCompletionCallback callback;
1764     std::unique_ptr<HttpTransaction> trans;
1765     int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
1766     EXPECT_THAT(rv, IsOk());
1767     ASSERT_TRUE(trans.get());
1768     rv = trans->Start(&request, callback.callback(), NetLogWithSource());
1769     // Now destroy the transaction so that RecordHistograms gets invoked.
1770     trans.reset();
1771   }
1772 }
1773 
1774 // Confirm if we have an empty cache, a read is marked as network verified.
TEST_F(HttpCacheTest,SimpleGET_NetworkAccessed_Network)1775 TEST_F(HttpCacheTest, SimpleGET_NetworkAccessed_Network) {
1776   MockHttpCache cache;
1777 
1778   // write to the cache
1779   HttpResponseInfo response_info;
1780   RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
1781                                      &response_info);
1782 
1783   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1784   EXPECT_EQ(0, cache.disk_cache()->open_count());
1785   EXPECT_EQ(1, cache.disk_cache()->create_count());
1786   EXPECT_TRUE(response_info.network_accessed);
1787   EXPECT_EQ(CacheEntryStatus::ENTRY_NOT_IN_CACHE,
1788             response_info.cache_entry_status);
1789 }
1790 
1791 // Confirm if we have a fresh entry in cache, it isn't marked as
1792 // network verified.
TEST_F(HttpCacheTest,SimpleGET_NetworkAccessed_Cache)1793 TEST_F(HttpCacheTest, SimpleGET_NetworkAccessed_Cache) {
1794   MockHttpCache cache;
1795 
1796   // Prime cache.
1797   MockTransaction transaction(kSimpleGET_Transaction);
1798 
1799   RunTransactionTest(cache.http_cache(), transaction);
1800   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1801   EXPECT_EQ(1, cache.disk_cache()->create_count());
1802 
1803   // Re-run transaction; make sure we don't mark the network as accessed.
1804   HttpResponseInfo response_info;
1805   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1806                                      &response_info);
1807 
1808   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1809   EXPECT_FALSE(response_info.network_accessed);
1810   EXPECT_EQ(CacheEntryStatus::ENTRY_USED, response_info.cache_entry_status);
1811 }
1812 
TEST_F(HttpCacheTest,SimpleGET_LoadBypassCache)1813 TEST_F(HttpCacheTest, SimpleGET_LoadBypassCache) {
1814   MockHttpCache cache;
1815 
1816   // Write to the cache.
1817   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1818 
1819   // Force this transaction to write to the cache again.
1820   MockTransaction transaction(kSimpleGET_Transaction);
1821   transaction.load_flags |= LOAD_BYPASS_CACHE;
1822 
1823   RecordingNetLogObserver net_log_observer;
1824   LoadTimingInfo load_timing_info;
1825 
1826   // Write to the cache.
1827   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
1828                                  NetLogWithSource::Make(NetLogSourceType::NONE),
1829                                  &load_timing_info);
1830 
1831   // Check that the NetLog was filled as expected.
1832   auto entries = GetFilteredNetLogEntries(net_log_observer);
1833 
1834   EXPECT_EQ(8u, entries.size());
1835   EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
1836                                     NetLogEventType::HTTP_CACHE_GET_BACKEND));
1837   EXPECT_TRUE(
1838       LogContainsEndEvent(entries, 1, NetLogEventType::HTTP_CACHE_GET_BACKEND));
1839   EXPECT_TRUE(LogContainsBeginEvent(entries, 2,
1840                                     NetLogEventType::HTTP_CACHE_DOOM_ENTRY));
1841   EXPECT_TRUE(
1842       LogContainsEndEvent(entries, 3, NetLogEventType::HTTP_CACHE_DOOM_ENTRY));
1843   EXPECT_TRUE(LogContainsBeginEvent(entries, 4,
1844                                     NetLogEventType::HTTP_CACHE_CREATE_ENTRY));
1845   EXPECT_TRUE(LogContainsEndEvent(entries, 5,
1846                                   NetLogEventType::HTTP_CACHE_CREATE_ENTRY));
1847   EXPECT_TRUE(LogContainsBeginEvent(entries, 6,
1848                                     NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1849   EXPECT_TRUE(LogContainsEndEvent(entries, 7,
1850                                   NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1851 
1852   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1853   EXPECT_EQ(0, cache.disk_cache()->open_count());
1854   EXPECT_EQ(2, cache.disk_cache()->create_count());
1855   TestLoadTimingNetworkRequest(load_timing_info);
1856 }
1857 
TEST_F(HttpCacheTest,SimpleGET_LoadBypassCache_Implicit)1858 TEST_F(HttpCacheTest, SimpleGET_LoadBypassCache_Implicit) {
1859   MockHttpCache cache;
1860 
1861   // write to the cache
1862   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1863 
1864   // force this transaction to write to the cache again
1865   MockTransaction transaction(kSimpleGET_Transaction);
1866   transaction.request_headers = "pragma: no-cache\r\n";
1867 
1868   RunTransactionTest(cache.http_cache(), transaction);
1869 
1870   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1871   EXPECT_EQ(0, cache.disk_cache()->open_count());
1872   EXPECT_EQ(2, cache.disk_cache()->create_count());
1873 }
1874 
TEST_F(HttpCacheTest,SimpleGET_LoadBypassCache_Implicit2)1875 TEST_F(HttpCacheTest, SimpleGET_LoadBypassCache_Implicit2) {
1876   MockHttpCache cache;
1877 
1878   // write to the cache
1879   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1880 
1881   // force this transaction to write to the cache again
1882   MockTransaction transaction(kSimpleGET_Transaction);
1883   transaction.request_headers = "cache-control: no-cache\r\n";
1884 
1885   RunTransactionTest(cache.http_cache(), transaction);
1886 
1887   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1888   EXPECT_EQ(0, cache.disk_cache()->open_count());
1889   EXPECT_EQ(2, cache.disk_cache()->create_count());
1890 }
1891 
TEST_F(HttpCacheTest,SimpleGET_LoadValidateCache)1892 TEST_F(HttpCacheTest, SimpleGET_LoadValidateCache) {
1893   MockHttpCache cache;
1894 
1895   // Write to the cache.
1896   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1897 
1898   // Read from the cache.
1899   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1900 
1901   // Force this transaction to validate the cache.
1902   MockTransaction transaction(kSimpleGET_Transaction);
1903   transaction.load_flags |= LOAD_VALIDATE_CACHE;
1904 
1905   HttpResponseInfo response_info;
1906   LoadTimingInfo load_timing_info;
1907   RunTransactionTestWithResponseInfoAndGetTiming(
1908       cache.http_cache(), transaction, &response_info,
1909       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info);
1910 
1911   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1912   EXPECT_EQ(1, cache.disk_cache()->open_count());
1913   EXPECT_EQ(1, cache.disk_cache()->create_count());
1914   EXPECT_TRUE(response_info.network_accessed);
1915   TestLoadTimingNetworkRequest(load_timing_info);
1916 }
1917 
TEST_F(HttpCacheTest,SimpleGET_LoadValidateCache_Implicit)1918 TEST_F(HttpCacheTest, SimpleGET_LoadValidateCache_Implicit) {
1919   MockHttpCache cache;
1920 
1921   // write to the cache
1922   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1923 
1924   // read from the cache
1925   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1926 
1927   // force this transaction to validate the cache
1928   MockTransaction transaction(kSimpleGET_Transaction);
1929   transaction.request_headers = "cache-control: max-age=0\r\n";
1930 
1931   RunTransactionTest(cache.http_cache(), transaction);
1932 
1933   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1934   EXPECT_EQ(1, cache.disk_cache()->open_count());
1935   EXPECT_EQ(1, cache.disk_cache()->create_count());
1936 }
1937 
1938 // Tests that |unused_since_prefetch| is updated accordingly (e.g. it is set to
1939 // true after a prefetch and set back to false when the prefetch is used).
TEST_F(HttpCacheTest,SimpleGET_UnusedSincePrefetch)1940 TEST_F(HttpCacheTest, SimpleGET_UnusedSincePrefetch) {
1941   MockHttpCache cache;
1942   HttpResponseInfo response_info;
1943 
1944   // A normal load does not have |unused_since_prefetch| set.
1945   RunTransactionTestWithResponseInfoAndGetTiming(
1946       cache.http_cache(), kSimpleGET_Transaction, &response_info,
1947       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1948   EXPECT_FALSE(response_info.unused_since_prefetch);
1949   EXPECT_FALSE(response_info.was_cached);
1950 
1951   // The prefetch itself does not have |unused_since_prefetch| set.
1952   MockTransaction prefetch_transaction(kSimpleGET_Transaction);
1953   prefetch_transaction.load_flags |= LOAD_PREFETCH;
1954   RunTransactionTestWithResponseInfoAndGetTiming(
1955       cache.http_cache(), prefetch_transaction, &response_info,
1956       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1957   EXPECT_FALSE(response_info.unused_since_prefetch);
1958   EXPECT_TRUE(response_info.was_cached);
1959 
1960   // A duplicated prefetch has |unused_since_prefetch| set.
1961   RunTransactionTestWithResponseInfoAndGetTiming(
1962       cache.http_cache(), prefetch_transaction, &response_info,
1963       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1964   EXPECT_TRUE(response_info.unused_since_prefetch);
1965   EXPECT_TRUE(response_info.was_cached);
1966 
1967   // |unused_since_prefetch| is still true after two prefetches in a row.
1968   RunTransactionTestWithResponseInfoAndGetTiming(
1969       cache.http_cache(), kSimpleGET_Transaction, &response_info,
1970       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1971   EXPECT_TRUE(response_info.unused_since_prefetch);
1972   EXPECT_TRUE(response_info.was_cached);
1973 
1974   // The resource has now been used, back to normal behavior.
1975   RunTransactionTestWithResponseInfoAndGetTiming(
1976       cache.http_cache(), kSimpleGET_Transaction, &response_info,
1977       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1978   EXPECT_FALSE(response_info.unused_since_prefetch);
1979   EXPECT_TRUE(response_info.was_cached);
1980 }
1981 
1982 // Tests that requests made with the LOAD_RESTRICTED_PREFETCH load flag result
1983 // in HttpResponseInfo entries with the |restricted_prefetch| flag set. Also
1984 // tests that responses with |restricted_prefetch| flag set can only be used by
1985 // requests that have the LOAD_CAN_USE_RESTRICTED_PREFETCH load flag.
TEST_F(HttpCacheTest,SimpleGET_RestrictedPrefetchIsRestrictedUntilReuse)1986 TEST_F(HttpCacheTest, SimpleGET_RestrictedPrefetchIsRestrictedUntilReuse) {
1987   MockHttpCache cache;
1988   HttpResponseInfo response_info;
1989 
1990   // A normal load does not have |restricted_prefetch| set.
1991   RunTransactionTestWithResponseInfoAndGetTiming(
1992       cache.http_cache(), kTypicalGET_Transaction, &response_info,
1993       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1994   EXPECT_FALSE(response_info.restricted_prefetch);
1995   EXPECT_FALSE(response_info.was_cached);
1996   EXPECT_TRUE(response_info.network_accessed);
1997 
1998   // A restricted prefetch is marked as |restricted_prefetch|.
1999   MockTransaction prefetch_transaction(kSimpleGET_Transaction);
2000   prefetch_transaction.load_flags |= LOAD_PREFETCH;
2001   prefetch_transaction.load_flags |= LOAD_RESTRICTED_PREFETCH;
2002   RunTransactionTestWithResponseInfoAndGetTiming(
2003       cache.http_cache(), prefetch_transaction, &response_info,
2004       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2005   EXPECT_TRUE(response_info.restricted_prefetch);
2006   EXPECT_FALSE(response_info.was_cached);
2007   EXPECT_TRUE(response_info.network_accessed);
2008 
2009   // Requests that are marked as able to reuse restricted prefetches can do so
2010   // correctly. Once it is reused, it is no longer considered as or marked
2011   // restricted.
2012   MockTransaction can_use_restricted_prefetch_transaction(
2013       kSimpleGET_Transaction);
2014   can_use_restricted_prefetch_transaction.load_flags |=
2015       LOAD_CAN_USE_RESTRICTED_PREFETCH;
2016   RunTransactionTestWithResponseInfoAndGetTiming(
2017       cache.http_cache(), can_use_restricted_prefetch_transaction,
2018       &response_info, NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2019   EXPECT_TRUE(response_info.restricted_prefetch);
2020   EXPECT_TRUE(response_info.was_cached);
2021   EXPECT_FALSE(response_info.network_accessed);
2022 
2023   // Later reuse is still no longer marked restricted.
2024   RunTransactionTestWithResponseInfoAndGetTiming(
2025       cache.http_cache(), kSimpleGET_Transaction, &response_info,
2026       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2027   EXPECT_FALSE(response_info.restricted_prefetch);
2028   EXPECT_TRUE(response_info.was_cached);
2029   EXPECT_FALSE(response_info.network_accessed);
2030 }
2031 
TEST_F(HttpCacheTest,SimpleGET_RestrictedPrefetchReuseIsLimited)2032 TEST_F(HttpCacheTest, SimpleGET_RestrictedPrefetchReuseIsLimited) {
2033   MockHttpCache cache;
2034   HttpResponseInfo response_info;
2035 
2036   // A restricted prefetch is marked as |restricted_prefetch|.
2037   MockTransaction prefetch_transaction(kSimpleGET_Transaction);
2038   prefetch_transaction.load_flags |= LOAD_PREFETCH;
2039   prefetch_transaction.load_flags |= LOAD_RESTRICTED_PREFETCH;
2040   RunTransactionTestWithResponseInfoAndGetTiming(
2041       cache.http_cache(), prefetch_transaction, &response_info,
2042       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2043   EXPECT_TRUE(response_info.restricted_prefetch);
2044   EXPECT_FALSE(response_info.was_cached);
2045   EXPECT_TRUE(response_info.network_accessed);
2046 
2047   // Requests that cannot reuse restricted prefetches fail to do so. The network
2048   // is accessed and the resulting response is not marked as
2049   // |restricted_prefetch|.
2050   RunTransactionTestWithResponseInfoAndGetTiming(
2051       cache.http_cache(), kSimpleGET_Transaction, &response_info,
2052       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2053   EXPECT_FALSE(response_info.restricted_prefetch);
2054   EXPECT_FALSE(response_info.was_cached);
2055   EXPECT_TRUE(response_info.network_accessed);
2056 
2057   // Future requests that are not marked as able to reuse restricted prefetches
2058   // can use the entry in the cache now, since it has been evicted in favor of
2059   // an unrestricted one.
2060   RunTransactionTestWithResponseInfoAndGetTiming(
2061       cache.http_cache(), kSimpleGET_Transaction, &response_info,
2062       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2063   EXPECT_FALSE(response_info.restricted_prefetch);
2064   EXPECT_TRUE(response_info.was_cached);
2065   EXPECT_FALSE(response_info.network_accessed);
2066 }
2067 
TEST_F(HttpCacheTest,SimpleGET_UnusedSincePrefetchWriteError)2068 TEST_F(HttpCacheTest, SimpleGET_UnusedSincePrefetchWriteError) {
2069   MockHttpCache cache;
2070   HttpResponseInfo response_info;
2071 
2072   // Do a prefetch.
2073   MockTransaction prefetch_transaction(kSimpleGET_Transaction);
2074   prefetch_transaction.load_flags |= LOAD_PREFETCH;
2075   RunTransactionTestWithResponseInfoAndGetTiming(
2076       cache.http_cache(), prefetch_transaction, &response_info,
2077       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2078   EXPECT_TRUE(response_info.unused_since_prefetch);
2079   EXPECT_FALSE(response_info.was_cached);
2080 
2081   // Try to use it while injecting a failure on write.
2082   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_WRITE);
2083   RunTransactionTestWithResponseInfoAndGetTiming(
2084       cache.http_cache(), kSimpleGET_Transaction, &response_info,
2085       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2086 }
2087 
2088 // Make sure that if a prefetch entry is truncated, then an attempt to re-use it
2089 // gets aborted in connected handler that truncated bit is not lost.
TEST_F(HttpCacheTest,PrefetchTruncateCancelInConnectedCallback)2090 TEST_F(HttpCacheTest, PrefetchTruncateCancelInConnectedCallback) {
2091   MockHttpCache cache;
2092 
2093   ScopedMockTransaction transaction(kSimpleGET_Transaction);
2094   transaction.response_headers =
2095       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2096       "Content-Length: 20\n"
2097       "Etag: \"foopy\"\n";
2098   transaction.data = "01234567890123456789";
2099   transaction.load_flags |= LOAD_PREFETCH | LOAD_CAN_USE_RESTRICTED_PREFETCH;
2100 
2101   // Do a truncated read of a prefetch request.
2102   {
2103     MockHttpRequest request(transaction);
2104     Context c;
2105 
2106     int rv = cache.CreateTransaction(&c.trans);
2107     ASSERT_THAT(rv, IsOk());
2108 
2109     rv = c.callback.GetResult(
2110         c.trans->Start(&request, c.callback.callback(), NetLogWithSource()));
2111     ASSERT_THAT(rv, IsOk());
2112 
2113     // Read less than the whole thing.
2114     scoped_refptr<IOBufferWithSize> buf =
2115         base::MakeRefCounted<IOBufferWithSize>(10);
2116     rv = c.callback.GetResult(
2117         c.trans->Read(buf.get(), buf->size(), c.callback.callback()));
2118     EXPECT_EQ(buf->size(), rv);
2119 
2120     // Destroy the transaction.
2121     c.trans.reset();
2122     base::RunLoop().RunUntilIdle();
2123 
2124     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/true,
2125                         /*data_size=*/10);
2126   }
2127 
2128   // Do a fetch that can use prefetch that aborts in connected handler.
2129   transaction.load_flags &= ~LOAD_PREFETCH;
2130   {
2131     MockHttpRequest request(transaction);
2132     Context c;
2133 
2134     int rv = cache.CreateTransaction(&c.trans);
2135     ASSERT_THAT(rv, IsOk());
2136     c.trans->SetConnectedCallback(base::BindRepeating(
2137         [](const TransportInfo& info, CompletionOnceCallback callback) -> int {
2138           return net::ERR_ABORTED;
2139         }));
2140     rv = c.callback.GetResult(
2141         c.trans->Start(&request, c.callback.callback(), NetLogWithSource()));
2142     EXPECT_EQ(net::ERR_ABORTED, rv);
2143 
2144     // Destroy the transaction.
2145     c.trans.reset();
2146     base::RunLoop().RunUntilIdle();
2147 
2148     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/true,
2149                         /*data_size=*/10);
2150   }
2151 
2152   // Now try again without abort.
2153   {
2154     MockHttpRequest request(transaction);
2155     RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
2156                                   /*response_info=*/nullptr);
2157     base::RunLoop().RunUntilIdle();
2158 
2159     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/false,
2160                         /*data_size=*/20);
2161   }
2162 }
2163 
2164 // Make sure that if a stale-while-revalidate entry is truncated, then an
2165 // attempt to re-use it gets aborted in connected handler that truncated bit is
2166 // not lost.
TEST_F(HttpCacheTest,StaleWhiteRevalidateTruncateCancelInConnectedCallback)2167 TEST_F(HttpCacheTest, StaleWhiteRevalidateTruncateCancelInConnectedCallback) {
2168   MockHttpCache cache;
2169 
2170   ScopedMockTransaction transaction(kSimpleGET_Transaction);
2171   transaction.response_headers =
2172       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2173       "Content-Length: 20\n"
2174       "Cache-Control: max-age=0, stale-while-revalidate=60\n"
2175       "Etag: \"foopy\"\n";
2176   transaction.data = "01234567890123456789";
2177   transaction.load_flags |= LOAD_SUPPORT_ASYNC_REVALIDATION;
2178 
2179   // Do a truncated read of a stale-while-revalidate resource.
2180   {
2181     MockHttpRequest request(transaction);
2182     Context c;
2183 
2184     int rv = cache.CreateTransaction(&c.trans);
2185     ASSERT_THAT(rv, IsOk());
2186 
2187     rv = c.callback.GetResult(
2188         c.trans->Start(&request, c.callback.callback(), NetLogWithSource()));
2189     ASSERT_THAT(rv, IsOk());
2190 
2191     // Read less than the whole thing.
2192     scoped_refptr<IOBufferWithSize> buf =
2193         base::MakeRefCounted<IOBufferWithSize>(10);
2194     rv = c.callback.GetResult(
2195         c.trans->Read(buf.get(), buf->size(), c.callback.callback()));
2196     EXPECT_EQ(buf->size(), rv);
2197 
2198     // Destroy the transaction.
2199     c.trans.reset();
2200     base::RunLoop().RunUntilIdle();
2201 
2202     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/true,
2203                         /*data_size=*/10);
2204   }
2205 
2206   // Do a fetch that uses that resource that aborts in connected handler.
2207   {
2208     MockHttpRequest request(transaction);
2209     Context c;
2210 
2211     int rv = cache.CreateTransaction(&c.trans);
2212     ASSERT_THAT(rv, IsOk());
2213     c.trans->SetConnectedCallback(base::BindRepeating(
2214         [](const TransportInfo& info, CompletionOnceCallback callback) -> int {
2215           return net::ERR_ABORTED;
2216         }));
2217     rv = c.callback.GetResult(
2218         c.trans->Start(&request, c.callback.callback(), NetLogWithSource()));
2219     EXPECT_EQ(net::ERR_ABORTED, rv);
2220 
2221     // Destroy the transaction.
2222     c.trans.reset();
2223     base::RunLoop().RunUntilIdle();
2224 
2225     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/true,
2226                         /*data_size=*/10);
2227   }
2228 
2229   // Now try again without abort.
2230   {
2231     MockHttpRequest request(transaction);
2232     RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
2233                                   /*response_info=*/nullptr);
2234     base::RunLoop().RunUntilIdle();
2235 
2236     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/false,
2237                         /*data_size=*/20);
2238   }
2239 }
2240 
2241 static const auto kPreserveRequestHeaders =
2242     base::BindRepeating([](const net::HttpRequestInfo* request,
2243                            std::string* response_status,
2244                            std::string* response_headers,
__anond56f448a0602(const net::HttpRequestInfo* request, std::string* response_status, std::string* response_headers, std::string* response_data) 2245                            std::string* response_data) {
2246       EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
2247     });
2248 
2249 // Tests that we don't remove extra headers for simple requests.
TEST_F(HttpCacheTest,SimpleGET_PreserveRequestHeaders)2250 TEST_F(HttpCacheTest, SimpleGET_PreserveRequestHeaders) {
2251   for (bool use_memory_entry_data : {false, true}) {
2252     MockHttpCache cache;
2253     cache.disk_cache()->set_support_in_memory_entry_data(use_memory_entry_data);
2254 
2255     MockTransaction transaction(kSimpleGET_Transaction);
2256     transaction.handler = kPreserveRequestHeaders;
2257     transaction.request_headers = EXTRA_HEADER;
2258     transaction.response_headers = "Cache-Control: max-age=0\n";
2259     AddMockTransaction(&transaction);
2260 
2261     // Write, then revalidate the entry.
2262     RunTransactionTest(cache.http_cache(), transaction);
2263     RunTransactionTest(cache.http_cache(), transaction);
2264 
2265     EXPECT_EQ(2, cache.network_layer()->transaction_count());
2266 
2267     // If the backend supports memory entry data, we can figure out that the
2268     // entry has caching-hostile headers w/o opening it.
2269     if (use_memory_entry_data) {
2270       EXPECT_EQ(0, cache.disk_cache()->open_count());
2271       EXPECT_EQ(2, cache.disk_cache()->create_count());
2272     } else {
2273       EXPECT_EQ(1, cache.disk_cache()->open_count());
2274       EXPECT_EQ(1, cache.disk_cache()->create_count());
2275     }
2276     RemoveMockTransaction(&transaction);
2277   }
2278 }
2279 
2280 // Tests that we don't remove extra headers for conditionalized requests.
TEST_F(HttpCacheTest,ConditionalizedGET_PreserveRequestHeaders)2281 TEST_F(HttpCacheTest, ConditionalizedGET_PreserveRequestHeaders) {
2282   for (bool use_memory_entry_data : {false, true}) {
2283     MockHttpCache cache;
2284     // Unlike in SimpleGET_PreserveRequestHeaders, this entry can be
2285     // conditionalized, so memory hints don't affect behavior.
2286     cache.disk_cache()->set_support_in_memory_entry_data(use_memory_entry_data);
2287 
2288     // Write to the cache.
2289     RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
2290 
2291     MockTransaction transaction(kETagGET_Transaction);
2292     transaction.handler = kPreserveRequestHeaders;
2293     transaction.request_headers = "If-None-Match: \"foopy\"\r\n" EXTRA_HEADER;
2294     AddMockTransaction(&transaction);
2295 
2296     RunTransactionTest(cache.http_cache(), transaction);
2297 
2298     EXPECT_EQ(2, cache.network_layer()->transaction_count());
2299     EXPECT_EQ(1, cache.disk_cache()->open_count());
2300     EXPECT_EQ(1, cache.disk_cache()->create_count());
2301     RemoveMockTransaction(&transaction);
2302   }
2303 }
2304 
TEST_F(HttpCacheTest,SimpleGET_ManyReaders)2305 TEST_F(HttpCacheTest, SimpleGET_ManyReaders) {
2306   MockHttpCache cache;
2307 
2308   MockHttpRequest request(kSimpleGET_Transaction);
2309 
2310   std::vector<std::unique_ptr<Context>> context_list;
2311   const int kNumTransactions = 5;
2312 
2313   for (int i = 0; i < kNumTransactions; ++i) {
2314     context_list.push_back(std::make_unique<Context>());
2315     auto& c = context_list[i];
2316 
2317     c->result = cache.CreateTransaction(&c->trans);
2318     ASSERT_THAT(c->result, IsOk());
2319     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
2320 
2321     c->result =
2322         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
2323   }
2324 
2325   // All requests are waiting for the active entry.
2326   for (auto& context : context_list) {
2327     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
2328   }
2329 
2330   // Allow all requests to move from the Create queue to the active entry.
2331   base::RunLoop().RunUntilIdle();
2332 
2333   // All requests are added to writers.
2334   std::string cache_key = request.CacheKey();
2335   EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
2336 
2337   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2338   EXPECT_EQ(0, cache.disk_cache()->open_count());
2339   EXPECT_EQ(1, cache.disk_cache()->create_count());
2340 
2341   // All requests are between Start and Read, i.e. idle.
2342   for (auto& context : context_list) {
2343     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
2344   }
2345 
2346   for (int i = 0; i < kNumTransactions; ++i) {
2347     auto& c = context_list[i];
2348     if (c->result == ERR_IO_PENDING)
2349       c->result = c->callback.WaitForResult();
2350 
2351     // After the 1st transaction has completed the response, all transactions
2352     // get added to readers.
2353     if (i > 0) {
2354       EXPECT_FALSE(cache.IsWriterPresent(cache_key));
2355       EXPECT_EQ(kNumTransactions - i, cache.GetCountReaders(cache_key));
2356     }
2357 
2358     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
2359   }
2360 
2361   // We should not have had to re-open the disk entry
2362   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2363   EXPECT_EQ(0, cache.disk_cache()->open_count());
2364   EXPECT_EQ(1, cache.disk_cache()->create_count());
2365 }
2366 
TEST_F(HttpCacheTest,RangeGET_FullAfterPartial)2367 TEST_F(HttpCacheTest, RangeGET_FullAfterPartial) {
2368   MockHttpCache cache;
2369 
2370   // Request a prefix.
2371   {
2372     ScopedMockTransaction transaction_pre(kRangeGET_TransactionOK);
2373     transaction_pre.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
2374     transaction_pre.data = "rg: 00-09 ";
2375     MockHttpRequest request_pre(transaction_pre);
2376 
2377     HttpResponseInfo response_pre;
2378     RunTransactionTestWithRequest(cache.http_cache(), transaction_pre,
2379                                   request_pre, &response_pre);
2380     ASSERT_TRUE(response_pre.headers != nullptr);
2381     EXPECT_EQ(206, response_pre.headers->response_code());
2382     EXPECT_EQ(1, cache.network_layer()->transaction_count());
2383     EXPECT_EQ(0, cache.disk_cache()->open_count());
2384     EXPECT_EQ(1, cache.disk_cache()->create_count());
2385   }
2386 
2387   {
2388     // Now request the full thing, but set validation to fail. This would
2389     // previously fail in the middle of data and truncate it; current behavior
2390     // restarts it, somewhat wastefully but gets the data back.
2391     RangeTransactionServer handler;
2392     handler.set_modified(true);
2393 
2394     ScopedMockTransaction transaction_all(kRangeGET_TransactionOK);
2395     transaction_all.request_headers = EXTRA_HEADER;
2396     transaction_all.data = "Not a range";
2397     MockHttpRequest request_all(transaction_all);
2398 
2399     HttpResponseInfo response_all;
2400     RunTransactionTestWithRequest(cache.http_cache(), transaction_all,
2401                                   request_all, &response_all);
2402     ASSERT_TRUE(response_all.headers != nullptr);
2403     EXPECT_EQ(200, response_all.headers->response_code());
2404     // 1 from previous test, failed validation, and re-try.
2405     EXPECT_EQ(3, cache.network_layer()->transaction_count());
2406     EXPECT_EQ(1, cache.disk_cache()->open_count());
2407     EXPECT_EQ(1, cache.disk_cache()->create_count());
2408   }
2409 }
2410 
2411 // Tests that when a range request transaction becomes a writer for the first
2412 // range and then fails conditionalization for the next range and decides to
2413 // doom the entry, then there should not be a dcheck assertion hit.
TEST_F(HttpCacheTest,RangeGET_OverlappingRangesCouldntConditionalize)2414 TEST_F(HttpCacheTest, RangeGET_OverlappingRangesCouldntConditionalize) {
2415   MockHttpCache cache;
2416 
2417   {
2418     ScopedMockTransaction transaction_pre(kRangeGET_TransactionOK);
2419     transaction_pre.request_headers = "Range: bytes = 10-19\r\n" EXTRA_HEADER;
2420     transaction_pre.data = "rg: 10-19 ";
2421     MockHttpRequest request_pre(transaction_pre);
2422 
2423     HttpResponseInfo response_pre;
2424     RunTransactionTestWithRequest(cache.http_cache(), transaction_pre,
2425                                   request_pre, &response_pre);
2426     ASSERT_TRUE(response_pre.headers != nullptr);
2427     EXPECT_EQ(206, response_pre.headers->response_code());
2428     EXPECT_EQ(1, cache.network_layer()->transaction_count());
2429     EXPECT_EQ(0, cache.disk_cache()->open_count());
2430     EXPECT_EQ(1, cache.disk_cache()->create_count());
2431   }
2432 
2433   {
2434     // First range skips validation because the response is fresh while the
2435     // second range requires validation since that range is not present in the
2436     // cache and during validation it fails conditionalization.
2437     cache.FailConditionalizations();
2438     ScopedMockTransaction transaction_pre(kRangeGET_TransactionOK);
2439     transaction_pre.request_headers = "Range: bytes = 10-29\r\n" EXTRA_HEADER;
2440 
2441     // TODO(crbug.com/992521): Fix this scenario to not return the cached bytes
2442     // repeatedly.
2443     transaction_pre.data = "rg: 10-19 rg: 10-19 rg: 20-29 ";
2444     MockHttpRequest request_pre(transaction_pre);
2445     HttpResponseInfo response_pre;
2446     RunTransactionTestWithRequest(cache.http_cache(), transaction_pre,
2447                                   request_pre, &response_pre);
2448     ASSERT_TRUE(response_pre.headers != nullptr);
2449     EXPECT_EQ(2, cache.network_layer()->transaction_count());
2450     EXPECT_EQ(1, cache.disk_cache()->open_count());
2451     EXPECT_EQ(2, cache.disk_cache()->create_count());
2452   }
2453 }
2454 
TEST_F(HttpCacheTest,RangeGET_FullAfterPartialReuse)2455 TEST_F(HttpCacheTest, RangeGET_FullAfterPartialReuse) {
2456   MockHttpCache cache;
2457 
2458   // Request a prefix.
2459   {
2460     ScopedMockTransaction transaction_pre(kRangeGET_TransactionOK);
2461     transaction_pre.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
2462     transaction_pre.data = "rg: 00-09 ";
2463     MockHttpRequest request_pre(transaction_pre);
2464 
2465     HttpResponseInfo response_pre;
2466     RunTransactionTestWithRequest(cache.http_cache(), transaction_pre,
2467                                   request_pre, &response_pre);
2468     ASSERT_TRUE(response_pre.headers != nullptr);
2469     EXPECT_EQ(206, response_pre.headers->response_code());
2470     EXPECT_EQ(1, cache.network_layer()->transaction_count());
2471     EXPECT_EQ(0, cache.disk_cache()->open_count());
2472     EXPECT_EQ(1, cache.disk_cache()->create_count());
2473   }
2474 
2475   {
2476     // Now request the full thing, revalidating successfully, so the full
2477     // file gets stored via a sparse-entry.
2478     ScopedMockTransaction transaction_all(kRangeGET_TransactionOK);
2479     transaction_all.request_headers = EXTRA_HEADER;
2480     transaction_all.data =
2481         "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49"
2482         " rg: 50-59 rg: 60-69 rg: 70-79 ";
2483     MockHttpRequest request_all(transaction_all);
2484 
2485     HttpResponseInfo response_all;
2486     RunTransactionTestWithRequest(cache.http_cache(), transaction_all,
2487                                   request_all, &response_all);
2488     ASSERT_TRUE(response_all.headers != nullptr);
2489     EXPECT_EQ(200, response_all.headers->response_code());
2490     // 1 from previous test, validation, and second chunk
2491     EXPECT_EQ(3, cache.network_layer()->transaction_count());
2492     EXPECT_EQ(1, cache.disk_cache()->open_count());
2493     EXPECT_EQ(1, cache.disk_cache()->create_count());
2494   }
2495 
2496   {
2497     // Grab it again, should not need re-validation.
2498     ScopedMockTransaction transaction_all2(kRangeGET_TransactionOK);
2499     transaction_all2.request_headers = EXTRA_HEADER;
2500     transaction_all2.data =
2501         "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49"
2502         " rg: 50-59 rg: 60-69 rg: 70-79 ";
2503     MockHttpRequest request_all2(transaction_all2);
2504 
2505     HttpResponseInfo response_all2;
2506     RunTransactionTestWithRequest(cache.http_cache(), transaction_all2,
2507                                   request_all2, &response_all2);
2508     ASSERT_TRUE(response_all2.headers != nullptr);
2509     EXPECT_EQ(200, response_all2.headers->response_code());
2510 
2511     // Only one more cache open, no new network traffic.
2512     EXPECT_EQ(3, cache.network_layer()->transaction_count());
2513     EXPECT_EQ(2, cache.disk_cache()->open_count());
2514     EXPECT_EQ(1, cache.disk_cache()->create_count());
2515   }
2516 }
2517 
2518 // This test verifies that the ConnectedCallback passed to a cache transaction
2519 // is called once per subrange in the case of a range request with a partial
2520 // cache hit.
TEST_F(HttpCacheTest,RangeGET_ConnectedCallbackCalledForEachRange)2521 TEST_F(HttpCacheTest, RangeGET_ConnectedCallbackCalledForEachRange) {
2522   MockHttpCache cache;
2523 
2524   // Request an infix range and populate the cache with it.
2525   {
2526     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2527     mock_transaction.request_headers = "Range: bytes = 20-29\r\n" EXTRA_HEADER;
2528     mock_transaction.data = "rg: 20-29 ";
2529     mock_transaction.transport_info = TestTransportInfo();
2530 
2531     RunTransactionTest(cache.http_cache(), mock_transaction);
2532   }
2533 
2534   // Request a surrounding range and observe that the callback is called once
2535   // per subrange, as split up by cache hits.
2536   {
2537     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2538     mock_transaction.request_headers = "Range: bytes = 10-39\r\n" EXTRA_HEADER;
2539     mock_transaction.data = "rg: 10-19 rg: 20-29 rg: 30-39 ";
2540     mock_transaction.transport_info = TestTransportInfo();
2541     MockHttpRequest request(mock_transaction);
2542 
2543     ConnectedHandler connected_handler;
2544 
2545     std::unique_ptr<HttpTransaction> transaction;
2546     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2547     ASSERT_THAT(transaction, NotNull());
2548 
2549     transaction->SetConnectedCallback(connected_handler.Callback());
2550 
2551     TestCompletionCallback callback;
2552     ASSERT_THAT(
2553         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2554         IsError(ERR_IO_PENDING));
2555     EXPECT_THAT(callback.WaitForResult(), IsOk());
2556 
2557     // 1 call for the first range's network transaction.
2558     EXPECT_THAT(connected_handler.transports(),
2559                 ElementsAre(TestTransportInfo()));
2560 
2561     // Switch the endpoint for the next network transaction to observe.
2562     // For ease, we just switch the port number.
2563     //
2564     // NOTE: This works because only the mock transaction struct's address is
2565     // registered with the mocking framework - the pointee data is consulted
2566     // each time it is read.
2567     mock_transaction.transport_info = TestTransportInfoWithPort(123);
2568 
2569     ReadAndVerifyTransaction(transaction.get(), mock_transaction);
2570 
2571     // A second call for the cached range, reported as coming from the original
2572     // endpoint it was cached from. A third call for the last range's network
2573     // transaction.
2574     EXPECT_THAT(connected_handler.transports(),
2575                 ElementsAre(TestTransportInfo(), CachedTestTransportInfo(),
2576                             TestTransportInfoWithPort(123)));
2577   }
2578 }
2579 
2580 // This test verifies that when the ConnectedCallback passed to a cache range
2581 // transaction returns an `ERR_INCONSISTENT_IP_ADDRESS_SPACE` error during a
2582 // partial read from cache, then the cache entry is invalidated.
TEST_F(HttpCacheTest,RangeGET_ConnectedCallbackReturnInconsistentIpError)2583 TEST_F(HttpCacheTest, RangeGET_ConnectedCallbackReturnInconsistentIpError) {
2584   MockHttpCache cache;
2585 
2586   // Request an infix range and populate the cache with it.
2587   {
2588     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2589     mock_transaction.request_headers = "Range: bytes = 20-29\r\n" EXTRA_HEADER;
2590     mock_transaction.data = "rg: 20-29 ";
2591     mock_transaction.transport_info = TestTransportInfo();
2592 
2593     RunTransactionTest(cache.http_cache(), mock_transaction);
2594   }
2595 
2596   ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2597   mock_transaction.request_headers = "Range: bytes = 10-39\r\n" EXTRA_HEADER;
2598   mock_transaction.data = "rg: 10-19 rg: 20-29 rg: 30-39 ";
2599   mock_transaction.transport_info = TestTransportInfo();
2600   MockHttpRequest request(mock_transaction);
2601 
2602   // Request a surrounding range. This *should* be read in three parts:
2603   //
2604   // 1. for the prefix: from the network
2605   // 2. for the cached infix: from the cache
2606   // 3. for the suffix: from the network
2607   //
2608   // The connected callback returns OK for 1), but fails during 2). As a result,
2609   // the transaction fails partway and 3) is never created. The cache entry is
2610   // invalidated as a result of the specific error code.
2611   {
2612     ConnectedHandler connected_handler;
2613 
2614     std::unique_ptr<HttpTransaction> transaction;
2615     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2616     ASSERT_THAT(transaction, NotNull());
2617 
2618     transaction->SetConnectedCallback(connected_handler.Callback());
2619 
2620     TestCompletionCallback callback;
2621     ASSERT_THAT(
2622         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2623         IsError(ERR_IO_PENDING));
2624     EXPECT_THAT(callback.WaitForResult(), IsOk());
2625 
2626     // 1 call for the first range's network transaction.
2627     EXPECT_THAT(connected_handler.transports(),
2628                 ElementsAre(TestTransportInfo()));
2629 
2630     // Set the callback to return an error the next time it is called.
2631     connected_handler.set_result(ERR_INCONSISTENT_IP_ADDRESS_SPACE);
2632 
2633     std::string content;
2634     EXPECT_THAT(ReadTransaction(transaction.get(), &content),
2635                 IsError(ERR_INCONSISTENT_IP_ADDRESS_SPACE));
2636 
2637     // A second call that failed.
2638     EXPECT_THAT(connected_handler.transports(),
2639                 ElementsAre(TestTransportInfo(), CachedTestTransportInfo()));
2640   }
2641 
2642   // Request the same range again, observe that nothing is read from cache.
2643   {
2644     ConnectedHandler connected_handler;
2645 
2646     std::unique_ptr<HttpTransaction> transaction;
2647     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2648     ASSERT_THAT(transaction, NotNull());
2649 
2650     transaction->SetConnectedCallback(connected_handler.Callback());
2651 
2652     TestCompletionCallback callback;
2653     ASSERT_THAT(
2654         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2655         IsError(ERR_IO_PENDING));
2656     EXPECT_THAT(callback.WaitForResult(), IsOk());
2657 
2658     std::string content;
2659     EXPECT_THAT(ReadTransaction(transaction.get(), &content), IsOk());
2660     EXPECT_EQ(content, mock_transaction.data);
2661 
2662     // 1 call for the network transaction from which the whole response was
2663     // read. The first 20 bytes were cached by the previous two requests, but
2664     // the cache entry was doomed during the last transaction so they are not
2665     // used here.
2666     EXPECT_THAT(connected_handler.transports(),
2667                 ElementsAre(TestTransportInfo()));
2668   }
2669 }
2670 
2671 // This test verifies that when the ConnectedCallback passed to a cache range
2672 // transaction returns an `ERR_INCONSISTENT_IP_ADDRESS_SPACE` error during a
2673 // network transaction, then the cache entry is invalidated.
TEST_F(HttpCacheTest,RangeGET_ConnectedCallbackReturnInconsistentIpErrorForNetwork)2674 TEST_F(HttpCacheTest,
2675        RangeGET_ConnectedCallbackReturnInconsistentIpErrorForNetwork) {
2676   MockHttpCache cache;
2677 
2678   // Request a prefix range and populate the cache with it.
2679   {
2680     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2681     mock_transaction.request_headers = "Range: bytes = 10-19\r\n" EXTRA_HEADER;
2682     mock_transaction.data = "rg: 10-19 ";
2683     mock_transaction.transport_info = TestTransportInfo();
2684 
2685     RunTransactionTest(cache.http_cache(), mock_transaction);
2686   }
2687 
2688   ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2689   mock_transaction.request_headers = "Range: bytes = 10-29\r\n" EXTRA_HEADER;
2690   mock_transaction.data = "rg: 10-19 rg: 20-29 ";
2691   mock_transaction.transport_info = TestTransportInfo();
2692   MockHttpRequest request(mock_transaction);
2693 
2694   // Request a longer range. This *should* be read in two parts:
2695   //
2696   // 1. for the prefix: from the cache
2697   // 2. for the suffix: from the network
2698   {
2699     ConnectedHandler connected_handler;
2700 
2701     std::unique_ptr<HttpTransaction> transaction;
2702     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2703     ASSERT_THAT(transaction, NotNull());
2704 
2705     transaction->SetConnectedCallback(connected_handler.Callback());
2706 
2707     TestCompletionCallback callback;
2708     ASSERT_THAT(
2709         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2710         IsError(ERR_IO_PENDING));
2711     EXPECT_THAT(callback.WaitForResult(), IsOk());
2712 
2713     // 1 call for the first range's network transaction.
2714     EXPECT_THAT(connected_handler.transports(),
2715                 ElementsAre(CachedTestTransportInfo()));
2716 
2717     // Set the callback to return an error the next time it is called.
2718     connected_handler.set_result(ERR_INCONSISTENT_IP_ADDRESS_SPACE);
2719 
2720     std::string content;
2721     EXPECT_THAT(ReadTransaction(transaction.get(), &content),
2722                 IsError(ERR_INCONSISTENT_IP_ADDRESS_SPACE));
2723 
2724     // A second call that failed.
2725     EXPECT_THAT(connected_handler.transports(),
2726                 ElementsAre(CachedTestTransportInfo(), TestTransportInfo()));
2727   }
2728 
2729   // Request the same range again, observe that nothing is read from cache.
2730   {
2731     ConnectedHandler connected_handler;
2732 
2733     std::unique_ptr<HttpTransaction> transaction;
2734     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2735     ASSERT_THAT(transaction, NotNull());
2736 
2737     transaction->SetConnectedCallback(connected_handler.Callback());
2738 
2739     TestCompletionCallback callback;
2740     ASSERT_THAT(
2741         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2742         IsError(ERR_IO_PENDING));
2743     EXPECT_THAT(callback.WaitForResult(), IsOk());
2744 
2745     std::string content;
2746     EXPECT_THAT(ReadTransaction(transaction.get(), &content), IsOk());
2747     EXPECT_EQ(content, mock_transaction.data);
2748 
2749     // 1 call for the network transaction from which the whole response was
2750     // read. The first 20 bytes were cached by the previous two requests, but
2751     // the cache entry was doomed during the last transaction so they are not
2752     // used here.
2753     EXPECT_THAT(connected_handler.transports(),
2754                 ElementsAre(TestTransportInfo()));
2755   }
2756 }
2757 
2758 // This test verifies that when the ConnectedCallback passed to a cache
2759 // transaction returns an error for the second (or third) subrange transaction,
2760 // the overall cache transaction fails with that error. The cache entry is still
2761 // usable after that.
TEST_F(HttpCacheTest,RangeGET_ConnectedCallbackReturnErrorSecondTime)2762 TEST_F(HttpCacheTest, RangeGET_ConnectedCallbackReturnErrorSecondTime) {
2763   MockHttpCache cache;
2764 
2765   // Request an infix range and populate the cache with it.
2766   {
2767     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2768     mock_transaction.request_headers = "Range: bytes = 20-29\r\n" EXTRA_HEADER;
2769     mock_transaction.data = "rg: 20-29 ";
2770     mock_transaction.transport_info = TestTransportInfo();
2771 
2772     RunTransactionTest(cache.http_cache(), mock_transaction);
2773   }
2774 
2775   ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2776   mock_transaction.request_headers = "Range: bytes = 10-39\r\n" EXTRA_HEADER;
2777   mock_transaction.data = "rg: 10-19 rg: 20-29 rg: 30-39 ";
2778   mock_transaction.transport_info = TestTransportInfo();
2779   MockHttpRequest request(mock_transaction);
2780 
2781   // Request a surrounding range. This *should* be read in three parts:
2782   //
2783   // 1. for the prefix: from the network
2784   // 2. for the cached infix: from the cache
2785   // 3. for the suffix: from the network
2786   //
2787   // The connected callback returns OK for 1), but fails during 2). As a result,
2788   // the transaction fails partway and 3) is never created. The prefix is still
2789   // cached, such that the cache entry ends up with both the prefix and infix.
2790   {
2791     ConnectedHandler connected_handler;
2792 
2793     std::unique_ptr<HttpTransaction> transaction;
2794     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2795     ASSERT_THAT(transaction, NotNull());
2796 
2797     transaction->SetConnectedCallback(connected_handler.Callback());
2798 
2799     TestCompletionCallback callback;
2800     ASSERT_THAT(
2801         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2802         IsError(ERR_IO_PENDING));
2803     EXPECT_THAT(callback.WaitForResult(), IsOk());
2804 
2805     // 1 call for the first range's network transaction.
2806     EXPECT_THAT(connected_handler.transports(),
2807                 ElementsAre(TestTransportInfo()));
2808 
2809     // Set the callback to return an error the next time it is called. The exact
2810     // error code is irrelevant, what matters is that it is reflected in the
2811     // overall status of the transaction.
2812     connected_handler.set_result(ERR_NOT_IMPLEMENTED);
2813 
2814     std::string content;
2815     EXPECT_THAT(ReadTransaction(transaction.get(), &content),
2816                 IsError(ERR_NOT_IMPLEMENTED));
2817 
2818     // A second call that failed.
2819     EXPECT_THAT(connected_handler.transports(),
2820                 ElementsAre(TestTransportInfo(), CachedTestTransportInfo()));
2821   }
2822 
2823   // Request the same range again, observe that the prefix and infix are both
2824   // read from cache. Only the suffix is fetched from the network.
2825   {
2826     ConnectedHandler connected_handler;
2827 
2828     std::unique_ptr<HttpTransaction> transaction;
2829     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2830     ASSERT_THAT(transaction, NotNull());
2831 
2832     transaction->SetConnectedCallback(connected_handler.Callback());
2833 
2834     TestCompletionCallback callback;
2835     ASSERT_THAT(
2836         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2837         IsError(ERR_IO_PENDING));
2838     EXPECT_THAT(callback.WaitForResult(), IsOk());
2839 
2840     // 1 call for the first range's cache transaction: the first 20 bytes were
2841     // cached by the previous two requests.
2842     EXPECT_THAT(connected_handler.transports(),
2843                 ElementsAre(CachedTestTransportInfo()));
2844 
2845     std::string content;
2846     EXPECT_THAT(ReadTransaction(transaction.get(), &content), IsOk());
2847     EXPECT_EQ(content, mock_transaction.data);
2848 
2849     // A second call from the network transaction for the last 10 bytes.
2850     EXPECT_THAT(connected_handler.transports(),
2851                 ElementsAre(CachedTestTransportInfo(), TestTransportInfo()));
2852   }
2853 }
2854 
2855 // This test verifies that the ConnectedCallback passed to a cache transaction
2856 // is called once per subrange in the case of a range request with a partial
2857 // cache hit, even when a prefix of the range is cached.
TEST_F(HttpCacheTest,RangeGET_ConnectedCallbackCalledForEachRangeWithPrefix)2858 TEST_F(HttpCacheTest, RangeGET_ConnectedCallbackCalledForEachRangeWithPrefix) {
2859   MockHttpCache cache;
2860 
2861   // Request a prefix range and populate the cache with it.
2862   {
2863     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2864     mock_transaction.request_headers = "Range: bytes = 10-19\r\n" EXTRA_HEADER;
2865     mock_transaction.data = "rg: 10-19 ";
2866     mock_transaction.transport_info = TestTransportInfo();
2867 
2868     RunTransactionTest(cache.http_cache(), mock_transaction);
2869   }
2870 
2871   // Request a surrounding range and observe that the callback is called once
2872   // per subrange, as split up by cache hits.
2873   {
2874     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2875     mock_transaction.request_headers = "Range: bytes = 10-39\r\n" EXTRA_HEADER;
2876     mock_transaction.data = "rg: 10-19 rg: 20-29 rg: 30-39 ";
2877     mock_transaction.transport_info = TestTransportInfoWithPort(123);
2878     MockHttpRequest request(mock_transaction);
2879 
2880     ConnectedHandler connected_handler;
2881 
2882     std::unique_ptr<HttpTransaction> transaction;
2883     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2884     ASSERT_THAT(transaction, NotNull());
2885 
2886     transaction->SetConnectedCallback(connected_handler.Callback());
2887 
2888     TestCompletionCallback callback;
2889     ASSERT_THAT(
2890         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2891         IsError(ERR_IO_PENDING));
2892     EXPECT_THAT(callback.WaitForResult(), IsOk());
2893 
2894     // 1 call for the first range from the cache, reported as coming from the
2895     // endpoint which initially served the cached range.
2896     EXPECT_THAT(connected_handler.transports(),
2897                 ElementsAre(CachedTestTransportInfo()));
2898 
2899     ReadAndVerifyTransaction(transaction.get(), mock_transaction);
2900 
2901     // A second call for the last range's network transaction.
2902     EXPECT_THAT(
2903         connected_handler.transports(),
2904         ElementsAre(CachedTestTransportInfo(), TestTransportInfoWithPort(123)));
2905   }
2906 }
2907 
2908 // Tests that a range transaction is still usable even if it's unable to access
2909 // the cache.
TEST_F(HttpCacheTest,RangeGET_FailedCacheAccess)2910 TEST_F(HttpCacheTest, RangeGET_FailedCacheAccess) {
2911   MockHttpCache cache;
2912 
2913   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
2914   MockHttpRequest request(transaction);
2915 
2916   auto c = std::make_unique<Context>();
2917   c->result = cache.CreateTransaction(&c->trans);
2918   ASSERT_THAT(c->result, IsOk());
2919   EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
2920 
2921   cache.disk_cache()->set_fail_requests(true);
2922 
2923   c->result =
2924       c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
2925 
2926   base::RunLoop().RunUntilIdle();
2927 
2928   EXPECT_FALSE(cache.IsWriterPresent(kRangeGET_TransactionOK.url));
2929 
2930   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2931   EXPECT_EQ(0, cache.disk_cache()->open_count());
2932   EXPECT_EQ(0, cache.disk_cache()->create_count());
2933 
2934   c->result = c->callback.WaitForResult();
2935 
2936   ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK);
2937 
2938   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2939   EXPECT_EQ(0, cache.disk_cache()->open_count());
2940   EXPECT_EQ(0, cache.disk_cache()->create_count());
2941 }
2942 
2943 // Tests that we can have parallel validation on range requests.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationNoMatch)2944 TEST_F(HttpCacheTest, RangeGET_ParallelValidationNoMatch) {
2945   MockHttpCache cache;
2946 
2947   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
2948   MockHttpRequest request(transaction);
2949 
2950   std::vector<std::unique_ptr<Context>> context_list;
2951   const int kNumTransactions = 5;
2952 
2953   for (int i = 0; i < kNumTransactions; ++i) {
2954     context_list.push_back(std::make_unique<Context>());
2955     auto& c = context_list[i];
2956 
2957     c->result = cache.CreateTransaction(&c->trans);
2958     ASSERT_THAT(c->result, IsOk());
2959     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
2960 
2961     c->result =
2962         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
2963   }
2964 
2965   // All requests are waiting for the active entry.
2966   for (auto& context : context_list) {
2967     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
2968   }
2969 
2970   // Allow all requests to move from the Create queue to the active entry.
2971   base::RunLoop().RunUntilIdle();
2972 
2973   // First entry created is doomed due to 2nd transaction's validation leading
2974   // to restarting of the queued transactions.
2975   EXPECT_TRUE(cache.IsWriterPresent(request.CacheKey()));
2976 
2977   // TODO(shivanisha): The restarted transactions race for creating the entry
2978   // and thus instead of all 4 succeeding, 2 of them succeed. This is very
2979   // implementation specific and happens because the queued transactions get
2980   // restarted synchronously and get to the queue of creating the entry before
2981   // the transaction that is restarting them. Fix the test to make it less
2982   // vulnerable to any scheduling changes in the code.
2983   EXPECT_EQ(5, cache.network_layer()->transaction_count());
2984   EXPECT_EQ(0, cache.disk_cache()->open_count());
2985   EXPECT_EQ(3, cache.disk_cache()->create_count());
2986 
2987   for (auto& context : context_list) {
2988     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
2989   }
2990 
2991   for (int i = 0; i < kNumTransactions; ++i) {
2992     auto& c = context_list[i];
2993     if (c->result == ERR_IO_PENDING)
2994       c->result = c->callback.WaitForResult();
2995 
2996     ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK);
2997   }
2998 
2999   EXPECT_EQ(5, cache.network_layer()->transaction_count());
3000   EXPECT_EQ(0, cache.disk_cache()->open_count());
3001   EXPECT_EQ(3, cache.disk_cache()->create_count());
3002 }
3003 
3004 // Tests that if a transaction is dooming the entry and the entry was doomed by
3005 // another transaction that was not part of the entry and created a new entry,
3006 // the new entry should not be incorrectly doomed. (crbug.com/736993)
TEST_F(HttpCacheTest,RangeGET_ParallelValidationNoMatchDoomEntry)3007 TEST_F(HttpCacheTest, RangeGET_ParallelValidationNoMatchDoomEntry) {
3008   MockHttpCache cache;
3009 
3010   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3011   MockHttpRequest request(transaction);
3012 
3013   MockTransaction dooming_transaction(kRangeGET_TransactionOK);
3014   dooming_transaction.load_flags |= LOAD_BYPASS_CACHE;
3015   MockHttpRequest dooming_request(dooming_transaction);
3016 
3017   std::vector<std::unique_ptr<Context>> context_list;
3018   const int kNumTransactions = 3;
3019 
3020   scoped_refptr<MockDiskEntry> first_entry;
3021   scoped_refptr<MockDiskEntry> second_entry;
3022   for (int i = 0; i < kNumTransactions; ++i) {
3023     context_list.push_back(std::make_unique<Context>());
3024     auto& c = context_list[i];
3025 
3026     c->result = cache.CreateTransaction(&c->trans);
3027     ASSERT_THAT(c->result, IsOk());
3028     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3029 
3030     MockHttpRequest* this_request = &request;
3031 
3032     if (i == 2)
3033       this_request = &dooming_request;
3034 
3035     if (i == 1) {
3036       ASSERT_TRUE(first_entry);
3037       first_entry->SetDefer(MockDiskEntry::DEFER_READ);
3038     }
3039 
3040     c->result = c->trans->Start(this_request, c->callback.callback(),
3041                                 NetLogWithSource());
3042 
3043     // Continue the transactions. 2nd will pause at the cache reading state and
3044     // 3rd transaction will doom the entry.
3045     base::RunLoop().RunUntilIdle();
3046 
3047     std::string cache_key = request.CacheKey();
3048     // Check status of the first and second entries after every transaction.
3049     switch (i) {
3050       case 0:
3051         first_entry = cache.disk_cache()->GetDiskEntryRef(cache_key);
3052         break;
3053       case 1:
3054         EXPECT_FALSE(first_entry->is_doomed());
3055         break;
3056       case 2:
3057         EXPECT_TRUE(first_entry->is_doomed());
3058         second_entry = cache.disk_cache()->GetDiskEntryRef(cache_key);
3059         EXPECT_FALSE(second_entry->is_doomed());
3060         break;
3061     }
3062   }
3063   // Resume cache read by 1st transaction which will lead to dooming the entry
3064   // as well since the entry cannot be validated. This double dooming should not
3065   // lead to an assertion.
3066   first_entry->ResumeDiskEntryOperation();
3067   base::RunLoop().RunUntilIdle();
3068 
3069   // Since second_entry is already created, when 1st transaction goes on to
3070   // create an entry, it will get ERR_CACHE_RACE leading to dooming of
3071   // second_entry and creation of a third entry.
3072   EXPECT_TRUE(second_entry->is_doomed());
3073 
3074   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3075   EXPECT_EQ(0, cache.disk_cache()->open_count());
3076   EXPECT_EQ(3, cache.disk_cache()->create_count());
3077 
3078   for (auto& context : context_list) {
3079     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
3080   }
3081 
3082   for (auto& c : context_list) {
3083     ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK);
3084   }
3085 
3086   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3087   EXPECT_EQ(0, cache.disk_cache()->open_count());
3088   EXPECT_EQ(3, cache.disk_cache()->create_count());
3089 }
3090 
3091 // Same as above but tests that the 2nd transaction does not do anything if
3092 // there is nothing to doom. (crbug.com/736993)
TEST_F(HttpCacheTest,RangeGET_ParallelValidationNoMatchDoomEntry1)3093 TEST_F(HttpCacheTest, RangeGET_ParallelValidationNoMatchDoomEntry1) {
3094   MockHttpCache cache;
3095 
3096   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3097   MockHttpRequest request(transaction);
3098 
3099   MockTransaction dooming_transaction(kRangeGET_TransactionOK);
3100   dooming_transaction.load_flags |= LOAD_BYPASS_CACHE;
3101   MockHttpRequest dooming_request(dooming_transaction);
3102 
3103   std::vector<std::unique_ptr<Context>> context_list;
3104   const int kNumTransactions = 3;
3105 
3106   scoped_refptr<MockDiskEntry> first_entry;
3107   for (int i = 0; i < kNumTransactions; ++i) {
3108     context_list.push_back(std::make_unique<Context>());
3109     auto& c = context_list[i];
3110 
3111     c->result = cache.CreateTransaction(&c->trans);
3112     ASSERT_THAT(c->result, IsOk());
3113     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3114 
3115     MockHttpRequest* this_request = &request;
3116 
3117     if (i == 2) {
3118       this_request = &dooming_request;
3119       cache.disk_cache()->SetDefer(MockDiskEntry::DEFER_CREATE);
3120     }
3121 
3122     if (i == 1) {
3123       ASSERT_TRUE(first_entry);
3124       first_entry->SetDefer(MockDiskEntry::DEFER_READ);
3125     }
3126 
3127     c->result = c->trans->Start(this_request, c->callback.callback(),
3128                                 NetLogWithSource());
3129 
3130     // Continue the transactions. 2nd will pause at the cache reading state and
3131     // 3rd transaction will doom the entry and pause before creating a new
3132     // entry.
3133     base::RunLoop().RunUntilIdle();
3134 
3135     // Check status of the entry after every transaction.
3136     switch (i) {
3137       case 0:
3138         first_entry = cache.disk_cache()->GetDiskEntryRef(request.CacheKey());
3139         break;
3140       case 1:
3141         EXPECT_FALSE(first_entry->is_doomed());
3142         break;
3143       case 2:
3144         EXPECT_TRUE(first_entry->is_doomed());
3145         break;
3146     }
3147   }
3148   // Resume cache read by 2nd transaction which will lead to dooming the entry
3149   // as well since the entry cannot be validated. This double dooming should not
3150   // lead to an assertion.
3151   first_entry->ResumeDiskEntryOperation();
3152   base::RunLoop().RunUntilIdle();
3153 
3154   // Resume creation of entry by 3rd transaction.
3155   cache.disk_cache()->ResumeCacheOperation();
3156   base::RunLoop().RunUntilIdle();
3157 
3158   // Note that since 3rd transaction's entry is already created but its
3159   // callback is deferred, MockDiskCache's implementation returns
3160   // ERR_CACHE_CREATE_FAILURE when 2nd transaction tries to create an entry
3161   // during that time, leading to it switching over to pass-through mode.
3162   // Thus the number of entries is 2 below.
3163   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3164   EXPECT_EQ(0, cache.disk_cache()->open_count());
3165   EXPECT_EQ(2, cache.disk_cache()->create_count());
3166 
3167   for (auto& context : context_list) {
3168     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
3169   }
3170 
3171   for (auto& c : context_list) {
3172     ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK);
3173   }
3174 
3175   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3176   EXPECT_EQ(0, cache.disk_cache()->open_count());
3177   EXPECT_EQ(2, cache.disk_cache()->create_count());
3178 }
3179 
3180 // Tests parallel validation on range requests with non-overlapping ranges.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationDifferentRanges)3181 TEST_F(HttpCacheTest, RangeGET_ParallelValidationDifferentRanges) {
3182   MockHttpCache cache;
3183 
3184   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3185 
3186   std::vector<std::unique_ptr<Context>> context_list;
3187   const int kNumTransactions = 2;
3188 
3189   for (int i = 0; i < kNumTransactions; ++i) {
3190     context_list.push_back(std::make_unique<Context>());
3191   }
3192 
3193   // Let 1st transaction complete headers phase for ranges 40-49.
3194   std::string first_read;
3195   MockHttpRequest request1(transaction);
3196   {
3197     auto& c = context_list[0];
3198     c->result = cache.CreateTransaction(&c->trans);
3199     ASSERT_THAT(c->result, IsOk());
3200     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3201 
3202     c->result =
3203         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3204     base::RunLoop().RunUntilIdle();
3205 
3206     // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns
3207     // true.
3208     const int kBufferSize = 5;
3209     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
3210     ReleaseBufferCompletionCallback cb(buffer.get());
3211     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3212     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3213 
3214     std::string data_read(buffer->data(), kBufferSize);
3215     first_read = data_read;
3216 
3217     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3218   }
3219 
3220   // 2nd transaction requests ranges 30-39.
3221   transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3222   MockHttpRequest request2(transaction);
3223   {
3224     auto& c = context_list[1];
3225     c->result = cache.CreateTransaction(&c->trans);
3226     ASSERT_THAT(c->result, IsOk());
3227     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3228 
3229     c->result =
3230         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3231     base::RunLoop().RunUntilIdle();
3232 
3233     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3234   }
3235 
3236   std::string cache_key = request2.CacheKey();
3237   EXPECT_TRUE(cache.IsWriterPresent(cache_key));
3238   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
3239 
3240   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3241   EXPECT_EQ(0, cache.disk_cache()->open_count());
3242   EXPECT_EQ(1, cache.disk_cache()->create_count());
3243 
3244   for (int i = 0; i < kNumTransactions; ++i) {
3245     auto& c = context_list[i];
3246     if (c->result == ERR_IO_PENDING)
3247       c->result = c->callback.WaitForResult();
3248 
3249     if (i == 0) {
3250       ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
3251                                         transaction);
3252       continue;
3253     }
3254 
3255     transaction.data = "rg: 30-39 ";
3256     ReadAndVerifyTransaction(c->trans.get(), transaction);
3257   }
3258 
3259   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3260   EXPECT_EQ(0, cache.disk_cache()->open_count());
3261   EXPECT_EQ(1, cache.disk_cache()->create_count());
3262 
3263   // Fetch from the cache to check that ranges 30-49 have been successfully
3264   // cached.
3265   {
3266     MockTransaction range_transaction(kRangeGET_TransactionOK);
3267     range_transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
3268     range_transaction.data = "rg: 30-39 rg: 40-49 ";
3269     std::string headers;
3270     RunTransactionTestWithResponse(cache.http_cache(), range_transaction,
3271                                    &headers);
3272     Verify206Response(headers, 30, 49);
3273   }
3274 
3275   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3276   EXPECT_EQ(1, cache.disk_cache()->open_count());
3277   EXPECT_EQ(1, cache.disk_cache()->create_count());
3278 
3279   context_list.clear();
3280 }
3281 
3282 // Tests that a request does not create Writers when readers is not empty.
TEST_F(HttpCacheTest,RangeGET_DoNotCreateWritersWhenReaderExists)3283 TEST_F(HttpCacheTest, RangeGET_DoNotCreateWritersWhenReaderExists) {
3284   MockHttpCache cache;
3285 
3286   // Save a request in the cache so that the next request can become a
3287   // reader.
3288   MockTransaction transaction(kRangeGET_Transaction);
3289   transaction.request_headers = EXTRA_HEADER;
3290   AddMockTransaction(&transaction);
3291   RunTransactionTest(cache.http_cache(), transaction);
3292 
3293   // Let this request be a reader since it doesn't need validation as per its
3294   // load flag.
3295   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
3296   MockHttpRequest request(transaction);
3297   Context context;
3298   context.result = cache.CreateTransaction(&context.trans);
3299   ASSERT_THAT(context.result, IsOk());
3300   context.result = context.trans->Start(&request, context.callback.callback(),
3301                                         NetLogWithSource());
3302   base::RunLoop().RunUntilIdle();
3303   std::string cache_key = request.CacheKey();
3304   EXPECT_EQ(1, cache.GetCountReaders(cache_key));
3305   RemoveMockTransaction(&transaction);
3306 
3307   // A range request should now "not" create Writers while readers is still
3308   // non-empty.
3309   MockTransaction range_transaction(kRangeGET_Transaction);
3310   range_transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
3311   AddMockTransaction(&range_transaction);
3312   MockHttpRequest range_request(range_transaction);
3313   Context range_context;
3314   range_context.result = cache.CreateTransaction(&range_context.trans);
3315   ASSERT_THAT(range_context.result, IsOk());
3316   range_context.result = range_context.trans->Start(
3317       &range_request, range_context.callback.callback(), NetLogWithSource());
3318   base::RunLoop().RunUntilIdle();
3319 
3320   EXPECT_EQ(1, cache.GetCountReaders(cache_key));
3321   EXPECT_FALSE(cache.IsWriterPresent(cache_key));
3322   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
3323 
3324   RemoveMockTransaction(&range_transaction);
3325 }
3326 
3327 // Tests parallel validation on range requests can be successfully restarted
3328 // when there is a cache lock timeout.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationCacheLockTimeout)3329 TEST_F(HttpCacheTest, RangeGET_ParallelValidationCacheLockTimeout) {
3330   MockHttpCache cache;
3331 
3332   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3333 
3334   std::vector<std::unique_ptr<Context>> context_list;
3335   const int kNumTransactions = 2;
3336 
3337   for (int i = 0; i < kNumTransactions; ++i) {
3338     context_list.push_back(std::make_unique<Context>());
3339   }
3340 
3341   // Let 1st transaction complete headers phase for ranges 40-49.
3342   std::string first_read;
3343   MockHttpRequest request1(transaction);
3344   {
3345     auto& c = context_list[0];
3346     c->result = cache.CreateTransaction(&c->trans);
3347     ASSERT_THAT(c->result, IsOk());
3348     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3349 
3350     c->result =
3351         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3352     base::RunLoop().RunUntilIdle();
3353 
3354     // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns
3355     // true.
3356     const int kBufferSize = 5;
3357     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
3358     ReleaseBufferCompletionCallback cb(buffer.get());
3359     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3360     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3361 
3362     std::string data_read(buffer->data(), kBufferSize);
3363     first_read = data_read;
3364 
3365     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3366   }
3367 
3368   // Cache lock timeout will lead to dooming the entry since the transaction may
3369   // have already written the headers.
3370   cache.SimulateCacheLockTimeoutAfterHeaders();
3371 
3372   // 2nd transaction requests ranges 30-39.
3373   transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3374   MockHttpRequest request2(transaction);
3375   {
3376     auto& c = context_list[1];
3377     c->result = cache.CreateTransaction(&c->trans);
3378     ASSERT_THAT(c->result, IsOk());
3379     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3380 
3381     c->result =
3382         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3383     base::RunLoop().RunUntilIdle();
3384 
3385     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3386   }
3387 
3388   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(request1.CacheKey()));
3389 
3390   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3391   EXPECT_EQ(0, cache.disk_cache()->open_count());
3392   EXPECT_EQ(1, cache.disk_cache()->create_count());
3393 
3394   for (int i = 0; i < kNumTransactions; ++i) {
3395     auto& c = context_list[i];
3396     if (c->result == ERR_IO_PENDING)
3397       c->result = c->callback.WaitForResult();
3398 
3399     if (i == 0) {
3400       ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
3401                                         transaction);
3402       continue;
3403     }
3404 
3405     transaction.data = "rg: 30-39 ";
3406     ReadAndVerifyTransaction(c->trans.get(), transaction);
3407   }
3408 
3409   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3410   EXPECT_EQ(0, cache.disk_cache()->open_count());
3411   EXPECT_EQ(1, cache.disk_cache()->create_count());
3412 }
3413 
3414 // Tests a full request and a simultaneous range request and the range request
3415 // dooms the entry created by the full request due to not being able to
3416 // conditionalize.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationCouldntConditionalize)3417 TEST_F(HttpCacheTest, RangeGET_ParallelValidationCouldntConditionalize) {
3418   MockHttpCache cache;
3419 
3420   MockTransaction mock_transaction(kSimpleGET_Transaction);
3421   mock_transaction.url = kRangeGET_TransactionOK.url;
3422   ScopedMockTransaction transaction(mock_transaction);
3423 
3424   // Remove the cache-control and other headers so that the response cannot be
3425   // conditionalized.
3426   transaction.response_headers = "";
3427 
3428   std::vector<std::unique_ptr<Context>> context_list;
3429   const int kNumTransactions = 2;
3430 
3431   for (int i = 0; i < kNumTransactions; ++i) {
3432     context_list.push_back(std::make_unique<Context>());
3433   }
3434 
3435   // Let 1st transaction complete headers phase for no range and read some part
3436   // of the response and write in the cache.
3437   std::string first_read;
3438   MockHttpRequest request1(transaction);
3439   {
3440     request1.url = GURL(kRangeGET_TransactionOK.url);
3441     auto& c = context_list[0];
3442     c->result = cache.CreateTransaction(&c->trans);
3443     ASSERT_THAT(c->result, IsOk());
3444     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3445 
3446     c->result =
3447         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3448     base::RunLoop().RunUntilIdle();
3449 
3450     const int kBufferSize = 5;
3451     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
3452     ReleaseBufferCompletionCallback cb(buffer.get());
3453     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3454     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3455 
3456     std::string data_read(buffer->data(), kBufferSize);
3457     first_read = data_read;
3458 
3459     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3460   }
3461 
3462   // 2nd transaction requests a range.
3463   ScopedMockTransaction range_transaction(kRangeGET_TransactionOK);
3464   range_transaction.request_headers = "Range: bytes = 0-29\r\n" EXTRA_HEADER;
3465   MockHttpRequest request2(range_transaction);
3466   {
3467     auto& c = context_list[1];
3468     c->result = cache.CreateTransaction(&c->trans);
3469     ASSERT_THAT(c->result, IsOk());
3470     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3471 
3472     c->result =
3473         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3474     base::RunLoop().RunUntilIdle();
3475 
3476     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3477   }
3478 
3479   // The second request would have doomed the 1st entry and created a new entry.
3480   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3481   EXPECT_EQ(0, cache.disk_cache()->open_count());
3482   EXPECT_EQ(2, cache.disk_cache()->create_count());
3483 
3484   for (int i = 0; i < kNumTransactions; ++i) {
3485     auto& c = context_list[i];
3486     if (c->result == ERR_IO_PENDING)
3487       c->result = c->callback.WaitForResult();
3488 
3489     if (i == 0) {
3490       ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
3491                                         transaction);
3492       continue;
3493     }
3494     range_transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 ";
3495     ReadAndVerifyTransaction(c->trans.get(), range_transaction);
3496   }
3497   context_list.clear();
3498 }
3499 
3500 // Tests a 200 request and a simultaneous range request where conditionalization
3501 // is possible.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationCouldConditionalize)3502 TEST_F(HttpCacheTest, RangeGET_ParallelValidationCouldConditionalize) {
3503   MockHttpCache cache;
3504 
3505   MockTransaction mock_transaction(kSimpleGET_Transaction);
3506   mock_transaction.url = kRangeGET_TransactionOK.url;
3507   mock_transaction.data = kFullRangeData;
3508   std::string response_headers_str = base::StrCat(
3509       {"ETag: StrongOne\n",
3510        "Content-Length:", base::NumberToString(strlen(kFullRangeData)), "\n"});
3511   mock_transaction.response_headers = response_headers_str.c_str();
3512 
3513   ScopedMockTransaction transaction(mock_transaction);
3514 
3515   std::vector<std::unique_ptr<Context>> context_list;
3516   const int kNumTransactions = 2;
3517 
3518   for (int i = 0; i < kNumTransactions; ++i) {
3519     context_list.push_back(std::make_unique<Context>());
3520   }
3521 
3522   // Let 1st transaction complete headers phase for no range and read some part
3523   // of the response and write in the cache.
3524   std::string first_read;
3525   MockHttpRequest request1(transaction);
3526   {
3527     request1.url = GURL(kRangeGET_TransactionOK.url);
3528     auto& c = context_list[0];
3529     c->result = cache.CreateTransaction(&c->trans);
3530     ASSERT_THAT(c->result, IsOk());
3531     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3532 
3533     c->result =
3534         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3535     base::RunLoop().RunUntilIdle();
3536 
3537     const int kBufferSize = 5;
3538     auto buffer = base::MakeRefCounted<IOBufferWithSize>(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     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
3614     ReleaseBufferCompletionCallback cb(buffer.get());
3615     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3616     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3617 
3618     std::string data_read(buffer->data(), kBufferSize);
3619     first_read = data_read;
3620 
3621     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3622   }
3623 
3624   // 2nd transaction requests ranges 30-49.
3625   transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
3626   MockHttpRequest request2(transaction);
3627   {
3628     auto& c = context_list[1];
3629     c->result = cache.CreateTransaction(&c->trans);
3630     ASSERT_THAT(c->result, IsOk());
3631     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3632 
3633     c->result =
3634         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3635     base::RunLoop().RunUntilIdle();
3636 
3637     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3638   }
3639 
3640   std::string cache_key = request1.CacheKey();
3641   EXPECT_TRUE(cache.IsWriterPresent(cache_key));
3642   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
3643 
3644   // Should have created another transaction for the uncached range.
3645   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3646   EXPECT_EQ(0, cache.disk_cache()->open_count());
3647   EXPECT_EQ(1, cache.disk_cache()->create_count());
3648 
3649   for (int i = 0; i < kNumTransactions; ++i) {
3650     auto& c = context_list[i];
3651     if (c->result == ERR_IO_PENDING)
3652       c->result = c->callback.WaitForResult();
3653 
3654     if (i == 0) {
3655       ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
3656                                         transaction);
3657       continue;
3658     }
3659 
3660     transaction.data = "rg: 30-39 rg: 40-49 ";
3661     ReadAndVerifyTransaction(c->trans.get(), transaction);
3662   }
3663 
3664   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3665   EXPECT_EQ(0, cache.disk_cache()->open_count());
3666   EXPECT_EQ(1, cache.disk_cache()->create_count());
3667 
3668   // Fetch from the cache to check that ranges 30-49 have been successfully
3669   // cached.
3670   {
3671     MockTransaction range_transaction(kRangeGET_TransactionOK);
3672     range_transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
3673     range_transaction.data = "rg: 30-39 rg: 40-49 ";
3674     std::string headers;
3675     RunTransactionTestWithResponse(cache.http_cache(), range_transaction,
3676                                    &headers);
3677     Verify206Response(headers, 30, 49);
3678   }
3679 
3680   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3681   EXPECT_EQ(0, cache.disk_cache()->open_count());
3682   EXPECT_EQ(1, cache.disk_cache()->create_count());
3683 }
3684 
3685 // Tests parallel validation on range requests with overlapping ranges and the
3686 // impact of deleting the writer on transactions that have validated.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationRestartDoneHeaders)3687 TEST_F(HttpCacheTest, RangeGET_ParallelValidationRestartDoneHeaders) {
3688   MockHttpCache cache;
3689 
3690   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3691 
3692   std::vector<std::unique_ptr<Context>> context_list;
3693   const int kNumTransactions = 2;
3694 
3695   for (int i = 0; i < kNumTransactions; ++i) {
3696     context_list.push_back(std::make_unique<Context>());
3697   }
3698 
3699   // Let 1st transaction complete headers phase for ranges 40-59.
3700   std::string first_read;
3701   transaction.request_headers = "Range: bytes = 40-59\r\n" EXTRA_HEADER;
3702   MockHttpRequest request1(transaction);
3703   {
3704     auto& c = context_list[0];
3705     c->result = cache.CreateTransaction(&c->trans);
3706     ASSERT_THAT(c->result, IsOk());
3707     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3708 
3709     c->result =
3710         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3711     base::RunLoop().RunUntilIdle();
3712 
3713     // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns
3714     // true.
3715     const int kBufferSize = 10;
3716     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
3717     ReleaseBufferCompletionCallback cb(buffer.get());
3718     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3719     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3720 
3721     std::string data_read(buffer->data(), kBufferSize);
3722     first_read = data_read;
3723 
3724     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3725   }
3726 
3727   // 2nd transaction requests ranges 30-59.
3728   transaction.request_headers = "Range: bytes = 30-59\r\n" EXTRA_HEADER;
3729   MockHttpRequest request2(transaction);
3730   {
3731     auto& c = context_list[1];
3732     c->result = cache.CreateTransaction(&c->trans);
3733     ASSERT_THAT(c->result, IsOk());
3734     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3735 
3736     c->result =
3737         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3738     base::RunLoop().RunUntilIdle();
3739 
3740     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3741   }
3742 
3743   std::string cache_key = request1.CacheKey();
3744   EXPECT_TRUE(cache.IsWriterPresent(cache_key));
3745   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
3746 
3747   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3748   EXPECT_EQ(0, cache.disk_cache()->open_count());
3749   EXPECT_EQ(1, cache.disk_cache()->create_count());
3750 
3751   // Delete the writer transaction.
3752   context_list[0].reset();
3753 
3754   base::RunLoop().RunUntilIdle();
3755 
3756   transaction.data = "rg: 30-39 rg: 40-49 rg: 50-59 ";
3757   ReadAndVerifyTransaction(context_list[1]->trans.get(), transaction);
3758 
3759   // Create another network transaction since the 2nd transaction is restarted.
3760   // 30-39 will be read from network, 40-49 from the cache and 50-59 from the
3761   // network.
3762   EXPECT_EQ(4, cache.network_layer()->transaction_count());
3763   EXPECT_EQ(0, cache.disk_cache()->open_count());
3764   EXPECT_EQ(1, cache.disk_cache()->create_count());
3765 
3766   // Fetch from the cache to check that ranges 30-49 have been successfully
3767   // cached.
3768   {
3769     MockTransaction range_transaction(kRangeGET_TransactionOK);
3770     range_transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
3771     range_transaction.data = "rg: 30-39 rg: 40-49 ";
3772     std::string headers;
3773     RunTransactionTestWithResponse(cache.http_cache(), range_transaction,
3774                                    &headers);
3775     Verify206Response(headers, 30, 49);
3776   }
3777 
3778   EXPECT_EQ(4, cache.network_layer()->transaction_count());
3779   EXPECT_EQ(1, cache.disk_cache()->open_count());
3780   EXPECT_EQ(1, cache.disk_cache()->create_count());
3781 }
3782 
3783 // A test of doing a range request to a cached 301 response
TEST_F(HttpCacheTest,RangeGET_CachedRedirect)3784 TEST_F(HttpCacheTest, RangeGET_CachedRedirect) {
3785   RangeTransactionServer handler;
3786   handler.set_redirect(true);
3787 
3788   MockHttpCache cache;
3789   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3790   transaction.request_headers = "Range: bytes = 0-\r\n" EXTRA_HEADER;
3791   transaction.status = "HTTP/1.1 301 Moved Permanently";
3792   transaction.response_headers = "Location: /elsewhere\nContent-Length:5";
3793   transaction.data = "12345";
3794   MockHttpRequest request(transaction);
3795 
3796   TestCompletionCallback callback;
3797 
3798   // Write to the cache.
3799   {
3800     std::unique_ptr<HttpTransaction> trans;
3801     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
3802 
3803     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
3804     if (rv == ERR_IO_PENDING)
3805       rv = callback.WaitForResult();
3806     ASSERT_THAT(rv, IsOk());
3807 
3808     const HttpResponseInfo* info = trans->GetResponseInfo();
3809     ASSERT_TRUE(info);
3810 
3811     EXPECT_EQ(info->headers->response_code(), 301);
3812 
3813     std::string location;
3814     info->headers->EnumerateHeader(nullptr, "Location", &location);
3815     EXPECT_EQ(location, "/elsewhere");
3816 
3817     ReadAndVerifyTransaction(trans.get(), transaction);
3818   }
3819   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3820   EXPECT_EQ(0, cache.disk_cache()->open_count());
3821   EXPECT_EQ(1, cache.disk_cache()->create_count());
3822 
3823   // Active entries in the cache are not retired synchronously. Make
3824   // sure the next run hits the MockHttpCache and open_count is
3825   // correct.
3826   base::RunLoop().RunUntilIdle();
3827 
3828   // Read from the cache.
3829   {
3830     std::unique_ptr<HttpTransaction> trans;
3831     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
3832 
3833     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
3834     if (rv == ERR_IO_PENDING)
3835       rv = callback.WaitForResult();
3836     ASSERT_THAT(rv, IsOk());
3837 
3838     const HttpResponseInfo* info = trans->GetResponseInfo();
3839     ASSERT_TRUE(info);
3840 
3841     EXPECT_EQ(info->headers->response_code(), 301);
3842 
3843     std::string location;
3844     info->headers->EnumerateHeader(nullptr, "Location", &location);
3845     EXPECT_EQ(location, "/elsewhere");
3846 
3847     trans->DoneReading();
3848   }
3849   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3850   EXPECT_EQ(1, cache.disk_cache()->open_count());
3851   EXPECT_EQ(1, cache.disk_cache()->create_count());
3852 
3853   // Now read the full body. This normally would not be done for a 301 by
3854   // higher layers, but e.g. a 500 could hit a further bug here.
3855   {
3856     std::unique_ptr<HttpTransaction> trans;
3857     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
3858 
3859     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
3860     if (rv == ERR_IO_PENDING)
3861       rv = callback.WaitForResult();
3862     ASSERT_THAT(rv, IsOk());
3863 
3864     const HttpResponseInfo* info = trans->GetResponseInfo();
3865     ASSERT_TRUE(info);
3866 
3867     EXPECT_EQ(info->headers->response_code(), 301);
3868 
3869     std::string location;
3870     info->headers->EnumerateHeader(nullptr, "Location", &location);
3871     EXPECT_EQ(location, "/elsewhere");
3872 
3873     ReadAndVerifyTransaction(trans.get(), transaction);
3874   }
3875   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3876   // No extra open since it picks up a previous ActiveEntry.
3877   EXPECT_EQ(1, cache.disk_cache()->open_count());
3878   EXPECT_EQ(1, cache.disk_cache()->create_count());
3879 }
3880 
3881 // A transaction that fails to validate an entry, while attempting to write
3882 // the response, should still get data to its consumer even if the attempt to
3883 // create a new entry fails.
TEST_F(HttpCacheTest,SimpleGET_ValidationFailureWithCreateFailure)3884 TEST_F(HttpCacheTest, SimpleGET_ValidationFailureWithCreateFailure) {
3885   MockHttpCache cache;
3886   MockHttpRequest request(kSimpleGET_Transaction);
3887   request.load_flags |= LOAD_VALIDATE_CACHE;
3888   std::vector<std::unique_ptr<Context>> context_list;
3889 
3890   // Create and run the first, successful, transaction to prime the cache.
3891   context_list.push_back(std::make_unique<Context>());
3892   auto& c1 = context_list.back();
3893   c1->result = cache.CreateTransaction(&c1->trans);
3894   ASSERT_THAT(c1->result, IsOk());
3895   EXPECT_EQ(LOAD_STATE_IDLE, c1->trans->GetLoadState());
3896   c1->result =
3897       c1->trans->Start(&request, c1->callback.callback(), NetLogWithSource());
3898   EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, c1->trans->GetLoadState());
3899   base::RunLoop().RunUntilIdle();
3900 
3901   EXPECT_TRUE(cache.IsWriterPresent(request.CacheKey()));
3902   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3903   EXPECT_EQ(0, cache.disk_cache()->open_count());
3904   EXPECT_EQ(1, cache.disk_cache()->create_count());
3905 
3906   // Create and start the second transaction, which will fail its validation
3907   // during the call to RunUntilIdle().
3908   context_list.push_back(std::make_unique<Context>());
3909   auto& c2 = context_list.back();
3910   c2->result = cache.CreateTransaction(&c2->trans);
3911   ASSERT_THAT(c2->result, IsOk());
3912   EXPECT_EQ(LOAD_STATE_IDLE, c2->trans->GetLoadState());
3913   c2->result =
3914       c2->trans->Start(&request, c2->callback.callback(), NetLogWithSource());
3915   // Expect idle at this point because we should be able to find and use the
3916   // Active Entry that c1 created instead of waiting on the cache to open the
3917   // entry.
3918   EXPECT_EQ(LOAD_STATE_IDLE, c2->trans->GetLoadState());
3919 
3920   cache.disk_cache()->set_fail_requests(true);
3921   // The transaction, c2, should now attempt to validate the entry, fail when it
3922   // receives a 200 OK response, attempt to create a new entry, fail to create,
3923   // and then continue onward without an entry.
3924   base::RunLoop().RunUntilIdle();
3925 
3926   // All requests depend on the writer, and the writer is between Start and
3927   // Read, i.e. idle.
3928   for (auto& context : context_list) {
3929     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
3930   }
3931 
3932   // Confirm that both transactions correctly Read() the data.
3933   for (auto& context : context_list) {
3934     if (context->result == ERR_IO_PENDING)
3935       context->result = context->callback.WaitForResult();
3936     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
3937   }
3938 
3939   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3940   EXPECT_EQ(0, cache.disk_cache()->open_count());
3941   EXPECT_EQ(1, cache.disk_cache()->create_count());
3942 }
3943 
3944 // Parallel validation results in 200.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationNoMatch)3945 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationNoMatch) {
3946   MockHttpCache cache;
3947   MockHttpRequest request(kSimpleGET_Transaction);
3948   request.load_flags |= LOAD_VALIDATE_CACHE;
3949   std::vector<std::unique_ptr<Context>> context_list;
3950   const int kNumTransactions = 5;
3951   for (int i = 0; i < kNumTransactions; ++i) {
3952     context_list.push_back(std::make_unique<Context>());
3953     auto& c = context_list[i];
3954     c->result = cache.CreateTransaction(&c->trans);
3955     ASSERT_THAT(c->result, IsOk());
3956     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3957     c->result =
3958         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
3959   }
3960 
3961   // All requests are waiting for the active entry.
3962   for (auto& context : context_list) {
3963     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
3964   }
3965 
3966   // Allow all requests to move from the Create queue to the active entry.
3967   base::RunLoop().RunUntilIdle();
3968 
3969   // The first request should be a writer at this point, and the subsequent
3970   // requests should have passed the validation phase and created their own
3971   // entries since none of them matched the headers of the earlier one.
3972   EXPECT_TRUE(cache.IsWriterPresent(request.CacheKey()));
3973 
3974   EXPECT_EQ(5, cache.network_layer()->transaction_count());
3975   EXPECT_EQ(0, cache.disk_cache()->open_count());
3976   EXPECT_EQ(5, cache.disk_cache()->create_count());
3977 
3978   // All requests depend on the writer, and the writer is between Start and
3979   // Read, i.e. idle.
3980   for (auto& context : context_list) {
3981     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
3982   }
3983 
3984   for (auto& context : context_list) {
3985     if (context->result == ERR_IO_PENDING)
3986       context->result = context->callback.WaitForResult();
3987     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
3988   }
3989 
3990   EXPECT_EQ(5, cache.network_layer()->transaction_count());
3991   EXPECT_EQ(0, cache.disk_cache()->open_count());
3992   EXPECT_EQ(5, cache.disk_cache()->create_count());
3993 }
3994 
TEST_F(HttpCacheTest,RangeGET_Enormous)3995 TEST_F(HttpCacheTest, RangeGET_Enormous) {
3996   // Test for how blockfile's limit on range namespace interacts with
3997   // HttpCache::Transaction.
3998   // See https://crbug.com/770694
3999   base::ScopedTempDir temp_dir;
4000   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
4001 
4002   auto backend_factory = std::make_unique<HttpCache::DefaultBackend>(
4003       DISK_CACHE, CACHE_BACKEND_BLOCKFILE,
4004       /*file_operations_factory=*/nullptr, temp_dir.GetPath(), 1024 * 1024,
4005       false);
4006   MockHttpCache cache(std::move(backend_factory));
4007 
4008   RangeTransactionServer handler;
4009   handler.set_length(2305843009213693962);
4010 
4011   // Prime with a range it can store.
4012   {
4013     ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4014     transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
4015     transaction.data = "rg: 00-09 ";
4016     MockHttpRequest request(transaction);
4017 
4018     HttpResponseInfo response;
4019     RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
4020                                   &response);
4021     ASSERT_TRUE(response.headers != nullptr);
4022     EXPECT_EQ(206, response.headers->response_code());
4023     EXPECT_EQ(1, cache.network_layer()->transaction_count());
4024   }
4025 
4026   // Try with a range it can't. Should still work.
4027   {
4028     ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4029     transaction.request_headers =
4030         "Range: bytes = "
4031         "2305843009213693952-2305843009213693961\r\n" EXTRA_HEADER;
4032     transaction.data = "rg: 52-61 ";
4033     MockHttpRequest request(transaction);
4034 
4035     HttpResponseInfo response;
4036     RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
4037                                   &response);
4038     ASSERT_TRUE(response.headers != nullptr);
4039     EXPECT_EQ(206, response.headers->response_code());
4040     EXPECT_EQ(2, cache.network_layer()->transaction_count());
4041   }
4042 
4043   // Can't actually cache it due to backend limitations. If the network
4044   // transaction count is 2, this test isn't covering what it needs to.
4045   {
4046     ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4047     transaction.request_headers =
4048         "Range: bytes = "
4049         "2305843009213693952-2305843009213693961\r\n" EXTRA_HEADER;
4050     transaction.data = "rg: 52-61 ";
4051     MockHttpRequest request(transaction);
4052 
4053     HttpResponseInfo response;
4054     RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
4055                                   &response);
4056     ASSERT_TRUE(response.headers != nullptr);
4057     EXPECT_EQ(206, response.headers->response_code());
4058     EXPECT_EQ(3, cache.network_layer()->transaction_count());
4059   }
4060 }
4061 
4062 // Parallel validation results in 200 for 1 transaction and validation matches
4063 // for subsequent transactions.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationNoMatch1)4064 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationNoMatch1) {
4065   MockHttpCache cache;
4066   MockHttpRequest request(kSimpleGET_Transaction);
4067 
4068   MockTransaction transaction(kSimpleGET_Transaction);
4069   transaction.load_flags |= LOAD_VALIDATE_CACHE;
4070   MockHttpRequest validate_request(transaction);
4071   std::vector<std::unique_ptr<Context>> context_list;
4072   const int kNumTransactions = 5;
4073   for (int i = 0; i < kNumTransactions; ++i) {
4074     context_list.push_back(std::make_unique<Context>());
4075     auto& c = context_list[i];
4076     c->result = cache.CreateTransaction(&c->trans);
4077     ASSERT_THAT(c->result, IsOk());
4078     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
4079 
4080     MockHttpRequest* this_request = &request;
4081     if (i == 1)
4082       this_request = &validate_request;
4083 
4084     c->result = c->trans->Start(this_request, c->callback.callback(),
4085                                 NetLogWithSource());
4086   }
4087 
4088   // All requests are waiting for the active entry.
4089   for (auto& context : context_list) {
4090     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
4091   }
4092 
4093   // Allow all requests to move from the Create queue to the active entry.
4094   base::RunLoop().RunUntilIdle();
4095 
4096   // The new entry will have all the transactions except the first one which
4097   // will continue in the doomed entry.
4098   EXPECT_EQ(kNumTransactions - 1,
4099             cache.GetCountWriterTransactions(validate_request.CacheKey()));
4100 
4101   EXPECT_EQ(1, cache.disk_cache()->doomed_count());
4102 
4103   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4104   EXPECT_EQ(0, cache.disk_cache()->open_count());
4105   EXPECT_EQ(2, cache.disk_cache()->create_count());
4106 
4107   for (auto& context : context_list) {
4108     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
4109   }
4110 
4111   for (auto& context : context_list) {
4112     if (context->result == ERR_IO_PENDING)
4113       context->result = context->callback.WaitForResult();
4114 
4115     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
4116   }
4117 
4118   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4119   EXPECT_EQ(0, cache.disk_cache()->open_count());
4120   EXPECT_EQ(2, cache.disk_cache()->create_count());
4121 }
4122 
4123 // Tests that a GET followed by a DELETE results in DELETE immediately starting
4124 // the headers phase and the entry is doomed.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationDelete)4125 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationDelete) {
4126   MockHttpCache cache;
4127 
4128   MockHttpRequest request(kSimpleGET_Transaction);
4129   request.load_flags |= LOAD_VALIDATE_CACHE;
4130 
4131   MockHttpRequest delete_request(kSimpleGET_Transaction);
4132   delete_request.method = "DELETE";
4133 
4134   std::vector<std::unique_ptr<Context>> context_list;
4135   const int kNumTransactions = 2;
4136 
4137   for (int i = 0; i < kNumTransactions; ++i) {
4138     context_list.push_back(std::make_unique<Context>());
4139     auto& c = context_list[i];
4140 
4141     MockHttpRequest* this_request = &request;
4142     if (i == 1)
4143       this_request = &delete_request;
4144 
4145     c->result = cache.CreateTransaction(&c->trans);
4146     ASSERT_THAT(c->result, IsOk());
4147     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
4148 
4149     c->result = c->trans->Start(this_request, c->callback.callback(),
4150                                 NetLogWithSource());
4151   }
4152 
4153   // All requests are waiting for the active entry.
4154   for (auto& context : context_list) {
4155     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
4156   }
4157 
4158   // Allow all requests to move from the Create queue to the active entry.
4159   base::RunLoop().RunUntilIdle();
4160 
4161   // The first request should be a writer at this point, and the subsequent
4162   // request should have passed the validation phase and doomed the existing
4163   // entry.
4164   EXPECT_TRUE(cache.disk_cache()->IsDiskEntryDoomed(request.CacheKey()));
4165 
4166   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4167   EXPECT_EQ(0, cache.disk_cache()->open_count());
4168   EXPECT_EQ(1, cache.disk_cache()->create_count());
4169 
4170   // All requests depend on the writer, and the writer is between Start and
4171   // Read, i.e. idle.
4172   for (auto& context : context_list) {
4173     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
4174   }
4175 
4176   for (auto& context : context_list) {
4177     if (context->result == ERR_IO_PENDING)
4178       context->result = context->callback.WaitForResult();
4179     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
4180   }
4181 
4182   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4183   EXPECT_EQ(0, cache.disk_cache()->open_count());
4184   EXPECT_EQ(1, cache.disk_cache()->create_count());
4185 }
4186 
4187 // Tests that a transaction which is in validated queue can be destroyed without
4188 // any impact to other transactions.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationCancelValidated)4189 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationCancelValidated) {
4190   MockHttpCache cache;
4191 
4192   MockHttpRequest request(kSimpleGET_Transaction);
4193 
4194   MockTransaction transaction(kSimpleGET_Transaction);
4195   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
4196   MockHttpRequest read_only_request(transaction);
4197 
4198   std::vector<std::unique_ptr<Context>> context_list;
4199   const int kNumTransactions = 2;
4200 
4201   for (int i = 0; i < kNumTransactions; ++i) {
4202     context_list.push_back(std::make_unique<Context>());
4203     auto& c = context_list[i];
4204 
4205     c->result = cache.CreateTransaction(&c->trans);
4206     ASSERT_THAT(c->result, IsOk());
4207 
4208     MockHttpRequest* current_request = i == 1 ? &read_only_request : &request;
4209 
4210     c->result = c->trans->Start(current_request, c->callback.callback(),
4211                                 NetLogWithSource());
4212   }
4213 
4214   // Allow all requests to move from the Create queue to the active entry.
4215   base::RunLoop().RunUntilIdle();
4216 
4217   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4218   EXPECT_EQ(0, cache.disk_cache()->open_count());
4219   EXPECT_EQ(1, cache.disk_cache()->create_count());
4220 
4221   std::string cache_key = request.CacheKey();
4222   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
4223   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
4224 
4225   context_list[1].reset();
4226 
4227   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(cache_key));
4228 
4229   // Complete the rest of the transactions.
4230   for (auto& context : context_list) {
4231     if (!context)
4232       continue;
4233     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
4234   }
4235 
4236   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4237   EXPECT_EQ(0, cache.disk_cache()->open_count());
4238   EXPECT_EQ(1, cache.disk_cache()->create_count());
4239 }
4240 
4241 // Tests that an idle writer transaction can be deleted without impacting the
4242 // existing writers.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingCancelIdleTransaction)4243 TEST_F(HttpCacheTest, SimpleGET_ParallelWritingCancelIdleTransaction) {
4244   MockHttpCache cache;
4245 
4246   MockHttpRequest request(kSimpleGET_Transaction);
4247 
4248   std::vector<std::unique_ptr<Context>> context_list;
4249   const int kNumTransactions = 2;
4250 
4251   for (int i = 0; i < kNumTransactions; ++i) {
4252     context_list.push_back(std::make_unique<Context>());
4253     auto& c = context_list[i];
4254 
4255     c->result = cache.CreateTransaction(&c->trans);
4256     ASSERT_THAT(c->result, IsOk());
4257 
4258     c->result =
4259         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
4260   }
4261 
4262   // Allow all requests to move from the Create queue to the active entry.
4263   base::RunLoop().RunUntilIdle();
4264 
4265   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4266   EXPECT_EQ(0, cache.disk_cache()->open_count());
4267   EXPECT_EQ(1, cache.disk_cache()->create_count());
4268 
4269   // Both transactions would be added to writers.
4270   std::string cache_key = request.CacheKey();
4271   EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
4272 
4273   context_list[1].reset();
4274 
4275   EXPECT_EQ(kNumTransactions - 1, cache.GetCountWriterTransactions(cache_key));
4276 
4277   // Complete the rest of the transactions.
4278   for (auto& context : context_list) {
4279     if (!context)
4280       continue;
4281     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
4282   }
4283 
4284   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4285   EXPECT_EQ(0, cache.disk_cache()->open_count());
4286   EXPECT_EQ(1, cache.disk_cache()->create_count());
4287 }
4288 
4289 // Tests that a transaction which is in validated queue can timeout and start
4290 // the headers phase again.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationValidatedTimeout)4291 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationValidatedTimeout) {
4292   MockHttpCache cache;
4293 
4294   MockHttpRequest request(kSimpleGET_Transaction);
4295 
4296   MockTransaction transaction(kSimpleGET_Transaction);
4297   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
4298   MockHttpRequest read_only_request(transaction);
4299 
4300   std::vector<std::unique_ptr<Context>> context_list;
4301   const int kNumTransactions = 2;
4302 
4303   for (int i = 0; i < kNumTransactions; ++i) {
4304     context_list.push_back(std::make_unique<Context>());
4305     auto& c = context_list[i];
4306 
4307     MockHttpRequest* this_request = &request;
4308     if (i == 1) {
4309       this_request = &read_only_request;
4310       cache.SimulateCacheLockTimeoutAfterHeaders();
4311     }
4312 
4313     c->result = cache.CreateTransaction(&c->trans);
4314     ASSERT_THAT(c->result, IsOk());
4315 
4316     c->result = c->trans->Start(this_request, c->callback.callback(),
4317                                 NetLogWithSource());
4318   }
4319 
4320   // Allow all requests to move from the Create queue to the active entry.
4321   base::RunLoop().RunUntilIdle();
4322 
4323   // The first request should be a writer at this point, and the subsequent
4324   // requests should have completed validation, timed out and restarted.
4325   // Since it is a read only request, it will error out.
4326 
4327   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4328   EXPECT_EQ(0, cache.disk_cache()->open_count());
4329   EXPECT_EQ(1, cache.disk_cache()->create_count());
4330 
4331   std::string cache_key = request.CacheKey();
4332   EXPECT_TRUE(cache.IsWriterPresent(cache_key));
4333   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(cache_key));
4334 
4335   base::RunLoop().RunUntilIdle();
4336 
4337   int rv = context_list[1]->callback.WaitForResult();
4338   EXPECT_EQ(ERR_CACHE_MISS, rv);
4339 
4340   ReadAndVerifyTransaction(context_list[0]->trans.get(),
4341                            kSimpleGET_Transaction);
4342 }
4343 
4344 // Tests that a transaction which is in readers can be destroyed without
4345 // any impact to other transactions.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationCancelReader)4346 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationCancelReader) {
4347   MockHttpCache cache;
4348 
4349   MockHttpRequest request(kSimpleGET_Transaction);
4350 
4351   MockTransaction transaction(kSimpleGET_Transaction);
4352   transaction.load_flags |= LOAD_VALIDATE_CACHE;
4353   MockHttpRequest validate_request(transaction);
4354 
4355   int kNumTransactions = 4;
4356   std::vector<std::unique_ptr<Context>> context_list;
4357 
4358   for (int i = 0; i < kNumTransactions; ++i) {
4359     context_list.push_back(std::make_unique<Context>());
4360     auto& c = context_list[i];
4361 
4362     c->result = cache.CreateTransaction(&c->trans);
4363     ASSERT_THAT(c->result, IsOk());
4364 
4365     MockHttpRequest* this_request = &request;
4366     if (i == 3) {
4367       this_request = &validate_request;
4368       c->trans->SetBeforeNetworkStartCallback(base::BindOnce(&DeferCallback));
4369     }
4370 
4371     c->result = c->trans->Start(this_request, c->callback.callback(),
4372                                 NetLogWithSource());
4373   }
4374 
4375   // Allow all requests to move from the Create queue to the active entry.
4376   base::RunLoop().RunUntilIdle();
4377 
4378   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4379   EXPECT_EQ(0, cache.disk_cache()->open_count());
4380   EXPECT_EQ(1, cache.disk_cache()->create_count());
4381 
4382   std::string cache_key = request.CacheKey();
4383 
4384   EXPECT_EQ(kNumTransactions - 1, cache.GetCountWriterTransactions(cache_key));
4385   EXPECT_TRUE(cache.IsHeadersTransactionPresent(cache_key));
4386 
4387   // Complete the response body.
4388   ReadAndVerifyTransaction(context_list[0]->trans.get(),
4389                            kSimpleGET_Transaction);
4390 
4391   // Rest of the transactions should move to readers.
4392   EXPECT_FALSE(cache.IsWriterPresent(cache_key));
4393   EXPECT_EQ(kNumTransactions - 2, cache.GetCountReaders(cache_key));
4394   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(cache_key));
4395   EXPECT_TRUE(cache.IsHeadersTransactionPresent(cache_key));
4396 
4397   // Add 2 new transactions.
4398   kNumTransactions = 6;
4399 
4400   for (int i = 4; i < kNumTransactions; ++i) {
4401     context_list.push_back(std::make_unique<Context>());
4402     auto& c = context_list[i];
4403 
4404     c->result = cache.CreateTransaction(&c->trans);
4405     ASSERT_THAT(c->result, IsOk());
4406 
4407     c->result =
4408         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
4409   }
4410 
4411   EXPECT_EQ(2, cache.GetCountAddToEntryQueue(cache_key));
4412 
4413   // Delete a reader.
4414   context_list[1].reset();
4415 
4416   // Deleting the reader did not impact any other transaction.
4417   EXPECT_EQ(1, cache.GetCountReaders(cache_key));
4418   EXPECT_EQ(2, cache.GetCountAddToEntryQueue(cache_key));
4419   EXPECT_TRUE(cache.IsHeadersTransactionPresent(cache_key));
4420 
4421   // Resume network start for headers_transaction. It will doom the entry as it
4422   // will be a 200 and will go to network for the response body.
4423   context_list[3]->trans->ResumeNetworkStart();
4424 
4425   // The pending transactions will be added to a new entry as writers.
4426   base::RunLoop().RunUntilIdle();
4427 
4428   EXPECT_EQ(3, cache.GetCountWriterTransactions(cache_key));
4429 
4430   // Complete the rest of the transactions.
4431   for (int i = 2; i < kNumTransactions; ++i) {
4432     ReadAndVerifyTransaction(context_list[i]->trans.get(),
4433                              kSimpleGET_Transaction);
4434   }
4435 
4436   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4437   EXPECT_EQ(0, cache.disk_cache()->open_count());
4438   EXPECT_EQ(2, cache.disk_cache()->create_count());
4439 }
4440 
4441 // Tests that when the only writer goes away, it immediately cleans up rather
4442 // than wait for the network request to finish. See https://crbug.com/804868.
TEST_F(HttpCacheTest,SimpleGET_HangingCacheWriteCleanup)4443 TEST_F(HttpCacheTest, SimpleGET_HangingCacheWriteCleanup) {
4444   MockHttpCache mock_cache;
4445   MockHttpRequest request(kSimpleGET_Transaction);
4446 
4447   std::unique_ptr<HttpTransaction> transaction;
4448   mock_cache.CreateTransaction(&transaction);
4449   TestCompletionCallback callback;
4450   int result =
4451       transaction->Start(&request, callback.callback(), NetLogWithSource());
4452 
4453   // Get the transaction ready to read.
4454   result = callback.GetResult(result);
4455 
4456   // Read the first byte.
4457   auto buffer = base::MakeRefCounted<IOBufferWithSize>(1);
4458   ReleaseBufferCompletionCallback buffer_callback(buffer.get());
4459   result = transaction->Read(buffer.get(), 1, buffer_callback.callback());
4460   EXPECT_EQ(1, buffer_callback.GetResult(result));
4461 
4462   // Read the second byte, but leave the cache write hanging.
4463   std::string cache_key = request.CacheKey();
4464   scoped_refptr<MockDiskEntry> entry =
4465       mock_cache.disk_cache()->GetDiskEntryRef(cache_key);
4466   entry->SetDefer(MockDiskEntry::DEFER_WRITE);
4467 
4468   buffer = base::MakeRefCounted<IOBufferWithSize>(1);
4469   ReleaseBufferCompletionCallback buffer_callback2(buffer.get());
4470   result = transaction->Read(buffer.get(), 1, buffer_callback2.callback());
4471   EXPECT_EQ(ERR_IO_PENDING, result);
4472   base::RunLoop().RunUntilIdle();
4473   EXPECT_TRUE(mock_cache.IsWriterPresent(cache_key));
4474 
4475   // At this point the next byte should have been read from the network but is
4476   // waiting to be written to the cache. Destroy the transaction and make sure
4477   // that everything has been cleaned up.
4478   transaction = nullptr;
4479   EXPECT_FALSE(mock_cache.IsWriterPresent(cache_key));
4480   EXPECT_FALSE(mock_cache.network_layer()->last_transaction());
4481 }
4482 
4483 // Tests that a transaction writer can be destroyed mid-read.
4484 // A waiting for read transaction should be able to read the data that was
4485 // driven by the Read started by the cancelled writer.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingCancelWriter)4486 TEST_F(HttpCacheTest, SimpleGET_ParallelWritingCancelWriter) {
4487   MockHttpCache cache;
4488 
4489   MockHttpRequest request(kSimpleGET_Transaction);
4490 
4491   MockTransaction transaction(kSimpleGET_Transaction);
4492   transaction.load_flags |= LOAD_VALIDATE_CACHE;
4493   MockHttpRequest validate_request(transaction);
4494 
4495   const int kNumTransactions = 3;
4496   std::vector<std::unique_ptr<Context>> context_list;
4497 
4498   for (int i = 0; i < kNumTransactions; ++i) {
4499     context_list.push_back(std::make_unique<Context>());
4500     auto& c = context_list[i];
4501 
4502     c->result = cache.CreateTransaction(&c->trans);
4503     ASSERT_THAT(c->result, IsOk());
4504 
4505     MockHttpRequest* this_request = &request;
4506     if (i == 2) {
4507       this_request = &validate_request;
4508       c->trans->SetBeforeNetworkStartCallback(base::BindOnce(&DeferCallback));
4509     }
4510 
4511     c->result = c->trans->Start(this_request, c->callback.callback(),
4512                                 NetLogWithSource());
4513   }
4514 
4515   // Allow all requests to move from the Create queue to the active entry.
4516   base::RunLoop().RunUntilIdle();
4517 
4518   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4519   EXPECT_EQ(0, cache.disk_cache()->open_count());
4520   EXPECT_EQ(1, cache.disk_cache()->create_count());
4521 
4522   std::string cache_key = validate_request.CacheKey();
4523   EXPECT_TRUE(cache.IsHeadersTransactionPresent(cache_key));
4524   EXPECT_EQ(2, cache.GetCountWriterTransactions(cache_key));
4525 
4526   // Initiate Read from both writers and kill 1 of them mid-read.
4527   std::string first_read;
4528   for (int i = 0; i < 2; i++) {
4529     auto& c = context_list[i];
4530     const int kBufferSize = 5;
4531     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
4532     ReleaseBufferCompletionCallback cb(buffer.get());
4533     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
4534     EXPECT_EQ(ERR_IO_PENDING, c->result);
4535     // Deleting one writer at this point will not impact other transactions
4536     // since writers contain more transactions.
4537     if (i == 1) {
4538       context_list[0].reset();
4539       base::RunLoop().RunUntilIdle();
4540       EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
4541       std::string data_read(buffer->data(), kBufferSize);
4542       first_read = data_read;
4543     }
4544   }
4545 
4546   // Resume network start for headers_transaction. It will doom the existing
4547   // entry and create a new entry due to validation returning a 200.
4548   auto& c = context_list[2];
4549   c->trans->ResumeNetworkStart();
4550 
4551   base::RunLoop().RunUntilIdle();
4552 
4553   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
4554 
4555   // Complete the rest of the transactions.
4556   for (int i = 0; i < kNumTransactions; i++) {
4557     auto& context = context_list[i];
4558     if (!context)
4559       continue;
4560     if (i == 1)
4561       ReadRemainingAndVerifyTransaction(context->trans.get(), first_read,
4562                                         kSimpleGET_Transaction);
4563     else
4564       ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
4565   }
4566 
4567   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4568   EXPECT_EQ(0, cache.disk_cache()->open_count());
4569   EXPECT_EQ(2, cache.disk_cache()->create_count());
4570 }
4571 
4572 // Tests the case when network read failure happens. Idle and waiting
4573 // transactions should fail and headers transaction should be restarted.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingNetworkReadFailed)4574 TEST_F(HttpCacheTest, SimpleGET_ParallelWritingNetworkReadFailed) {
4575   MockHttpCache cache;
4576 
4577   ScopedMockTransaction fail_transaction(kSimpleGET_Transaction);
4578   fail_transaction.read_return_code = ERR_INTERNET_DISCONNECTED;
4579   MockHttpRequest failing_request(fail_transaction);
4580 
4581   MockHttpRequest request(kSimpleGET_Transaction);
4582 
4583   MockTransaction transaction(kSimpleGET_Transaction);
4584   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
4585   MockHttpRequest read_request(transaction);
4586 
4587   const int kNumTransactions = 4;
4588   std::vector<std::unique_ptr<Context>> context_list;
4589 
4590   for (int i = 0; i < kNumTransactions; ++i) {
4591     context_list.push_back(std::make_unique<Context>());
4592     auto& c = context_list[i];
4593 
4594     c->result = cache.CreateTransaction(&c->trans);
4595     ASSERT_THAT(c->result, IsOk());
4596 
4597     MockHttpRequest* this_request = &request;
4598     if (i == 0)
4599       this_request = &failing_request;
4600     if (i == 3)
4601       this_request = &read_request;
4602 
4603     c->result = c->trans->Start(this_request, c->callback.callback(),
4604                                 NetLogWithSource());
4605   }
4606 
4607   // Allow all requests to move from the Create queue to the active entry.
4608   base::RunLoop().RunUntilIdle();
4609 
4610   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4611   EXPECT_EQ(0, cache.disk_cache()->open_count());
4612   EXPECT_EQ(1, cache.disk_cache()->create_count());
4613 
4614   std::string cache_key = read_request.CacheKey();
4615   EXPECT_EQ(3, cache.GetCountWriterTransactions(cache_key));
4616   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
4617 
4618   // Initiate Read from two writers and let the first get a network failure.
4619   for (int i = 0; i < 2; i++) {
4620     auto& c = context_list[i];
4621     const int kBufferSize = 5;
4622     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
4623     c->result =
4624         c->trans->Read(buffer.get(), kBufferSize, c->callback.callback());
4625     EXPECT_EQ(ERR_IO_PENDING, c->result);
4626   }
4627 
4628   base::RunLoop().RunUntilIdle();
4629   for (int i = 0; i < 2; i++) {
4630     auto& c = context_list[i];
4631     c->result = c->callback.WaitForResult();
4632     EXPECT_EQ(ERR_INTERNET_DISCONNECTED, c->result);
4633   }
4634 
4635   // The entry should have been doomed and destroyed and the headers transaction
4636   // restarted. Since headers transaction is read-only it will error out.
4637   auto& read_only = context_list[3];
4638   read_only->result = read_only->callback.WaitForResult();
4639   EXPECT_EQ(ERR_CACHE_MISS, read_only->result);
4640 
4641   EXPECT_FALSE(cache.IsWriterPresent(cache_key));
4642 
4643   // Invoke Read on the 3rd transaction and it should get the error code back.
4644   auto& c = context_list[2];
4645   const int kBufferSize = 5;
4646   auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
4647   c->result = c->trans->Read(buffer.get(), kBufferSize, c->callback.callback());
4648   EXPECT_EQ(ERR_INTERNET_DISCONNECTED, c->result);
4649 }
4650 
4651 // Tests the case when cache write failure happens. Idle and waiting
4652 // transactions should fail and headers transaction should be restarted.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingCacheWriteFailed)4653 TEST_F(HttpCacheTest, SimpleGET_ParallelWritingCacheWriteFailed) {
4654   MockHttpCache cache;
4655 
4656   MockHttpRequest request(kSimpleGET_Transaction);
4657 
4658   MockTransaction transaction(kSimpleGET_Transaction);
4659   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
4660   MockHttpRequest read_request(transaction);
4661 
4662   const int kNumTransactions = 4;
4663   std::vector<std::unique_ptr<Context>> context_list;
4664 
4665   for (int i = 0; i < kNumTransactions; ++i) {
4666     context_list.push_back(std::make_unique<Context>());
4667     auto& c = context_list[i];
4668 
4669     c->result = cache.CreateTransaction(&c->trans);
4670     ASSERT_THAT(c->result, IsOk());
4671 
4672     MockHttpRequest* this_request = &request;
4673     if (i == 3)
4674       this_request = &read_request;
4675 
4676     c->result = c->trans->Start(this_request, c->callback.callback(),
4677                                 NetLogWithSource());
4678   }
4679 
4680   // Allow all requests to move from the Create queue to the active entry.
4681   base::RunLoop().RunUntilIdle();
4682 
4683   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4684   EXPECT_EQ(0, cache.disk_cache()->open_count());
4685   EXPECT_EQ(1, cache.disk_cache()->create_count());
4686 
4687   std::string cache_key = read_request.CacheKey();
4688   EXPECT_EQ(3, cache.GetCountWriterTransactions(cache_key));
4689   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
4690 
4691   // Initiate Read from two writers and let the first get a cache write failure.
4692   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_ALL);
4693   // We have to open the entry again to propagate the failure flag.
4694   disk_cache::Entry* en;
4695   cache.OpenBackendEntry(cache_key, &en);
4696   en->Close();
4697   const int kBufferSize = 5;
4698   std::vector<scoped_refptr<IOBuffer>> buffer(
4699       3, base::MakeRefCounted<IOBufferWithSize>(kBufferSize));
4700   for (int i = 0; i < 2; i++) {
4701     auto& c = context_list[i];
4702     c->result =
4703         c->trans->Read(buffer[i].get(), kBufferSize, c->callback.callback());
4704     EXPECT_EQ(ERR_IO_PENDING, c->result);
4705   }
4706 
4707   std::string first_read;
4708   base::RunLoop().RunUntilIdle();
4709   for (int i = 0; i < 2; i++) {
4710     auto& c = context_list[i];
4711     c->result = c->callback.WaitForResult();
4712     if (i == 0) {
4713       EXPECT_EQ(5, c->result);
4714       std::string data_read(buffer[i]->data(), kBufferSize);
4715       first_read = data_read;
4716     } else {
4717       EXPECT_EQ(ERR_CACHE_WRITE_FAILURE, c->result);
4718     }
4719   }
4720 
4721   // The entry should have been doomed and destroyed and the headers transaction
4722   // restarted. Since headers transaction is read-only it will error out.
4723   auto& read_only = context_list[3];
4724   read_only->result = read_only->callback.WaitForResult();
4725   EXPECT_EQ(ERR_CACHE_MISS, read_only->result);
4726 
4727   EXPECT_FALSE(cache.IsWriterPresent(cache_key));
4728 
4729   // Invoke Read on the 3rd transaction and it should get the error code back.
4730   auto& c = context_list[2];
4731   c->result =
4732       c->trans->Read(buffer[2].get(), kBufferSize, c->callback.callback());
4733   EXPECT_EQ(ERR_CACHE_WRITE_FAILURE, c->result);
4734 
4735   // The first transaction should be able to continue to read from the network
4736   // without writing to the cache.
4737   auto& succ_read = context_list[0];
4738   ReadRemainingAndVerifyTransaction(succ_read->trans.get(), first_read,
4739                                     kSimpleGET_Transaction);
4740 }
4741 
4742 // Tests that POST requests do not join existing transactions for parallel
4743 // writing to the cache. Note that two POSTs only map to the same entry if their
4744 // upload data identifier is same and that should happen for back-forward case
4745 // (LOAD_ONLY_FROM_CACHE). But this test tests without LOAD_ONLY_FROM_CACHE
4746 // because read-only transactions anyways do not join parallel writing.
4747 // TODO(shivanisha) Testing this because it is allowed by the code but looks
4748 // like the code should disallow two POSTs without LOAD_ONLY_FROM_CACHE with the
4749 // same upload data identifier to map to the same entry.
TEST_F(HttpCacheTest,SimplePOST_ParallelWritingDisallowed)4750 TEST_F(HttpCacheTest, SimplePOST_ParallelWritingDisallowed) {
4751   MockHttpCache cache;
4752 
4753   MockTransaction transaction(kSimplePOST_Transaction);
4754 
4755   const int64_t kUploadId = 1;  // Just a dummy value.
4756 
4757   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
4758   element_readers.push_back(
4759       std::make_unique<UploadBytesElementReader>("hello", 5));
4760   ElementsUploadDataStream upload_data_stream(std::move(element_readers),
4761                                               kUploadId);
4762 
4763   // Note that both transactions should have the same upload_data_stream
4764   // identifier to map to the same entry.
4765   transaction.load_flags = LOAD_SKIP_CACHE_VALIDATION;
4766   MockHttpRequest request(transaction);
4767   request.upload_data_stream = &upload_data_stream;
4768 
4769   const int kNumTransactions = 2;
4770   std::vector<std::unique_ptr<Context>> context_list;
4771 
4772   for (int i = 0; i < kNumTransactions; ++i) {
4773     context_list.push_back(std::make_unique<Context>());
4774     auto& c = context_list[i];
4775 
4776     c->result = cache.CreateTransaction(&c->trans);
4777     ASSERT_THAT(c->result, IsOk());
4778 
4779     c->result =
4780         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
4781 
4782     // Complete the headers phase request.
4783     base::RunLoop().RunUntilIdle();
4784   }
4785 
4786   std::string cache_key = request.CacheKey();
4787   // Only the 1st transaction gets added to writers.
4788   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
4789   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
4790 
4791   // Read the 1st transaction.
4792   ReadAndVerifyTransaction(context_list[0]->trans.get(),
4793                            kSimplePOST_Transaction);
4794 
4795   // 2nd transaction should now become a reader.
4796   base::RunLoop().RunUntilIdle();
4797   EXPECT_EQ(1, cache.GetCountReaders(cache_key));
4798   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(cache_key));
4799   ReadAndVerifyTransaction(context_list[1]->trans.get(),
4800                            kSimplePOST_Transaction);
4801 
4802   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4803   EXPECT_EQ(0, cache.disk_cache()->open_count());
4804   EXPECT_EQ(1, cache.disk_cache()->create_count());
4805 
4806   context_list.clear();
4807 }
4808 
4809 // Tests the case when parallel writing succeeds. Tests both idle and waiting
4810 // transactions.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingSuccess)4811 TEST_F(HttpCacheTest, SimpleGET_ParallelWritingSuccess) {
4812   MockHttpCache cache;
4813 
4814   MockHttpRequest request(kSimpleGET_Transaction);
4815 
4816   MockTransaction transaction(kSimpleGET_Transaction);
4817   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
4818   MockHttpRequest read_request(transaction);
4819 
4820   const int kNumTransactions = 4;
4821   std::vector<std::unique_ptr<Context>> context_list;
4822 
4823   for (int i = 0; i < kNumTransactions; ++i) {
4824     context_list.push_back(std::make_unique<Context>());
4825     auto& c = context_list[i];
4826 
4827     c->result = cache.CreateTransaction(&c->trans);
4828     ASSERT_THAT(c->result, IsOk());
4829 
4830     MockHttpRequest* this_request = &request;
4831     if (i == 3)
4832       this_request = &read_request;
4833 
4834     c->result = c->trans->Start(this_request, c->callback.callback(),
4835                                 NetLogWithSource());
4836   }
4837 
4838   // Allow all requests to move from the Create queue to the active entry.
4839   base::RunLoop().RunUntilIdle();
4840 
4841   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4842   EXPECT_EQ(0, cache.disk_cache()->open_count());
4843   EXPECT_EQ(1, cache.disk_cache()->create_count());
4844 
4845   std::string cache_key = request.CacheKey();
4846   EXPECT_EQ(3, cache.GetCountWriterTransactions(cache_key));
4847   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
4848 
4849   // Initiate Read from two writers.
4850   const int kBufferSize = 5;
4851   std::vector<scoped_refptr<IOBuffer>> buffer(
4852       3, base::MakeRefCounted<IOBufferWithSize>(kBufferSize));
4853   for (int i = 0; i < 2; i++) {
4854     auto& c = context_list[i];
4855     c->result =
4856         c->trans->Read(buffer[i].get(), kBufferSize, c->callback.callback());
4857     EXPECT_EQ(ERR_IO_PENDING, c->result);
4858   }
4859 
4860   std::vector<std::string> first_read(2);
4861   base::RunLoop().RunUntilIdle();
4862   for (int i = 0; i < 2; i++) {
4863     auto& c = context_list[i];
4864     c->result = c->callback.WaitForResult();
4865     EXPECT_EQ(5, c->result);
4866     std::string data_read(buffer[i]->data(), kBufferSize);
4867     first_read[i] = data_read;
4868   }
4869   EXPECT_EQ(first_read[0], first_read[1]);
4870 
4871   // The first transaction should be able to continue to read from the network
4872   // without writing to the cache.
4873   for (int i = 0; i < 2; i++) {
4874     auto& c = context_list[i];
4875     ReadRemainingAndVerifyTransaction(c->trans.get(), first_read[i],
4876                                       kSimpleGET_Transaction);
4877     if (i == 0) {
4878       // Remaining transactions should now be readers.
4879       EXPECT_EQ(3, cache.GetCountReaders(cache_key));
4880     }
4881   }
4882 
4883   // Verify the rest of the transactions.
4884   for (int i = 2; i < kNumTransactions; i++) {
4885     auto& c = context_list[i];
4886     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
4887   }
4888 
4889   context_list.clear();
4890 }
4891 
4892 // Tests the case when parallel writing involves things bigger than what cache
4893 // can store. In this case, the best we can do is re-fetch it.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingHuge)4894 TEST_F(HttpCacheTest, SimpleGET_ParallelWritingHuge) {
4895   MockHttpCache cache;
4896   cache.disk_cache()->set_max_file_size(10);
4897 
4898   MockTransaction transaction(kSimpleGET_Transaction);
4899   std::string response_headers = base::StrCat(
4900       {kSimpleGET_Transaction.response_headers, "Content-Length: ",
4901        base::NumberToString(strlen(kSimpleGET_Transaction.data)), "\n"});
4902   transaction.response_headers = response_headers.c_str();
4903   AddMockTransaction(&transaction);
4904   MockHttpRequest request(transaction);
4905 
4906   const int kNumTransactions = 4;
4907   std::vector<std::unique_ptr<Context>> context_list;
4908 
4909   for (int i = 0; i < kNumTransactions; ++i) {
4910     context_list.push_back(std::make_unique<Context>());
4911     auto& c = context_list[i];
4912 
4913     c->result = cache.CreateTransaction(&c->trans);
4914     ASSERT_THAT(c->result, IsOk());
4915 
4916     MockHttpRequest* this_request = &request;
4917     c->result = c->trans->Start(this_request, c->callback.callback(),
4918                                 NetLogWithSource());
4919   }
4920 
4921   // Start them up.
4922   base::RunLoop().RunUntilIdle();
4923 
4924   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4925   EXPECT_EQ(0, cache.disk_cache()->open_count());
4926   EXPECT_EQ(1, cache.disk_cache()->create_count());
4927 
4928   std::string cache_key = request.CacheKey();
4929   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
4930   EXPECT_EQ(kNumTransactions - 1, cache.GetCountDoneHeadersQueue(cache_key));
4931 
4932   // Initiate Read from first transaction.
4933   const int kBufferSize = 5;
4934   std::vector<scoped_refptr<IOBuffer>> buffer(
4935       kNumTransactions, base::MakeRefCounted<IOBufferWithSize>(kBufferSize));
4936   auto& c = context_list[0];
4937   c->result =
4938       c->trans->Read(buffer[0].get(), kBufferSize, c->callback.callback());
4939   EXPECT_EQ(ERR_IO_PENDING, c->result);
4940 
4941   // ... and complete it.
4942   std::vector<std::string> first_read(kNumTransactions);
4943   base::RunLoop().RunUntilIdle();
4944   c->result = c->callback.WaitForResult();
4945   EXPECT_EQ(kBufferSize, c->result);
4946   std::string data_read(buffer[0]->data(), kBufferSize);
4947   first_read[0] = data_read;
4948   EXPECT_EQ("<html", first_read[0]);
4949 
4950   // Complete all of them.
4951   for (int i = 0; i < kNumTransactions; i++) {
4952     ReadRemainingAndVerifyTransaction(context_list[i]->trans.get(),
4953                                       first_read[i], kSimpleGET_Transaction);
4954   }
4955 
4956   // Sadly all of them have to hit the network
4957   EXPECT_EQ(kNumTransactions, cache.network_layer()->transaction_count());
4958 
4959   context_list.clear();
4960   RemoveMockTransaction(&transaction);
4961 }
4962 
4963 // Tests that network transaction's info is saved correctly when a writer
4964 // transaction that created the network transaction becomes a reader. Also
4965 // verifies that the network bytes are only attributed to the transaction that
4966 // created the network transaction.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingVerifyNetworkBytes)4967 TEST_F(HttpCacheTest, SimpleGET_ParallelWritingVerifyNetworkBytes) {
4968   MockHttpCache cache;
4969 
4970   MockHttpRequest request(kSimpleGET_Transaction);
4971 
4972   const int kNumTransactions = 2;
4973   std::vector<std::unique_ptr<Context>> context_list;
4974 
4975   for (int i = 0; i < kNumTransactions; ++i) {
4976     context_list.push_back(std::make_unique<Context>());
4977     auto& c = context_list[i];
4978 
4979     c->result = cache.CreateTransaction(&c->trans);
4980     ASSERT_THAT(c->result, IsOk());
4981 
4982     c->result =
4983         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
4984   }
4985 
4986   // Allow all requests to move from the Create queue to the active entry.
4987   base::RunLoop().RunUntilIdle();
4988 
4989   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4990   EXPECT_EQ(0, cache.disk_cache()->open_count());
4991   EXPECT_EQ(1, cache.disk_cache()->create_count());
4992 
4993   std::string cache_key = request.CacheKey();
4994   EXPECT_EQ(2, cache.GetCountWriterTransactions(cache_key));
4995   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(cache_key));
4996 
4997   // Get the network bytes read by the first transaction.
4998   int total_received_bytes = context_list[0]->trans->GetTotalReceivedBytes();
4999   EXPECT_GT(total_received_bytes, 0);
5000 
5001   // Complete Read by the 2nd transaction so that the 1st transaction that
5002   // created the network transaction is now a reader.
5003   ReadAndVerifyTransaction(context_list[1]->trans.get(),
5004                            kSimpleGET_Transaction);
5005 
5006   EXPECT_EQ(1, cache.GetCountReaders(cache_key));
5007 
5008   // Verify that the network bytes read are not attributed to the 2nd
5009   // transaction but to the 1st.
5010   EXPECT_EQ(0, context_list[1]->trans->GetTotalReceivedBytes());
5011 
5012   EXPECT_GE(total_received_bytes,
5013             context_list[0]->trans->GetTotalReceivedBytes());
5014 
5015   ReadAndVerifyTransaction(context_list[0]->trans.get(),
5016                            kSimpleGET_Transaction);
5017 }
5018 
5019 // Tests than extra Read from the consumer should not hang/crash the browser.
TEST_F(HttpCacheTest,SimpleGET_ExtraRead)5020 TEST_F(HttpCacheTest, SimpleGET_ExtraRead) {
5021   MockHttpCache cache;
5022   MockHttpRequest request(kSimpleGET_Transaction);
5023   Context c;
5024 
5025   c.result = cache.CreateTransaction(&c.trans);
5026   ASSERT_THAT(c.result, IsOk());
5027 
5028   c.result =
5029       c.trans->Start(&request, c.callback.callback(), NetLogWithSource());
5030 
5031   base::RunLoop().RunUntilIdle();
5032 
5033   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5034   EXPECT_EQ(0, cache.disk_cache()->open_count());
5035   EXPECT_EQ(1, cache.disk_cache()->create_count());
5036 
5037   std::string cache_key = request.CacheKey();
5038   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
5039   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(cache_key));
5040 
5041   ReadAndVerifyTransaction(c.trans.get(), kSimpleGET_Transaction);
5042 
5043   // Perform an extra Read.
5044   const int kBufferSize = 10;
5045   auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
5046   c.result = c.trans->Read(buffer.get(), kBufferSize, c.callback.callback());
5047   EXPECT_EQ(0, c.result);
5048 }
5049 
5050 // Tests when a writer is destroyed mid-read, all the other writer transactions
5051 // can continue writing to the entry.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationCancelWriter)5052 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationCancelWriter) {
5053   MockHttpCache cache;
5054 
5055   ScopedMockTransaction transaction(kSimpleGET_Transaction);
5056   transaction.response_headers =
5057       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5058       "Content-Length: 22\n"
5059       "Etag: \"foopy\"\n";
5060   MockHttpRequest request(transaction);
5061 
5062   const int kNumTransactions = 3;
5063   std::vector<std::unique_ptr<Context>> context_list;
5064 
5065   for (int i = 0; i < kNumTransactions; ++i) {
5066     context_list.push_back(std::make_unique<Context>());
5067     auto& c = context_list[i];
5068 
5069     c->result = cache.CreateTransaction(&c->trans);
5070     ASSERT_THAT(c->result, IsOk());
5071 
5072     c->result =
5073         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5074   }
5075 
5076   // Allow all requests to move from the Create queue to the active entry.
5077   base::RunLoop().RunUntilIdle();
5078 
5079   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5080   EXPECT_EQ(0, cache.disk_cache()->open_count());
5081   EXPECT_EQ(1, cache.disk_cache()->create_count());
5082 
5083   std::string cache_key = request.CacheKey();
5084   EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
5085 
5086   // Let first transaction read some bytes.
5087   {
5088     auto& c = context_list[0];
5089     const int kBufferSize = 5;
5090     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
5091     ReleaseBufferCompletionCallback cb(buffer.get());
5092     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
5093     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
5094   }
5095 
5096   // Deleting the active transaction at this point will not impact the other
5097   // transactions since there are other transactions in writers.
5098   context_list[0].reset();
5099 
5100   base::RunLoop().RunUntilIdle();
5101 
5102   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5103   EXPECT_EQ(0, cache.disk_cache()->open_count());
5104   EXPECT_EQ(1, cache.disk_cache()->create_count());
5105 
5106   // Complete the rest of the transactions.
5107   for (auto& context : context_list) {
5108     if (!context)
5109       continue;
5110     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
5111   }
5112 }
5113 
5114 // Tests that when StopCaching is invoked on a writer, dependent transactions
5115 // are restarted.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationStopCaching)5116 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationStopCaching) {
5117   MockHttpCache cache;
5118 
5119   MockHttpRequest request(kSimpleGET_Transaction);
5120 
5121   MockTransaction transaction(kSimpleGET_Transaction);
5122   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
5123   MockHttpRequest read_only_request(transaction);
5124 
5125   const int kNumTransactions = 2;
5126   std::vector<std::unique_ptr<Context>> context_list;
5127 
5128   for (int i = 0; i < kNumTransactions; ++i) {
5129     context_list.push_back(std::make_unique<Context>());
5130     auto& c = context_list[i];
5131 
5132     c->result = cache.CreateTransaction(&c->trans);
5133     ASSERT_THAT(c->result, IsOk());
5134 
5135     MockHttpRequest* this_request = &request;
5136     if (i == 1) {
5137       this_request = &read_only_request;
5138     }
5139 
5140     c->result = c->trans->Start(this_request, c->callback.callback(),
5141                                 NetLogWithSource());
5142   }
5143 
5144   // Allow all requests to move from the Create queue to the active entry.
5145   base::RunLoop().RunUntilIdle();
5146 
5147   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5148   EXPECT_EQ(0, cache.disk_cache()->open_count());
5149   EXPECT_EQ(1, cache.disk_cache()->create_count());
5150 
5151   std::string cache_key = request.CacheKey();
5152   EXPECT_EQ(kNumTransactions - 1, cache.GetCountWriterTransactions(cache_key));
5153   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
5154 
5155   // Invoking StopCaching on the writer will lead to dooming the entry and
5156   // restarting the validated transactions. Since it is a read-only transaction
5157   // it will error out.
5158   context_list[0]->trans->StopCaching();
5159 
5160   base::RunLoop().RunUntilIdle();
5161 
5162   int rv = context_list[1]->callback.WaitForResult();
5163   EXPECT_EQ(ERR_CACHE_MISS, rv);
5164 
5165   ReadAndVerifyTransaction(context_list[0]->trans.get(),
5166                            kSimpleGET_Transaction);
5167 }
5168 
5169 // Tests that when StopCaching is invoked on a writer transaction, it is a
5170 // no-op if there are other writer transactions.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritersStopCachingNoOp)5171 TEST_F(HttpCacheTest, SimpleGET_ParallelWritersStopCachingNoOp) {
5172   MockHttpCache cache;
5173 
5174   MockHttpRequest request(kSimpleGET_Transaction);
5175 
5176   MockTransaction transaction(kSimpleGET_Transaction);
5177   transaction.load_flags |= LOAD_VALIDATE_CACHE;
5178   MockHttpRequest validate_request(transaction);
5179 
5180   const int kNumTransactions = 3;
5181   std::vector<std::unique_ptr<Context>> context_list;
5182 
5183   for (int i = 0; i < kNumTransactions; ++i) {
5184     context_list.push_back(std::make_unique<Context>());
5185     auto& c = context_list[i];
5186 
5187     c->result = cache.CreateTransaction(&c->trans);
5188     ASSERT_THAT(c->result, IsOk());
5189 
5190     MockHttpRequest* this_request = &request;
5191     if (i == 2) {
5192       this_request = &validate_request;
5193       c->trans->SetBeforeNetworkStartCallback(base::BindOnce(&DeferCallback));
5194     }
5195 
5196     c->result = c->trans->Start(this_request, c->callback.callback(),
5197                                 NetLogWithSource());
5198   }
5199 
5200   // Allow all requests to move from the Create queue to the active entry.
5201   base::RunLoop().RunUntilIdle();
5202 
5203   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5204   EXPECT_EQ(0, cache.disk_cache()->open_count());
5205   EXPECT_EQ(1, cache.disk_cache()->create_count());
5206 
5207   std::string cache_key = request.CacheKey();
5208   EXPECT_TRUE(cache.IsHeadersTransactionPresent(cache_key));
5209   EXPECT_EQ(kNumTransactions - 1, cache.GetCountWriterTransactions(cache_key));
5210 
5211   // Invoking StopCaching on the writer will be a no-op since there are multiple
5212   // transaction in writers.
5213   context_list[0]->trans->StopCaching();
5214 
5215   // Resume network start for headers_transaction.
5216   auto& c = context_list[2];
5217   c->trans->ResumeNetworkStart();
5218   base::RunLoop().RunUntilIdle();
5219   // After validation old entry will be doomed and headers_transaction will be
5220   // added to the new entry.
5221   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
5222 
5223   // Complete the rest of the transactions.
5224   for (auto& context : context_list) {
5225     if (!context)
5226       continue;
5227     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
5228   }
5229 
5230   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5231   EXPECT_EQ(0, cache.disk_cache()->open_count());
5232   EXPECT_EQ(2, cache.disk_cache()->create_count());
5233 }
5234 
5235 // Tests that a transaction is currently in headers phase and is destroyed
5236 // leading to destroying the entry.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationCancelHeaders)5237 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationCancelHeaders) {
5238   MockHttpCache cache;
5239 
5240   MockHttpRequest request(kSimpleGET_Transaction);
5241 
5242   const int kNumTransactions = 2;
5243   std::vector<std::unique_ptr<Context>> context_list;
5244 
5245   for (int i = 0; i < kNumTransactions; ++i) {
5246     context_list.push_back(std::make_unique<Context>());
5247     auto& c = context_list[i];
5248 
5249     c->result = cache.CreateTransaction(&c->trans);
5250     ASSERT_THAT(c->result, IsOk());
5251 
5252     if (i == 0)
5253       c->trans->SetBeforeNetworkStartCallback(base::BindOnce(&DeferCallback));
5254 
5255     c->result =
5256         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5257   }
5258 
5259   base::RunLoop().RunUntilIdle();
5260 
5261   std::string cache_key = request.CacheKey();
5262   EXPECT_TRUE(cache.IsHeadersTransactionPresent(cache_key));
5263   EXPECT_EQ(1, cache.GetCountAddToEntryQueue(cache_key));
5264 
5265   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5266   EXPECT_EQ(0, cache.disk_cache()->open_count());
5267   EXPECT_EQ(1, cache.disk_cache()->create_count());
5268 
5269   // Delete the headers transaction.
5270   context_list[0].reset();
5271 
5272   base::RunLoop().RunUntilIdle();
5273 
5274   // Complete the rest of the transactions.
5275   for (auto& context : context_list) {
5276     if (!context)
5277       continue;
5278     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
5279   }
5280 
5281   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5282   EXPECT_EQ(0, cache.disk_cache()->open_count());
5283   EXPECT_EQ(2, cache.disk_cache()->create_count());
5284 }
5285 
5286 // Similar to the above test, except here cache write fails and the
5287 // validated transactions should be restarted.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritersFailWrite)5288 TEST_F(HttpCacheTest, SimpleGET_ParallelWritersFailWrite) {
5289   MockHttpCache cache;
5290 
5291   MockHttpRequest request(kSimpleGET_Transaction);
5292 
5293   const int kNumTransactions = 5;
5294   std::vector<std::unique_ptr<Context>> context_list;
5295 
5296   for (int i = 0; i < kNumTransactions; ++i) {
5297     context_list.push_back(std::make_unique<Context>());
5298     auto& c = context_list[i];
5299 
5300     c->result = cache.CreateTransaction(&c->trans);
5301     ASSERT_THAT(c->result, IsOk());
5302     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
5303 
5304     c->result =
5305         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5306   }
5307 
5308   // All requests are waiting for the active entry.
5309   for (auto& context : context_list) {
5310     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
5311   }
5312 
5313   // Allow all requests to move from the Create queue to the active entry.
5314   base::RunLoop().RunUntilIdle();
5315 
5316   // All transactions become writers.
5317   std::string cache_key = request.CacheKey();
5318   EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
5319 
5320   // All requests depend on the writer, and the writer is between Start and
5321   // Read, i.e. idle.
5322   for (auto& context : context_list) {
5323     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
5324   }
5325 
5326   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5327   EXPECT_EQ(0, cache.disk_cache()->open_count());
5328   EXPECT_EQ(1, cache.disk_cache()->create_count());
5329 
5330   // Fail the request.
5331   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_ALL);
5332   // We have to open the entry again to propagate the failure flag.
5333   disk_cache::Entry* en;
5334   cache.OpenBackendEntry(cache_key, &en);
5335   en->Close();
5336 
5337   for (int i = 0; i < kNumTransactions; ++i) {
5338     auto& c = context_list[i];
5339     if (c->result == ERR_IO_PENDING)
5340       c->result = c->callback.WaitForResult();
5341     if (i == 1) {
5342       // The earlier entry must be destroyed and its disk entry doomed.
5343       EXPECT_TRUE(cache.disk_cache()->IsDiskEntryDoomed(cache_key));
5344     }
5345 
5346     if (i == 0) {
5347       // Consumer gets the response even if cache write failed.
5348       ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5349     } else {
5350       // Read should lead to a failure being returned.
5351       const int kBufferSize = 5;
5352       auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
5353       ReleaseBufferCompletionCallback cb(buffer.get());
5354       c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
5355       EXPECT_EQ(ERR_CACHE_WRITE_FAILURE, cb.GetResult(c->result));
5356     }
5357   }
5358 }
5359 
5360 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
5361 // If cancelling a request is racing with another request for the same resource
5362 // finishing, we have to make sure that we remove both transactions from the
5363 // entry.
TEST_F(HttpCacheTest,SimpleGET_RacingReaders)5364 TEST_F(HttpCacheTest, SimpleGET_RacingReaders) {
5365   MockHttpCache cache;
5366 
5367   MockHttpRequest request(kSimpleGET_Transaction);
5368   MockHttpRequest reader_request(kSimpleGET_Transaction);
5369   reader_request.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
5370 
5371   std::vector<std::unique_ptr<Context>> context_list;
5372   const int kNumTransactions = 5;
5373 
5374   for (int i = 0; i < kNumTransactions; ++i) {
5375     context_list.push_back(std::make_unique<Context>());
5376     Context* c = context_list[i].get();
5377 
5378     c->result = cache.CreateTransaction(&c->trans);
5379     ASSERT_THAT(c->result, IsOk());
5380 
5381     MockHttpRequest* this_request = &request;
5382     if (i == 1 || i == 2)
5383       this_request = &reader_request;
5384 
5385     c->result = c->trans->Start(this_request, c->callback.callback(),
5386                                 NetLogWithSource());
5387   }
5388 
5389   // Allow all requests to move from the Create queue to the active entry.
5390   base::RunLoop().RunUntilIdle();
5391 
5392   // The first request should be a writer at this point, and the subsequent
5393   // requests should be pending.
5394 
5395   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5396   EXPECT_EQ(0, cache.disk_cache()->open_count());
5397   EXPECT_EQ(1, cache.disk_cache()->create_count());
5398 
5399   Context* c = context_list[0].get();
5400   ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
5401   c->result = c->callback.WaitForResult();
5402   ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5403 
5404   // Now all transactions should be waiting for read to be invoked. Two readers
5405   // are because of the load flags and remaining two transactions were converted
5406   // to readers after skipping validation. Note that the remaining two went on
5407   // to process the headers in parallel with readers present on the entry.
5408   EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState());
5409   EXPECT_EQ(LOAD_STATE_IDLE, context_list[3]->trans->GetLoadState());
5410 
5411   c = context_list[1].get();
5412   ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
5413   c->result = c->callback.WaitForResult();
5414   if (c->result == OK)
5415     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5416 
5417   // At this point we have one reader, two pending transactions and a task on
5418   // the queue to move to the next transaction. Now we cancel the request that
5419   // is the current reader, and expect the queued task to be able to start the
5420   // next request.
5421 
5422   c = context_list[2].get();
5423   c->trans.reset();
5424 
5425   for (int i = 3; i < kNumTransactions; ++i) {
5426     c = context_list[i].get();
5427     if (c->result == ERR_IO_PENDING)
5428       c->result = c->callback.WaitForResult();
5429     if (c->result == OK)
5430       ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5431   }
5432 
5433   // We should not have had to re-open the disk entry.
5434 
5435   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5436   EXPECT_EQ(0, cache.disk_cache()->open_count());
5437   EXPECT_EQ(1, cache.disk_cache()->create_count());
5438 }
5439 
5440 // Tests that we can doom an entry with pending transactions and delete one of
5441 // the pending transactions before the first one completes.
5442 // See http://code.google.com/p/chromium/issues/detail?id=25588
TEST_F(HttpCacheTest,SimpleGET_DoomWithPending)5443 TEST_F(HttpCacheTest, SimpleGET_DoomWithPending) {
5444   // We need simultaneous doomed / not_doomed entries so let's use a real cache.
5445   MockHttpCache cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
5446 
5447   MockHttpRequest request(kSimpleGET_Transaction);
5448   MockHttpRequest writer_request(kSimpleGET_Transaction);
5449   writer_request.load_flags = LOAD_BYPASS_CACHE;
5450 
5451   std::vector<std::unique_ptr<Context>> context_list;
5452   const int kNumTransactions = 4;
5453 
5454   for (int i = 0; i < kNumTransactions; ++i) {
5455     context_list.push_back(std::make_unique<Context>());
5456     Context* c = context_list[i].get();
5457 
5458     c->result = cache.CreateTransaction(&c->trans);
5459     ASSERT_THAT(c->result, IsOk());
5460 
5461     MockHttpRequest* this_request = &request;
5462     if (i == 3)
5463       this_request = &writer_request;
5464 
5465     c->result = c->trans->Start(this_request, c->callback.callback(),
5466                                 NetLogWithSource());
5467   }
5468 
5469   base::RunLoop().RunUntilIdle();
5470 
5471   // The first request should be a writer at this point, and the two subsequent
5472   // requests should be pending. The last request doomed the first entry.
5473 
5474   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5475 
5476   // Cancel the second transaction. Note that this and the 3rd transactions
5477   // would have completed their headers phase and would be waiting in the
5478   // done_headers_queue when the 2nd transaction is cancelled.
5479   context_list[1].reset();
5480 
5481   for (int i = 0; i < kNumTransactions; ++i) {
5482     if (i == 1)
5483       continue;
5484     Context* c = context_list[i].get();
5485     ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
5486     c->result = c->callback.WaitForResult();
5487     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5488   }
5489 }
5490 
TEST_F(HttpCacheTest,DoomDoesNotSetHints)5491 TEST_F(HttpCacheTest, DoomDoesNotSetHints) {
5492   // Test that a doomed writer doesn't set in-memory index hints.
5493   MockHttpCache cache;
5494   cache.disk_cache()->set_support_in_memory_entry_data(true);
5495 
5496   // Request 1 is a normal one to a no-cache/no-etag resource, to potentially
5497   // set a "this is unvalidatable" hint in the cache. We also need it to
5498   // actually write out to the doomed entry after request 2 does its thing,
5499   // so its transaction is paused.
5500   MockTransaction no_cache_transaction(kSimpleGET_Transaction);
5501   no_cache_transaction.response_headers = "Cache-Control: no-cache\n";
5502   AddMockTransaction(&no_cache_transaction);
5503   MockHttpRequest request1(no_cache_transaction);
5504 
5505   Context c1;
5506   c1.result = cache.CreateTransaction(&c1.trans);
5507   ASSERT_THAT(c1.result, IsOk());
5508   c1.trans->SetBeforeNetworkStartCallback(
5509       base::BindOnce([](bool* defer) { *defer = true; }));
5510   c1.result =
5511       c1.trans->Start(&request1, c1.callback.callback(), NetLogWithSource());
5512   ASSERT_THAT(c1.result, IsError(ERR_IO_PENDING));
5513 
5514   // It starts, copies over headers info, but doesn't get to proceed.
5515   base::RunLoop().RunUntilIdle();
5516   RemoveMockTransaction(&no_cache_transaction);
5517 
5518   // Request 2 sets LOAD_BYPASS_CACHE to force the first one to be doomed ---
5519   // it'll want to be a writer.
5520   MockHttpRequest request2(kSimpleGET_Transaction);
5521   request2.load_flags = LOAD_BYPASS_CACHE;
5522 
5523   Context c2;
5524   c2.result = cache.CreateTransaction(&c2.trans);
5525   ASSERT_THAT(c2.result, IsOk());
5526   c2.result =
5527       c2.trans->Start(&request2, c2.callback.callback(), NetLogWithSource());
5528   ASSERT_THAT(c2.result, IsError(ERR_IO_PENDING));
5529 
5530   // Run Request2, then let the first one wrap up.
5531   base::RunLoop().RunUntilIdle();
5532   c2.callback.WaitForResult();
5533   ReadAndVerifyTransaction(c2.trans.get(), kSimpleGET_Transaction);
5534 
5535   c1.trans->ResumeNetworkStart();
5536   c1.callback.WaitForResult();
5537   ReadAndVerifyTransaction(c1.trans.get(), no_cache_transaction);
5538 
5539   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5540   EXPECT_EQ(0, cache.disk_cache()->open_count());
5541   EXPECT_EQ(2, cache.disk_cache()->create_count());
5542 
5543   // Request 3 tries to read from cache, and it should successfully do so. It's
5544   // run after the previous two transactions finish so it doesn't try to
5545   // cooperate with them, and is entirely driven by the state of the cache.
5546   MockHttpRequest request3(kSimpleGET_Transaction);
5547   Context context3;
5548   context3.result = cache.CreateTransaction(&context3.trans);
5549   ASSERT_THAT(context3.result, IsOk());
5550   context3.result = context3.trans->Start(
5551       &request3, context3.callback.callback(), NetLogWithSource());
5552   base::RunLoop().RunUntilIdle();
5553   ASSERT_THAT(context3.result, IsError(ERR_IO_PENDING));
5554   context3.result = context3.callback.WaitForResult();
5555   ReadAndVerifyTransaction(context3.trans.get(), kSimpleGET_Transaction);
5556 
5557   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5558   EXPECT_EQ(1, cache.disk_cache()->open_count());
5559   EXPECT_EQ(2, cache.disk_cache()->create_count());
5560 }
5561 
5562 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
5563 // We may attempt to delete an entry synchronously with the act of adding a new
5564 // transaction to said entry.
TEST_F(HttpCacheTest,FastNoStoreGET_DoneWithPending)5565 TEST_F(HttpCacheTest, FastNoStoreGET_DoneWithPending) {
5566   MockHttpCache cache;
5567 
5568   // The headers will be served right from the call to Start() the request.
5569   MockHttpRequest request(kFastNoStoreGET_Transaction);
5570   FastTransactionServer request_handler;
5571   AddMockTransaction(&kFastNoStoreGET_Transaction);
5572 
5573   std::vector<std::unique_ptr<Context>> context_list;
5574   const int kNumTransactions = 3;
5575 
5576   for (int i = 0; i < kNumTransactions; ++i) {
5577     context_list.push_back(std::make_unique<Context>());
5578     Context* c = context_list[i].get();
5579 
5580     c->result = cache.CreateTransaction(&c->trans);
5581     ASSERT_THAT(c->result, IsOk());
5582 
5583     c->result =
5584         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5585   }
5586 
5587   // Allow all requests to move from the Create queue to the active entry.
5588   base::RunLoop().RunUntilIdle();
5589 
5590   // The first request should be a writer at this point, and the subsequent
5591   // requests should have completed validation. Since the validation does not
5592   // result in a match, a new entry would be created.
5593 
5594   EXPECT_EQ(3, cache.network_layer()->transaction_count());
5595   EXPECT_EQ(0, cache.disk_cache()->open_count());
5596   EXPECT_EQ(3, cache.disk_cache()->create_count());
5597 
5598   // Now, make sure that the second request asks for the entry not to be stored.
5599   request_handler.set_no_store(true);
5600 
5601   for (int i = 0; i < kNumTransactions; ++i) {
5602     Context* c = context_list[i].get();
5603     if (c->result == ERR_IO_PENDING)
5604       c->result = c->callback.WaitForResult();
5605     ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction);
5606     context_list[i].reset();
5607   }
5608 
5609   EXPECT_EQ(3, cache.network_layer()->transaction_count());
5610   EXPECT_EQ(0, cache.disk_cache()->open_count());
5611   EXPECT_EQ(3, cache.disk_cache()->create_count());
5612 
5613   RemoveMockTransaction(&kFastNoStoreGET_Transaction);
5614 }
5615 
TEST_F(HttpCacheTest,SimpleGET_ManyWriters_CancelFirst)5616 TEST_F(HttpCacheTest, SimpleGET_ManyWriters_CancelFirst) {
5617   MockHttpCache cache;
5618 
5619   MockHttpRequest request(kSimpleGET_Transaction);
5620 
5621   std::vector<std::unique_ptr<Context>> context_list;
5622   const int kNumTransactions = 2;
5623 
5624   for (int i = 0; i < kNumTransactions; ++i) {
5625     context_list.push_back(std::make_unique<Context>());
5626     Context* c = context_list[i].get();
5627 
5628     c->result = cache.CreateTransaction(&c->trans);
5629     ASSERT_THAT(c->result, IsOk());
5630 
5631     c->result =
5632         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5633   }
5634 
5635   // Allow all requests to move from the Create queue to the active entry.
5636   // All would have been added to writers.
5637   base::RunLoop().RunUntilIdle();
5638   std::string cache_key =
5639       *cache.http_cache()->GenerateCacheKeyForRequest(&request);
5640   EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
5641 
5642   // The second transaction skipped validation, thus only one network
5643   // transaction is created.
5644   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5645   EXPECT_EQ(0, cache.disk_cache()->open_count());
5646   EXPECT_EQ(1, cache.disk_cache()->create_count());
5647 
5648   for (int i = 0; i < kNumTransactions; ++i) {
5649     Context* c = context_list[i].get();
5650     if (c->result == ERR_IO_PENDING)
5651       c->result = c->callback.WaitForResult();
5652     // Destroy only the first transaction.
5653     // This should not impact the other writer transaction and the network
5654     // transaction will continue to be used by that transaction.
5655     if (i == 0) {
5656       context_list[i].reset();
5657     }
5658   }
5659 
5660   // Complete the rest of the transactions.
5661   for (int i = 1; i < kNumTransactions; ++i) {
5662     Context* c = context_list[i].get();
5663     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5664   }
5665 
5666   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5667   EXPECT_EQ(0, cache.disk_cache()->open_count());
5668   EXPECT_EQ(1, cache.disk_cache()->create_count());
5669 }
5670 
5671 // Tests that we can cancel requests that are queued waiting to open the disk
5672 // cache entry.
TEST_F(HttpCacheTest,SimpleGET_ManyWriters_CancelCreate)5673 TEST_F(HttpCacheTest, SimpleGET_ManyWriters_CancelCreate) {
5674   MockHttpCache cache;
5675 
5676   MockHttpRequest request(kSimpleGET_Transaction);
5677 
5678   std::vector<std::unique_ptr<Context>> context_list;
5679   const int kNumTransactions = 5;
5680 
5681   for (int i = 0; i < kNumTransactions; i++) {
5682     context_list.push_back(std::make_unique<Context>());
5683     Context* c = context_list[i].get();
5684 
5685     c->result = cache.CreateTransaction(&c->trans);
5686     ASSERT_THAT(c->result, IsOk());
5687 
5688     c->result =
5689         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5690   }
5691 
5692   // The first request should be creating the disk cache entry and the others
5693   // should be pending.
5694 
5695   EXPECT_EQ(0, cache.network_layer()->transaction_count());
5696   EXPECT_EQ(0, cache.disk_cache()->open_count());
5697   EXPECT_EQ(1, cache.disk_cache()->create_count());
5698 
5699   // Cancel a request from the pending queue.
5700   context_list[3].reset();
5701 
5702   // Cancel the request that is creating the entry. This will force the pending
5703   // operations to restart.
5704   context_list[0].reset();
5705 
5706   // Complete the rest of the transactions.
5707   for (int i = 1; i < kNumTransactions; i++) {
5708     Context* c = context_list[i].get();
5709     if (c) {
5710       c->result = c->callback.GetResult(c->result);
5711       ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5712     }
5713   }
5714 
5715   // We should have had to re-create the disk entry.
5716 
5717   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5718   EXPECT_EQ(0, cache.disk_cache()->open_count());
5719   EXPECT_EQ(2, cache.disk_cache()->create_count());
5720 }
5721 
5722 // Tests that we can cancel a single request to open a disk cache entry.
TEST_F(HttpCacheTest,SimpleGET_CancelCreate)5723 TEST_F(HttpCacheTest, SimpleGET_CancelCreate) {
5724   MockHttpCache cache;
5725 
5726   MockHttpRequest request(kSimpleGET_Transaction);
5727 
5728   auto c = std::make_unique<Context>();
5729 
5730   c->result = cache.CreateTransaction(&c->trans);
5731   ASSERT_THAT(c->result, IsOk());
5732 
5733   c->result =
5734       c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5735   EXPECT_THAT(c->result, IsError(ERR_IO_PENDING));
5736 
5737   // Release the reference that the mock disk cache keeps for this entry, so
5738   // that we test that the http cache handles the cancellation correctly.
5739   cache.disk_cache()->ReleaseAll();
5740   c.reset();
5741 
5742   base::RunLoop().RunUntilIdle();
5743   EXPECT_EQ(1, cache.disk_cache()->create_count());
5744 }
5745 
5746 // Tests that we delete/create entries even if multiple requests are queued.
TEST_F(HttpCacheTest,SimpleGET_ManyWriters_BypassCache)5747 TEST_F(HttpCacheTest, SimpleGET_ManyWriters_BypassCache) {
5748   MockHttpCache cache;
5749 
5750   MockHttpRequest request(kSimpleGET_Transaction);
5751   request.load_flags = LOAD_BYPASS_CACHE;
5752 
5753   std::vector<std::unique_ptr<Context>> context_list;
5754   const int kNumTransactions = 5;
5755 
5756   for (int i = 0; i < kNumTransactions; i++) {
5757     context_list.push_back(std::make_unique<Context>());
5758     Context* c = context_list[i].get();
5759 
5760     c->result = cache.CreateTransaction(&c->trans);
5761     ASSERT_THAT(c->result, IsOk());
5762 
5763     c->result =
5764         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5765   }
5766 
5767   // The first request should be deleting the disk cache entry and the others
5768   // should be pending.
5769 
5770   EXPECT_EQ(0, cache.network_layer()->transaction_count());
5771   EXPECT_EQ(0, cache.disk_cache()->open_count());
5772   EXPECT_EQ(0, cache.disk_cache()->create_count());
5773 
5774   // Complete the transactions.
5775   for (int i = 0; i < kNumTransactions; i++) {
5776     Context* c = context_list[i].get();
5777     c->result = c->callback.GetResult(c->result);
5778     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5779   }
5780 
5781   // We should have had to re-create the disk entry multiple times.
5782 
5783   EXPECT_EQ(5, cache.network_layer()->transaction_count());
5784   EXPECT_EQ(0, cache.disk_cache()->open_count());
5785   EXPECT_EQ(5, cache.disk_cache()->create_count());
5786 }
5787 
5788 // Tests that a (simulated) timeout allows transactions waiting on the cache
5789 // lock to continue.
TEST_F(HttpCacheTest,SimpleGET_WriterTimeout)5790 TEST_F(HttpCacheTest, SimpleGET_WriterTimeout) {
5791   MockHttpCache cache;
5792   cache.SimulateCacheLockTimeout();
5793 
5794   MockHttpRequest request(kSimpleGET_Transaction);
5795   Context c1, c2;
5796   ASSERT_THAT(cache.CreateTransaction(&c1.trans), IsOk());
5797   ASSERT_EQ(ERR_IO_PENDING, c1.trans->Start(&request, c1.callback.callback(),
5798                                             NetLogWithSource()));
5799   ASSERT_THAT(cache.CreateTransaction(&c2.trans), IsOk());
5800   ASSERT_EQ(ERR_IO_PENDING, c2.trans->Start(&request, c2.callback.callback(),
5801                                             NetLogWithSource()));
5802 
5803   // The second request is queued after the first one.
5804 
5805   c2.callback.WaitForResult();
5806   ReadAndVerifyTransaction(c2.trans.get(), kSimpleGET_Transaction);
5807 
5808   // Complete the first transaction.
5809   c1.callback.WaitForResult();
5810   ReadAndVerifyTransaction(c1.trans.get(), kSimpleGET_Transaction);
5811 }
5812 
5813 // Tests that a (simulated) timeout allows transactions waiting on the cache
5814 // lock to continue but read only transactions to error out.
TEST_F(HttpCacheTest,SimpleGET_WriterTimeoutReadOnlyError)5815 TEST_F(HttpCacheTest, SimpleGET_WriterTimeoutReadOnlyError) {
5816   MockHttpCache cache;
5817 
5818   // Simulate timeout.
5819   cache.SimulateCacheLockTimeout();
5820 
5821   MockHttpRequest request(kSimpleGET_Transaction);
5822   Context c1, c2;
5823   ASSERT_THAT(cache.CreateTransaction(&c1.trans), IsOk());
5824   ASSERT_EQ(ERR_IO_PENDING, c1.trans->Start(&request, c1.callback.callback(),
5825                                             NetLogWithSource()));
5826 
5827   request.load_flags = LOAD_ONLY_FROM_CACHE;
5828   ASSERT_THAT(cache.CreateTransaction(&c2.trans), IsOk());
5829   ASSERT_EQ(ERR_IO_PENDING, c2.trans->Start(&request, c2.callback.callback(),
5830                                             NetLogWithSource()));
5831 
5832   // The second request is queued after the first one.
5833   int res = c2.callback.WaitForResult();
5834   ASSERT_EQ(ERR_CACHE_MISS, res);
5835 
5836   // Complete the first transaction.
5837   c1.callback.WaitForResult();
5838   ReadAndVerifyTransaction(c1.trans.get(), kSimpleGET_Transaction);
5839 }
5840 
TEST_F(HttpCacheTest,SimpleGET_AbandonedCacheRead)5841 TEST_F(HttpCacheTest, SimpleGET_AbandonedCacheRead) {
5842   MockHttpCache cache;
5843 
5844   // write to the cache
5845   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5846 
5847   MockHttpRequest request(kSimpleGET_Transaction);
5848   TestCompletionCallback callback;
5849 
5850   std::unique_ptr<HttpTransaction> trans;
5851   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
5852   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5853   if (rv == ERR_IO_PENDING)
5854     rv = callback.WaitForResult();
5855   ASSERT_THAT(rv, IsOk());
5856 
5857   auto buf = base::MakeRefCounted<IOBufferWithSize>(256);
5858   rv = trans->Read(buf.get(), 256, callback.callback());
5859   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5860 
5861   // Test that destroying the transaction while it is reading from the cache
5862   // works properly.
5863   trans.reset();
5864 
5865   // Make sure we pump any pending events, which should include a call to
5866   // HttpCache::Transaction::OnCacheReadCompleted.
5867   base::RunLoop().RunUntilIdle();
5868 }
5869 
5870 // Tests that we can delete the HttpCache and deal with queued transactions
5871 // ("waiting for the backend" as opposed to Active or Doomed entries).
TEST_F(HttpCacheTest,SimpleGET_ManyWriters_DeleteCache)5872 TEST_F(HttpCacheTest, SimpleGET_ManyWriters_DeleteCache) {
5873   auto cache = std::make_unique<MockHttpCache>(
5874       std::make_unique<MockBackendNoCbFactory>());
5875 
5876   MockHttpRequest request(kSimpleGET_Transaction);
5877 
5878   std::vector<std::unique_ptr<Context>> context_list;
5879   const int kNumTransactions = 5;
5880 
5881   for (int i = 0; i < kNumTransactions; i++) {
5882     context_list.push_back(std::make_unique<Context>());
5883     Context* c = context_list[i].get();
5884 
5885     c->result = cache->CreateTransaction(&c->trans);
5886     ASSERT_THAT(c->result, IsOk());
5887 
5888     c->result =
5889         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5890   }
5891 
5892   // The first request should be creating the disk cache entry and the others
5893   // should be pending.
5894 
5895   EXPECT_EQ(0, cache->network_layer()->transaction_count());
5896   EXPECT_EQ(0, cache->disk_cache()->open_count());
5897   EXPECT_EQ(0, cache->disk_cache()->create_count());
5898 
5899   cache.reset();
5900 }
5901 
5902 // Tests that we queue requests when initializing the backend.
TEST_F(HttpCacheTest,SimpleGET_WaitForBackend)5903 TEST_F(HttpCacheTest, SimpleGET_WaitForBackend) {
5904   auto factory = std::make_unique<MockBlockingBackendFactory>();
5905   MockBlockingBackendFactory* factory_ptr = factory.get();
5906   MockHttpCache cache(std::move(factory));
5907 
5908   MockHttpRequest request0(kSimpleGET_Transaction);
5909   MockHttpRequest request1(kTypicalGET_Transaction);
5910   MockHttpRequest request2(kETagGET_Transaction);
5911 
5912   std::vector<std::unique_ptr<Context>> context_list;
5913   const int kNumTransactions = 3;
5914 
5915   for (int i = 0; i < kNumTransactions; i++) {
5916     context_list.push_back(std::make_unique<Context>());
5917     Context* c = context_list[i].get();
5918 
5919     c->result = cache.CreateTransaction(&c->trans);
5920     ASSERT_THAT(c->result, IsOk());
5921   }
5922 
5923   context_list[0]->result = context_list[0]->trans->Start(
5924       &request0, context_list[0]->callback.callback(), NetLogWithSource());
5925   context_list[1]->result = context_list[1]->trans->Start(
5926       &request1, context_list[1]->callback.callback(), NetLogWithSource());
5927   context_list[2]->result = context_list[2]->trans->Start(
5928       &request2, context_list[2]->callback.callback(), NetLogWithSource());
5929 
5930   // Just to make sure that everything is still pending.
5931   base::RunLoop().RunUntilIdle();
5932 
5933   // The first request should be creating the disk cache.
5934   EXPECT_FALSE(context_list[0]->callback.have_result());
5935 
5936   factory_ptr->FinishCreation();
5937 
5938   base::RunLoop().RunUntilIdle();
5939   EXPECT_EQ(3, cache.network_layer()->transaction_count());
5940   EXPECT_EQ(3, cache.disk_cache()->create_count());
5941 
5942   for (int i = 0; i < kNumTransactions; ++i) {
5943     EXPECT_TRUE(context_list[i]->callback.have_result());
5944     context_list[i].reset();
5945   }
5946 }
5947 
5948 // Tests that we can cancel requests that are queued waiting for the backend
5949 // to be initialized.
TEST_F(HttpCacheTest,SimpleGET_WaitForBackend_CancelCreate)5950 TEST_F(HttpCacheTest, SimpleGET_WaitForBackend_CancelCreate) {
5951   auto factory = std::make_unique<MockBlockingBackendFactory>();
5952   MockBlockingBackendFactory* factory_ptr = factory.get();
5953   MockHttpCache cache(std::move(factory));
5954 
5955   MockHttpRequest request0(kSimpleGET_Transaction);
5956   MockHttpRequest request1(kTypicalGET_Transaction);
5957   MockHttpRequest request2(kETagGET_Transaction);
5958 
5959   std::vector<std::unique_ptr<Context>> context_list;
5960   const int kNumTransactions = 3;
5961 
5962   for (int i = 0; i < kNumTransactions; i++) {
5963     context_list.push_back(std::make_unique<Context>());
5964     Context* c = context_list[i].get();
5965 
5966     c->result = cache.CreateTransaction(&c->trans);
5967     ASSERT_THAT(c->result, IsOk());
5968   }
5969 
5970   context_list[0]->result = context_list[0]->trans->Start(
5971       &request0, context_list[0]->callback.callback(), NetLogWithSource());
5972   context_list[1]->result = context_list[1]->trans->Start(
5973       &request1, context_list[1]->callback.callback(), NetLogWithSource());
5974   context_list[2]->result = context_list[2]->trans->Start(
5975       &request2, context_list[2]->callback.callback(), NetLogWithSource());
5976 
5977   // Just to make sure that everything is still pending.
5978   base::RunLoop().RunUntilIdle();
5979 
5980   // The first request should be creating the disk cache.
5981   EXPECT_FALSE(context_list[0]->callback.have_result());
5982 
5983   // Cancel a request from the pending queue.
5984   context_list[1].reset();
5985 
5986   // Cancel the request that is creating the entry.
5987   context_list[0].reset();
5988 
5989   // Complete the last transaction.
5990   factory_ptr->FinishCreation();
5991 
5992   context_list[2]->result =
5993       context_list[2]->callback.GetResult(context_list[2]->result);
5994   ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction);
5995 
5996   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5997   EXPECT_EQ(1, cache.disk_cache()->create_count());
5998 }
5999 
6000 // Tests that we can delete the HttpCache while creating the backend.
TEST_F(HttpCacheTest,DeleteCacheWaitingForBackend)6001 TEST_F(HttpCacheTest, DeleteCacheWaitingForBackend) {
6002   auto factory = std::make_unique<MockBlockingBackendFactory>();
6003   MockBlockingBackendFactory* factory_ptr = factory.get();
6004   auto cache = std::make_unique<MockHttpCache>(std::move(factory));
6005 
6006   MockHttpRequest request(kSimpleGET_Transaction);
6007 
6008   auto c = std::make_unique<Context>();
6009   c->result = cache->CreateTransaction(&c->trans);
6010   ASSERT_THAT(c->result, IsOk());
6011 
6012   c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
6013 
6014   // Just to make sure that everything is still pending.
6015   base::RunLoop().RunUntilIdle();
6016 
6017   // The request should be creating the disk cache.
6018   EXPECT_FALSE(c->callback.have_result());
6019 
6020   // Manually arrange for completion to happen after ~HttpCache.
6021   // This can't be done via FinishCreation() since that's in `factory`, and
6022   // that's owned by `cache`.
6023   disk_cache::BackendResultCallback callback = factory_ptr->ReleaseCallback();
6024 
6025   cache.reset();
6026   base::RunLoop().RunUntilIdle();
6027 
6028   // Simulate the backend completion callback running now the HttpCache is gone.
6029   std::move(callback).Run(disk_cache::BackendResult::MakeError(ERR_ABORTED));
6030 }
6031 
6032 // Tests that we can delete the cache while creating the backend, from within
6033 // one of the callbacks.
TEST_F(HttpCacheTest,DeleteCacheWaitingForBackend2)6034 TEST_F(HttpCacheTest, DeleteCacheWaitingForBackend2) {
6035   auto factory = std::make_unique<MockBlockingBackendFactory>();
6036   MockBlockingBackendFactory* factory_ptr = factory.get();
6037   auto cache = std::make_unique<MockHttpCache>(std::move(factory));
6038   auto* cache_ptr = cache.get();
6039 
6040   DeleteCacheCompletionCallback cb(std::move(cache));
6041   disk_cache::Backend* backend;
6042   int rv = cache_ptr->http_cache()->GetBackend(&backend, cb.callback());
6043   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6044 
6045   // Now let's queue a regular transaction
6046   MockHttpRequest request(kSimpleGET_Transaction);
6047 
6048   auto c = std::make_unique<Context>();
6049   c->result = cache_ptr->CreateTransaction(&c->trans);
6050   ASSERT_THAT(c->result, IsOk());
6051 
6052   c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
6053 
6054   // And another direct backend request.
6055   TestCompletionCallback cb2;
6056   rv = cache_ptr->http_cache()->GetBackend(&backend, cb2.callback());
6057   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6058 
6059   // Just to make sure that everything is still pending.
6060   base::RunLoop().RunUntilIdle();
6061 
6062   // The request should be queued.
6063   EXPECT_FALSE(c->callback.have_result());
6064 
6065   // Generate the callback.
6066   factory_ptr->FinishCreation();
6067   rv = cb.WaitForResult();
6068 
6069   // The cache should be gone by now.
6070   base::RunLoop().RunUntilIdle();
6071   EXPECT_THAT(c->callback.GetResult(c->result), IsOk());
6072   EXPECT_FALSE(cb2.have_result());
6073 }
6074 
TEST_F(HttpCacheTest,TypicalGET_ConditionalRequest)6075 TEST_F(HttpCacheTest, TypicalGET_ConditionalRequest) {
6076   MockHttpCache cache;
6077 
6078   // write to the cache
6079   RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
6080 
6081   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6082   EXPECT_EQ(0, cache.disk_cache()->open_count());
6083   EXPECT_EQ(1, cache.disk_cache()->create_count());
6084 
6085   // Get the same URL again, but this time we expect it to result
6086   // in a conditional request.
6087   LoadTimingInfo load_timing_info;
6088   RunTransactionTestAndGetTiming(cache.http_cache(), kTypicalGET_Transaction,
6089                                  NetLogWithSource::Make(NetLogSourceType::NONE),
6090                                  &load_timing_info);
6091 
6092   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6093   EXPECT_EQ(1, cache.disk_cache()->open_count());
6094   EXPECT_EQ(1, cache.disk_cache()->create_count());
6095   TestLoadTimingNetworkRequest(load_timing_info);
6096 }
6097 
6098 static const auto kETagGetConditionalRequestHandler =
6099     base::BindRepeating([](const HttpRequestInfo* request,
6100                            std::string* response_status,
6101                            std::string* response_headers,
__anond56f448a0802(const HttpRequestInfo* request, std::string* response_status, std::string* response_headers, std::string* response_data) 6102                            std::string* response_data) {
6103       EXPECT_TRUE(
6104           request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
6105       response_status->assign("HTTP/1.1 304 Not Modified");
6106       response_headers->assign(kETagGET_Transaction.response_headers);
6107       response_data->clear();
6108     });
6109 
TEST_F(HttpCacheTest,ETagGET_ConditionalRequest_304)6110 TEST_F(HttpCacheTest, ETagGET_ConditionalRequest_304) {
6111   MockHttpCache cache;
6112 
6113   ScopedMockTransaction transaction(kETagGET_Transaction);
6114 
6115   // write to the cache
6116   RunTransactionTest(cache.http_cache(), transaction);
6117 
6118   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6119   EXPECT_EQ(0, cache.disk_cache()->open_count());
6120   EXPECT_EQ(1, cache.disk_cache()->create_count());
6121 
6122   // Get the same URL again, but this time we expect it to result
6123   // in a conditional request.
6124   transaction.load_flags = LOAD_VALIDATE_CACHE;
6125   transaction.handler = kETagGetConditionalRequestHandler;
6126   LoadTimingInfo load_timing_info;
6127   IPEndPoint remote_endpoint;
6128   RunTransactionTestAndGetTimingAndConnectedSocketAddress(
6129       cache.http_cache(), transaction,
6130       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info,
6131       &remote_endpoint);
6132 
6133   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6134   EXPECT_EQ(1, cache.disk_cache()->open_count());
6135   EXPECT_EQ(1, cache.disk_cache()->create_count());
6136   TestLoadTimingNetworkRequest(load_timing_info);
6137 
6138   EXPECT_FALSE(remote_endpoint.address().empty());
6139 }
6140 
6141 class RevalidationServer {
6142  public:
6143   RevalidationServer() = default;
6144 
EtagUsed()6145   bool EtagUsed() { return etag_used_; }
LastModifiedUsed()6146   bool LastModifiedUsed() { return last_modified_used_; }
6147 
GetHandlerCallback()6148   MockTransactionHandler GetHandlerCallback() {
6149     return base::BindLambdaForTesting([this](const HttpRequestInfo* request,
6150                                              std::string* response_status,
6151                                              std::string* response_headers,
6152                                              std::string* response_data) {
6153       if (request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch)) {
6154         etag_used_ = true;
6155       }
6156 
6157       if (request->extra_headers.HasHeader(
6158               HttpRequestHeaders::kIfModifiedSince)) {
6159         last_modified_used_ = true;
6160       }
6161 
6162       if (etag_used_ || last_modified_used_) {
6163         response_status->assign("HTTP/1.1 304 Not Modified");
6164         response_headers->assign(kTypicalGET_Transaction.response_headers);
6165         response_data->clear();
6166       } else {
6167         response_status->assign(kTypicalGET_Transaction.status);
6168         response_headers->assign(kTypicalGET_Transaction.response_headers);
6169         response_data->assign(kTypicalGET_Transaction.data);
6170       }
6171     });
6172   }
6173 
6174  private:
6175   bool etag_used_ = false;
6176   bool last_modified_used_ = false;
6177 };
6178 
6179 // Tests revalidation after a vary match.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMatch)6180 TEST_F(HttpCacheTest, GET_ValidateCache_VaryMatch) {
6181   MockHttpCache cache;
6182 
6183   // Write to the cache.
6184   MockTransaction transaction(kTypicalGET_Transaction);
6185   transaction.request_headers = "Foo: bar\r\n";
6186   transaction.response_headers =
6187       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6188       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6189       "Etag: \"foopy\"\n"
6190       "Cache-Control: max-age=0\n"
6191       "Vary: Foo\n";
6192   AddMockTransaction(&transaction);
6193   RunTransactionTest(cache.http_cache(), transaction);
6194 
6195   // Read from the cache.
6196   RevalidationServer server;
6197   transaction.handler = server.GetHandlerCallback();
6198   LoadTimingInfo load_timing_info;
6199   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
6200                                  NetLogWithSource::Make(NetLogSourceType::NONE),
6201                                  &load_timing_info);
6202 
6203   EXPECT_TRUE(server.EtagUsed());
6204   EXPECT_TRUE(server.LastModifiedUsed());
6205   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6206   EXPECT_EQ(1, cache.disk_cache()->open_count());
6207   EXPECT_EQ(1, cache.disk_cache()->create_count());
6208   TestLoadTimingNetworkRequest(load_timing_info);
6209   RemoveMockTransaction(&transaction);
6210 }
6211 
6212 // Tests revalidation after a vary mismatch if etag is present.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMismatch)6213 TEST_F(HttpCacheTest, GET_ValidateCache_VaryMismatch) {
6214   MockHttpCache cache;
6215 
6216   // Write to the cache.
6217   MockTransaction transaction(kTypicalGET_Transaction);
6218   transaction.request_headers = "Foo: bar\r\n";
6219   transaction.response_headers =
6220       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6221       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6222       "Etag: \"foopy\"\n"
6223       "Cache-Control: max-age=0\n"
6224       "Vary: Foo\n";
6225   AddMockTransaction(&transaction);
6226   RunTransactionTest(cache.http_cache(), transaction);
6227 
6228   // Read from the cache and revalidate the entry.
6229   RevalidationServer server;
6230   transaction.handler = server.GetHandlerCallback();
6231   transaction.request_headers = "Foo: none\r\n";
6232   LoadTimingInfo load_timing_info;
6233   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
6234                                  NetLogWithSource::Make(NetLogSourceType::NONE),
6235                                  &load_timing_info);
6236 
6237   EXPECT_TRUE(server.EtagUsed());
6238   EXPECT_FALSE(server.LastModifiedUsed());
6239   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6240   EXPECT_EQ(1, cache.disk_cache()->open_count());
6241   EXPECT_EQ(1, cache.disk_cache()->create_count());
6242   TestLoadTimingNetworkRequest(load_timing_info);
6243   RemoveMockTransaction(&transaction);
6244 }
6245 
6246 // Tests revalidation after a vary mismatch due to vary: * if etag is present.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMismatchStar)6247 TEST_F(HttpCacheTest, GET_ValidateCache_VaryMismatchStar) {
6248   MockHttpCache cache;
6249 
6250   // Write to the cache.
6251   MockTransaction transaction(kTypicalGET_Transaction);
6252   transaction.response_headers =
6253       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6254       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6255       "Etag: \"foopy\"\n"
6256       "Cache-Control: max-age=0\n"
6257       "Vary: *\n";
6258   AddMockTransaction(&transaction);
6259   RunTransactionTest(cache.http_cache(), transaction);
6260 
6261   // Read from the cache and revalidate the entry.
6262   RevalidationServer server;
6263   transaction.handler = server.GetHandlerCallback();
6264   LoadTimingInfo load_timing_info;
6265   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
6266                                  NetLogWithSource::Make(NetLogSourceType::NONE),
6267                                  &load_timing_info);
6268 
6269   EXPECT_TRUE(server.EtagUsed());
6270   EXPECT_FALSE(server.LastModifiedUsed());
6271   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6272   EXPECT_EQ(1, cache.disk_cache()->open_count());
6273   EXPECT_EQ(1, cache.disk_cache()->create_count());
6274   TestLoadTimingNetworkRequest(load_timing_info);
6275   RemoveMockTransaction(&transaction);
6276 }
6277 
6278 // Tests lack of revalidation after a vary mismatch and no etag.
TEST_F(HttpCacheTest,GET_DontValidateCache_VaryMismatch)6279 TEST_F(HttpCacheTest, GET_DontValidateCache_VaryMismatch) {
6280   MockHttpCache cache;
6281 
6282   // Write to the cache.
6283   MockTransaction transaction(kTypicalGET_Transaction);
6284   transaction.request_headers = "Foo: bar\r\n";
6285   transaction.response_headers =
6286       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6287       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6288       "Cache-Control: max-age=0\n"
6289       "Vary: Foo\n";
6290   AddMockTransaction(&transaction);
6291   RunTransactionTest(cache.http_cache(), transaction);
6292 
6293   // Read from the cache and don't revalidate the entry.
6294   RevalidationServer server;
6295   transaction.handler = server.GetHandlerCallback();
6296   transaction.request_headers = "Foo: none\r\n";
6297   LoadTimingInfo load_timing_info;
6298   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
6299                                  NetLogWithSource::Make(NetLogSourceType::NONE),
6300                                  &load_timing_info);
6301 
6302   EXPECT_FALSE(server.EtagUsed());
6303   EXPECT_FALSE(server.LastModifiedUsed());
6304   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6305   EXPECT_EQ(1, cache.disk_cache()->open_count());
6306   EXPECT_EQ(1, cache.disk_cache()->create_count());
6307   TestLoadTimingNetworkRequest(load_timing_info);
6308   RemoveMockTransaction(&transaction);
6309 }
6310 
6311 // Tests that a new vary header provided when revalidating an entry is saved.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMatch_UpdateVary)6312 TEST_F(HttpCacheTest, GET_ValidateCache_VaryMatch_UpdateVary) {
6313   MockHttpCache cache;
6314 
6315   // Write to the cache.
6316   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6317   transaction.request_headers = "Foo: bar\r\n Name: bar\r\n";
6318   transaction.response_headers =
6319       "Etag: \"foopy\"\n"
6320       "Cache-Control: max-age=0\n"
6321       "Vary: Foo\n";
6322   RunTransactionTest(cache.http_cache(), transaction);
6323 
6324   // Validate the entry and change the vary field in the response.
6325   transaction.request_headers = "Foo: bar\r\n Name: none\r\n";
6326   transaction.status = "HTTP/1.1 304 Not Modified";
6327   transaction.response_headers =
6328       "Etag: \"foopy\"\n"
6329       "Cache-Control: max-age=3600\n"
6330       "Vary: Name\n";
6331   RunTransactionTest(cache.http_cache(), transaction);
6332 
6333   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6334   EXPECT_EQ(1, cache.disk_cache()->open_count());
6335   EXPECT_EQ(1, cache.disk_cache()->create_count());
6336 
6337   // Make sure that the ActiveEntry is gone.
6338   base::RunLoop().RunUntilIdle();
6339 
6340   // Generate a vary mismatch.
6341   transaction.request_headers = "Foo: bar\r\n Name: bar\r\n";
6342   RunTransactionTest(cache.http_cache(), transaction);
6343 
6344   EXPECT_EQ(3, cache.network_layer()->transaction_count());
6345   EXPECT_EQ(2, cache.disk_cache()->open_count());
6346   EXPECT_EQ(1, cache.disk_cache()->create_count());
6347 }
6348 
6349 // Tests that new request headers causing a vary mismatch are paired with the
6350 // new response when the server says the old response can be used.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMismatch_UpdateRequestHeader)6351 TEST_F(HttpCacheTest, GET_ValidateCache_VaryMismatch_UpdateRequestHeader) {
6352   MockHttpCache cache;
6353 
6354   // Write to the cache.
6355   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6356   transaction.request_headers = "Foo: bar\r\n";
6357   transaction.response_headers =
6358       "Etag: \"foopy\"\n"
6359       "Cache-Control: max-age=3600\n"
6360       "Vary: Foo\n";
6361   RunTransactionTest(cache.http_cache(), transaction);
6362 
6363   // Vary-mismatch validation receives 304.
6364   transaction.request_headers = "Foo: none\r\n";
6365   transaction.status = "HTTP/1.1 304 Not Modified";
6366   RunTransactionTest(cache.http_cache(), transaction);
6367 
6368   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6369   EXPECT_EQ(1, cache.disk_cache()->open_count());
6370   EXPECT_EQ(1, cache.disk_cache()->create_count());
6371 
6372   // Make sure that the ActiveEntry is gone.
6373   base::RunLoop().RunUntilIdle();
6374 
6375   // Generate a vary mismatch.
6376   transaction.request_headers = "Foo: bar\r\n";
6377   RunTransactionTest(cache.http_cache(), transaction);
6378 
6379   EXPECT_EQ(3, cache.network_layer()->transaction_count());
6380   EXPECT_EQ(2, cache.disk_cache()->open_count());
6381   EXPECT_EQ(1, cache.disk_cache()->create_count());
6382 }
6383 
6384 // Tests that a 304 without vary headers doesn't delete the previously stored
6385 // vary data after a vary match revalidation.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMatch_DontDeleteVary)6386 TEST_F(HttpCacheTest, GET_ValidateCache_VaryMatch_DontDeleteVary) {
6387   MockHttpCache cache;
6388 
6389   // Write to the cache.
6390   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6391   transaction.request_headers = "Foo: bar\r\n";
6392   transaction.response_headers =
6393       "Etag: \"foopy\"\n"
6394       "Cache-Control: max-age=0\n"
6395       "Vary: Foo\n";
6396   RunTransactionTest(cache.http_cache(), transaction);
6397 
6398   // Validate the entry and remove the vary field in the response.
6399   transaction.status = "HTTP/1.1 304 Not Modified";
6400   transaction.response_headers =
6401       "Etag: \"foopy\"\n"
6402       "Cache-Control: max-age=3600\n";
6403   RunTransactionTest(cache.http_cache(), transaction);
6404 
6405   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6406   EXPECT_EQ(1, cache.disk_cache()->open_count());
6407   EXPECT_EQ(1, cache.disk_cache()->create_count());
6408 
6409   // Make sure that the ActiveEntry is gone.
6410   base::RunLoop().RunUntilIdle();
6411 
6412   // Generate a vary mismatch.
6413   transaction.request_headers = "Foo: none\r\n";
6414   RunTransactionTest(cache.http_cache(), transaction);
6415 
6416   EXPECT_EQ(3, cache.network_layer()->transaction_count());
6417   EXPECT_EQ(2, cache.disk_cache()->open_count());
6418   EXPECT_EQ(1, cache.disk_cache()->create_count());
6419 }
6420 
6421 // Tests that a 304 without vary headers doesn't delete the previously stored
6422 // vary data after a vary mismatch.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMismatch_DontDeleteVary)6423 TEST_F(HttpCacheTest, GET_ValidateCache_VaryMismatch_DontDeleteVary) {
6424   MockHttpCache cache;
6425 
6426   // Write to the cache.
6427   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6428   transaction.request_headers = "Foo: bar\r\n";
6429   transaction.response_headers =
6430       "Etag: \"foopy\"\n"
6431       "Cache-Control: max-age=3600\n"
6432       "Vary: Foo\n";
6433   RunTransactionTest(cache.http_cache(), transaction);
6434 
6435   // Vary-mismatch validation receives 304 and no vary header.
6436   transaction.request_headers = "Foo: none\r\n";
6437   transaction.status = "HTTP/1.1 304 Not Modified";
6438   transaction.response_headers =
6439       "Etag: \"foopy\"\n"
6440       "Cache-Control: max-age=3600\n";
6441   RunTransactionTest(cache.http_cache(), transaction);
6442 
6443   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6444   EXPECT_EQ(1, cache.disk_cache()->open_count());
6445   EXPECT_EQ(1, cache.disk_cache()->create_count());
6446 
6447   // Make sure that the ActiveEntry is gone.
6448   base::RunLoop().RunUntilIdle();
6449 
6450   // Generate a vary mismatch.
6451   transaction.request_headers = "Foo: bar\r\n";
6452   RunTransactionTest(cache.http_cache(), transaction);
6453 
6454   EXPECT_EQ(3, cache.network_layer()->transaction_count());
6455   EXPECT_EQ(2, cache.disk_cache()->open_count());
6456   EXPECT_EQ(1, cache.disk_cache()->create_count());
6457 }
6458 
ETagGet_UnconditionalRequest_Handler(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)6459 static void ETagGet_UnconditionalRequest_Handler(const HttpRequestInfo* request,
6460                                                  std::string* response_status,
6461                                                  std::string* response_headers,
6462                                                  std::string* response_data) {
6463   EXPECT_FALSE(
6464       request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
6465 }
6466 
TEST_F(HttpCacheTest,ETagGET_Http10)6467 TEST_F(HttpCacheTest, ETagGET_Http10) {
6468   MockHttpCache cache;
6469 
6470   ScopedMockTransaction transaction(kETagGET_Transaction);
6471   transaction.status = "HTTP/1.0 200 OK";
6472 
6473   // Write to the cache.
6474   RunTransactionTest(cache.http_cache(), transaction);
6475 
6476   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6477   EXPECT_EQ(0, cache.disk_cache()->open_count());
6478   EXPECT_EQ(1, cache.disk_cache()->create_count());
6479 
6480   // Get the same URL again, without generating a conditional request.
6481   transaction.load_flags = LOAD_VALIDATE_CACHE;
6482   transaction.handler =
6483       base::BindRepeating(&ETagGet_UnconditionalRequest_Handler);
6484   RunTransactionTest(cache.http_cache(), transaction);
6485 
6486   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6487   EXPECT_EQ(1, cache.disk_cache()->open_count());
6488   EXPECT_EQ(1, cache.disk_cache()->create_count());
6489 }
6490 
TEST_F(HttpCacheTest,ETagGET_Http10_Range)6491 TEST_F(HttpCacheTest, ETagGET_Http10_Range) {
6492   MockHttpCache cache;
6493 
6494   ScopedMockTransaction transaction(kETagGET_Transaction);
6495   transaction.status = "HTTP/1.0 200 OK";
6496 
6497   // Write to the cache.
6498   RunTransactionTest(cache.http_cache(), transaction);
6499 
6500   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6501   EXPECT_EQ(0, cache.disk_cache()->open_count());
6502   EXPECT_EQ(1, cache.disk_cache()->create_count());
6503 
6504   // Get the same URL again, but use a byte range request.
6505   transaction.load_flags = LOAD_VALIDATE_CACHE;
6506   transaction.handler =
6507       base::BindRepeating(&ETagGet_UnconditionalRequest_Handler);
6508   transaction.request_headers = "Range: bytes = 5-\r\n";
6509   RunTransactionTest(cache.http_cache(), transaction);
6510 
6511   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6512   EXPECT_EQ(1, cache.disk_cache()->open_count());
6513   EXPECT_EQ(2, cache.disk_cache()->create_count());
6514 }
6515 
ETagGet_ConditionalRequest_NoStore_Handler(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)6516 static void ETagGet_ConditionalRequest_NoStore_Handler(
6517     const HttpRequestInfo* request,
6518     std::string* response_status,
6519     std::string* response_headers,
6520     std::string* response_data) {
6521   EXPECT_TRUE(
6522       request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
6523   response_status->assign("HTTP/1.1 304 Not Modified");
6524   response_headers->assign("Cache-Control: no-store\n");
6525   response_data->clear();
6526 }
6527 
TEST_F(HttpCacheTest,ETagGET_ConditionalRequest_304_NoStore)6528 TEST_F(HttpCacheTest, ETagGET_ConditionalRequest_304_NoStore) {
6529   MockHttpCache cache;
6530 
6531   ScopedMockTransaction transaction(kETagGET_Transaction);
6532 
6533   // Write to the cache.
6534   RunTransactionTest(cache.http_cache(), transaction);
6535 
6536   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6537   EXPECT_EQ(0, cache.disk_cache()->open_count());
6538   EXPECT_EQ(1, cache.disk_cache()->create_count());
6539 
6540   // Get the same URL again, but this time we expect it to result
6541   // in a conditional request.
6542   transaction.load_flags = LOAD_VALIDATE_CACHE;
6543   transaction.handler =
6544       base::BindRepeating(&ETagGet_ConditionalRequest_NoStore_Handler);
6545   RunTransactionTest(cache.http_cache(), transaction);
6546 
6547   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6548   EXPECT_EQ(1, cache.disk_cache()->open_count());
6549   EXPECT_EQ(1, cache.disk_cache()->create_count());
6550 
6551   ScopedMockTransaction transaction2(kETagGET_Transaction);
6552 
6553   // Write to the cache again. This should create a new entry.
6554   RunTransactionTest(cache.http_cache(), transaction2);
6555 
6556   EXPECT_EQ(3, cache.network_layer()->transaction_count());
6557   EXPECT_EQ(1, cache.disk_cache()->open_count());
6558   EXPECT_EQ(2, cache.disk_cache()->create_count());
6559 }
6560 
6561 // Helper that does 4 requests using HttpCache:
6562 //
6563 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
6564 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
6565 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
6566 //     be returned.
6567 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
6568 //     returned.
6569 // The entry will be created once and will be opened for the 3 subsequent
6570 // requests.
ConditionalizedRequestUpdatesCacheHelper(const Response & net_response_1,const Response & net_response_2,const Response & cached_response_2,const char * extra_request_headers)6571 static void ConditionalizedRequestUpdatesCacheHelper(
6572     const Response& net_response_1,
6573     const Response& net_response_2,
6574     const Response& cached_response_2,
6575     const char* extra_request_headers) {
6576   MockHttpCache cache;
6577 
6578   // The URL we will be requesting.
6579   const char kUrl[] = "http://foobar.com/main.css";
6580 
6581   // Junk network response.
6582   static const Response kUnexpectedResponse = {
6583     "HTTP/1.1 500 Unexpected",
6584     "Server: unexpected_header",
6585     "unexpected body"
6586   };
6587 
6588   // We will control the network layer's responses for |kUrl| using
6589   // |mock_network_response|.
6590   MockTransaction mock_network_response = {nullptr};
6591   mock_network_response.url = kUrl;
6592   AddMockTransaction(&mock_network_response);
6593 
6594   // Request |kUrl| for the first time. It should hit the network and
6595   // receive |kNetResponse1|, which it saves into the HTTP cache.
6596 
6597   MockTransaction request = {nullptr};
6598   request.url = kUrl;
6599   request.method = "GET";
6600   request.request_headers = "";
6601 
6602   net_response_1.AssignTo(&mock_network_response);  // Network mock.
6603   net_response_1.AssignTo(&request);                // Expected result.
6604 
6605   std::string response_headers;
6606   RunTransactionTestWithResponse(
6607       cache.http_cache(), request, &response_headers);
6608 
6609   EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
6610   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6611   EXPECT_EQ(0, cache.disk_cache()->open_count());
6612   EXPECT_EQ(1, cache.disk_cache()->create_count());
6613 
6614   // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
6615   // cache, so we don't hit the network.
6616 
6617   request.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
6618 
6619   kUnexpectedResponse.AssignTo(&mock_network_response);  // Network mock.
6620   net_response_1.AssignTo(&request);                     // Expected result.
6621 
6622   RunTransactionTestWithResponse(
6623       cache.http_cache(), request, &response_headers);
6624 
6625   EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
6626   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6627   EXPECT_EQ(1, cache.disk_cache()->open_count());
6628   EXPECT_EQ(1, cache.disk_cache()->create_count());
6629 
6630   // Request |kUrl| yet again, but this time give the request an
6631   // "If-Modified-Since" header. This will cause the request to re-hit the
6632   // network. However now the network response is going to be
6633   // different -- this simulates a change made to the CSS file.
6634 
6635   request.request_headers = extra_request_headers;
6636   request.load_flags = LOAD_NORMAL;
6637 
6638   net_response_2.AssignTo(&mock_network_response);  // Network mock.
6639   net_response_2.AssignTo(&request);                // Expected result.
6640 
6641   RunTransactionTestWithResponse(
6642       cache.http_cache(), request, &response_headers);
6643 
6644   EXPECT_EQ(net_response_2.status_and_headers(), response_headers);
6645   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6646   EXPECT_EQ(1, cache.disk_cache()->open_count());
6647   EXPECT_EQ(1, cache.disk_cache()->create_count());
6648 
6649   // Finally, request |kUrl| again. This request should be serviced from
6650   // the cache. Moreover, the value in the cache should be |kNetResponse2|
6651   // and NOT |kNetResponse1|. The previous step should have replaced the
6652   // value in the cache with the modified response.
6653 
6654   request.request_headers = "";
6655   request.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
6656 
6657   kUnexpectedResponse.AssignTo(&mock_network_response);  // Network mock.
6658   cached_response_2.AssignTo(&request);                  // Expected result.
6659 
6660   RunTransactionTestWithResponse(
6661       cache.http_cache(), request, &response_headers);
6662 
6663   EXPECT_EQ(cached_response_2.status_and_headers(), response_headers);
6664   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6665   EXPECT_EQ(2, cache.disk_cache()->open_count());
6666   EXPECT_EQ(1, cache.disk_cache()->create_count());
6667 
6668   RemoveMockTransaction(&mock_network_response);
6669 }
6670 
6671 // Check that when an "if-modified-since" header is attached
6672 // to the request, the result still updates the cached entry.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache1)6673 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache1) {
6674   // First network response for |kUrl|.
6675   static const Response kNetResponse1 = {
6676     "HTTP/1.1 200 OK",
6677     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6678     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6679     "body1"
6680   };
6681 
6682   // Second network response for |kUrl|.
6683   static const Response kNetResponse2 = {
6684     "HTTP/1.1 200 OK",
6685     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6686     "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
6687     "body2"
6688   };
6689 
6690   const char extra_headers[] =
6691       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
6692 
6693   ConditionalizedRequestUpdatesCacheHelper(
6694       kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
6695 }
6696 
6697 // Check that when an "if-none-match" header is attached
6698 // to the request, the result updates the cached entry.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache2)6699 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache2) {
6700   // First network response for |kUrl|.
6701   static const Response kNetResponse1 = {
6702     "HTTP/1.1 200 OK",
6703     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6704     "Etag: \"ETAG1\"\n"
6705     "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n",  // Should never expire.
6706     "body1"
6707   };
6708 
6709   // Second network response for |kUrl|.
6710   static const Response kNetResponse2 = {
6711     "HTTP/1.1 200 OK",
6712     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6713     "Etag: \"ETAG2\"\n"
6714     "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n",  // Should never expire.
6715     "body2"
6716   };
6717 
6718   const char extra_headers[] = "If-None-Match: \"ETAG1\"\r\n";
6719 
6720   ConditionalizedRequestUpdatesCacheHelper(
6721       kNetResponse1, kNetResponse2, kNetResponse2, extra_headers);
6722 }
6723 
6724 // Check that when an "if-modified-since" header is attached
6725 // to a request, the 304 (not modified result) result updates the cached
6726 // headers, and the 304 response is returned rather than the cached response.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache3)6727 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache3) {
6728   // First network response for |kUrl|.
6729   static const Response kNetResponse1 = {
6730     "HTTP/1.1 200 OK",
6731     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6732     "Server: server1\n"
6733     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6734     "body1"
6735   };
6736 
6737   // Second network response for |kUrl|.
6738   static const Response kNetResponse2 = {
6739     "HTTP/1.1 304 Not Modified",
6740     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6741     "Server: server2\n"
6742     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6743     ""
6744   };
6745 
6746   static const Response kCachedResponse2 = {
6747     "HTTP/1.1 200 OK",
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     "body1"
6752   };
6753 
6754   const char extra_headers[] =
6755       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
6756 
6757   ConditionalizedRequestUpdatesCacheHelper(
6758       kNetResponse1, kNetResponse2, kCachedResponse2, extra_headers);
6759 }
6760 
6761 // Test that when doing an externally conditionalized if-modified-since
6762 // and there is no corresponding cache entry, a new cache entry is NOT
6763 // created (304 response).
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache4)6764 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache4) {
6765   MockHttpCache cache;
6766 
6767   const char kUrl[] = "http://foobar.com/main.css";
6768 
6769   static const Response kNetResponse = {
6770     "HTTP/1.1 304 Not Modified",
6771     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6772     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6773     ""
6774   };
6775 
6776   const char kExtraRequestHeaders[] =
6777       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
6778 
6779   // We will control the network layer's responses for |kUrl| using
6780   // |mock_network_response|.
6781   MockTransaction mock_network_response = {nullptr};
6782   mock_network_response.url = kUrl;
6783   AddMockTransaction(&mock_network_response);
6784 
6785   MockTransaction request = {nullptr};
6786   request.url = kUrl;
6787   request.method = "GET";
6788   request.request_headers = kExtraRequestHeaders;
6789 
6790   kNetResponse.AssignTo(&mock_network_response);  // Network mock.
6791   kNetResponse.AssignTo(&request);                // Expected result.
6792 
6793   std::string response_headers;
6794   RunTransactionTestWithResponse(
6795       cache.http_cache(), request, &response_headers);
6796 
6797   EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
6798   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6799   EXPECT_EQ(0, cache.disk_cache()->open_count());
6800   EXPECT_EQ(0, cache.disk_cache()->create_count());
6801 
6802   RemoveMockTransaction(&mock_network_response);
6803 }
6804 
6805 // Test that when doing an externally conditionalized if-modified-since
6806 // and there is no corresponding cache entry, a new cache entry is NOT
6807 // created (200 response).
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache5)6808 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache5) {
6809   MockHttpCache cache;
6810 
6811   const char kUrl[] = "http://foobar.com/main.css";
6812 
6813   static const Response kNetResponse = {
6814     "HTTP/1.1 200 OK",
6815     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6816     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6817     "foobar!!!"
6818   };
6819 
6820   const char kExtraRequestHeaders[] =
6821       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
6822 
6823   // We will control the network layer's responses for |kUrl| using
6824   // |mock_network_response|.
6825   MockTransaction mock_network_response = {nullptr};
6826   mock_network_response.url = kUrl;
6827   AddMockTransaction(&mock_network_response);
6828 
6829   MockTransaction request = {nullptr};
6830   request.url = kUrl;
6831   request.method = "GET";
6832   request.request_headers = kExtraRequestHeaders;
6833 
6834   kNetResponse.AssignTo(&mock_network_response);  // Network mock.
6835   kNetResponse.AssignTo(&request);                // Expected result.
6836 
6837   std::string response_headers;
6838   RunTransactionTestWithResponse(
6839       cache.http_cache(), request, &response_headers);
6840 
6841   EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
6842   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6843   EXPECT_EQ(0, cache.disk_cache()->open_count());
6844   EXPECT_EQ(0, cache.disk_cache()->create_count());
6845 
6846   RemoveMockTransaction(&mock_network_response);
6847 }
6848 
6849 // Test that when doing an externally conditionalized if-modified-since
6850 // if the date does not match the cache entry's last-modified date,
6851 // then we do NOT use the response (304) to update the cache.
6852 // (the if-modified-since date is 2 days AFTER the cache's modification date).
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache6)6853 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache6) {
6854   static const Response kNetResponse1 = {
6855     "HTTP/1.1 200 OK",
6856     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6857     "Server: server1\n"
6858     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6859     "body1"
6860   };
6861 
6862   // Second network response for |kUrl|.
6863   static const Response kNetResponse2 = {
6864     "HTTP/1.1 304 Not Modified",
6865     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6866     "Server: server2\n"
6867     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6868     ""
6869   };
6870 
6871   // This is two days in the future from the original response's last-modified
6872   // date!
6873   const char kExtraRequestHeaders[] =
6874       "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
6875 
6876   ConditionalizedRequestUpdatesCacheHelper(
6877       kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
6878 }
6879 
6880 // Test that when doing an externally conditionalized if-none-match
6881 // if the etag does not match the cache entry's etag, then we do not use the
6882 // response (304) to update the cache.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache7)6883 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache7) {
6884   static const Response kNetResponse1 = {
6885     "HTTP/1.1 200 OK",
6886     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6887     "Etag: \"Foo1\"\n"
6888     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6889     "body1"
6890   };
6891 
6892   // Second network response for |kUrl|.
6893   static const Response kNetResponse2 = {
6894     "HTTP/1.1 304 Not Modified",
6895     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6896     "Etag: \"Foo2\"\n"
6897     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6898     ""
6899   };
6900 
6901   // Different etag from original response.
6902   const char kExtraRequestHeaders[] = "If-None-Match: \"Foo2\"\r\n";
6903 
6904   ConditionalizedRequestUpdatesCacheHelper(
6905       kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
6906 }
6907 
6908 // Test that doing an externally conditionalized request with both if-none-match
6909 // and if-modified-since updates the cache.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache8)6910 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache8) {
6911   static const Response kNetResponse1 = {
6912     "HTTP/1.1 200 OK",
6913     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6914     "Etag: \"Foo1\"\n"
6915     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6916     "body1"
6917   };
6918 
6919   // Second network response for |kUrl|.
6920   static const Response kNetResponse2 = {
6921     "HTTP/1.1 200 OK",
6922     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6923     "Etag: \"Foo2\"\n"
6924     "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
6925     "body2"
6926   };
6927 
6928   const char kExtraRequestHeaders[] =
6929       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
6930       "If-None-Match: \"Foo1\"\r\n";
6931 
6932   ConditionalizedRequestUpdatesCacheHelper(
6933       kNetResponse1, kNetResponse2, kNetResponse2, kExtraRequestHeaders);
6934 }
6935 
6936 // Test that doing an externally conditionalized request with both if-none-match
6937 // and if-modified-since does not update the cache with only one match.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache9)6938 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache9) {
6939   static const Response kNetResponse1 = {
6940     "HTTP/1.1 200 OK",
6941     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6942     "Etag: \"Foo1\"\n"
6943     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6944     "body1"
6945   };
6946 
6947   // Second network response for |kUrl|.
6948   static const Response kNetResponse2 = {
6949     "HTTP/1.1 200 OK",
6950     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6951     "Etag: \"Foo2\"\n"
6952     "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
6953     "body2"
6954   };
6955 
6956   // The etag doesn't match what we have stored.
6957   const char kExtraRequestHeaders[] =
6958       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
6959       "If-None-Match: \"Foo2\"\r\n";
6960 
6961   ConditionalizedRequestUpdatesCacheHelper(
6962       kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
6963 }
6964 
6965 // Test that doing an externally conditionalized request with both if-none-match
6966 // and if-modified-since does not update the cache with only one match.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache10)6967 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache10) {
6968   static const Response kNetResponse1 = {
6969     "HTTP/1.1 200 OK",
6970     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6971     "Etag: \"Foo1\"\n"
6972     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6973     "body1"
6974   };
6975 
6976   // Second network response for |kUrl|.
6977   static const Response kNetResponse2 = {
6978     "HTTP/1.1 200 OK",
6979     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6980     "Etag: \"Foo2\"\n"
6981     "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
6982     "body2"
6983   };
6984 
6985   // The modification date doesn't match what we have stored.
6986   const char kExtraRequestHeaders[] =
6987       "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
6988       "If-None-Match: \"Foo1\"\r\n";
6989 
6990   ConditionalizedRequestUpdatesCacheHelper(
6991       kNetResponse1, kNetResponse2, kNetResponse1, kExtraRequestHeaders);
6992 }
6993 
TEST_F(HttpCacheTest,UrlContainingHash)6994 TEST_F(HttpCacheTest, UrlContainingHash) {
6995   MockHttpCache cache;
6996 
6997   // Do a typical GET request -- should write an entry into our cache.
6998   MockTransaction trans(kTypicalGET_Transaction);
6999   RunTransactionTest(cache.http_cache(), trans);
7000 
7001   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7002   EXPECT_EQ(0, cache.disk_cache()->open_count());
7003   EXPECT_EQ(1, cache.disk_cache()->create_count());
7004 
7005   // Request the same URL, but this time with a reference section (hash).
7006   // Since the cache key strips the hash sections, this should be a cache hit.
7007   std::string url_with_hash = std::string(trans.url) + "#multiple#hashes";
7008   trans.url = url_with_hash.c_str();
7009   trans.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7010 
7011   RunTransactionTest(cache.http_cache(), trans);
7012 
7013   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7014   EXPECT_EQ(1, cache.disk_cache()->open_count());
7015   EXPECT_EQ(1, cache.disk_cache()->create_count());
7016 }
7017 
7018 // Tests that we skip the cache for POST requests that do not have an upload
7019 // identifier.
TEST_F(HttpCacheTest,SimplePOST_SkipsCache)7020 TEST_F(HttpCacheTest, SimplePOST_SkipsCache) {
7021   MockHttpCache cache;
7022 
7023   RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
7024 
7025   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7026   EXPECT_EQ(0, cache.disk_cache()->open_count());
7027   EXPECT_EQ(0, cache.disk_cache()->create_count());
7028 }
7029 
7030 // Tests POST handling with a disabled cache (no DCHECK).
TEST_F(HttpCacheTest,SimplePOST_DisabledCache)7031 TEST_F(HttpCacheTest, SimplePOST_DisabledCache) {
7032   MockHttpCache cache;
7033   cache.http_cache()->set_mode(HttpCache::Mode::DISABLE);
7034 
7035   RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
7036 
7037   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7038   EXPECT_EQ(0, cache.disk_cache()->open_count());
7039   EXPECT_EQ(0, cache.disk_cache()->create_count());
7040 }
7041 
TEST_F(HttpCacheTest,SimplePOST_LoadOnlyFromCache_Miss)7042 TEST_F(HttpCacheTest, SimplePOST_LoadOnlyFromCache_Miss) {
7043   MockHttpCache cache;
7044 
7045   MockTransaction transaction(kSimplePOST_Transaction);
7046   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7047 
7048   MockHttpRequest request(transaction);
7049   TestCompletionCallback callback;
7050 
7051   std::unique_ptr<HttpTransaction> trans;
7052   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
7053   ASSERT_TRUE(trans.get());
7054 
7055   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
7056   ASSERT_THAT(callback.GetResult(rv), IsError(ERR_CACHE_MISS));
7057 
7058   trans.reset();
7059 
7060   EXPECT_EQ(0, cache.network_layer()->transaction_count());
7061   EXPECT_EQ(0, cache.disk_cache()->open_count());
7062   EXPECT_EQ(0, cache.disk_cache()->create_count());
7063 }
7064 
TEST_F(HttpCacheTest,SimplePOST_LoadOnlyFromCache_Hit)7065 TEST_F(HttpCacheTest, SimplePOST_LoadOnlyFromCache_Hit) {
7066   MockHttpCache cache;
7067 
7068   // Test that we hit the cache for POST requests.
7069 
7070   MockTransaction transaction(kSimplePOST_Transaction);
7071 
7072   const int64_t kUploadId = 1;  // Just a dummy value.
7073 
7074   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7075   element_readers.push_back(
7076       std::make_unique<UploadBytesElementReader>("hello", 5));
7077   ElementsUploadDataStream upload_data_stream(std::move(element_readers),
7078                                               kUploadId);
7079   MockHttpRequest request(transaction);
7080   request.upload_data_stream = &upload_data_stream;
7081 
7082   // Populate the cache.
7083   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
7084                                 nullptr);
7085 
7086   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7087   EXPECT_EQ(0, cache.disk_cache()->open_count());
7088   EXPECT_EQ(1, cache.disk_cache()->create_count());
7089 
7090   // Load from cache.
7091   request.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7092   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
7093                                 nullptr);
7094 
7095   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7096   EXPECT_EQ(1, cache.disk_cache()->open_count());
7097   EXPECT_EQ(1, cache.disk_cache()->create_count());
7098 }
7099 
7100 // Test that we don't hit the cache for POST requests if there is a byte range.
TEST_F(HttpCacheTest,SimplePOST_WithRanges)7101 TEST_F(HttpCacheTest, SimplePOST_WithRanges) {
7102   MockHttpCache cache;
7103 
7104   MockTransaction transaction(kSimplePOST_Transaction);
7105   transaction.request_headers = "Range: bytes = 0-4\r\n";
7106 
7107   const int64_t kUploadId = 1;  // Just a dummy value.
7108 
7109   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7110   element_readers.push_back(
7111       std::make_unique<UploadBytesElementReader>("hello", 5));
7112   ElementsUploadDataStream upload_data_stream(std::move(element_readers),
7113                                               kUploadId);
7114 
7115   MockHttpRequest request(transaction);
7116   request.upload_data_stream = &upload_data_stream;
7117 
7118   // Attempt to populate the cache.
7119   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
7120                                 nullptr);
7121 
7122   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7123   EXPECT_EQ(0, cache.disk_cache()->open_count());
7124   EXPECT_EQ(0, cache.disk_cache()->create_count());
7125 }
7126 
7127 // Tests that a POST is cached separately from a GET.
TEST_F(HttpCacheTest,SimplePOST_SeparateCache)7128 TEST_F(HttpCacheTest, SimplePOST_SeparateCache) {
7129   MockHttpCache cache;
7130 
7131   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7132   element_readers.push_back(
7133       std::make_unique<UploadBytesElementReader>("hello", 5));
7134   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 1);
7135 
7136   MockTransaction transaction(kSimplePOST_Transaction);
7137   MockHttpRequest req1(transaction);
7138   req1.upload_data_stream = &upload_data_stream;
7139 
7140   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7141 
7142   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7143   EXPECT_EQ(0, cache.disk_cache()->open_count());
7144   EXPECT_EQ(1, cache.disk_cache()->create_count());
7145 
7146   transaction.method = "GET";
7147   MockHttpRequest req2(transaction);
7148 
7149   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7150 
7151   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7152   EXPECT_EQ(0, cache.disk_cache()->open_count());
7153   EXPECT_EQ(2, cache.disk_cache()->create_count());
7154 }
7155 
7156 // Tests that a successful POST invalidates a previously cached GET.
TEST_F(HttpCacheTest,SimplePOST_Invalidate_205)7157 TEST_F(HttpCacheTest, SimplePOST_Invalidate_205) {
7158   MockHttpCache cache;
7159 
7160   MockTransaction transaction(kSimpleGET_Transaction);
7161   AddMockTransaction(&transaction);
7162   MockHttpRequest req1(transaction);
7163 
7164   // Attempt to populate the cache.
7165   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7166 
7167   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7168   EXPECT_EQ(0, cache.disk_cache()->open_count());
7169   EXPECT_EQ(1, cache.disk_cache()->create_count());
7170 
7171   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7172   element_readers.push_back(
7173       std::make_unique<UploadBytesElementReader>("hello", 5));
7174   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 1);
7175 
7176   transaction.method = "POST";
7177   transaction.status = "HTTP/1.1 205 No Content";
7178   MockHttpRequest req2(transaction);
7179   req2.upload_data_stream = &upload_data_stream;
7180 
7181   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7182 
7183   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7184   EXPECT_EQ(0, cache.disk_cache()->open_count());
7185   EXPECT_EQ(2, cache.disk_cache()->create_count());
7186 
7187   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7188 
7189   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7190   EXPECT_EQ(0, cache.disk_cache()->open_count());
7191   EXPECT_EQ(3, cache.disk_cache()->create_count());
7192   RemoveMockTransaction(&transaction);
7193 }
7194 
7195 // Tests that a successful POST invalidates a previously cached GET,
7196 // with cache split by top-frame origin.
TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,SimplePOST_Invalidate_205_SplitCache)7197 TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,
7198        SimplePOST_Invalidate_205_SplitCache) {
7199   SchemefulSite site_a(GURL("http://a.com"));
7200   SchemefulSite site_b(GURL("http://b.com"));
7201 
7202   MockHttpCache cache;
7203 
7204   MockTransaction transaction(kSimpleGET_Transaction);
7205   AddMockTransaction(&transaction);
7206   MockHttpRequest req1(transaction);
7207   req1.network_isolation_key = NetworkIsolationKey(site_a, site_a);
7208   req1.network_anonymization_key =
7209       net::NetworkAnonymizationKey::CreateSameSite(site_a);
7210 
7211   // Attempt to populate the cache.
7212   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7213 
7214   // Same for a different origin.
7215   MockHttpRequest req1b(transaction);
7216   req1b.network_isolation_key = NetworkIsolationKey(site_b, site_b);
7217   req1b.network_anonymization_key =
7218       net::NetworkAnonymizationKey::CreateSameSite(site_b);
7219   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1b,
7220                                 nullptr);
7221 
7222   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7223   EXPECT_EQ(0, cache.disk_cache()->open_count());
7224   EXPECT_EQ(2, cache.disk_cache()->create_count());
7225 
7226   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7227   element_readers.push_back(
7228       std::make_unique<UploadBytesElementReader>("hello", 5));
7229   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 1);
7230 
7231   transaction.method = "POST";
7232   transaction.status = "HTTP/1.1 205 No Content";
7233   MockHttpRequest req2(transaction);
7234   req2.upload_data_stream = &upload_data_stream;
7235   req2.network_isolation_key = NetworkIsolationKey(site_a, site_a);
7236   req2.network_anonymization_key =
7237       net::NetworkAnonymizationKey::CreateSameSite(site_a);
7238 
7239   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7240 
7241   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7242   EXPECT_EQ(0, cache.disk_cache()->open_count());
7243   EXPECT_EQ(3, cache.disk_cache()->create_count());
7244 
7245   // req1b should still be cached, since it has a different top-level frame
7246   // origin.
7247   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1b,
7248                                 nullptr);
7249   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7250   EXPECT_EQ(1, cache.disk_cache()->open_count());
7251   EXPECT_EQ(3, cache.disk_cache()->create_count());
7252 
7253   // req1 should not be cached after the POST.
7254   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7255   EXPECT_EQ(4, cache.network_layer()->transaction_count());
7256   EXPECT_EQ(1, cache.disk_cache()->open_count());
7257   EXPECT_EQ(4, cache.disk_cache()->create_count());
7258 
7259   RemoveMockTransaction(&transaction);
7260 }
7261 
7262 // Tests that a successful POST invalidates a previously cached GET, even when
7263 // there is no upload identifier.
TEST_F(HttpCacheTest,SimplePOST_NoUploadId_Invalidate_205)7264 TEST_F(HttpCacheTest, SimplePOST_NoUploadId_Invalidate_205) {
7265   MockHttpCache cache;
7266 
7267   MockTransaction transaction(kSimpleGET_Transaction);
7268   AddMockTransaction(&transaction);
7269   MockHttpRequest req1(transaction);
7270 
7271   // Attempt to populate the cache.
7272   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7273 
7274   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7275   EXPECT_EQ(0, cache.disk_cache()->open_count());
7276   EXPECT_EQ(1, cache.disk_cache()->create_count());
7277 
7278   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7279   element_readers.push_back(
7280       std::make_unique<UploadBytesElementReader>("hello", 5));
7281   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7282 
7283   transaction.method = "POST";
7284   transaction.status = "HTTP/1.1 205 No Content";
7285   MockHttpRequest req2(transaction);
7286   req2.upload_data_stream = &upload_data_stream;
7287 
7288   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7289 
7290   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7291   EXPECT_EQ(0, cache.disk_cache()->open_count());
7292   EXPECT_EQ(1, cache.disk_cache()->create_count());
7293 
7294   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7295 
7296   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7297   EXPECT_EQ(0, cache.disk_cache()->open_count());
7298   EXPECT_EQ(2, cache.disk_cache()->create_count());
7299   RemoveMockTransaction(&transaction);
7300 }
7301 
7302 // Tests that processing a POST before creating the backend doesn't crash.
TEST_F(HttpCacheTest,SimplePOST_NoUploadId_NoBackend)7303 TEST_F(HttpCacheTest, SimplePOST_NoUploadId_NoBackend) {
7304   // This will initialize a cache object with NULL backend.
7305   auto factory = std::make_unique<MockBlockingBackendFactory>();
7306   factory->set_fail(true);
7307   factory->FinishCreation();
7308   MockHttpCache cache(std::move(factory));
7309 
7310   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7311   element_readers.push_back(
7312       std::make_unique<UploadBytesElementReader>("hello", 5));
7313   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7314 
7315   MockTransaction transaction(kSimplePOST_Transaction);
7316   AddMockTransaction(&transaction);
7317   MockHttpRequest req(transaction);
7318   req.upload_data_stream = &upload_data_stream;
7319 
7320   RunTransactionTestWithRequest(cache.http_cache(), transaction, req, nullptr);
7321 
7322   RemoveMockTransaction(&transaction);
7323 }
7324 
7325 // Tests that we don't invalidate entries as a result of a failed POST.
TEST_F(HttpCacheTest,SimplePOST_DontInvalidate_100)7326 TEST_F(HttpCacheTest, SimplePOST_DontInvalidate_100) {
7327   MockHttpCache cache;
7328 
7329   MockTransaction transaction(kSimpleGET_Transaction);
7330   AddMockTransaction(&transaction);
7331   MockHttpRequest req1(transaction);
7332 
7333   // Attempt to populate the cache.
7334   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7335 
7336   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7337   EXPECT_EQ(0, cache.disk_cache()->open_count());
7338   EXPECT_EQ(1, cache.disk_cache()->create_count());
7339 
7340   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7341   element_readers.push_back(
7342       std::make_unique<UploadBytesElementReader>("hello", 5));
7343   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 1);
7344 
7345   transaction.method = "POST";
7346   transaction.status = "HTTP/1.1 100 Continue";
7347   MockHttpRequest req2(transaction);
7348   req2.upload_data_stream = &upload_data_stream;
7349 
7350   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7351 
7352   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7353   EXPECT_EQ(0, cache.disk_cache()->open_count());
7354   EXPECT_EQ(2, cache.disk_cache()->create_count());
7355 
7356   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7357 
7358   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7359   EXPECT_EQ(1, cache.disk_cache()->open_count());
7360   EXPECT_EQ(2, cache.disk_cache()->create_count());
7361   RemoveMockTransaction(&transaction);
7362 }
7363 
7364 // Tests that a HEAD request is not cached by itself.
TEST_F(HttpCacheTest,SimpleHEAD_LoadOnlyFromCache_Miss)7365 TEST_F(HttpCacheTest, SimpleHEAD_LoadOnlyFromCache_Miss) {
7366   MockHttpCache cache;
7367   MockTransaction transaction(kSimplePOST_Transaction);
7368   AddMockTransaction(&transaction);
7369   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7370   transaction.method = "HEAD";
7371 
7372   MockHttpRequest request(transaction);
7373   TestCompletionCallback callback;
7374 
7375   std::unique_ptr<HttpTransaction> trans;
7376   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
7377   ASSERT_TRUE(trans.get());
7378 
7379   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
7380   ASSERT_THAT(callback.GetResult(rv), IsError(ERR_CACHE_MISS));
7381 
7382   trans.reset();
7383 
7384   EXPECT_EQ(0, cache.network_layer()->transaction_count());
7385   EXPECT_EQ(0, cache.disk_cache()->open_count());
7386   EXPECT_EQ(0, cache.disk_cache()->create_count());
7387   RemoveMockTransaction(&transaction);
7388 }
7389 
7390 // Tests that a HEAD request is served from a cached GET.
TEST_F(HttpCacheTest,SimpleHEAD_LoadOnlyFromCache_Hit)7391 TEST_F(HttpCacheTest, SimpleHEAD_LoadOnlyFromCache_Hit) {
7392   MockHttpCache cache;
7393   MockTransaction transaction(kSimpleGET_Transaction);
7394   AddMockTransaction(&transaction);
7395 
7396   // Populate the cache.
7397   RunTransactionTest(cache.http_cache(), transaction);
7398 
7399   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7400   EXPECT_EQ(0, cache.disk_cache()->open_count());
7401   EXPECT_EQ(1, cache.disk_cache()->create_count());
7402 
7403   // Load from cache.
7404   transaction.method = "HEAD";
7405   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7406   transaction.data = "";
7407   RunTransactionTest(cache.http_cache(), transaction);
7408 
7409   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7410   EXPECT_EQ(1, cache.disk_cache()->open_count());
7411   EXPECT_EQ(1, cache.disk_cache()->create_count());
7412   RemoveMockTransaction(&transaction);
7413 }
7414 
7415 // Tests that a read-only request served from the cache preserves CL.
TEST_F(HttpCacheTest,SimpleHEAD_ContentLengthOnHit_Read)7416 TEST_F(HttpCacheTest, SimpleHEAD_ContentLengthOnHit_Read) {
7417   MockHttpCache cache;
7418   MockTransaction transaction(kSimpleGET_Transaction);
7419   AddMockTransaction(&transaction);
7420   transaction.response_headers = "Content-Length: 42\n";
7421 
7422   // Populate the cache.
7423   RunTransactionTest(cache.http_cache(), transaction);
7424 
7425   // Load from cache.
7426   transaction.method = "HEAD";
7427   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7428   transaction.data = "";
7429   std::string headers;
7430 
7431   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7432 
7433   EXPECT_EQ("HTTP/1.1 200 OK\nContent-Length: 42\n", headers);
7434   RemoveMockTransaction(&transaction);
7435 }
7436 
7437 // Tests that a read-write request served from the cache preserves CL.
TEST_F(HttpCacheTest,ETagHEAD_ContentLengthOnHit_ReadWrite)7438 TEST_F(HttpCacheTest, ETagHEAD_ContentLengthOnHit_ReadWrite) {
7439   MockHttpCache cache;
7440   MockTransaction transaction(kETagGET_Transaction);
7441   AddMockTransaction(&transaction);
7442   std::string server_headers(kETagGET_Transaction.response_headers);
7443   server_headers.append("Content-Length: 42\n");
7444   transaction.response_headers = server_headers.data();
7445 
7446   // Populate the cache.
7447   RunTransactionTest(cache.http_cache(), transaction);
7448 
7449   // Load from cache.
7450   transaction.method = "HEAD";
7451   transaction.data = "";
7452   std::string headers;
7453 
7454   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7455 
7456   EXPECT_NE(std::string::npos, headers.find("Content-Length: 42\n"));
7457   RemoveMockTransaction(&transaction);
7458 }
7459 
7460 // Tests that a HEAD request that includes byte ranges bypasses the cache.
TEST_F(HttpCacheTest,SimpleHEAD_WithRanges)7461 TEST_F(HttpCacheTest, SimpleHEAD_WithRanges) {
7462   MockHttpCache cache;
7463   MockTransaction transaction(kSimpleGET_Transaction);
7464   AddMockTransaction(&transaction);
7465 
7466   // Populate the cache.
7467   RunTransactionTest(cache.http_cache(), transaction);
7468 
7469   // Load from cache.
7470   transaction.method = "HEAD";
7471   transaction.request_headers = "Range: bytes = 0-4\r\n";
7472   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7473   transaction.start_return_code = ERR_CACHE_MISS;
7474   RunTransactionTest(cache.http_cache(), transaction);
7475 
7476   EXPECT_EQ(0, cache.disk_cache()->open_count());
7477   EXPECT_EQ(1, cache.disk_cache()->create_count());
7478   RemoveMockTransaction(&transaction);
7479 }
7480 
7481 // Tests that a HEAD request can be served from a partially cached resource.
TEST_F(HttpCacheTest,SimpleHEAD_WithCachedRanges)7482 TEST_F(HttpCacheTest, SimpleHEAD_WithCachedRanges) {
7483   MockHttpCache cache;
7484   AddMockTransaction(&kRangeGET_TransactionOK);
7485 
7486   // Write to the cache (40-49).
7487   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
7488   RemoveMockTransaction(&kRangeGET_TransactionOK);
7489 
7490   MockTransaction transaction(kSimpleGET_Transaction);
7491 
7492   transaction.url = kRangeGET_TransactionOK.url;
7493   transaction.method = "HEAD";
7494   transaction.data = "";
7495   AddMockTransaction(&transaction);
7496   std::string headers;
7497 
7498   // Load from cache.
7499   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7500 
7501   EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
7502   EXPECT_NE(std::string::npos, headers.find("Content-Length: 80\n"));
7503   EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
7504   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7505   EXPECT_EQ(1, cache.disk_cache()->open_count());
7506   EXPECT_EQ(1, cache.disk_cache()->create_count());
7507   RemoveMockTransaction(&transaction);
7508 }
7509 
7510 // Tests that a HEAD request can be served from a truncated resource.
TEST_F(HttpCacheTest,SimpleHEAD_WithTruncatedEntry)7511 TEST_F(HttpCacheTest, SimpleHEAD_WithTruncatedEntry) {
7512   MockHttpCache cache;
7513   AddMockTransaction(&kRangeGET_TransactionOK);
7514 
7515   std::string raw_headers("HTTP/1.1 200 OK\n"
7516                           "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7517                           "ETag: \"foo\"\n"
7518                           "Accept-Ranges: bytes\n"
7519                           "Content-Length: 80\n");
7520   CreateTruncatedEntry(raw_headers, &cache);
7521   RemoveMockTransaction(&kRangeGET_TransactionOK);
7522 
7523   MockTransaction transaction(kSimpleGET_Transaction);
7524 
7525   transaction.url = kRangeGET_TransactionOK.url;
7526   transaction.method = "HEAD";
7527   transaction.data = "";
7528   AddMockTransaction(&transaction);
7529   std::string headers;
7530 
7531   // Load from cache.
7532   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7533 
7534   EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
7535   EXPECT_NE(std::string::npos, headers.find("Content-Length: 80\n"));
7536   EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
7537   EXPECT_EQ(0, cache.network_layer()->transaction_count());
7538   EXPECT_EQ(1, cache.disk_cache()->open_count());
7539   EXPECT_EQ(1, cache.disk_cache()->create_count());
7540   RemoveMockTransaction(&transaction);
7541 }
7542 
7543 // Tests that a HEAD request updates the cached response.
TEST_F(HttpCacheTest,TypicalHEAD_UpdatesResponse)7544 TEST_F(HttpCacheTest, TypicalHEAD_UpdatesResponse) {
7545   MockHttpCache cache;
7546   MockTransaction transaction(kTypicalGET_Transaction);
7547   AddMockTransaction(&transaction);
7548 
7549   // Populate the cache.
7550   RunTransactionTest(cache.http_cache(), transaction);
7551 
7552   // Update the cache.
7553   transaction.method = "HEAD";
7554   transaction.response_headers = "Foo: bar\n";
7555   transaction.data = "";
7556   transaction.status = "HTTP/1.1 304 Not Modified\n";
7557   std::string headers;
7558   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7559   RemoveMockTransaction(&transaction);
7560 
7561   EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
7562   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7563 
7564   MockTransaction transaction2(kTypicalGET_Transaction);
7565   AddMockTransaction(&transaction2);
7566 
7567   // Make sure we are done with the previous transaction.
7568   base::RunLoop().RunUntilIdle();
7569 
7570   // Load from the cache.
7571   transaction2.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7572   RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
7573 
7574   EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
7575   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7576   EXPECT_EQ(2, cache.disk_cache()->open_count());
7577   EXPECT_EQ(1, cache.disk_cache()->create_count());
7578   RemoveMockTransaction(&transaction2);
7579 }
7580 
7581 // Tests that an externally conditionalized HEAD request updates the cache.
TEST_F(HttpCacheTest,TypicalHEAD_ConditionalizedRequestUpdatesResponse)7582 TEST_F(HttpCacheTest, TypicalHEAD_ConditionalizedRequestUpdatesResponse) {
7583   MockHttpCache cache;
7584   MockTransaction transaction(kTypicalGET_Transaction);
7585   AddMockTransaction(&transaction);
7586 
7587   // Populate the cache.
7588   RunTransactionTest(cache.http_cache(), transaction);
7589 
7590   // Update the cache.
7591   transaction.method = "HEAD";
7592   transaction.request_headers =
7593       "If-Modified-Since: Wed, 28 Nov 2007 00:40:09 GMT\r\n";
7594   transaction.response_headers = "Foo: bar\n";
7595   transaction.data = "";
7596   transaction.status = "HTTP/1.1 304 Not Modified\n";
7597   std::string headers;
7598   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7599   RemoveMockTransaction(&transaction);
7600 
7601   EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 304 Not Modified\n"));
7602   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7603 
7604   MockTransaction transaction2(kTypicalGET_Transaction);
7605   AddMockTransaction(&transaction2);
7606 
7607   // Make sure we are done with the previous transaction.
7608   base::RunLoop().RunUntilIdle();
7609 
7610   // Load from the cache.
7611   transaction2.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7612   RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
7613 
7614   EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
7615   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7616   EXPECT_EQ(2, cache.disk_cache()->open_count());
7617   EXPECT_EQ(1, cache.disk_cache()->create_count());
7618   RemoveMockTransaction(&transaction2);
7619 }
7620 
7621 // Tests that a HEAD request invalidates an old cached entry.
TEST_F(HttpCacheTest,SimpleHEAD_InvalidatesEntry)7622 TEST_F(HttpCacheTest, SimpleHEAD_InvalidatesEntry) {
7623   MockHttpCache cache;
7624   MockTransaction transaction(kTypicalGET_Transaction);
7625   AddMockTransaction(&transaction);
7626 
7627   // Populate the cache.
7628   RunTransactionTest(cache.http_cache(), transaction);
7629 
7630   // Update the cache.
7631   transaction.method = "HEAD";
7632   transaction.data = "";
7633   RunTransactionTest(cache.http_cache(), transaction);
7634   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7635 
7636   // Load from the cache.
7637   transaction.method = "GET";
7638   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7639   transaction.start_return_code = ERR_CACHE_MISS;
7640   RunTransactionTest(cache.http_cache(), transaction);
7641 
7642   RemoveMockTransaction(&transaction);
7643 }
7644 
7645 // Tests that we do not cache the response of a PUT.
TEST_F(HttpCacheTest,SimplePUT_Miss)7646 TEST_F(HttpCacheTest, SimplePUT_Miss) {
7647   MockHttpCache cache;
7648 
7649   MockTransaction transaction(kSimplePOST_Transaction);
7650   transaction.method = "PUT";
7651 
7652   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7653   element_readers.push_back(
7654       std::make_unique<UploadBytesElementReader>("hello", 5));
7655   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7656 
7657   MockHttpRequest request(transaction);
7658   request.upload_data_stream = &upload_data_stream;
7659 
7660   // Attempt to populate the cache.
7661   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
7662                                 nullptr);
7663 
7664   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7665   EXPECT_EQ(0, cache.disk_cache()->open_count());
7666   EXPECT_EQ(0, cache.disk_cache()->create_count());
7667 }
7668 
7669 // Tests that we invalidate entries as a result of a PUT.
TEST_F(HttpCacheTest,SimplePUT_Invalidate)7670 TEST_F(HttpCacheTest, SimplePUT_Invalidate) {
7671   MockHttpCache cache;
7672 
7673   MockTransaction transaction(kSimpleGET_Transaction);
7674   MockHttpRequest req1(transaction);
7675 
7676   // Attempt to populate the cache.
7677   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7678 
7679   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7680   EXPECT_EQ(0, cache.disk_cache()->open_count());
7681   EXPECT_EQ(1, cache.disk_cache()->create_count());
7682 
7683   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7684   element_readers.push_back(
7685       std::make_unique<UploadBytesElementReader>("hello", 5));
7686   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7687 
7688   transaction.method = "PUT";
7689   MockHttpRequest req2(transaction);
7690   req2.upload_data_stream = &upload_data_stream;
7691 
7692   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7693 
7694   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7695   EXPECT_EQ(1, cache.disk_cache()->open_count());
7696   EXPECT_EQ(1, cache.disk_cache()->create_count());
7697 
7698   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7699 
7700   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7701   EXPECT_EQ(1, cache.disk_cache()->open_count());
7702   EXPECT_EQ(2, cache.disk_cache()->create_count());
7703 }
7704 
7705 // Tests that we invalidate entries as a result of a PUT.
TEST_F(HttpCacheTest,SimplePUT_Invalidate_305)7706 TEST_F(HttpCacheTest, SimplePUT_Invalidate_305) {
7707   MockHttpCache cache;
7708 
7709   MockTransaction transaction(kSimpleGET_Transaction);
7710   AddMockTransaction(&transaction);
7711   MockHttpRequest req1(transaction);
7712 
7713   // Attempt to populate the cache.
7714   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7715 
7716   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7717   EXPECT_EQ(0, cache.disk_cache()->open_count());
7718   EXPECT_EQ(1, cache.disk_cache()->create_count());
7719 
7720   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7721   element_readers.push_back(
7722       std::make_unique<UploadBytesElementReader>("hello", 5));
7723   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7724 
7725   transaction.method = "PUT";
7726   transaction.status = "HTTP/1.1 305 Use Proxy";
7727   MockHttpRequest req2(transaction);
7728   req2.upload_data_stream = &upload_data_stream;
7729 
7730   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7731 
7732   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7733   EXPECT_EQ(1, cache.disk_cache()->open_count());
7734   EXPECT_EQ(1, cache.disk_cache()->create_count());
7735 
7736   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7737 
7738   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7739   EXPECT_EQ(1, cache.disk_cache()->open_count());
7740   EXPECT_EQ(2, cache.disk_cache()->create_count());
7741   RemoveMockTransaction(&transaction);
7742 }
7743 
7744 // Tests that we don't invalidate entries as a result of a failed PUT.
TEST_F(HttpCacheTest,SimplePUT_DontInvalidate_404)7745 TEST_F(HttpCacheTest, SimplePUT_DontInvalidate_404) {
7746   MockHttpCache cache;
7747 
7748   MockTransaction transaction(kSimpleGET_Transaction);
7749   AddMockTransaction(&transaction);
7750   MockHttpRequest req1(transaction);
7751 
7752   // Attempt to populate the cache.
7753   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7754 
7755   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7756   EXPECT_EQ(0, cache.disk_cache()->open_count());
7757   EXPECT_EQ(1, cache.disk_cache()->create_count());
7758 
7759   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7760   element_readers.push_back(
7761       std::make_unique<UploadBytesElementReader>("hello", 5));
7762   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7763 
7764   transaction.method = "PUT";
7765   transaction.status = "HTTP/1.1 404 Not Found";
7766   MockHttpRequest req2(transaction);
7767   req2.upload_data_stream = &upload_data_stream;
7768 
7769   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7770 
7771   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7772   EXPECT_EQ(1, cache.disk_cache()->open_count());
7773   EXPECT_EQ(1, cache.disk_cache()->create_count());
7774 
7775   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7776 
7777   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7778   EXPECT_EQ(2, cache.disk_cache()->open_count());
7779   EXPECT_EQ(1, cache.disk_cache()->create_count());
7780   RemoveMockTransaction(&transaction);
7781 }
7782 
7783 // Tests that we do not cache the response of a DELETE.
TEST_F(HttpCacheTest,SimpleDELETE_Miss)7784 TEST_F(HttpCacheTest, SimpleDELETE_Miss) {
7785   MockHttpCache cache;
7786 
7787   MockTransaction transaction(kSimplePOST_Transaction);
7788   transaction.method = "DELETE";
7789 
7790   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7791   element_readers.push_back(
7792       std::make_unique<UploadBytesElementReader>("hello", 5));
7793   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7794 
7795   MockHttpRequest request(transaction);
7796   request.upload_data_stream = &upload_data_stream;
7797 
7798   // Attempt to populate the cache.
7799   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
7800                                 nullptr);
7801 
7802   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7803   EXPECT_EQ(0, cache.disk_cache()->open_count());
7804   EXPECT_EQ(0, cache.disk_cache()->create_count());
7805 }
7806 
7807 // Tests that we invalidate entries as a result of a DELETE.
TEST_F(HttpCacheTest,SimpleDELETE_Invalidate)7808 TEST_F(HttpCacheTest, SimpleDELETE_Invalidate) {
7809   MockHttpCache cache;
7810 
7811   MockTransaction transaction(kSimpleGET_Transaction);
7812   MockHttpRequest req1(transaction);
7813 
7814   // Attempt to populate the cache.
7815   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7816 
7817   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7818   EXPECT_EQ(0, cache.disk_cache()->open_count());
7819   EXPECT_EQ(1, cache.disk_cache()->create_count());
7820 
7821   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7822   element_readers.push_back(
7823       std::make_unique<UploadBytesElementReader>("hello", 5));
7824   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7825 
7826   transaction.method = "DELETE";
7827   MockHttpRequest req2(transaction);
7828   req2.upload_data_stream = &upload_data_stream;
7829 
7830   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7831 
7832   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7833   EXPECT_EQ(1, cache.disk_cache()->open_count());
7834   EXPECT_EQ(1, cache.disk_cache()->create_count());
7835 
7836   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7837 
7838   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7839   EXPECT_EQ(1, cache.disk_cache()->open_count());
7840   EXPECT_EQ(2, cache.disk_cache()->create_count());
7841 }
7842 
7843 // Tests that we invalidate entries as a result of a DELETE.
TEST_F(HttpCacheTest,SimpleDELETE_Invalidate_301)7844 TEST_F(HttpCacheTest, SimpleDELETE_Invalidate_301) {
7845   MockHttpCache cache;
7846 
7847   MockTransaction transaction(kSimpleGET_Transaction);
7848   AddMockTransaction(&transaction);
7849 
7850   // Attempt to populate the cache.
7851   RunTransactionTest(cache.http_cache(), transaction);
7852 
7853   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7854   EXPECT_EQ(0, cache.disk_cache()->open_count());
7855   EXPECT_EQ(1, cache.disk_cache()->create_count());
7856 
7857   transaction.method = "DELETE";
7858   transaction.status = "HTTP/1.1 301 Moved Permanently ";
7859 
7860   RunTransactionTest(cache.http_cache(), transaction);
7861 
7862   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7863   EXPECT_EQ(1, cache.disk_cache()->open_count());
7864   EXPECT_EQ(1, cache.disk_cache()->create_count());
7865 
7866   transaction.method = "GET";
7867   RunTransactionTest(cache.http_cache(), transaction);
7868 
7869   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7870   EXPECT_EQ(1, cache.disk_cache()->open_count());
7871   EXPECT_EQ(2, cache.disk_cache()->create_count());
7872   RemoveMockTransaction(&transaction);
7873 }
7874 
7875 // Tests that we don't invalidate entries as a result of a failed DELETE.
TEST_F(HttpCacheTest,SimpleDELETE_DontInvalidate_416)7876 TEST_F(HttpCacheTest, SimpleDELETE_DontInvalidate_416) {
7877   MockHttpCache cache;
7878 
7879   MockTransaction transaction(kSimpleGET_Transaction);
7880   AddMockTransaction(&transaction);
7881 
7882   // Attempt to populate the cache.
7883   RunTransactionTest(cache.http_cache(), transaction);
7884 
7885   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7886   EXPECT_EQ(0, cache.disk_cache()->open_count());
7887   EXPECT_EQ(1, cache.disk_cache()->create_count());
7888 
7889   transaction.method = "DELETE";
7890   transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
7891 
7892   RunTransactionTest(cache.http_cache(), transaction);
7893 
7894   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7895   EXPECT_EQ(1, cache.disk_cache()->open_count());
7896   EXPECT_EQ(1, cache.disk_cache()->create_count());
7897 
7898   transaction.method = "GET";
7899   transaction.status = "HTTP/1.1 200 OK";
7900   RunTransactionTest(cache.http_cache(), transaction);
7901 
7902   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7903   EXPECT_EQ(2, cache.disk_cache()->open_count());
7904   EXPECT_EQ(1, cache.disk_cache()->create_count());
7905   RemoveMockTransaction(&transaction);
7906 }
7907 
7908 // Tests that we invalidate entries as a result of a PATCH.
TEST_F(HttpCacheTest,SimplePATCH_Invalidate)7909 TEST_F(HttpCacheTest, SimplePATCH_Invalidate) {
7910   MockHttpCache cache;
7911 
7912   MockTransaction transaction(kSimpleGET_Transaction);
7913   MockHttpRequest req1(transaction);
7914 
7915   // Attempt to populate the cache.
7916   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7917 
7918   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7919   EXPECT_EQ(0, cache.disk_cache()->open_count());
7920   EXPECT_EQ(1, cache.disk_cache()->create_count());
7921 
7922   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7923   element_readers.push_back(
7924       std::make_unique<UploadBytesElementReader>("hello", 5));
7925   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7926 
7927   transaction.method = "PATCH";
7928   MockHttpRequest req2(transaction);
7929   req2.upload_data_stream = &upload_data_stream;
7930 
7931   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7932 
7933   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7934   EXPECT_EQ(1, cache.disk_cache()->open_count());
7935   EXPECT_EQ(1, cache.disk_cache()->create_count());
7936 
7937   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7938 
7939   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7940   EXPECT_EQ(1, cache.disk_cache()->open_count());
7941   EXPECT_EQ(2, cache.disk_cache()->create_count());
7942 }
7943 
7944 // Tests that we invalidate entries as a result of a PATCH.
TEST_F(HttpCacheTest,SimplePATCH_Invalidate_301)7945 TEST_F(HttpCacheTest, SimplePATCH_Invalidate_301) {
7946   MockHttpCache cache;
7947 
7948   MockTransaction transaction(kSimpleGET_Transaction);
7949   AddMockTransaction(&transaction);
7950 
7951   // Attempt to populate the cache.
7952   RunTransactionTest(cache.http_cache(), transaction);
7953 
7954   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7955   EXPECT_EQ(0, cache.disk_cache()->open_count());
7956   EXPECT_EQ(1, cache.disk_cache()->create_count());
7957 
7958   transaction.method = "PATCH";
7959   transaction.status = "HTTP/1.1 301 Moved Permanently ";
7960 
7961   RunTransactionTest(cache.http_cache(), transaction);
7962 
7963   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7964   EXPECT_EQ(1, cache.disk_cache()->open_count());
7965   EXPECT_EQ(1, cache.disk_cache()->create_count());
7966 
7967   transaction.method = "GET";
7968   RunTransactionTest(cache.http_cache(), transaction);
7969 
7970   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7971   EXPECT_EQ(1, cache.disk_cache()->open_count());
7972   EXPECT_EQ(2, cache.disk_cache()->create_count());
7973   RemoveMockTransaction(&transaction);
7974 }
7975 
7976 // Tests that we don't invalidate entries as a result of a failed PATCH.
TEST_F(HttpCacheTest,SimplePATCH_DontInvalidate_416)7977 TEST_F(HttpCacheTest, SimplePATCH_DontInvalidate_416) {
7978   MockHttpCache cache;
7979 
7980   MockTransaction transaction(kSimpleGET_Transaction);
7981   AddMockTransaction(&transaction);
7982 
7983   // Attempt to populate the cache.
7984   RunTransactionTest(cache.http_cache(), transaction);
7985 
7986   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7987   EXPECT_EQ(0, cache.disk_cache()->open_count());
7988   EXPECT_EQ(1, cache.disk_cache()->create_count());
7989 
7990   transaction.method = "PATCH";
7991   transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
7992 
7993   RunTransactionTest(cache.http_cache(), transaction);
7994 
7995   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7996   EXPECT_EQ(1, cache.disk_cache()->open_count());
7997   EXPECT_EQ(1, cache.disk_cache()->create_count());
7998 
7999   transaction.method = "GET";
8000   transaction.status = "HTTP/1.1 200 OK";
8001   RunTransactionTest(cache.http_cache(), transaction);
8002 
8003   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8004   EXPECT_EQ(2, cache.disk_cache()->open_count());
8005   EXPECT_EQ(1, cache.disk_cache()->create_count());
8006   RemoveMockTransaction(&transaction);
8007 }
8008 
8009 // Tests that we don't invalidate entries after a failed network transaction.
TEST_F(HttpCacheTest,SimpleGET_DontInvalidateOnFailure)8010 TEST_F(HttpCacheTest, SimpleGET_DontInvalidateOnFailure) {
8011   MockHttpCache cache;
8012 
8013   // Populate the cache.
8014   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
8015   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8016 
8017   // Fail the network request.
8018   MockTransaction transaction(kSimpleGET_Transaction);
8019   transaction.start_return_code = ERR_FAILED;
8020   transaction.load_flags |= LOAD_VALIDATE_CACHE;
8021 
8022   AddMockTransaction(&transaction);
8023   RunTransactionTest(cache.http_cache(), transaction);
8024   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8025   RemoveMockTransaction(&transaction);
8026 
8027   transaction.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
8028   transaction.start_return_code = OK;
8029   AddMockTransaction(&transaction);
8030   RunTransactionTest(cache.http_cache(), transaction);
8031 
8032   // Make sure the transaction didn't reach the network.
8033   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8034   RemoveMockTransaction(&transaction);
8035 }
8036 
TEST_F(HttpCacheTest,RangeGET_SkipsCache)8037 TEST_F(HttpCacheTest, RangeGET_SkipsCache) {
8038   MockHttpCache cache;
8039 
8040   // Test that we skip the cache for range GET requests.  Eventually, we will
8041   // want to cache these, but we'll still have cases where skipping the cache
8042   // makes sense, so we want to make sure that it works properly.
8043 
8044   RunTransactionTest(cache.http_cache(), kRangeGET_Transaction);
8045 
8046   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8047   EXPECT_EQ(0, cache.disk_cache()->open_count());
8048   EXPECT_EQ(0, cache.disk_cache()->create_count());
8049 
8050   MockTransaction transaction(kSimpleGET_Transaction);
8051   transaction.request_headers = "If-None-Match: foo\r\n";
8052   RunTransactionTest(cache.http_cache(), transaction);
8053 
8054   EXPECT_EQ(2, 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   transaction.request_headers =
8059       "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
8060   RunTransactionTest(cache.http_cache(), transaction);
8061 
8062   EXPECT_EQ(3, 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 
8067 // Test that we skip the cache for range requests that include a validation
8068 // header.
TEST_F(HttpCacheTest,RangeGET_SkipsCache2)8069 TEST_F(HttpCacheTest, RangeGET_SkipsCache2) {
8070   MockHttpCache cache;
8071 
8072   MockTransaction transaction(kRangeGET_Transaction);
8073   transaction.request_headers = "If-None-Match: foo\r\n"
8074                                 EXTRA_HEADER
8075                                 "Range: bytes = 40-49\r\n";
8076   RunTransactionTest(cache.http_cache(), transaction);
8077 
8078   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8079   EXPECT_EQ(0, cache.disk_cache()->open_count());
8080   EXPECT_EQ(0, cache.disk_cache()->create_count());
8081 
8082   transaction.request_headers =
8083       "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n"
8084       EXTRA_HEADER
8085       "Range: bytes = 40-49\r\n";
8086   RunTransactionTest(cache.http_cache(), transaction);
8087 
8088   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8089   EXPECT_EQ(0, cache.disk_cache()->open_count());
8090   EXPECT_EQ(0, cache.disk_cache()->create_count());
8091 
8092   transaction.request_headers = "If-Range: bla\r\n"
8093                                 EXTRA_HEADER
8094                                 "Range: bytes = 40-49\r\n";
8095   RunTransactionTest(cache.http_cache(), transaction);
8096 
8097   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8098   EXPECT_EQ(0, cache.disk_cache()->open_count());
8099   EXPECT_EQ(0, cache.disk_cache()->create_count());
8100 }
8101 
TEST_F(HttpCacheTest,SimpleGET_DoesntLogHeaders)8102 TEST_F(HttpCacheTest, SimpleGET_DoesntLogHeaders) {
8103   MockHttpCache cache;
8104 
8105   RecordingNetLogObserver net_log_observer;
8106   RunTransactionTestWithLog(cache.http_cache(), kSimpleGET_Transaction,
8107                             NetLogWithSource::Make(NetLogSourceType::NONE));
8108 
8109   EXPECT_FALSE(LogContainsEventType(
8110       net_log_observer, NetLogEventType::HTTP_CACHE_CALLER_REQUEST_HEADERS));
8111 }
8112 
TEST_F(HttpCacheTest,RangeGET_LogsHeaders)8113 TEST_F(HttpCacheTest, RangeGET_LogsHeaders) {
8114   MockHttpCache cache;
8115 
8116   RecordingNetLogObserver net_log_observer;
8117   RunTransactionTestWithLog(cache.http_cache(), kRangeGET_Transaction,
8118                             NetLogWithSource::Make(NetLogSourceType::NONE));
8119 
8120   EXPECT_TRUE(LogContainsEventType(
8121       net_log_observer, NetLogEventType::HTTP_CACHE_CALLER_REQUEST_HEADERS));
8122 }
8123 
TEST_F(HttpCacheTest,ExternalValidation_LogsHeaders)8124 TEST_F(HttpCacheTest, ExternalValidation_LogsHeaders) {
8125   MockHttpCache cache;
8126 
8127   RecordingNetLogObserver net_log_observer;
8128   MockTransaction transaction(kSimpleGET_Transaction);
8129   transaction.request_headers = "If-None-Match: foo\r\n" EXTRA_HEADER;
8130   RunTransactionTestWithLog(cache.http_cache(), transaction,
8131                             NetLogWithSource::Make(NetLogSourceType::NONE));
8132 
8133   EXPECT_TRUE(LogContainsEventType(
8134       net_log_observer, NetLogEventType::HTTP_CACHE_CALLER_REQUEST_HEADERS));
8135 }
8136 
TEST_F(HttpCacheTest,SpecialHeaders_LogsHeaders)8137 TEST_F(HttpCacheTest, SpecialHeaders_LogsHeaders) {
8138   MockHttpCache cache;
8139 
8140   RecordingNetLogObserver net_log_observer;
8141   MockTransaction transaction(kSimpleGET_Transaction);
8142   transaction.request_headers = "cache-control: no-cache\r\n" EXTRA_HEADER;
8143   RunTransactionTestWithLog(cache.http_cache(), transaction,
8144                             NetLogWithSource::Make(NetLogSourceType::NONE));
8145 
8146   EXPECT_TRUE(LogContainsEventType(
8147       net_log_observer, NetLogEventType::HTTP_CACHE_CALLER_REQUEST_HEADERS));
8148 }
8149 
8150 // Tests that receiving 206 for a regular request is handled correctly.
TEST_F(HttpCacheTest,GET_Crazy206)8151 TEST_F(HttpCacheTest, GET_Crazy206) {
8152   MockHttpCache cache;
8153 
8154   // Write to the cache.
8155   MockTransaction transaction(kRangeGET_TransactionOK);
8156   AddMockTransaction(&transaction);
8157   transaction.request_headers = EXTRA_HEADER;
8158   transaction.handler = MockTransactionHandler();
8159   RunTransactionTest(cache.http_cache(), transaction);
8160 
8161   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8162   EXPECT_EQ(0, cache.disk_cache()->open_count());
8163   EXPECT_EQ(1, cache.disk_cache()->create_count());
8164 
8165   // This should read again from the net.
8166   RunTransactionTest(cache.http_cache(), transaction);
8167 
8168   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8169   EXPECT_EQ(0, cache.disk_cache()->open_count());
8170   EXPECT_EQ(2, cache.disk_cache()->create_count());
8171   RemoveMockTransaction(&transaction);
8172 }
8173 
8174 // Tests that receiving 416 for a regular request is handled correctly.
TEST_F(HttpCacheTest,GET_Crazy416)8175 TEST_F(HttpCacheTest, GET_Crazy416) {
8176   MockHttpCache cache;
8177 
8178   // Write to the cache.
8179   MockTransaction transaction(kSimpleGET_Transaction);
8180   AddMockTransaction(&transaction);
8181   transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
8182   RunTransactionTest(cache.http_cache(), transaction);
8183 
8184   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8185   EXPECT_EQ(0, cache.disk_cache()->open_count());
8186   EXPECT_EQ(1, cache.disk_cache()->create_count());
8187 
8188   RemoveMockTransaction(&transaction);
8189 }
8190 
8191 // Tests that we don't store partial responses that can't be validated.
TEST_F(HttpCacheTest,RangeGET_NoStrongValidators)8192 TEST_F(HttpCacheTest, RangeGET_NoStrongValidators) {
8193   MockHttpCache cache;
8194   std::string headers;
8195 
8196   // Attempt to write to the cache (40-49).
8197   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8198   transaction.response_headers = "Content-Length: 10\n"
8199                                  "Cache-Control: max-age=3600\n"
8200                                  "ETag: w/\"foo\"\n";
8201   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8202 
8203   Verify206Response(headers, 40, 49);
8204   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8205   EXPECT_EQ(0, cache.disk_cache()->open_count());
8206   EXPECT_EQ(1, cache.disk_cache()->create_count());
8207 
8208   // Now verify that there's no cached data.
8209   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8210                                  &headers);
8211 
8212   Verify206Response(headers, 40, 49);
8213   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8214   EXPECT_EQ(0, cache.disk_cache()->open_count());
8215   EXPECT_EQ(2, cache.disk_cache()->create_count());
8216 }
8217 
8218 // Tests failures to conditionalize byte range requests.
TEST_F(HttpCacheTest,RangeGET_NoConditionalization)8219 TEST_F(HttpCacheTest, RangeGET_NoConditionalization) {
8220   MockHttpCache cache;
8221   cache.FailConditionalizations();
8222   std::string headers;
8223 
8224   // Write to the cache (40-49).
8225   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8226   transaction.response_headers = "Content-Length: 10\n"
8227                                  "ETag: \"foo\"\n";
8228   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8229 
8230   Verify206Response(headers, 40, 49);
8231   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8232   EXPECT_EQ(0, cache.disk_cache()->open_count());
8233   EXPECT_EQ(1, cache.disk_cache()->create_count());
8234 
8235   // Now verify that the cached data is not used.
8236   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8237                                  &headers);
8238 
8239   Verify206Response(headers, 40, 49);
8240   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8241   EXPECT_EQ(1, cache.disk_cache()->open_count());
8242   EXPECT_EQ(2, cache.disk_cache()->create_count());
8243 }
8244 
8245 // Tests that restarting a partial request when the cached data cannot be
8246 // revalidated logs an event.
TEST_F(HttpCacheTest,RangeGET_NoValidation_LogsRestart)8247 TEST_F(HttpCacheTest, RangeGET_NoValidation_LogsRestart) {
8248   MockHttpCache cache;
8249   cache.FailConditionalizations();
8250 
8251   // Write to the cache (40-49).
8252   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8253   transaction.response_headers = "Content-Length: 10\n"
8254                                  "ETag: \"foo\"\n";
8255   RunTransactionTest(cache.http_cache(), transaction);
8256 
8257   // Now verify that the cached data is not used.
8258   RecordingNetLogObserver net_log_observer;
8259   RunTransactionTestWithLog(cache.http_cache(), kRangeGET_TransactionOK,
8260                             NetLogWithSource::Make(NetLogSourceType::NONE));
8261 
8262   EXPECT_TRUE(LogContainsEventType(
8263       net_log_observer, NetLogEventType::HTTP_CACHE_RESTART_PARTIAL_REQUEST));
8264 }
8265 
8266 // Tests that a failure to conditionalize a regular request (no range) with a
8267 // sparse entry results in a full response.
TEST_F(HttpCacheTest,GET_NoConditionalization)8268 TEST_F(HttpCacheTest, GET_NoConditionalization) {
8269   for (bool use_memory_entry_data : {false, true}) {
8270     MockHttpCache cache;
8271     cache.disk_cache()->set_support_in_memory_entry_data(use_memory_entry_data);
8272     cache.FailConditionalizations();
8273     std::string headers;
8274 
8275     // Write to the cache (40-49).
8276     ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8277     transaction.response_headers =
8278         "Content-Length: 10\n"
8279         "ETag: \"foo\"\n";
8280     RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8281 
8282     Verify206Response(headers, 40, 49);
8283     EXPECT_EQ(1, cache.network_layer()->transaction_count());
8284     EXPECT_EQ(0, cache.disk_cache()->open_count());
8285     EXPECT_EQ(1, cache.disk_cache()->create_count());
8286 
8287     // Now verify that the cached data is not used.
8288     // Don't ask for a range. The cache will attempt to use the cached data but
8289     // should discard it as it cannot be validated. A regular request should go
8290     // to the server and a new entry should be created.
8291     transaction.request_headers = EXTRA_HEADER;
8292     transaction.data = "Not a range";
8293     RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8294 
8295     EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
8296     EXPECT_EQ(2, cache.network_layer()->transaction_count());
8297     EXPECT_EQ(1, cache.disk_cache()->open_count());
8298     EXPECT_EQ(2, cache.disk_cache()->create_count());
8299 
8300     // The last response was saved.
8301     RunTransactionTest(cache.http_cache(), transaction);
8302     EXPECT_EQ(3, cache.network_layer()->transaction_count());
8303     if (use_memory_entry_data) {
8304       // The cache entry isn't really useful, since when
8305       // &RangeTransactionServer::RangeHandler gets a non-range request,
8306       // (the network transaction #2) it returns headers without ETag,
8307       // Last-Modified or caching headers, with a Date in 2007 (so no heuristic
8308       // freshness), so it's both expired and not conditionalizable --- so in
8309       // this branch we avoid opening it.
8310       EXPECT_EQ(1, cache.disk_cache()->open_count());
8311       EXPECT_EQ(3, cache.disk_cache()->create_count());
8312     } else {
8313       EXPECT_EQ(2, cache.disk_cache()->open_count());
8314       EXPECT_EQ(2, cache.disk_cache()->create_count());
8315     }
8316   }
8317 }
8318 
8319 // Verifies that conditionalization failures when asking for a range that would
8320 // require the cache to modify the range to ask, result in a network request
8321 // that matches the user's one.
TEST_F(HttpCacheTest,RangeGET_NoConditionalization2)8322 TEST_F(HttpCacheTest, RangeGET_NoConditionalization2) {
8323   MockHttpCache cache;
8324   cache.FailConditionalizations();
8325   std::string headers;
8326 
8327   // Write to the cache (40-49).
8328   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8329   transaction.response_headers = "Content-Length: 10\n"
8330                                  "ETag: \"foo\"\n";
8331   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8332 
8333   Verify206Response(headers, 40, 49);
8334   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8335   EXPECT_EQ(0, cache.disk_cache()->open_count());
8336   EXPECT_EQ(1, cache.disk_cache()->create_count());
8337 
8338   // Now verify that the cached data is not used.
8339   // Ask for a range that extends before and after the cached data so that the
8340   // cache would normally mix data from three sources. After deleting the entry,
8341   // the response will come from a single network request.
8342   transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
8343   transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
8344   transaction.response_headers = kRangeGET_TransactionOK.response_headers;
8345   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8346 
8347   Verify206Response(headers, 20, 59);
8348   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8349   EXPECT_EQ(1, cache.disk_cache()->open_count());
8350   EXPECT_EQ(2, cache.disk_cache()->create_count());
8351 
8352   // The last response was saved.
8353   RunTransactionTest(cache.http_cache(), transaction);
8354   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8355   EXPECT_EQ(2, cache.disk_cache()->open_count());
8356   EXPECT_EQ(2, cache.disk_cache()->create_count());
8357 }
8358 
8359 // Tests that we cache partial responses that lack content-length.
TEST_F(HttpCacheTest,RangeGET_NoContentLength)8360 TEST_F(HttpCacheTest, RangeGET_NoContentLength) {
8361   MockHttpCache cache;
8362   std::string headers;
8363 
8364   // Attempt to write to the cache (40-49).
8365   MockTransaction transaction(kRangeGET_TransactionOK);
8366   AddMockTransaction(&transaction);
8367   transaction.response_headers = "ETag: \"foo\"\n"
8368                                  "Accept-Ranges: bytes\n"
8369                                  "Content-Range: bytes 40-49/80\n";
8370   transaction.handler = MockTransactionHandler();
8371   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8372 
8373   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8374   EXPECT_EQ(0, cache.disk_cache()->open_count());
8375   EXPECT_EQ(1, cache.disk_cache()->create_count());
8376 
8377   // Now verify that there's no cached data.
8378   transaction.handler =
8379       base::BindRepeating(&RangeTransactionServer::RangeHandler);
8380   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8381                                  &headers);
8382 
8383   Verify206Response(headers, 40, 49);
8384   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8385   EXPECT_EQ(1, cache.disk_cache()->open_count());
8386   EXPECT_EQ(1, cache.disk_cache()->create_count());
8387 
8388   RemoveMockTransaction(&transaction);
8389 }
8390 
8391 // Tests that we can cache range requests and fetch random blocks from the
8392 // cache and the network.
TEST_F(HttpCacheTest,RangeGET_OK)8393 TEST_F(HttpCacheTest, RangeGET_OK) {
8394   MockHttpCache cache;
8395   AddMockTransaction(&kRangeGET_TransactionOK);
8396   std::string headers;
8397 
8398   // Write to the cache (40-49).
8399   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8400                                  &headers);
8401 
8402   Verify206Response(headers, 40, 49);
8403   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8404   EXPECT_EQ(0, cache.disk_cache()->open_count());
8405   EXPECT_EQ(1, cache.disk_cache()->create_count());
8406 
8407   // Read from the cache (40-49).
8408   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8409                                  &headers);
8410 
8411   Verify206Response(headers, 40, 49);
8412   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8413   EXPECT_EQ(1, cache.disk_cache()->open_count());
8414   EXPECT_EQ(1, cache.disk_cache()->create_count());
8415 
8416   // Make sure we are done with the previous transaction.
8417   base::RunLoop().RunUntilIdle();
8418 
8419   // Write to the cache (30-39).
8420   MockTransaction transaction(kRangeGET_TransactionOK);
8421   transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
8422   transaction.data = "rg: 30-39 ";
8423   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8424 
8425   Verify206Response(headers, 30, 39);
8426   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8427   EXPECT_EQ(2, cache.disk_cache()->open_count());
8428   EXPECT_EQ(1, cache.disk_cache()->create_count());
8429 
8430   // Make sure we are done with the previous transaction.
8431   base::RunLoop().RunUntilIdle();
8432 
8433   // Write and read from the cache (20-59).
8434   transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
8435   transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
8436   LoadTimingInfo load_timing_info;
8437   RunTransactionTestWithResponseAndGetTiming(
8438       cache.http_cache(), transaction, &headers,
8439       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info);
8440 
8441   Verify206Response(headers, 20, 59);
8442   EXPECT_EQ(4, cache.network_layer()->transaction_count());
8443   EXPECT_EQ(3, cache.disk_cache()->open_count());
8444   EXPECT_EQ(1, cache.disk_cache()->create_count());
8445   TestLoadTimingNetworkRequest(load_timing_info);
8446 
8447   RemoveMockTransaction(&kRangeGET_TransactionOK);
8448 }
8449 
TEST_F(HttpCacheTest,RangeGET_CacheReadError)8450 TEST_F(HttpCacheTest, RangeGET_CacheReadError) {
8451   // Tests recovery on cache read error on range request.
8452   MockHttpCache cache;
8453   AddMockTransaction(&kRangeGET_TransactionOK);
8454   std::string headers;
8455 
8456   // Write to the cache (40-49).
8457   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8458                                  &headers);
8459 
8460   Verify206Response(headers, 40, 49);
8461   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8462   EXPECT_EQ(0, cache.disk_cache()->open_count());
8463   EXPECT_EQ(1, cache.disk_cache()->create_count());
8464 
8465   cache.disk_cache()->set_soft_failures_one_instance(MockDiskEntry::FAIL_ALL);
8466 
8467   // Try to read from the cache (40-49), which will fail quickly enough to
8468   // restart, due to the failure injected above.  This should still be a range
8469   // request. (https://crbug.com/891212)
8470   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8471                                  &headers);
8472 
8473   Verify206Response(headers, 40, 49);
8474   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8475   EXPECT_EQ(1, cache.disk_cache()->open_count());
8476   EXPECT_EQ(2, cache.disk_cache()->create_count());
8477 
8478   RemoveMockTransaction(&kRangeGET_TransactionOK);
8479 }
8480 
8481 // Tests that range requests with no-store get correct content-length
8482 // (https://crbug.com/700197).
TEST_F(HttpCacheTest,RangeGET_NoStore)8483 TEST_F(HttpCacheTest, RangeGET_NoStore) {
8484   MockHttpCache cache;
8485 
8486   MockTransaction transaction(kRangeGET_TransactionOK);
8487   std::string response_headers = base::StrCat(
8488       {kRangeGET_TransactionOK.response_headers, "Cache-Control: no-store\n"});
8489   transaction.response_headers = response_headers.c_str();
8490   AddMockTransaction(&transaction);
8491 
8492   std::string headers;
8493   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8494 
8495   Verify206Response(headers, 40, 49);
8496   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8497   EXPECT_EQ(0, cache.disk_cache()->open_count());
8498   EXPECT_EQ(1, cache.disk_cache()->create_count());
8499 
8500   RemoveMockTransaction(&transaction);
8501 }
8502 
8503 // Tests a 304 setting no-store on existing 206 entry.
TEST_F(HttpCacheTest,RangeGET_NoStore304)8504 TEST_F(HttpCacheTest, RangeGET_NoStore304) {
8505   MockHttpCache cache;
8506 
8507   MockTransaction transaction(kRangeGET_TransactionOK);
8508   std::string response_headers = base::StrCat(
8509       {kRangeGET_TransactionOK.response_headers, "Cache-Control: max-age=0\n"});
8510   transaction.response_headers = response_headers.c_str();
8511   AddMockTransaction(&transaction);
8512 
8513   std::string headers;
8514   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8515 
8516   Verify206Response(headers, 40, 49);
8517   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8518   EXPECT_EQ(0, cache.disk_cache()->open_count());
8519   EXPECT_EQ(1, cache.disk_cache()->create_count());
8520 
8521   response_headers = base::StrCat(
8522       {kRangeGET_TransactionOK.response_headers, "Cache-Control: no-store\n"});
8523   transaction.response_headers = response_headers.c_str();
8524   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8525   Verify206Response(headers, 40, 49);
8526 
8527   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8528   EXPECT_EQ(1, cache.disk_cache()->open_count());
8529   EXPECT_EQ(1, cache.disk_cache()->create_count());
8530 
8531   // Fetch again, this one should be from newly created cache entry, due to
8532   // earlier no-store.
8533   transaction.response_headers = kRangeGET_TransactionOK.response_headers;
8534   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8535   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8536   EXPECT_EQ(1, cache.disk_cache()->open_count());
8537   EXPECT_EQ(2, cache.disk_cache()->create_count());
8538   Verify206Response(headers, 40, 49);
8539 
8540   RemoveMockTransaction(&transaction);
8541 }
8542 
8543 // Tests that we can cache range requests and fetch random blocks from the
8544 // cache and the network, with synchronous responses.
TEST_F(HttpCacheTest,RangeGET_SyncOK)8545 TEST_F(HttpCacheTest, RangeGET_SyncOK) {
8546   MockHttpCache cache;
8547 
8548   MockTransaction transaction(kRangeGET_TransactionOK);
8549   transaction.test_mode = TEST_MODE_SYNC_ALL;
8550   AddMockTransaction(&transaction);
8551 
8552   // Write to the cache (40-49).
8553   std::string headers;
8554   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8555 
8556   Verify206Response(headers, 40, 49);
8557   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8558   EXPECT_EQ(0, cache.disk_cache()->open_count());
8559   EXPECT_EQ(1, cache.disk_cache()->create_count());
8560 
8561   // Read from the cache (40-49).
8562   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8563 
8564   Verify206Response(headers, 40, 49);
8565   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8566   EXPECT_EQ(0, cache.disk_cache()->open_count());
8567   EXPECT_EQ(1, cache.disk_cache()->create_count());
8568 
8569   // Make sure we are done with the previous transaction.
8570   base::RunLoop().RunUntilIdle();
8571 
8572   // Write to the cache (30-39).
8573   transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
8574   transaction.data = "rg: 30-39 ";
8575   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8576 
8577   Verify206Response(headers, 30, 39);
8578   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8579   EXPECT_EQ(1, cache.disk_cache()->open_count());
8580   EXPECT_EQ(1, cache.disk_cache()->create_count());
8581 
8582   // Make sure we are done with the previous transaction.
8583   base::RunLoop().RunUntilIdle();
8584 
8585   // Write and read from the cache (20-59).
8586   transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
8587   transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
8588   LoadTimingInfo load_timing_info;
8589   RunTransactionTestWithResponseAndGetTiming(
8590       cache.http_cache(), transaction, &headers,
8591       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info);
8592 
8593   Verify206Response(headers, 20, 59);
8594   EXPECT_EQ(4, cache.network_layer()->transaction_count());
8595   EXPECT_EQ(2, cache.disk_cache()->open_count());
8596   EXPECT_EQ(1, cache.disk_cache()->create_count());
8597   TestLoadTimingNetworkRequest(load_timing_info);
8598 
8599   RemoveMockTransaction(&transaction);
8600 }
8601 
8602 // Tests that if the previous transaction is cancelled while busy (doing sparse
8603 // IO), a new transaction (that reuses that same ActiveEntry) waits until the
8604 // entry is ready again.
TEST_F(HttpCacheTest,Sparse_WaitForEntry)8605 TEST_F(HttpCacheTest, Sparse_WaitForEntry) {
8606   MockHttpCache cache;
8607 
8608   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8609 
8610   // Create a sparse entry.
8611   RunTransactionTest(cache.http_cache(), transaction);
8612 
8613   // Simulate a previous transaction being cancelled.
8614   disk_cache::Entry* entry;
8615   MockHttpRequest request(transaction);
8616   std::string cache_key =
8617       *cache.http_cache()->GenerateCacheKeyForRequest(&request);
8618   ASSERT_TRUE(cache.OpenBackendEntry(cache_key, &entry));
8619   entry->CancelSparseIO();
8620 
8621   // Test with a range request.
8622   RunTransactionTest(cache.http_cache(), transaction);
8623 
8624   // Now test with a regular request.
8625   entry->CancelSparseIO();
8626   transaction.request_headers = EXTRA_HEADER;
8627   transaction.data = kFullRangeData;
8628   RunTransactionTest(cache.http_cache(), transaction);
8629 
8630   entry->Close();
8631 }
8632 
8633 // Tests that we don't revalidate an entry unless we are required to do so.
TEST_F(HttpCacheTest,RangeGET_Revalidate1)8634 TEST_F(HttpCacheTest, RangeGET_Revalidate1) {
8635   MockHttpCache cache;
8636   std::string headers;
8637 
8638   // Write to the cache (40-49).
8639   MockTransaction transaction(kRangeGET_TransactionOK);
8640   transaction.response_headers =
8641       "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
8642       "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n"  // Should never expire.
8643       "ETag: \"foo\"\n"
8644       "Accept-Ranges: bytes\n"
8645       "Content-Length: 10\n";
8646   AddMockTransaction(&transaction);
8647   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8648 
8649   Verify206Response(headers, 40, 49);
8650   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8651   EXPECT_EQ(0, cache.disk_cache()->open_count());
8652   EXPECT_EQ(1, cache.disk_cache()->create_count());
8653 
8654   // Read from the cache (40-49).
8655   NetLogWithSource net_log_with_source =
8656       NetLogWithSource::Make(NetLogSourceType::NONE);
8657   LoadTimingInfo load_timing_info;
8658   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
8659                                              &headers, net_log_with_source,
8660                                              &load_timing_info);
8661 
8662   Verify206Response(headers, 40, 49);
8663   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8664   EXPECT_EQ(1, cache.disk_cache()->open_count());
8665   EXPECT_EQ(1, cache.disk_cache()->create_count());
8666   TestLoadTimingCachedResponse(load_timing_info);
8667 
8668   // Read again forcing the revalidation.
8669   transaction.load_flags |= LOAD_VALIDATE_CACHE;
8670   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
8671                                              &headers, net_log_with_source,
8672                                              &load_timing_info);
8673 
8674   Verify206Response(headers, 40, 49);
8675   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8676   EXPECT_EQ(1, cache.disk_cache()->open_count());
8677   EXPECT_EQ(1, cache.disk_cache()->create_count());
8678   TestLoadTimingNetworkRequest(load_timing_info);
8679 
8680   RemoveMockTransaction(&transaction);
8681 }
8682 
8683 // Checks that we revalidate an entry when the headers say so.
TEST_F(HttpCacheTest,RangeGET_Revalidate2)8684 TEST_F(HttpCacheTest, RangeGET_Revalidate2) {
8685   MockHttpCache cache;
8686   std::string headers;
8687 
8688   // Write to the cache (40-49).
8689   MockTransaction transaction(kRangeGET_TransactionOK);
8690   transaction.response_headers =
8691       "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
8692       "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n"  // Expired.
8693       "ETag: \"foo\"\n"
8694       "Accept-Ranges: bytes\n"
8695       "Content-Length: 10\n";
8696   AddMockTransaction(&transaction);
8697   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8698 
8699   Verify206Response(headers, 40, 49);
8700   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8701   EXPECT_EQ(0, cache.disk_cache()->open_count());
8702   EXPECT_EQ(1, cache.disk_cache()->create_count());
8703 
8704   // Read from the cache (40-49).
8705   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8706   Verify206Response(headers, 40, 49);
8707 
8708   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8709   EXPECT_EQ(1, cache.disk_cache()->open_count());
8710   EXPECT_EQ(1, cache.disk_cache()->create_count());
8711 
8712   RemoveMockTransaction(&transaction);
8713 }
8714 
8715 // Tests that we deal with 304s for range requests.
TEST_F(HttpCacheTest,RangeGET_304)8716 TEST_F(HttpCacheTest, RangeGET_304) {
8717   MockHttpCache cache;
8718   AddMockTransaction(&kRangeGET_TransactionOK);
8719   std::string headers;
8720 
8721   // Write to the cache (40-49).
8722   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8723                                  &headers);
8724 
8725   Verify206Response(headers, 40, 49);
8726   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8727   EXPECT_EQ(0, cache.disk_cache()->open_count());
8728   EXPECT_EQ(1, cache.disk_cache()->create_count());
8729 
8730   // Read from the cache (40-49).
8731   RangeTransactionServer handler;
8732   handler.set_not_modified(true);
8733   MockTransaction transaction(kRangeGET_TransactionOK);
8734   transaction.load_flags |= LOAD_VALIDATE_CACHE;
8735   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8736 
8737   Verify206Response(headers, 40, 49);
8738   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8739   EXPECT_EQ(1, cache.disk_cache()->open_count());
8740   EXPECT_EQ(1, cache.disk_cache()->create_count());
8741 
8742   RemoveMockTransaction(&kRangeGET_TransactionOK);
8743 }
8744 
8745 // Tests that we deal with 206s when revalidating range requests.
TEST_F(HttpCacheTest,RangeGET_ModifiedResult)8746 TEST_F(HttpCacheTest, RangeGET_ModifiedResult) {
8747   MockHttpCache cache;
8748   AddMockTransaction(&kRangeGET_TransactionOK);
8749   std::string headers;
8750 
8751   // Write to the cache (40-49).
8752   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8753                                  &headers);
8754 
8755   Verify206Response(headers, 40, 49);
8756   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8757   EXPECT_EQ(0, cache.disk_cache()->open_count());
8758   EXPECT_EQ(1, cache.disk_cache()->create_count());
8759 
8760   // Attempt to read from the cache (40-49).
8761   RangeTransactionServer handler;
8762   handler.set_modified(true);
8763   MockTransaction transaction(kRangeGET_TransactionOK);
8764   transaction.load_flags |= LOAD_VALIDATE_CACHE;
8765   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8766 
8767   Verify206Response(headers, 40, 49);
8768   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8769   EXPECT_EQ(1, cache.disk_cache()->open_count());
8770   EXPECT_EQ(1, cache.disk_cache()->create_count());
8771 
8772   // And the entry should be gone.
8773   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
8774   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8775   EXPECT_EQ(1, cache.disk_cache()->open_count());
8776   EXPECT_EQ(2, cache.disk_cache()->create_count());
8777 
8778   RemoveMockTransaction(&kRangeGET_TransactionOK);
8779 }
8780 
8781 // Tests that when a server returns 206 with a sub-range of the requested range,
8782 // and there is nothing stored in the cache, the returned response is passed to
8783 // the caller as is. In this context, a subrange means a response that starts
8784 // with the same byte that was requested, but that is not the whole range that
8785 // was requested.
TEST_F(HttpCacheTest,RangeGET_206ReturnsSubrangeRange_NoCachedContent)8786 TEST_F(HttpCacheTest, RangeGET_206ReturnsSubrangeRange_NoCachedContent) {
8787   MockHttpCache cache;
8788   std::string headers;
8789 
8790   // Request a large range (40-59). The server sends 40-49.
8791   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8792   transaction.request_headers = "Range: bytes = 40-59\r\n" EXTRA_HEADER;
8793   transaction.response_headers =
8794       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
8795       "ETag: \"foo\"\n"
8796       "Accept-Ranges: bytes\n"
8797       "Content-Length: 10\n"
8798       "Content-Range: bytes 40-49/80\n";
8799   transaction.handler = MockTransactionHandler();
8800   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8801 
8802   Verify206Response(headers, 40, 49);
8803   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8804   EXPECT_EQ(0, cache.disk_cache()->open_count());
8805   EXPECT_EQ(1, cache.disk_cache()->create_count());
8806 }
8807 
8808 // Tests that when a server returns 206 with a sub-range of the requested range,
8809 // and there was an entry stored in the cache, the cache gets out of the way.
TEST_F(HttpCacheTest,RangeGET_206ReturnsSubrangeRange_CachedContent)8810 TEST_F(HttpCacheTest, RangeGET_206ReturnsSubrangeRange_CachedContent) {
8811   MockHttpCache cache;
8812   std::string headers;
8813 
8814   // Write to the cache (70-79).
8815   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8816   transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
8817   transaction.data = "rg: 70-79 ";
8818   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8819   Verify206Response(headers, 70, 79);
8820 
8821   // Request a large range (40-79). The cache will ask the server for 40-59.
8822   // The server returns 40-49. The cache should consider the server confused and
8823   // abort caching, restarting the request without caching.
8824   transaction.request_headers = "Range: bytes = 40-79\r\n" EXTRA_HEADER;
8825   transaction.response_headers =
8826       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
8827       "ETag: \"foo\"\n"
8828       "Accept-Ranges: bytes\n"
8829       "Content-Length: 10\n"
8830       "Content-Range: bytes 40-49/80\n";
8831   transaction.handler = MockTransactionHandler();
8832   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8833 
8834   // Two new network requests were issued, one from the cache and another after
8835   // deleting the entry.
8836   Verify206Response(headers, 40, 49);
8837   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8838   EXPECT_EQ(1, cache.disk_cache()->open_count());
8839   EXPECT_EQ(1, cache.disk_cache()->create_count());
8840 
8841   // The entry was deleted.
8842   RunTransactionTest(cache.http_cache(), transaction);
8843   EXPECT_EQ(4, cache.network_layer()->transaction_count());
8844   EXPECT_EQ(1, cache.disk_cache()->open_count());
8845   EXPECT_EQ(2, cache.disk_cache()->create_count());
8846 }
8847 
8848 // Tests that when a server returns 206 with a sub-range of the requested range,
8849 // and there was an entry stored in the cache, the cache gets out of the way,
8850 // when the caller is not using ranges.
TEST_F(HttpCacheTest,GET_206ReturnsSubrangeRange_CachedContent)8851 TEST_F(HttpCacheTest, GET_206ReturnsSubrangeRange_CachedContent) {
8852   MockHttpCache cache;
8853   std::string headers;
8854 
8855   // Write to the cache (70-79).
8856   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8857   transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
8858   transaction.data = "rg: 70-79 ";
8859   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8860   Verify206Response(headers, 70, 79);
8861 
8862   // Don't ask for a range. The cache will ask the server for 0-69.
8863   // The server returns 40-49. The cache should consider the server confused and
8864   // abort caching, restarting the request.
8865   // The second network request should not be a byte range request so the server
8866   // should return 200 + "Not a range"
8867   transaction.request_headers = "X-Return-Default-Range:\r\n" EXTRA_HEADER;
8868   transaction.data = "Not a range";
8869   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8870 
8871   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
8872   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8873   EXPECT_EQ(1, cache.disk_cache()->open_count());
8874   EXPECT_EQ(1, cache.disk_cache()->create_count());
8875 
8876   // The entry was deleted.
8877   RunTransactionTest(cache.http_cache(), transaction);
8878   EXPECT_EQ(4, cache.network_layer()->transaction_count());
8879   EXPECT_EQ(1, cache.disk_cache()->open_count());
8880   EXPECT_EQ(2, cache.disk_cache()->create_count());
8881 }
8882 
8883 // Tests that when a server returns 206 with a random range and there is
8884 // nothing stored in the cache, the returned response is passed to the caller
8885 // as is. In this context, a WrongRange means that the returned range may or may
8886 // not have any relationship with the requested range (may or may not be
8887 // contained). The important part is that the first byte doesn't match the first
8888 // requested byte.
TEST_F(HttpCacheTest,RangeGET_206ReturnsWrongRange_NoCachedContent)8889 TEST_F(HttpCacheTest, RangeGET_206ReturnsWrongRange_NoCachedContent) {
8890   MockHttpCache cache;
8891   std::string headers;
8892 
8893   // Request a large range (30-59). The server sends (40-49).
8894   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8895   transaction.request_headers = "Range: bytes = 30-59\r\n" EXTRA_HEADER;
8896   transaction.response_headers =
8897       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
8898       "ETag: \"foo\"\n"
8899       "Accept-Ranges: bytes\n"
8900       "Content-Length: 10\n"
8901       "Content-Range: bytes 40-49/80\n";
8902   transaction.handler = MockTransactionHandler();
8903   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8904 
8905   Verify206Response(headers, 40, 49);
8906   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8907   EXPECT_EQ(0, cache.disk_cache()->open_count());
8908   EXPECT_EQ(1, cache.disk_cache()->create_count());
8909 
8910   // The entry was deleted.
8911   RunTransactionTest(cache.http_cache(), transaction);
8912   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8913   EXPECT_EQ(0, cache.disk_cache()->open_count());
8914   EXPECT_EQ(2, cache.disk_cache()->create_count());
8915 }
8916 
8917 // Tests that when a server returns 206 with a random range and there is
8918 // an entry stored in the cache, the cache gets out of the way.
TEST_F(HttpCacheTest,RangeGET_206ReturnsWrongRange_CachedContent)8919 TEST_F(HttpCacheTest, RangeGET_206ReturnsWrongRange_CachedContent) {
8920   MockHttpCache cache;
8921   std::string headers;
8922 
8923   // Write to the cache (70-79).
8924   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8925   transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
8926   transaction.data = "rg: 70-79 ";
8927   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8928   Verify206Response(headers, 70, 79);
8929 
8930   // Request a large range (30-79). The cache will ask the server for 30-69.
8931   // The server returns 40-49. The cache should consider the server confused and
8932   // abort caching, returning the weird range to the caller.
8933   transaction.request_headers = "Range: bytes = 30-79\r\n" EXTRA_HEADER;
8934   transaction.response_headers =
8935       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
8936       "ETag: \"foo\"\n"
8937       "Accept-Ranges: bytes\n"
8938       "Content-Length: 10\n"
8939       "Content-Range: bytes 40-49/80\n";
8940   transaction.handler = MockTransactionHandler();
8941   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8942 
8943   Verify206Response(headers, 40, 49);
8944   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8945   EXPECT_EQ(1, cache.disk_cache()->open_count());
8946   EXPECT_EQ(1, cache.disk_cache()->create_count());
8947 
8948   // The entry was deleted.
8949   RunTransactionTest(cache.http_cache(), transaction);
8950   EXPECT_EQ(4, cache.network_layer()->transaction_count());
8951   EXPECT_EQ(1, cache.disk_cache()->open_count());
8952   EXPECT_EQ(2, cache.disk_cache()->create_count());
8953 }
8954 
8955 // Tests that when a caller asks for a range beyond EOF, with an empty cache,
8956 // the response matches the one provided by the server.
TEST_F(HttpCacheTest,RangeGET_206ReturnsSmallerFile_NoCachedContent)8957 TEST_F(HttpCacheTest, RangeGET_206ReturnsSmallerFile_NoCachedContent) {
8958   MockHttpCache cache;
8959   std::string headers;
8960 
8961   // Request a large range (70-99). The server sends 70-79.
8962   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8963   transaction.request_headers = "Range: bytes = 70-99\r\n" EXTRA_HEADER;
8964   transaction.data = "rg: 70-79 ";
8965   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8966 
8967   Verify206Response(headers, 70, 79);
8968   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8969   EXPECT_EQ(0, cache.disk_cache()->open_count());
8970   EXPECT_EQ(1, cache.disk_cache()->create_count());
8971 
8972   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
8973   EXPECT_EQ(1, cache.disk_cache()->open_count());
8974 }
8975 
8976 // Tests that when a caller asks for a range beyond EOF, with a cached entry,
8977 // the cache automatically fixes the request.
TEST_F(HttpCacheTest,RangeGET_206ReturnsSmallerFile_CachedContent)8978 TEST_F(HttpCacheTest, RangeGET_206ReturnsSmallerFile_CachedContent) {
8979   MockHttpCache cache;
8980   std::string headers;
8981 
8982   // Write to the cache (40-49).
8983   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8984   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8985 
8986   // Request a large range (70-99). The server sends 70-79.
8987   transaction.request_headers = "Range: bytes = 70-99\r\n" EXTRA_HEADER;
8988   transaction.data = "rg: 70-79 ";
8989   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8990 
8991   Verify206Response(headers, 70, 79);
8992   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8993   EXPECT_EQ(1, cache.disk_cache()->open_count());
8994   EXPECT_EQ(1, cache.disk_cache()->create_count());
8995 
8996   // The entry was not deleted (the range was automatically fixed).
8997   RunTransactionTest(cache.http_cache(), transaction);
8998   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8999   EXPECT_EQ(2, cache.disk_cache()->open_count());
9000   EXPECT_EQ(1, cache.disk_cache()->create_count());
9001 }
9002 
9003 // Tests that when a caller asks for a not-satisfiable range, the server's
9004 // response is forwarded to the caller.
TEST_F(HttpCacheTest,RangeGET_416_NoCachedContent)9005 TEST_F(HttpCacheTest, RangeGET_416_NoCachedContent) {
9006   MockHttpCache cache;
9007   std::string headers;
9008 
9009   // Request a range beyond EOF (80-99).
9010   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9011   transaction.request_headers = "Range: bytes = 80-99\r\n" EXTRA_HEADER;
9012   transaction.data = "";
9013   transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
9014   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9015 
9016   EXPECT_EQ(0U, headers.find(transaction.status));
9017   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9018   EXPECT_EQ(0, cache.disk_cache()->open_count());
9019   EXPECT_EQ(1, cache.disk_cache()->create_count());
9020 
9021   // The entry was deleted.
9022   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9023   EXPECT_EQ(2, cache.disk_cache()->create_count());
9024 }
9025 
9026 // Tests that we cache 301s for range requests.
TEST_F(HttpCacheTest,RangeGET_301)9027 TEST_F(HttpCacheTest, RangeGET_301) {
9028   MockHttpCache cache;
9029   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9030   transaction.status = "HTTP/1.1 301 Moved Permanently";
9031   transaction.response_headers = "Location: http://www.bar.com/\n";
9032   transaction.data = "";
9033   transaction.handler = MockTransactionHandler();
9034 
9035   // Write to the cache.
9036   RunTransactionTest(cache.http_cache(), transaction);
9037   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9038   EXPECT_EQ(0, cache.disk_cache()->open_count());
9039   EXPECT_EQ(1, cache.disk_cache()->create_count());
9040 
9041   // Read from the cache.
9042   RunTransactionTest(cache.http_cache(), transaction);
9043   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9044   EXPECT_EQ(1, cache.disk_cache()->open_count());
9045   EXPECT_EQ(1, cache.disk_cache()->create_count());
9046 }
9047 
9048 // Tests that we can cache range requests when the start or end is unknown.
9049 // We start with one suffix request, followed by a request from a given point.
TEST_F(HttpCacheTest,UnknownRangeGET_1)9050 TEST_F(HttpCacheTest, UnknownRangeGET_1) {
9051   MockHttpCache cache;
9052   AddMockTransaction(&kRangeGET_TransactionOK);
9053   std::string headers;
9054 
9055   // Write to the cache (70-79).
9056   MockTransaction transaction(kRangeGET_TransactionOK);
9057   transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
9058   transaction.data = "rg: 70-79 ";
9059   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9060 
9061   Verify206Response(headers, 70, 79);
9062   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9063   EXPECT_EQ(0, cache.disk_cache()->open_count());
9064   EXPECT_EQ(1, cache.disk_cache()->create_count());
9065 
9066   // Make sure we are done with the previous transaction.
9067   base::RunLoop().RunUntilIdle();
9068 
9069   // Write and read from the cache (60-79).
9070   transaction.request_headers = "Range: bytes = 60-\r\n" EXTRA_HEADER;
9071   transaction.data = "rg: 60-69 rg: 70-79 ";
9072   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9073 
9074   Verify206Response(headers, 60, 79);
9075   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9076   EXPECT_EQ(1, cache.disk_cache()->open_count());
9077   EXPECT_EQ(1, cache.disk_cache()->create_count());
9078 
9079   RemoveMockTransaction(&kRangeGET_TransactionOK);
9080 }
9081 
9082 // Tests that we can cache range requests when the start or end is unknown.
9083 // We start with one request from a given point, followed by a suffix request.
9084 // We'll also verify that synchronous cache responses work as intended.
TEST_F(HttpCacheTest,UnknownRangeGET_2)9085 TEST_F(HttpCacheTest, UnknownRangeGET_2) {
9086   MockHttpCache cache;
9087   std::string headers;
9088 
9089   MockTransaction transaction(kRangeGET_TransactionOK);
9090   transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
9091                           TEST_MODE_SYNC_CACHE_READ |
9092                           TEST_MODE_SYNC_CACHE_WRITE;
9093   AddMockTransaction(&transaction);
9094 
9095   // Write to the cache (70-79).
9096   transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
9097   transaction.data = "rg: 70-79 ";
9098   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9099 
9100   Verify206Response(headers, 70, 79);
9101   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9102   EXPECT_EQ(0, cache.disk_cache()->open_count());
9103   EXPECT_EQ(1, cache.disk_cache()->create_count());
9104 
9105   // Make sure we are done with the previous transaction.
9106   base::RunLoop().RunUntilIdle();
9107 
9108   // Write and read from the cache (60-79).
9109   transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
9110   transaction.data = "rg: 60-69 rg: 70-79 ";
9111   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9112 
9113   Verify206Response(headers, 60, 79);
9114   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9115   EXPECT_EQ(1, cache.disk_cache()->open_count());
9116   EXPECT_EQ(1, cache.disk_cache()->create_count());
9117 
9118   RemoveMockTransaction(&transaction);
9119 }
9120 
9121 // Similar to UnknownRangeGET_2, except that the resource size is empty.
9122 // Regression test for crbug.com/813061, and probably https://crbug.com/1375128
TEST_F(HttpCacheTest,UnknownRangeGET_3)9123 TEST_F(HttpCacheTest, UnknownRangeGET_3) {
9124   MockHttpCache cache;
9125   std::string headers;
9126 
9127   ScopedMockTransaction transaction(kSimpleGET_Transaction);
9128   transaction.response_headers =
9129       "Cache-Control: max-age=10000\n"
9130       "Content-Length: 0\n",
9131   transaction.data = "";
9132   transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
9133                           TEST_MODE_SYNC_CACHE_READ |
9134                           TEST_MODE_SYNC_CACHE_WRITE;
9135 
9136   // Write the empty resource to the cache.
9137   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9138 
9139   EXPECT_EQ(
9140       "HTTP/1.1 200 OK\nCache-Control: max-age=10000\nContent-Length: 0\n",
9141       headers);
9142   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9143   EXPECT_EQ(0, cache.disk_cache()->open_count());
9144   EXPECT_EQ(1, cache.disk_cache()->create_count());
9145 
9146   // Make sure we are done with the previous transaction.
9147   base::RunLoop().RunUntilIdle();
9148 
9149   // Write and read from the cache. This used to trigger a DCHECK
9150   // (or loop infinitely with it off).
9151   transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
9152   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9153 
9154   EXPECT_EQ(
9155       "HTTP/1.1 200 OK\nCache-Control: max-age=10000\nContent-Length: 0\n",
9156       headers);
9157   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9158   EXPECT_EQ(1, cache.disk_cache()->open_count());
9159   EXPECT_EQ(1, cache.disk_cache()->create_count());
9160 }
9161 
9162 // Testcase for https://crbug.com/1433305, validation of range request to a
9163 // cache 302, which is notably bodiless.
TEST_F(HttpCacheTest,UnknownRangeGET_302)9164 TEST_F(HttpCacheTest, UnknownRangeGET_302) {
9165   MockHttpCache cache;
9166   std::string headers;
9167 
9168   ScopedMockTransaction transaction(kSimpleGET_Transaction);
9169   transaction.status = "HTTP/1.1 302 Found";
9170   transaction.response_headers =
9171       "Cache-Control: max-age=0\n"
9172       "Content-Length: 0\n"
9173       "Location: https://example.org/\n",
9174 
9175   transaction.data = "";
9176   transaction.request_headers = "Range: bytes = 0-\r\n" EXTRA_HEADER;
9177   transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
9178                           TEST_MODE_SYNC_CACHE_READ |
9179                           TEST_MODE_SYNC_CACHE_WRITE;
9180 
9181   // Write the empty resource to the cache.
9182   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9183 
9184   EXPECT_EQ(
9185       "HTTP/1.1 302 Found\n"
9186       "Cache-Control: max-age=0\n"
9187       "Content-Length: 0\n"
9188       "Location: https://example.org/\n",
9189       headers);
9190   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9191   EXPECT_EQ(0, cache.disk_cache()->open_count());
9192   EXPECT_EQ(1, cache.disk_cache()->create_count());
9193 
9194   // Make sure we are done with the previous transaction.
9195   base::RunLoop().RunUntilIdle();
9196 
9197   // Try to read from the cache. This should send a network request to
9198   // validate it, and get a different redirect.
9199   transaction.response_headers =
9200       "Cache-Control: max-age=0\n"
9201       "Content-Length: 0\n"
9202       "Location: https://example.com/\n",
9203   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9204 
9205   EXPECT_EQ(
9206       "HTTP/1.1 302 Found\n"
9207       "Cache-Control: max-age=0\n"
9208       "Content-Length: 0\n"
9209       "Location: https://example.com/\n",
9210       headers);
9211   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9212   EXPECT_EQ(1, cache.disk_cache()->open_count());
9213   // A new entry is created since this one isn't conditionalizable.
9214   EXPECT_EQ(2, cache.disk_cache()->create_count());
9215 }
9216 
9217 // Testcase for https://crbug.com/1433305, validation of range request to a
9218 // cache 302, which is notably bodiless, where the 302 is replaced with an
9219 // actual body.
TEST_F(HttpCacheTest,UnknownRangeGET_302_Replaced)9220 TEST_F(HttpCacheTest, UnknownRangeGET_302_Replaced) {
9221   MockHttpCache cache;
9222   std::string headers;
9223 
9224   ScopedMockTransaction transaction(kSimpleGET_Transaction);
9225   transaction.status = "HTTP/1.1 302 Found";
9226   transaction.response_headers =
9227       "Cache-Control: max-age=0\n"
9228       "Content-Length: 0\n"
9229       "Location: https://example.org/\n",
9230 
9231   transaction.data = "";
9232   transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
9233                           TEST_MODE_SYNC_CACHE_READ |
9234                           TEST_MODE_SYNC_CACHE_WRITE;
9235 
9236   // Write the empty resource to the cache.
9237   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9238 
9239   EXPECT_EQ(
9240       "HTTP/1.1 302 Found\n"
9241       "Cache-Control: max-age=0\n"
9242       "Content-Length: 0\n"
9243       "Location: https://example.org/\n",
9244       headers);
9245   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9246   EXPECT_EQ(0, cache.disk_cache()->open_count());
9247   EXPECT_EQ(1, cache.disk_cache()->create_count());
9248 
9249   // Make sure we are done with the previous transaction.
9250   base::RunLoop().RunUntilIdle();
9251 
9252   // Try to read from the cache. This should send a network request to
9253   // validate it, and get a different response.
9254   transaction.handler =
9255       base::BindRepeating(&RangeTransactionServer::RangeHandler);
9256   transaction.request_headers = "Range: bytes = -30\r\n" EXTRA_HEADER;
9257   // Tail 30 bytes out of 80
9258   transaction.data = "rg: 50-59 rg: 60-69 rg: 70-79 ";
9259   transaction.status = "HTTP/1.1 206 Partial Content";
9260   transaction.response_headers = "Content-Length: 10\n";
9261   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9262 
9263   EXPECT_EQ(
9264       "HTTP/1.1 206 Partial Content\n"
9265       "Content-Range: bytes 50-79/80\n"
9266       "Content-Length: 30\n",
9267       headers);
9268   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9269   EXPECT_EQ(1, cache.disk_cache()->open_count());
9270   // A new entry is created since this one isn't conditionalizable.
9271   EXPECT_EQ(2, cache.disk_cache()->create_count());
9272 }
9273 
9274 // Tests that receiving Not Modified when asking for an open range doesn't mess
9275 // up things.
TEST_F(HttpCacheTest,UnknownRangeGET_304)9276 TEST_F(HttpCacheTest, UnknownRangeGET_304) {
9277   MockHttpCache cache;
9278   std::string headers;
9279 
9280   MockTransaction transaction(kRangeGET_TransactionOK);
9281   AddMockTransaction(&transaction);
9282 
9283   RangeTransactionServer handler;
9284   handler.set_not_modified(true);
9285 
9286   // Ask for the end of the file, without knowing the length.
9287   transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
9288   transaction.data = "";
9289   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9290 
9291   // We just bypass the cache.
9292   EXPECT_EQ(0U, headers.find("HTTP/1.1 304 Not Modified\n"));
9293   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9294   EXPECT_EQ(0, cache.disk_cache()->open_count());
9295   EXPECT_EQ(1, cache.disk_cache()->create_count());
9296 
9297   RunTransactionTest(cache.http_cache(), transaction);
9298   EXPECT_EQ(2, cache.disk_cache()->create_count());
9299 
9300   RemoveMockTransaction(&transaction);
9301 }
9302 
9303 // Tests that we can handle non-range requests when we have cached a range.
TEST_F(HttpCacheTest,GET_Previous206)9304 TEST_F(HttpCacheTest, GET_Previous206) {
9305   MockHttpCache cache;
9306   AddMockTransaction(&kRangeGET_TransactionOK);
9307   std::string headers;
9308   NetLogWithSource net_log_with_source =
9309       NetLogWithSource::Make(NetLogSourceType::NONE);
9310   LoadTimingInfo load_timing_info;
9311 
9312   // Write to the cache (40-49).
9313   RunTransactionTestWithResponseAndGetTiming(
9314       cache.http_cache(), kRangeGET_TransactionOK, &headers,
9315       net_log_with_source, &load_timing_info);
9316 
9317   Verify206Response(headers, 40, 49);
9318   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9319   EXPECT_EQ(0, cache.disk_cache()->open_count());
9320   EXPECT_EQ(1, cache.disk_cache()->create_count());
9321   TestLoadTimingNetworkRequest(load_timing_info);
9322 
9323   // Write and read from the cache (0-79), when not asked for a range.
9324   MockTransaction transaction(kRangeGET_TransactionOK);
9325   transaction.request_headers = EXTRA_HEADER;
9326   transaction.data = kFullRangeData;
9327   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
9328                                              &headers, net_log_with_source,
9329                                              &load_timing_info);
9330 
9331   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
9332   EXPECT_EQ(3, cache.network_layer()->transaction_count());
9333   EXPECT_EQ(1, cache.disk_cache()->open_count());
9334   EXPECT_EQ(1, cache.disk_cache()->create_count());
9335   TestLoadTimingNetworkRequest(load_timing_info);
9336 
9337   RemoveMockTransaction(&kRangeGET_TransactionOK);
9338 }
9339 
9340 // Tests that we can handle non-range requests when we have cached the first
9341 // part of the object and the server replies with 304 (Not Modified).
TEST_F(HttpCacheTest,GET_Previous206_NotModified)9342 TEST_F(HttpCacheTest, GET_Previous206_NotModified) {
9343   MockHttpCache cache;
9344 
9345   MockTransaction transaction(kRangeGET_TransactionOK);
9346   AddMockTransaction(&transaction);
9347   std::string headers;
9348   NetLogWithSource net_log_with_source =
9349       NetLogWithSource::Make(NetLogSourceType::NONE);
9350 
9351   LoadTimingInfo load_timing_info;
9352 
9353   // Write to the cache (0-9).
9354   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
9355   transaction.data = "rg: 00-09 ";
9356   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
9357                                              &headers, net_log_with_source,
9358                                              &load_timing_info);
9359   Verify206Response(headers, 0, 9);
9360   TestLoadTimingNetworkRequest(load_timing_info);
9361 
9362   // Write to the cache (70-79).
9363   transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
9364   transaction.data = "rg: 70-79 ";
9365   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
9366                                              &headers, net_log_with_source,
9367                                              &load_timing_info);
9368   Verify206Response(headers, 70, 79);
9369 
9370   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9371   EXPECT_EQ(1, cache.disk_cache()->open_count());
9372   EXPECT_EQ(1, cache.disk_cache()->create_count());
9373   TestLoadTimingNetworkRequest(load_timing_info);
9374 
9375   // Read from the cache (0-9), write and read from cache (10 - 79).
9376   transaction.load_flags |= LOAD_VALIDATE_CACHE;
9377   transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER;
9378   transaction.data = kFullRangeData;
9379   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
9380                                              &headers, net_log_with_source,
9381                                              &load_timing_info);
9382 
9383   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
9384   EXPECT_EQ(4, cache.network_layer()->transaction_count());
9385   EXPECT_EQ(2, cache.disk_cache()->open_count());
9386   EXPECT_EQ(1, cache.disk_cache()->create_count());
9387   TestLoadTimingNetworkRequest(load_timing_info);
9388 
9389   RemoveMockTransaction(&transaction);
9390 }
9391 
9392 // Tests that we can handle a regular request to a sparse entry, that results in
9393 // new content provided by the server (206).
TEST_F(HttpCacheTest,GET_Previous206_NewContent)9394 TEST_F(HttpCacheTest, GET_Previous206_NewContent) {
9395   MockHttpCache cache;
9396   AddMockTransaction(&kRangeGET_TransactionOK);
9397   std::string headers;
9398 
9399   // Write to the cache (0-9).
9400   MockTransaction transaction(kRangeGET_TransactionOK);
9401   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
9402   transaction.data = "rg: 00-09 ";
9403   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9404 
9405   Verify206Response(headers, 0, 9);
9406   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9407   EXPECT_EQ(0, cache.disk_cache()->open_count());
9408   EXPECT_EQ(1, cache.disk_cache()->create_count());
9409 
9410   // Now we'll issue a request without any range that should result first in a
9411   // 206 (when revalidating), and then in a weird standard answer: the test
9412   // server will not modify the response so we'll get the default range... a
9413   // real server will answer with 200.
9414   MockTransaction transaction2(kRangeGET_TransactionOK);
9415   transaction2.request_headers = EXTRA_HEADER;
9416   transaction2.load_flags |= LOAD_VALIDATE_CACHE;
9417   transaction2.data = "Not a range";
9418   RangeTransactionServer handler;
9419   handler.set_modified(true);
9420   LoadTimingInfo load_timing_info;
9421   RunTransactionTestWithResponseAndGetTiming(
9422       cache.http_cache(), transaction2, &headers,
9423       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info);
9424 
9425   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
9426   EXPECT_EQ(3, cache.network_layer()->transaction_count());
9427   EXPECT_EQ(1, cache.disk_cache()->open_count());
9428   EXPECT_EQ(1, cache.disk_cache()->create_count());
9429   TestLoadTimingNetworkRequest(load_timing_info);
9430 
9431   // Verify that the previous request deleted the entry.
9432   RunTransactionTest(cache.http_cache(), transaction);
9433   EXPECT_EQ(2, cache.disk_cache()->create_count());
9434 
9435   RemoveMockTransaction(&transaction);
9436 }
9437 
9438 // Tests that we can handle cached 206 responses that are not sparse.
TEST_F(HttpCacheTest,GET_Previous206_NotSparse)9439 TEST_F(HttpCacheTest, GET_Previous206_NotSparse) {
9440   MockHttpCache cache;
9441 
9442   MockHttpRequest request(kSimpleGET_Transaction);
9443   // Create a disk cache entry that stores 206 headers while not being sparse.
9444   disk_cache::Entry* entry;
9445   ASSERT_TRUE(cache.CreateBackendEntry(request.CacheKey(), &entry, nullptr));
9446 
9447   std::string raw_headers(kRangeGET_TransactionOK.status);
9448   raw_headers.append("\n");
9449   raw_headers.append(kRangeGET_TransactionOK.response_headers);
9450 
9451   HttpResponseInfo response;
9452   response.headers = base::MakeRefCounted<HttpResponseHeaders>(
9453       HttpUtil::AssembleRawHeaders(raw_headers));
9454   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
9455 
9456   auto buf(base::MakeRefCounted<IOBufferWithSize>(500));
9457   int len = static_cast<int>(base::strlcpy(buf->data(),
9458                                            kRangeGET_TransactionOK.data, 500));
9459   TestCompletionCallback cb;
9460   int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
9461   EXPECT_EQ(len, cb.GetResult(rv));
9462   entry->Close();
9463 
9464   // Now see that we don't use the stored entry.
9465   std::string headers;
9466   LoadTimingInfo load_timing_info;
9467   RunTransactionTestWithResponseAndGetTiming(
9468       cache.http_cache(), kSimpleGET_Transaction, &headers,
9469       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info);
9470 
9471   // We are expecting a 200.
9472   std::string expected_headers(kSimpleGET_Transaction.status);
9473   expected_headers.append("\n");
9474   expected_headers.append(kSimpleGET_Transaction.response_headers);
9475   EXPECT_EQ(expected_headers, headers);
9476   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9477   EXPECT_EQ(1, cache.disk_cache()->open_count());
9478   EXPECT_EQ(2, cache.disk_cache()->create_count());
9479   TestLoadTimingNetworkRequest(load_timing_info);
9480 }
9481 
9482 // Tests that we can handle cached 206 responses that are not sparse. This time
9483 // we issue a range request and expect to receive a range.
TEST_F(HttpCacheTest,RangeGET_Previous206_NotSparse_2)9484 TEST_F(HttpCacheTest, RangeGET_Previous206_NotSparse_2) {
9485   MockHttpCache cache;
9486   AddMockTransaction(&kRangeGET_TransactionOK);
9487 
9488   // Create a disk cache entry that stores 206 headers while not being sparse.
9489   MockHttpRequest request(kRangeGET_TransactionOK);
9490   disk_cache::Entry* entry;
9491   ASSERT_TRUE(cache.CreateBackendEntry(request.CacheKey(), &entry, nullptr));
9492 
9493   std::string raw_headers(kRangeGET_TransactionOK.status);
9494   raw_headers.append("\n");
9495   raw_headers.append(kRangeGET_TransactionOK.response_headers);
9496 
9497   HttpResponseInfo response;
9498   response.headers = base::MakeRefCounted<HttpResponseHeaders>(
9499       HttpUtil::AssembleRawHeaders(raw_headers));
9500   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
9501 
9502   auto buf = base::MakeRefCounted<IOBufferWithSize>(500);
9503   int len = static_cast<int>(base::strlcpy(buf->data(),
9504                                            kRangeGET_TransactionOK.data, 500));
9505   TestCompletionCallback cb;
9506   int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
9507   EXPECT_EQ(len, cb.GetResult(rv));
9508   entry->Close();
9509 
9510   // Now see that we don't use the stored entry.
9511   std::string headers;
9512   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
9513                                  &headers);
9514 
9515   // We are expecting a 206.
9516   Verify206Response(headers, 40, 49);
9517   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9518   EXPECT_EQ(1, cache.disk_cache()->open_count());
9519   EXPECT_EQ(2, cache.disk_cache()->create_count());
9520 
9521   RemoveMockTransaction(&kRangeGET_TransactionOK);
9522 }
9523 
9524 // Tests that we can handle cached 206 responses that can't be validated.
TEST_F(HttpCacheTest,GET_Previous206_NotValidation)9525 TEST_F(HttpCacheTest, GET_Previous206_NotValidation) {
9526   MockHttpCache cache;
9527 
9528   MockHttpRequest request(kSimpleGET_Transaction);
9529   // Create a disk cache entry that stores 206 headers.
9530   disk_cache::Entry* entry;
9531   ASSERT_TRUE(cache.CreateBackendEntry(request.CacheKey(), &entry, nullptr));
9532 
9533   // Make sure that the headers cannot be validated with the server.
9534   std::string raw_headers(kRangeGET_TransactionOK.status);
9535   raw_headers.append("\n");
9536   raw_headers.append("Content-Length: 80\n");
9537 
9538   HttpResponseInfo response;
9539   response.headers = base::MakeRefCounted<HttpResponseHeaders>(
9540       HttpUtil::AssembleRawHeaders(raw_headers));
9541   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
9542 
9543   auto buf = base::MakeRefCounted<IOBufferWithSize>(500);
9544   int len = static_cast<int>(base::strlcpy(buf->data(),
9545                                            kRangeGET_TransactionOK.data, 500));
9546   TestCompletionCallback cb;
9547   int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
9548   EXPECT_EQ(len, cb.GetResult(rv));
9549   entry->Close();
9550 
9551   // Now see that we don't use the stored entry.
9552   std::string headers;
9553   RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
9554                                  &headers);
9555 
9556   // We are expecting a 200.
9557   std::string expected_headers(kSimpleGET_Transaction.status);
9558   expected_headers.append("\n");
9559   expected_headers.append(kSimpleGET_Transaction.response_headers);
9560   EXPECT_EQ(expected_headers, headers);
9561   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9562   EXPECT_EQ(1, cache.disk_cache()->open_count());
9563   EXPECT_EQ(2, cache.disk_cache()->create_count());
9564 }
9565 
9566 // Tests that we can handle range requests with cached 200 responses.
TEST_F(HttpCacheTest,RangeGET_Previous200)9567 TEST_F(HttpCacheTest, RangeGET_Previous200) {
9568   MockHttpCache cache;
9569 
9570   // Store the whole thing with status 200.
9571   MockTransaction transaction(kTypicalGET_Transaction);
9572   transaction.url = kRangeGET_TransactionOK.url;
9573   transaction.data = kFullRangeData;
9574   AddMockTransaction(&transaction);
9575   RunTransactionTest(cache.http_cache(), transaction);
9576   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9577   EXPECT_EQ(0, cache.disk_cache()->open_count());
9578   EXPECT_EQ(1, cache.disk_cache()->create_count());
9579 
9580   RemoveMockTransaction(&transaction);
9581   AddMockTransaction(&kRangeGET_TransactionOK);
9582 
9583   // Now see that we use the stored entry.
9584   std::string headers;
9585   MockTransaction transaction2(kRangeGET_TransactionOK);
9586   RangeTransactionServer handler;
9587   handler.set_not_modified(true);
9588   RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
9589 
9590   // We are expecting a 206.
9591   Verify206Response(headers, 40, 49);
9592   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9593   EXPECT_EQ(1, cache.disk_cache()->open_count());
9594   EXPECT_EQ(1, cache.disk_cache()->create_count());
9595 
9596   // The last transaction has finished so make sure the entry is deactivated.
9597   base::RunLoop().RunUntilIdle();
9598 
9599   // Make a request for an invalid range.
9600   MockTransaction transaction3(kRangeGET_TransactionOK);
9601   transaction3.request_headers = "Range: bytes = 80-90\r\n" EXTRA_HEADER;
9602   transaction3.data = transaction.data;
9603   transaction3.load_flags = LOAD_SKIP_CACHE_VALIDATION;
9604   RunTransactionTestWithResponse(cache.http_cache(), transaction3, &headers);
9605   EXPECT_EQ(2, cache.disk_cache()->open_count());
9606   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 "));
9607   EXPECT_EQ(std::string::npos, headers.find("Content-Range:"));
9608   EXPECT_EQ(std::string::npos, headers.find("Content-Length: 80"));
9609 
9610   // Make sure the entry is deactivated.
9611   base::RunLoop().RunUntilIdle();
9612 
9613   // Even though the request was invalid, we should have the entry.
9614   RunTransactionTest(cache.http_cache(), transaction2);
9615   EXPECT_EQ(3, cache.disk_cache()->open_count());
9616 
9617   // Make sure the entry is deactivated.
9618   base::RunLoop().RunUntilIdle();
9619 
9620   // Now we should receive a range from the server and drop the stored entry.
9621   handler.set_not_modified(false);
9622   transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
9623   RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
9624   Verify206Response(headers, 40, 49);
9625   EXPECT_EQ(4, cache.network_layer()->transaction_count());
9626   EXPECT_EQ(4, cache.disk_cache()->open_count());
9627   EXPECT_EQ(1, cache.disk_cache()->create_count());
9628 
9629   RunTransactionTest(cache.http_cache(), transaction2);
9630   EXPECT_EQ(2, cache.disk_cache()->create_count());
9631 
9632   RemoveMockTransaction(&kRangeGET_TransactionOK);
9633 }
9634 
9635 // Tests that we can handle a 200 response when dealing with sparse entries.
TEST_F(HttpCacheTest,RangeRequestResultsIn200)9636 TEST_F(HttpCacheTest, RangeRequestResultsIn200) {
9637   MockHttpCache cache;
9638   AddMockTransaction(&kRangeGET_TransactionOK);
9639   std::string headers;
9640 
9641   // Write to the cache (70-79).
9642   MockTransaction transaction(kRangeGET_TransactionOK);
9643   transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
9644   transaction.data = "rg: 70-79 ";
9645   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9646 
9647   Verify206Response(headers, 70, 79);
9648   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9649   EXPECT_EQ(0, cache.disk_cache()->open_count());
9650   EXPECT_EQ(1, cache.disk_cache()->create_count());
9651 
9652   // Now we'll issue a request that results in a plain 200 response, but to
9653   // the to the same URL that we used to store sparse data, and making sure
9654   // that we ask for a range.
9655   RemoveMockTransaction(&kRangeGET_TransactionOK);
9656   MockTransaction transaction2(kSimpleGET_Transaction);
9657   transaction2.url = kRangeGET_TransactionOK.url;
9658   transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
9659   AddMockTransaction(&transaction2);
9660 
9661   RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
9662 
9663   std::string expected_headers(kSimpleGET_Transaction.status);
9664   expected_headers.append("\n");
9665   expected_headers.append(kSimpleGET_Transaction.response_headers);
9666   EXPECT_EQ(expected_headers, headers);
9667   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9668   EXPECT_EQ(1, cache.disk_cache()->open_count());
9669   EXPECT_EQ(1, cache.disk_cache()->create_count());
9670 
9671   RemoveMockTransaction(&transaction2);
9672 }
9673 
9674 // Tests that a range request that falls outside of the size that we know about
9675 // only deletes the entry if the resource has indeed changed.
TEST_F(HttpCacheTest,RangeGET_MoreThanCurrentSize)9676 TEST_F(HttpCacheTest, RangeGET_MoreThanCurrentSize) {
9677   MockHttpCache cache;
9678   AddMockTransaction(&kRangeGET_TransactionOK);
9679   std::string headers;
9680 
9681   // Write to the cache (40-49).
9682   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
9683                                  &headers);
9684 
9685   Verify206Response(headers, 40, 49);
9686   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9687   EXPECT_EQ(0, cache.disk_cache()->open_count());
9688   EXPECT_EQ(1, cache.disk_cache()->create_count());
9689 
9690   // A weird request should not delete this entry. Ask for bytes 120-.
9691   MockTransaction transaction(kRangeGET_TransactionOK);
9692   transaction.request_headers = "Range: bytes = 120-\r\n" EXTRA_HEADER;
9693   transaction.data = "";
9694   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9695 
9696   EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
9697   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9698   EXPECT_EQ(1, cache.disk_cache()->open_count());
9699   EXPECT_EQ(1, cache.disk_cache()->create_count());
9700 
9701   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9702   EXPECT_EQ(2, cache.disk_cache()->open_count());
9703   EXPECT_EQ(1, cache.disk_cache()->create_count());
9704 
9705   RemoveMockTransaction(&kRangeGET_TransactionOK);
9706 }
9707 
9708 // Tests that we don't delete a sparse entry when we cancel a request.
TEST_F(HttpCacheTest,RangeGET_Cancel)9709 TEST_F(HttpCacheTest, RangeGET_Cancel) {
9710   MockHttpCache cache;
9711   AddMockTransaction(&kRangeGET_TransactionOK);
9712 
9713   MockHttpRequest request(kRangeGET_TransactionOK);
9714 
9715   auto c = std::make_unique<Context>();
9716   int rv = cache.CreateTransaction(&c->trans);
9717   ASSERT_THAT(rv, IsOk());
9718 
9719   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
9720   if (rv == ERR_IO_PENDING)
9721     rv = c->callback.WaitForResult();
9722 
9723   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9724   EXPECT_EQ(0, cache.disk_cache()->open_count());
9725   EXPECT_EQ(1, cache.disk_cache()->create_count());
9726 
9727   // Make sure that the entry has some data stored.
9728   scoped_refptr<IOBufferWithSize> buf =
9729       base::MakeRefCounted<IOBufferWithSize>(10);
9730   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
9731   if (rv == ERR_IO_PENDING)
9732     rv = c->callback.WaitForResult();
9733   EXPECT_EQ(buf->size(), rv);
9734 
9735   // Destroy the transaction.
9736   c.reset();
9737 
9738   // Verify that the entry has not been deleted.
9739   disk_cache::Entry* entry;
9740   ASSERT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &entry));
9741   entry->Close();
9742   RemoveMockTransaction(&kRangeGET_TransactionOK);
9743 }
9744 
9745 // Tests that we don't mark an entry as truncated if it is partial and not
9746 // already truncated.
TEST_F(HttpCacheTest,RangeGET_CancelWhileReading)9747 TEST_F(HttpCacheTest, RangeGET_CancelWhileReading) {
9748   MockHttpCache cache;
9749   AddMockTransaction(&kRangeGET_TransactionOK);
9750 
9751   MockHttpRequest request(kRangeGET_TransactionOK);
9752 
9753   auto context = std::make_unique<Context>();
9754   int rv = cache.CreateTransaction(&context->trans);
9755   ASSERT_THAT(rv, IsOk());
9756 
9757   rv = context->trans->Start(&request, context->callback.callback(),
9758                              NetLogWithSource());
9759   if (rv == ERR_IO_PENDING)
9760     rv = context->callback.WaitForResult();
9761 
9762   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9763   EXPECT_EQ(0, cache.disk_cache()->open_count());
9764   EXPECT_EQ(1, cache.disk_cache()->create_count());
9765 
9766   // Start Read.
9767   scoped_refptr<IOBufferWithSize> buf =
9768       base::MakeRefCounted<IOBufferWithSize>(5);
9769   rv = context->trans->Read(buf.get(), buf->size(),
9770                             context->callback.callback());
9771   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9772 
9773   // Destroy the transaction.
9774   context.reset();
9775 
9776   // Complete Read.
9777   base::RunLoop().RunUntilIdle();
9778 
9779   // Verify that the entry has not been marked as truncated.
9780   VerifyTruncatedFlag(&cache, request.CacheKey(), false, 0);
9781   RemoveMockTransaction(&kRangeGET_TransactionOK);
9782 }
9783 
9784 // Tests that we don't delete a sparse entry when we start a new request after
9785 // cancelling the previous one.
TEST_F(HttpCacheTest,RangeGET_Cancel2)9786 TEST_F(HttpCacheTest, RangeGET_Cancel2) {
9787   MockHttpCache cache;
9788   AddMockTransaction(&kRangeGET_TransactionOK);
9789 
9790   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9791   MockHttpRequest request(kRangeGET_TransactionOK);
9792   request.load_flags |= LOAD_VALIDATE_CACHE;
9793 
9794   auto c = std::make_unique<Context>();
9795   int rv = cache.CreateTransaction(&c->trans);
9796   ASSERT_THAT(rv, IsOk());
9797 
9798   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
9799   if (rv == ERR_IO_PENDING)
9800     rv = c->callback.WaitForResult();
9801 
9802   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9803   EXPECT_EQ(1, cache.disk_cache()->open_count());
9804   EXPECT_EQ(1, cache.disk_cache()->create_count());
9805 
9806   // Make sure that we revalidate the entry and read from the cache (a single
9807   // read will return while waiting for the network).
9808   scoped_refptr<IOBufferWithSize> buf =
9809       base::MakeRefCounted<IOBufferWithSize>(5);
9810   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
9811   EXPECT_EQ(5, c->callback.GetResult(rv));
9812   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
9813   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9814 
9815   // Destroy the transaction before completing the read.
9816   c.reset();
9817 
9818   // We have the read and the delete (OnProcessPendingQueue) waiting on the
9819   // message loop. This means that a new transaction will just reuse the same
9820   // active entry (no open or create).
9821 
9822   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9823 
9824   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9825   EXPECT_EQ(1, cache.disk_cache()->open_count());
9826   EXPECT_EQ(1, cache.disk_cache()->create_count());
9827   RemoveMockTransaction(&kRangeGET_TransactionOK);
9828 }
9829 
9830 // A slight variation of the previous test, this time we cancel two requests in
9831 // a row, making sure that the second is waiting for the entry to be ready.
TEST_F(HttpCacheTest,RangeGET_Cancel3)9832 TEST_F(HttpCacheTest, RangeGET_Cancel3) {
9833   MockHttpCache cache;
9834   AddMockTransaction(&kRangeGET_TransactionOK);
9835 
9836   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9837   MockHttpRequest request(kRangeGET_TransactionOK);
9838   request.load_flags |= LOAD_VALIDATE_CACHE;
9839 
9840   auto c = std::make_unique<Context>();
9841   int rv = cache.CreateTransaction(&c->trans);
9842   ASSERT_THAT(rv, IsOk());
9843 
9844   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
9845   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9846   rv = c->callback.WaitForResult();
9847 
9848   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9849   EXPECT_EQ(1, cache.disk_cache()->open_count());
9850   EXPECT_EQ(1, cache.disk_cache()->create_count());
9851 
9852   // Make sure that we revalidate the entry and read from the cache (a single
9853   // read will return while waiting for the network).
9854   scoped_refptr<IOBufferWithSize> buf =
9855       base::MakeRefCounted<IOBufferWithSize>(5);
9856   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
9857   EXPECT_EQ(5, c->callback.GetResult(rv));
9858   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
9859   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9860 
9861   // Destroy the previous transaction before completing the read.
9862   c.reset();
9863 
9864   // We have the read and the delete (OnProcessPendingQueue) waiting on the
9865   // message loop. This means that a new transaction will just reuse the same
9866   // active entry (no open or create).
9867 
9868   c = std::make_unique<Context>();
9869   rv = cache.CreateTransaction(&c->trans);
9870   ASSERT_THAT(rv, IsOk());
9871 
9872   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
9873   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9874 
9875   MockDiskEntry::IgnoreCallbacks(true);
9876   base::RunLoop().RunUntilIdle();
9877   MockDiskEntry::IgnoreCallbacks(false);
9878 
9879   // The new transaction is waiting for the query range callback.
9880   c.reset();
9881 
9882   // And we should not crash when the callback is delivered.
9883   base::RunLoop().RunUntilIdle();
9884 
9885   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9886   EXPECT_EQ(1, cache.disk_cache()->open_count());
9887   EXPECT_EQ(1, cache.disk_cache()->create_count());
9888   RemoveMockTransaction(&kRangeGET_TransactionOK);
9889 }
9890 
9891 // Tests that an invalid range response results in no cached entry.
TEST_F(HttpCacheTest,RangeGET_InvalidResponse1)9892 TEST_F(HttpCacheTest, RangeGET_InvalidResponse1) {
9893   MockHttpCache cache;
9894   std::string headers;
9895 
9896   MockTransaction transaction(kRangeGET_TransactionOK);
9897   transaction.handler = MockTransactionHandler();
9898   transaction.response_headers = "Content-Range: bytes 40-49/45\n"
9899                                  "Content-Length: 10\n";
9900   AddMockTransaction(&transaction);
9901   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9902 
9903   std::string expected(transaction.status);
9904   expected.append("\n");
9905   expected.append(transaction.response_headers);
9906   EXPECT_EQ(expected, headers);
9907 
9908   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9909   EXPECT_EQ(0, cache.disk_cache()->open_count());
9910   EXPECT_EQ(1, cache.disk_cache()->create_count());
9911 
9912   // Verify that we don't have a cached entry.
9913   disk_cache::Entry* entry;
9914   MockHttpRequest request(transaction);
9915   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
9916 
9917   RemoveMockTransaction(&kRangeGET_TransactionOK);
9918 }
9919 
9920 // Tests that we reject a range that doesn't match the content-length.
TEST_F(HttpCacheTest,RangeGET_InvalidResponse2)9921 TEST_F(HttpCacheTest, RangeGET_InvalidResponse2) {
9922   MockHttpCache cache;
9923   std::string headers;
9924 
9925   MockTransaction transaction(kRangeGET_TransactionOK);
9926   transaction.handler = MockTransactionHandler();
9927   transaction.response_headers = "Content-Range: bytes 40-49/80\n"
9928                                  "Content-Length: 20\n";
9929   AddMockTransaction(&transaction);
9930   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9931 
9932   std::string expected(transaction.status);
9933   expected.append("\n");
9934   expected.append(transaction.response_headers);
9935   EXPECT_EQ(expected, headers);
9936 
9937   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9938   EXPECT_EQ(0, cache.disk_cache()->open_count());
9939   EXPECT_EQ(1, cache.disk_cache()->create_count());
9940 
9941   // Verify that we don't have a cached entry.
9942   disk_cache::Entry* entry;
9943   MockHttpRequest request(transaction);
9944   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
9945 
9946   RemoveMockTransaction(&kRangeGET_TransactionOK);
9947 }
9948 
9949 // Tests that if a server tells us conflicting information about a resource we
9950 // drop the entry.
TEST_F(HttpCacheTest,RangeGET_InvalidResponse3)9951 TEST_F(HttpCacheTest, RangeGET_InvalidResponse3) {
9952   MockHttpCache cache;
9953   std::string headers;
9954 
9955   MockTransaction transaction(kRangeGET_TransactionOK);
9956   transaction.handler = MockTransactionHandler();
9957   transaction.request_headers = "Range: bytes = 50-59\r\n" EXTRA_HEADER;
9958   std::string response_headers(transaction.response_headers);
9959   response_headers.append("Content-Range: bytes 50-59/160\n");
9960   transaction.response_headers = response_headers.c_str();
9961   AddMockTransaction(&transaction);
9962   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9963 
9964   Verify206Response(headers, 50, 59);
9965   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9966   EXPECT_EQ(0, cache.disk_cache()->open_count());
9967   EXPECT_EQ(1, cache.disk_cache()->create_count());
9968 
9969   RemoveMockTransaction(&transaction);
9970   AddMockTransaction(&kRangeGET_TransactionOK);
9971 
9972   // This transaction will report a resource size of 80 bytes, and we think it's
9973   // 160 so we should ignore the response.
9974   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
9975                                  &headers);
9976 
9977   Verify206Response(headers, 40, 49);
9978   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9979   EXPECT_EQ(1, cache.disk_cache()->open_count());
9980   EXPECT_EQ(1, cache.disk_cache()->create_count());
9981 
9982   // Verify that the entry is gone.
9983   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9984   EXPECT_EQ(1, cache.disk_cache()->open_count());
9985   EXPECT_EQ(2, cache.disk_cache()->create_count());
9986   RemoveMockTransaction(&kRangeGET_TransactionOK);
9987 }
9988 
9989 // Tests that we handle large range values properly.
TEST_F(HttpCacheTest,RangeGET_LargeValues)9990 TEST_F(HttpCacheTest, RangeGET_LargeValues) {
9991   // We need a real sparse cache for this test.
9992   MockHttpCache cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
9993   std::string headers;
9994 
9995   MockTransaction transaction(kRangeGET_TransactionOK);
9996   transaction.handler = MockTransactionHandler();
9997   transaction.request_headers = "Range: bytes = 4294967288-4294967297\r\n"
9998                                 EXTRA_HEADER;
9999   transaction.response_headers =
10000       "ETag: \"foo\"\n"
10001       "Content-Range: bytes 4294967288-4294967297/4294967299\n"
10002       "Content-Length: 10\n";
10003   AddMockTransaction(&transaction);
10004   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
10005 
10006   std::string expected(transaction.status);
10007   expected.append("\n");
10008   expected.append(transaction.response_headers);
10009   EXPECT_EQ(expected, headers);
10010 
10011   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10012 
10013   // Verify that we have a cached entry.
10014   disk_cache::Entry* en;
10015   MockHttpRequest request(transaction);
10016   ASSERT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &en));
10017   en->Close();
10018 
10019   RemoveMockTransaction(&kRangeGET_TransactionOK);
10020 }
10021 
10022 // Tests that we don't crash with a range request if the disk cache was not
10023 // initialized properly.
TEST_F(HttpCacheTest,RangeGET_NoDiskCache)10024 TEST_F(HttpCacheTest, RangeGET_NoDiskCache) {
10025   auto factory = std::make_unique<MockBlockingBackendFactory>();
10026   factory->set_fail(true);
10027   factory->FinishCreation();  // We'll complete synchronously.
10028   MockHttpCache cache(std::move(factory));
10029 
10030   AddMockTransaction(&kRangeGET_TransactionOK);
10031 
10032   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
10033   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10034 
10035   RemoveMockTransaction(&kRangeGET_TransactionOK);
10036 }
10037 
10038 // Tests that we handle byte range requests that skip the cache.
TEST_F(HttpCacheTest,RangeHEAD)10039 TEST_F(HttpCacheTest, RangeHEAD) {
10040   MockHttpCache cache;
10041   AddMockTransaction(&kRangeGET_TransactionOK);
10042 
10043   MockTransaction transaction(kRangeGET_TransactionOK);
10044   transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
10045   transaction.method = "HEAD";
10046   transaction.data = "rg: 70-79 ";
10047 
10048   std::string headers;
10049   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
10050 
10051   Verify206Response(headers, 70, 79);
10052   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10053   EXPECT_EQ(0, cache.disk_cache()->open_count());
10054   EXPECT_EQ(0, cache.disk_cache()->create_count());
10055 
10056   RemoveMockTransaction(&kRangeGET_TransactionOK);
10057 }
10058 
10059 // Tests that we don't crash when after reading from the cache we issue a
10060 // request for the next range and the server gives us a 200 synchronously.
TEST_F(HttpCacheTest,RangeGET_FastFlakyServer)10061 TEST_F(HttpCacheTest, RangeGET_FastFlakyServer) {
10062   MockHttpCache cache;
10063 
10064   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10065   transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER;
10066   transaction.test_mode = TEST_MODE_SYNC_NET_START;
10067   transaction.load_flags |= LOAD_VALIDATE_CACHE;
10068 
10069   // Write to the cache.
10070   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
10071 
10072   // And now read from the cache and the network.
10073   RangeTransactionServer handler;
10074   handler.set_bad_200(true);
10075   transaction.data = "Not a range";
10076   RecordingNetLogObserver net_log_observer;
10077   RunTransactionTestWithLog(cache.http_cache(), transaction,
10078                             NetLogWithSource::Make(NetLogSourceType::NONE));
10079 
10080   EXPECT_EQ(3, cache.network_layer()->transaction_count());
10081   EXPECT_EQ(1, cache.disk_cache()->open_count());
10082   EXPECT_EQ(1, cache.disk_cache()->create_count());
10083   EXPECT_TRUE(LogContainsEventType(
10084       net_log_observer, NetLogEventType::HTTP_CACHE_RE_SEND_PARTIAL_REQUEST));
10085 }
10086 
10087 // Tests that when the server gives us less data than expected, we don't keep
10088 // asking for more data.
TEST_F(HttpCacheTest,RangeGET_FastFlakyServer2)10089 TEST_F(HttpCacheTest, RangeGET_FastFlakyServer2) {
10090   MockHttpCache cache;
10091 
10092   // First, check with an empty cache (WRITE mode).
10093   MockTransaction transaction(kRangeGET_TransactionOK);
10094   transaction.request_headers = "Range: bytes = 40-49\r\n" EXTRA_HEADER;
10095   transaction.data = "rg: 40-";  // Less than expected.
10096   transaction.handler = MockTransactionHandler();
10097   std::string headers(transaction.response_headers);
10098   headers.append("Content-Range: bytes 40-49/80\n");
10099   transaction.response_headers = headers.c_str();
10100 
10101   AddMockTransaction(&transaction);
10102 
10103   // Write to the cache.
10104   RunTransactionTest(cache.http_cache(), transaction);
10105 
10106   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10107   EXPECT_EQ(0, cache.disk_cache()->open_count());
10108   EXPECT_EQ(1, cache.disk_cache()->create_count());
10109 
10110   // Now verify that even in READ_WRITE mode, we forward the bad response to
10111   // the caller.
10112   transaction.request_headers = "Range: bytes = 60-69\r\n" EXTRA_HEADER;
10113   transaction.data = "rg: 60-";  // Less than expected.
10114   headers = kRangeGET_TransactionOK.response_headers;
10115   headers.append("Content-Range: bytes 60-69/80\n");
10116   transaction.response_headers = headers.c_str();
10117 
10118   RunTransactionTest(cache.http_cache(), transaction);
10119 
10120   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10121   EXPECT_EQ(1, cache.disk_cache()->open_count());
10122   EXPECT_EQ(1, cache.disk_cache()->create_count());
10123 
10124   RemoveMockTransaction(&transaction);
10125 }
10126 
TEST_F(HttpCacheTest,RangeGET_OK_LoadOnlyFromCache)10127 TEST_F(HttpCacheTest, RangeGET_OK_LoadOnlyFromCache) {
10128   MockHttpCache cache;
10129   AddMockTransaction(&kRangeGET_TransactionOK);
10130 
10131   // Write to the cache (40-49).
10132   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
10133   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10134   EXPECT_EQ(0, cache.disk_cache()->open_count());
10135   EXPECT_EQ(1, cache.disk_cache()->create_count());
10136 
10137   // Force this transaction to read from the cache.
10138   MockTransaction transaction(kRangeGET_TransactionOK);
10139   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
10140 
10141   MockHttpRequest request(transaction);
10142   TestCompletionCallback callback;
10143 
10144   std::unique_ptr<HttpTransaction> trans;
10145   int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
10146   EXPECT_THAT(rv, IsOk());
10147   ASSERT_TRUE(trans.get());
10148 
10149   rv = trans->Start(&request, callback.callback(), NetLogWithSource());
10150   if (rv == ERR_IO_PENDING)
10151     rv = callback.WaitForResult();
10152   ASSERT_THAT(rv, IsError(ERR_CACHE_MISS));
10153 
10154   trans.reset();
10155 
10156   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10157   EXPECT_EQ(1, cache.disk_cache()->open_count());
10158   EXPECT_EQ(1, cache.disk_cache()->create_count());
10159 
10160   RemoveMockTransaction(&kRangeGET_TransactionOK);
10161 }
10162 
10163 // Tests the handling of the "truncation" flag.
TEST_F(HttpCacheTest,WriteResponseInfo_Truncated)10164 TEST_F(HttpCacheTest, WriteResponseInfo_Truncated) {
10165   MockHttpCache cache;
10166   disk_cache::Entry* entry;
10167   ASSERT_TRUE(cache.CreateBackendEntry(
10168       GenerateCacheKey("http://www.google.com"), &entry, nullptr));
10169 
10170   HttpResponseInfo response;
10171   response.headers = base::MakeRefCounted<HttpResponseHeaders>(
10172       HttpUtil::AssembleRawHeaders("HTTP/1.1 200 OK"));
10173 
10174   // Set the last argument for this to be an incomplete request.
10175   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
10176   bool truncated = false;
10177   EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
10178   EXPECT_TRUE(truncated);
10179 
10180   // And now test the opposite case.
10181   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
10182   truncated = true;
10183   EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
10184   EXPECT_FALSE(truncated);
10185   entry->Close();
10186 }
10187 
10188 // Tests basic pickling/unpickling of HttpResponseInfo.
TEST_F(HttpCacheTest,PersistHttpResponseInfo)10189 TEST_F(HttpCacheTest, PersistHttpResponseInfo) {
10190   const IPEndPoint expected_endpoint = IPEndPoint(IPAddress(1, 2, 3, 4), 80);
10191   // Set some fields (add more if needed.)
10192   HttpResponseInfo response1;
10193   response1.was_cached = false;
10194   response1.remote_endpoint = expected_endpoint;
10195   response1.headers =
10196       base::MakeRefCounted<HttpResponseHeaders>("HTTP/1.1 200 OK");
10197 
10198   // Pickle.
10199   base::Pickle pickle;
10200   response1.Persist(&pickle, false, false);
10201 
10202   // Unpickle.
10203   HttpResponseInfo response2;
10204   bool response_truncated;
10205   EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated));
10206   EXPECT_FALSE(response_truncated);
10207 
10208   // Verify fields.
10209   EXPECT_TRUE(response2.was_cached);  // InitFromPickle sets this flag.
10210   EXPECT_EQ(expected_endpoint, response2.remote_endpoint);
10211   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
10212 }
10213 
10214 // Tests that we delete an entry when the request is cancelled before starting
10215 // to read from the network.
TEST_F(HttpCacheTest,DoomOnDestruction)10216 TEST_F(HttpCacheTest, DoomOnDestruction) {
10217   MockHttpCache cache;
10218 
10219   MockHttpRequest request(kSimpleGET_Transaction);
10220 
10221   auto c = std::make_unique<Context>();
10222   int rv = cache.CreateTransaction(&c->trans);
10223   ASSERT_THAT(rv, IsOk());
10224 
10225   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10226   if (rv == ERR_IO_PENDING)
10227     c->result = c->callback.WaitForResult();
10228 
10229   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10230   EXPECT_EQ(0, cache.disk_cache()->open_count());
10231   EXPECT_EQ(1, cache.disk_cache()->create_count());
10232 
10233   // Destroy the transaction. We only have the headers so we should delete this
10234   // entry.
10235   c.reset();
10236 
10237   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
10238 
10239   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10240   EXPECT_EQ(0, cache.disk_cache()->open_count());
10241   EXPECT_EQ(2, cache.disk_cache()->create_count());
10242 }
10243 
10244 // Tests that we delete an entry when the request is cancelled if the response
10245 // does not have content-length and strong validators.
TEST_F(HttpCacheTest,DoomOnDestruction2)10246 TEST_F(HttpCacheTest, DoomOnDestruction2) {
10247   MockHttpCache cache;
10248 
10249   MockHttpRequest request(kSimpleGET_Transaction);
10250 
10251   auto c = std::make_unique<Context>();
10252   int rv = cache.CreateTransaction(&c->trans);
10253   ASSERT_THAT(rv, IsOk());
10254 
10255   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10256   if (rv == ERR_IO_PENDING)
10257     rv = c->callback.WaitForResult();
10258 
10259   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10260   EXPECT_EQ(0, cache.disk_cache()->open_count());
10261   EXPECT_EQ(1, cache.disk_cache()->create_count());
10262 
10263   // Make sure that the entry has some data stored.
10264   scoped_refptr<IOBufferWithSize> buf =
10265       base::MakeRefCounted<IOBufferWithSize>(10);
10266   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10267   if (rv == ERR_IO_PENDING)
10268     rv = c->callback.WaitForResult();
10269   EXPECT_EQ(buf->size(), rv);
10270 
10271   // Destroy the transaction.
10272   c.reset();
10273 
10274   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
10275 
10276   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10277   EXPECT_EQ(0, cache.disk_cache()->open_count());
10278   EXPECT_EQ(2, cache.disk_cache()->create_count());
10279 }
10280 
10281 // Tests that we delete an entry when the request is cancelled if the response
10282 // has an "Accept-Ranges: none" header.
TEST_F(HttpCacheTest,DoomOnDestruction3)10283 TEST_F(HttpCacheTest, DoomOnDestruction3) {
10284   MockHttpCache cache;
10285 
10286   MockTransaction transaction(kSimpleGET_Transaction);
10287   transaction.response_headers =
10288       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
10289       "Content-Length: 22\n"
10290       "Accept-Ranges: none\n"
10291       "Etag: \"foopy\"\n";
10292   AddMockTransaction(&transaction);
10293   MockHttpRequest request(transaction);
10294 
10295   auto c = std::make_unique<Context>();
10296   int rv = cache.CreateTransaction(&c->trans);
10297   ASSERT_THAT(rv, IsOk());
10298 
10299   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10300   if (rv == ERR_IO_PENDING)
10301     rv = c->callback.WaitForResult();
10302 
10303   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10304   EXPECT_EQ(0, cache.disk_cache()->open_count());
10305   EXPECT_EQ(1, cache.disk_cache()->create_count());
10306 
10307   // Make sure that the entry has some data stored.
10308   scoped_refptr<IOBufferWithSize> buf =
10309       base::MakeRefCounted<IOBufferWithSize>(10);
10310   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10311   if (rv == ERR_IO_PENDING)
10312     rv = c->callback.WaitForResult();
10313   EXPECT_EQ(buf->size(), rv);
10314 
10315   // Destroy the transaction.
10316   c.reset();
10317 
10318   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
10319 
10320   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10321   EXPECT_EQ(0, cache.disk_cache()->open_count());
10322   EXPECT_EQ(2, cache.disk_cache()->create_count());
10323 
10324   RemoveMockTransaction(&transaction);
10325 }
10326 
10327 // Tests that we mark an entry as incomplete when the request is cancelled.
TEST_F(HttpCacheTest,SetTruncatedFlag)10328 TEST_F(HttpCacheTest, SetTruncatedFlag) {
10329   MockHttpCache cache;
10330 
10331   ScopedMockTransaction transaction(kSimpleGET_Transaction);
10332   transaction.response_headers =
10333       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
10334       "Content-Length: 22\n"
10335       "Etag: \"foopy\"\n";
10336   MockHttpRequest request(transaction);
10337 
10338   auto c = std::make_unique<Context>();
10339 
10340   int rv = cache.CreateTransaction(&c->trans);
10341   ASSERT_THAT(rv, IsOk());
10342 
10343   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10344   if (rv == ERR_IO_PENDING)
10345     rv = c->callback.WaitForResult();
10346 
10347   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10348   EXPECT_EQ(0, cache.disk_cache()->open_count());
10349   EXPECT_EQ(1, cache.disk_cache()->create_count());
10350 
10351   // Make sure that the entry has some data stored.
10352   scoped_refptr<IOBufferWithSize> buf =
10353       base::MakeRefCounted<IOBufferWithSize>(10);
10354   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10355   if (rv == ERR_IO_PENDING)
10356     rv = c->callback.WaitForResult();
10357   EXPECT_EQ(buf->size(), rv);
10358 
10359   // We want to cancel the request when the transaction is busy.
10360   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10361   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10362   EXPECT_FALSE(c->callback.have_result());
10363 
10364   // Destroy the transaction.
10365   c->trans.reset();
10366 
10367   // Make sure that we don't invoke the callback. We may have an issue if the
10368   // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
10369   // could end up with the transaction being deleted twice if we send any
10370   // notification from the transaction destructor (see http://crbug.com/31723).
10371   EXPECT_FALSE(c->callback.have_result());
10372 
10373   base::RunLoop().RunUntilIdle();
10374   VerifyTruncatedFlag(&cache, request.CacheKey(), true, 0);
10375 }
10376 
10377 // Tests that we do not mark an entry as truncated when the request is
10378 // cancelled.
TEST_F(HttpCacheTest,DontSetTruncatedFlagForGarbledResponseCode)10379 TEST_F(HttpCacheTest, DontSetTruncatedFlagForGarbledResponseCode) {
10380   MockHttpCache cache;
10381 
10382   ScopedMockTransaction transaction(kSimpleGET_Transaction);
10383   transaction.response_headers =
10384       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
10385       "Content-Length: 22\n"
10386       "Etag: \"foopy\"\n";
10387   transaction.status = "HTTP/1.1 2";
10388   MockHttpRequest request(transaction);
10389 
10390   auto c = std::make_unique<Context>();
10391 
10392   int rv = cache.CreateTransaction(&c->trans);
10393   ASSERT_THAT(rv, IsOk());
10394 
10395   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10396   if (rv == ERR_IO_PENDING)
10397     rv = c->callback.WaitForResult();
10398 
10399   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10400   EXPECT_EQ(0, cache.disk_cache()->open_count());
10401   EXPECT_EQ(1, cache.disk_cache()->create_count());
10402 
10403   // Make sure that the entry has some data stored.
10404   scoped_refptr<IOBufferWithSize> buf =
10405       base::MakeRefCounted<IOBufferWithSize>(10);
10406   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10407   if (rv == ERR_IO_PENDING)
10408     rv = c->callback.WaitForResult();
10409   EXPECT_EQ(buf->size(), rv);
10410 
10411   // We want to cancel the request when the transaction is busy.
10412   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10413   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10414   EXPECT_FALSE(c->callback.have_result());
10415 
10416   MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL);
10417 
10418   // Destroy the transaction.
10419   c->trans.reset();
10420   MockHttpCache::SetTestMode(0);
10421 
10422   // Make sure that we don't invoke the callback. We may have an issue if the
10423   // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
10424   // could end up with the transaction being deleted twice if we send any
10425   // notification from the transaction destructor (see http://crbug.com/31723).
10426   EXPECT_FALSE(c->callback.have_result());
10427 
10428   // Verify that the entry is deleted as well, since the response status is
10429   // garbled. Note that the entry will be deleted after the pending Read is
10430   // complete.
10431   base::RunLoop().RunUntilIdle();
10432   disk_cache::Entry* entry;
10433   ASSERT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
10434 }
10435 
10436 // Tests that we don't mark an entry as truncated when we read everything.
TEST_F(HttpCacheTest,DontSetTruncatedFlag)10437 TEST_F(HttpCacheTest, DontSetTruncatedFlag) {
10438   MockHttpCache cache;
10439 
10440   ScopedMockTransaction transaction(kSimpleGET_Transaction);
10441   transaction.response_headers =
10442       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
10443       "Content-Length: 22\n"
10444       "Etag: \"foopy\"\n";
10445   MockHttpRequest request(transaction);
10446 
10447   auto c = std::make_unique<Context>();
10448   int rv = cache.CreateTransaction(&c->trans);
10449   ASSERT_THAT(rv, IsOk());
10450 
10451   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10452   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10453 
10454   // Read everything.
10455   scoped_refptr<IOBufferWithSize> buf =
10456       base::MakeRefCounted<IOBufferWithSize>(22);
10457   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10458   EXPECT_EQ(buf->size(), c->callback.GetResult(rv));
10459 
10460   // Destroy the transaction.
10461   c->trans.reset();
10462 
10463   // Verify that the entry is not marked as truncated.
10464   VerifyTruncatedFlag(&cache, request.CacheKey(), false, 0);
10465 }
10466 
10467 // Tests that sparse entries don't set the truncate flag.
TEST_F(HttpCacheTest,RangeGET_DontTruncate)10468 TEST_F(HttpCacheTest, RangeGET_DontTruncate) {
10469   MockHttpCache cache;
10470 
10471   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10472   transaction.request_headers = "Range: bytes = 0-19\r\n" EXTRA_HEADER;
10473 
10474   auto request = std::make_unique<MockHttpRequest>(transaction);
10475   std::unique_ptr<HttpTransaction> trans;
10476 
10477   int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
10478   EXPECT_THAT(rv, IsOk());
10479 
10480   TestCompletionCallback cb;
10481   rv = trans->Start(request.get(), cb.callback(), NetLogWithSource());
10482   EXPECT_EQ(0, cb.GetResult(rv));
10483 
10484   auto buf = base::MakeRefCounted<IOBufferWithSize>(10);
10485   rv = trans->Read(buf.get(), 10, cb.callback());
10486   EXPECT_EQ(10, cb.GetResult(rv));
10487 
10488   // Should not trigger any DCHECK.
10489   trans.reset();
10490   VerifyTruncatedFlag(&cache, request->CacheKey(), false, 0);
10491 }
10492 
10493 // Tests that sparse entries don't set the truncate flag (when the byte range
10494 //  starts after 0).
TEST_F(HttpCacheTest,RangeGET_DontTruncate2)10495 TEST_F(HttpCacheTest, RangeGET_DontTruncate2) {
10496   MockHttpCache cache;
10497 
10498   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10499   transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
10500 
10501   auto request = std::make_unique<MockHttpRequest>(transaction);
10502   std::unique_ptr<HttpTransaction> trans;
10503 
10504   int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
10505   EXPECT_THAT(rv, IsOk());
10506 
10507   TestCompletionCallback cb;
10508   rv = trans->Start(request.get(), cb.callback(), NetLogWithSource());
10509   EXPECT_EQ(0, cb.GetResult(rv));
10510 
10511   auto buf = base::MakeRefCounted<IOBufferWithSize>(10);
10512   rv = trans->Read(buf.get(), 10, cb.callback());
10513   EXPECT_EQ(10, cb.GetResult(rv));
10514 
10515   // Should not trigger any DCHECK.
10516   trans.reset();
10517   VerifyTruncatedFlag(&cache, request->CacheKey(), false, 0);
10518 }
10519 
10520 // Tests that we can continue with a request that was interrupted.
TEST_F(HttpCacheTest,GET_IncompleteResource)10521 TEST_F(HttpCacheTest, GET_IncompleteResource) {
10522   MockHttpCache cache;
10523   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10524 
10525   std::string raw_headers("HTTP/1.1 200 OK\n"
10526                           "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10527                           "ETag: \"foo\"\n"
10528                           "Accept-Ranges: bytes\n"
10529                           "Content-Length: 80\n");
10530   CreateTruncatedEntry(raw_headers, &cache);
10531 
10532   // Now make a regular request.
10533   std::string headers;
10534   transaction.request_headers = EXTRA_HEADER;
10535   transaction.data = kFullRangeData;
10536   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
10537 
10538   // We update the headers with the ones received while revalidating.
10539   std::string expected_headers(
10540       "HTTP/1.1 200 OK\n"
10541       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10542       "Accept-Ranges: bytes\n"
10543       "ETag: \"foo\"\n"
10544       "Content-Length: 80\n");
10545 
10546   EXPECT_EQ(expected_headers, headers);
10547   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10548   EXPECT_EQ(1, cache.disk_cache()->open_count());
10549   EXPECT_EQ(1, cache.disk_cache()->create_count());
10550 
10551   // Verify that the disk entry was updated.
10552   MockHttpRequest request(transaction);
10553   VerifyTruncatedFlag(&cache, request.CacheKey(), false, 80);
10554 }
10555 
10556 // Tests the handling of no-store when revalidating a truncated entry.
TEST_F(HttpCacheTest,GET_IncompleteResource_NoStore)10557 TEST_F(HttpCacheTest, GET_IncompleteResource_NoStore) {
10558   MockHttpCache cache;
10559   AddMockTransaction(&kRangeGET_TransactionOK);
10560 
10561   std::string raw_headers("HTTP/1.1 200 OK\n"
10562                           "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10563                           "ETag: \"foo\"\n"
10564                           "Accept-Ranges: bytes\n"
10565                           "Content-Length: 80\n");
10566   CreateTruncatedEntry(raw_headers, &cache);
10567   RemoveMockTransaction(&kRangeGET_TransactionOK);
10568 
10569   // Now make a regular request.
10570   MockTransaction transaction(kRangeGET_TransactionOK);
10571   transaction.request_headers = EXTRA_HEADER;
10572   std::string response_headers(transaction.response_headers);
10573   response_headers += ("Cache-Control: no-store\n");
10574   transaction.response_headers = response_headers.c_str();
10575   transaction.data = kFullRangeData;
10576   AddMockTransaction(&transaction);
10577 
10578   std::string headers;
10579   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
10580 
10581   // We update the headers with the ones received while revalidating.
10582   std::string expected_headers(
10583       "HTTP/1.1 200 OK\n"
10584       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10585       "Accept-Ranges: bytes\n"
10586       "Cache-Control: no-store\n"
10587       "ETag: \"foo\"\n"
10588       "Content-Length: 80\n");
10589 
10590   EXPECT_EQ(expected_headers, headers);
10591   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10592   EXPECT_EQ(1, cache.disk_cache()->open_count());
10593   EXPECT_EQ(1, cache.disk_cache()->create_count());
10594 
10595   // Verify that the disk entry was deleted.
10596   disk_cache::Entry* entry;
10597   MockHttpRequest request(transaction);
10598   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
10599   RemoveMockTransaction(&transaction);
10600 }
10601 
10602 // Tests cancelling a request after the server sent no-store.
TEST_F(HttpCacheTest,GET_IncompleteResource_Cancel)10603 TEST_F(HttpCacheTest, GET_IncompleteResource_Cancel) {
10604   MockHttpCache cache;
10605   AddMockTransaction(&kRangeGET_TransactionOK);
10606 
10607   std::string raw_headers("HTTP/1.1 200 OK\n"
10608                           "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10609                           "ETag: \"foo\"\n"
10610                           "Accept-Ranges: bytes\n"
10611                           "Content-Length: 80\n");
10612   CreateTruncatedEntry(raw_headers, &cache);
10613   RemoveMockTransaction(&kRangeGET_TransactionOK);
10614 
10615   // Now make a regular request.
10616   MockTransaction transaction(kRangeGET_TransactionOK);
10617   transaction.request_headers = EXTRA_HEADER;
10618   std::string response_headers(transaction.response_headers);
10619   response_headers += ("Cache-Control: no-store\n");
10620   transaction.response_headers = response_headers.c_str();
10621   transaction.data = kFullRangeData;
10622   AddMockTransaction(&transaction);
10623 
10624   MockHttpRequest request(transaction);
10625   auto c = std::make_unique<Context>();
10626 
10627   int rv = cache.CreateTransaction(&c->trans);
10628   ASSERT_THAT(rv, IsOk());
10629 
10630   // Queue another request to this transaction. We have to start this request
10631   // before the first one gets the response from the server and dooms the entry,
10632   // otherwise it will just create a new entry without being queued to the first
10633   // request.
10634   auto pending = std::make_unique<Context>();
10635   ASSERT_THAT(cache.CreateTransaction(&pending->trans), IsOk());
10636 
10637   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10638   EXPECT_EQ(ERR_IO_PENDING,
10639             pending->trans->Start(&request, pending->callback.callback(),
10640                                   NetLogWithSource()));
10641   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10642 
10643   // Make sure that the entry has some data stored.
10644   scoped_refptr<IOBufferWithSize> buf =
10645       base::MakeRefCounted<IOBufferWithSize>(5);
10646   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10647   EXPECT_EQ(5, c->callback.GetResult(rv));
10648 
10649   // Since |pending| is currently validating the already written headers
10650   // it will be restarted as well.
10651   c.reset();
10652   pending.reset();
10653 
10654   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10655   EXPECT_EQ(1, cache.disk_cache()->open_count());
10656   EXPECT_EQ(1, cache.disk_cache()->create_count());
10657 
10658   base::RunLoop().RunUntilIdle();
10659   RemoveMockTransaction(&transaction);
10660 }
10661 
10662 // Tests that we delete truncated entries if the server changes its mind midway.
TEST_F(HttpCacheTest,GET_IncompleteResource2)10663 TEST_F(HttpCacheTest, GET_IncompleteResource2) {
10664   MockHttpCache cache;
10665   AddMockTransaction(&kRangeGET_TransactionOK);
10666 
10667   // Content-length will be intentionally bad.
10668   std::string raw_headers("HTTP/1.1 200 OK\n"
10669                           "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10670                           "ETag: \"foo\"\n"
10671                           "Accept-Ranges: bytes\n"
10672                           "Content-Length: 50\n");
10673   CreateTruncatedEntry(raw_headers, &cache);
10674 
10675   // Now make a regular request. We expect the code to fail the validation and
10676   // retry the request without using byte ranges.
10677   std::string headers;
10678   MockTransaction transaction(kRangeGET_TransactionOK);
10679   transaction.request_headers = EXTRA_HEADER;
10680   transaction.data = "Not a range";
10681   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
10682 
10683   // The server will return 200 instead of a byte range.
10684   std::string expected_headers(
10685       "HTTP/1.1 200 OK\n"
10686       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n");
10687 
10688   EXPECT_EQ(expected_headers, headers);
10689   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10690   EXPECT_EQ(1, cache.disk_cache()->open_count());
10691   EXPECT_EQ(1, cache.disk_cache()->create_count());
10692 
10693   // Verify that the disk entry was deleted.
10694   disk_cache::Entry* entry;
10695   MockHttpRequest request(transaction);
10696   ASSERT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
10697   RemoveMockTransaction(&kRangeGET_TransactionOK);
10698 }
10699 
10700 // Tests that we always validate a truncated request.
TEST_F(HttpCacheTest,GET_IncompleteResource3)10701 TEST_F(HttpCacheTest, GET_IncompleteResource3) {
10702   MockHttpCache cache;
10703   AddMockTransaction(&kRangeGET_TransactionOK);
10704 
10705   // This should not require validation for 10 hours.
10706   std::string raw_headers("HTTP/1.1 200 OK\n"
10707                           "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
10708                           "ETag: \"foo\"\n"
10709                           "Cache-Control: max-age= 36000\n"
10710                           "Accept-Ranges: bytes\n"
10711                           "Content-Length: 80\n");
10712   CreateTruncatedEntry(raw_headers, &cache);
10713 
10714   // Now make a regular request.
10715   std::string headers;
10716   MockTransaction transaction(kRangeGET_TransactionOK);
10717   transaction.request_headers = EXTRA_HEADER;
10718   transaction.data = kFullRangeData;
10719 
10720   auto c = std::make_unique<Context>();
10721   int rv = cache.CreateTransaction(&c->trans);
10722   ASSERT_THAT(rv, IsOk());
10723 
10724   MockHttpRequest request(transaction);
10725   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10726   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10727 
10728   // We should have checked with the server before finishing Start().
10729   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10730   EXPECT_EQ(1, cache.disk_cache()->open_count());
10731   EXPECT_EQ(1, cache.disk_cache()->create_count());
10732 
10733   RemoveMockTransaction(&kRangeGET_TransactionOK);
10734 }
10735 
10736 // Tests that we handle 401s for truncated resources.
TEST_F(HttpCacheTest,GET_IncompleteResourceWithAuth)10737 TEST_F(HttpCacheTest, GET_IncompleteResourceWithAuth) {
10738   MockHttpCache cache;
10739   AddMockTransaction(&kRangeGET_TransactionOK);
10740 
10741   std::string raw_headers("HTTP/1.1 200 OK\n"
10742                           "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10743                           "ETag: \"foo\"\n"
10744                           "Accept-Ranges: bytes\n"
10745                           "Content-Length: 80\n");
10746   CreateTruncatedEntry(raw_headers, &cache);
10747 
10748   // Now make a regular request.
10749   MockTransaction transaction(kRangeGET_TransactionOK);
10750   transaction.request_headers = "X-Require-Mock-Auth: dummy\r\n"
10751                                 EXTRA_HEADER;
10752   transaction.data = kFullRangeData;
10753   RangeTransactionServer handler;
10754 
10755   auto c = std::make_unique<Context>();
10756   int rv = cache.CreateTransaction(&c->trans);
10757   ASSERT_THAT(rv, IsOk());
10758 
10759   MockHttpRequest request(transaction);
10760   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10761   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10762 
10763   const HttpResponseInfo* response = c->trans->GetResponseInfo();
10764   ASSERT_TRUE(response);
10765   ASSERT_EQ(401, response->headers->response_code());
10766   rv = c->trans->RestartWithAuth(AuthCredentials(), c->callback.callback());
10767   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10768   response = c->trans->GetResponseInfo();
10769   ASSERT_TRUE(response);
10770   ASSERT_EQ(200, response->headers->response_code());
10771 
10772   ReadAndVerifyTransaction(c->trans.get(), transaction);
10773   c.reset();  // The destructor could delete the entry.
10774   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10775 
10776   // Verify that the entry was deleted.
10777   disk_cache::Entry* entry;
10778   ASSERT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &entry));
10779   entry->Close();
10780 
10781   RemoveMockTransaction(&kRangeGET_TransactionOK);
10782 }
10783 
10784 // Test that the transaction won't retry failed partial requests
10785 // after it starts reading data.  http://crbug.com/474835
TEST_F(HttpCacheTest,TransactionRetryLimit)10786 TEST_F(HttpCacheTest, TransactionRetryLimit) {
10787   MockHttpCache cache;
10788 
10789   // Cache 0-9, so that we have data to read before failing.
10790   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10791   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
10792   transaction.data = "rg: 00-09 ";
10793 
10794   // Write to the cache.
10795   RunTransactionTest(cache.http_cache(), transaction);
10796   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10797 
10798   // And now read from the cache and the network.  10-19 will get a
10799   // 401, but will have already returned 0-9.
10800   // We do not set X-Require-Mock-Auth because that causes the mock
10801   // network transaction to become IsReadyToRestartForAuth().
10802   transaction.request_headers =
10803       "Range: bytes = 0-79\r\n"
10804       "X-Require-Mock-Auth-Alt: dummy\r\n" EXTRA_HEADER;
10805 
10806   auto c = std::make_unique<Context>();
10807   int rv = cache.CreateTransaction(&c->trans);
10808   ASSERT_THAT(rv, IsOk());
10809 
10810   MockHttpRequest request(transaction);
10811 
10812   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10813   if (rv == ERR_IO_PENDING)
10814     rv = c->callback.WaitForResult();
10815   std::string content;
10816   rv = ReadTransaction(c->trans.get(), &content);
10817   EXPECT_THAT(rv, IsError(ERR_CACHE_AUTH_FAILURE_AFTER_READ));
10818 }
10819 
10820 // Tests that we cache a 200 response to the validation request.
TEST_F(HttpCacheTest,GET_IncompleteResource4)10821 TEST_F(HttpCacheTest, GET_IncompleteResource4) {
10822   MockHttpCache cache;
10823   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10824 
10825   std::string raw_headers("HTTP/1.1 200 OK\n"
10826                           "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
10827                           "ETag: \"foo\"\n"
10828                           "Accept-Ranges: bytes\n"
10829                           "Content-Length: 80\n");
10830   CreateTruncatedEntry(raw_headers, &cache);
10831 
10832   // Now make a regular request.
10833   std::string headers;
10834   transaction.request_headers = EXTRA_HEADER;
10835   transaction.data = "Not a range";
10836   RangeTransactionServer handler;
10837   handler.set_bad_200(true);
10838   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
10839 
10840   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10841   EXPECT_EQ(1, cache.disk_cache()->open_count());
10842   EXPECT_EQ(1, cache.disk_cache()->create_count());
10843 
10844   // Verify that the disk entry was updated.
10845   MockHttpRequest request(transaction);
10846   VerifyTruncatedFlag(&cache, request.CacheKey(), false, 11);
10847 }
10848 
10849 // Tests that when we cancel a request that was interrupted, we mark it again
10850 // as truncated.
TEST_F(HttpCacheTest,GET_CancelIncompleteResource)10851 TEST_F(HttpCacheTest, GET_CancelIncompleteResource) {
10852   MockHttpCache cache;
10853   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10854 
10855   std::string raw_headers("HTTP/1.1 200 OK\n"
10856                           "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
10857                           "ETag: \"foo\"\n"
10858                           "Accept-Ranges: bytes\n"
10859                           "Content-Length: 80\n");
10860   CreateTruncatedEntry(raw_headers, &cache);
10861 
10862   // Now make a regular request.
10863   transaction.request_headers = EXTRA_HEADER;
10864 
10865   MockHttpRequest request(transaction);
10866   auto c = std::make_unique<Context>();
10867   int rv = cache.CreateTransaction(&c->trans);
10868   ASSERT_THAT(rv, IsOk());
10869 
10870   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10871   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10872 
10873   // Read 20 bytes from the cache, and 10 from the net.
10874   auto buf = base::MakeRefCounted<IOBufferWithSize>(100);
10875   rv = c->trans->Read(buf.get(), 20, c->callback.callback());
10876   EXPECT_EQ(20, c->callback.GetResult(rv));
10877   rv = c->trans->Read(buf.get(), 10, c->callback.callback());
10878   EXPECT_EQ(10, c->callback.GetResult(rv));
10879 
10880   // At this point, we are already reading so canceling the request should leave
10881   // a truncated one.
10882   c.reset();
10883 
10884   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10885   EXPECT_EQ(1, cache.disk_cache()->open_count());
10886   EXPECT_EQ(1, cache.disk_cache()->create_count());
10887 
10888   // Verify that the disk entry was updated: now we have 30 bytes.
10889   VerifyTruncatedFlag(&cache, request.CacheKey(), true, 30);
10890 }
10891 
10892 // Tests that we can handle range requests when we have a truncated entry.
TEST_F(HttpCacheTest,RangeGET_IncompleteResource)10893 TEST_F(HttpCacheTest, RangeGET_IncompleteResource) {
10894   MockHttpCache cache;
10895   AddMockTransaction(&kRangeGET_TransactionOK);
10896 
10897   // Content-length will be intentionally bogus.
10898   std::string raw_headers("HTTP/1.1 200 OK\n"
10899                           "Last-Modified: something\n"
10900                           "ETag: \"foo\"\n"
10901                           "Accept-Ranges: bytes\n"
10902                           "Content-Length: 10\n");
10903   CreateTruncatedEntry(raw_headers, &cache);
10904 
10905   // Now make a range request.
10906   std::string headers;
10907   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
10908                                  &headers);
10909 
10910   Verify206Response(headers, 40, 49);
10911   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10912   EXPECT_EQ(1, cache.disk_cache()->open_count());
10913   EXPECT_EQ(2, cache.disk_cache()->create_count());
10914 
10915   RemoveMockTransaction(&kRangeGET_TransactionOK);
10916 }
10917 
TEST_F(HttpCacheTest,SyncRead)10918 TEST_F(HttpCacheTest, SyncRead) {
10919   MockHttpCache cache;
10920 
10921   // This test ensures that a read that completes synchronously does not cause
10922   // any problems.
10923 
10924   ScopedMockTransaction transaction(kSimpleGET_Transaction);
10925   transaction.test_mode |= (TEST_MODE_SYNC_CACHE_START |
10926                             TEST_MODE_SYNC_CACHE_READ |
10927                             TEST_MODE_SYNC_CACHE_WRITE);
10928 
10929   MockHttpRequest r1(transaction),
10930                   r2(transaction),
10931                   r3(transaction);
10932 
10933   TestTransactionConsumer c1(DEFAULT_PRIORITY, cache.http_cache()),
10934       c2(DEFAULT_PRIORITY, cache.http_cache()),
10935       c3(DEFAULT_PRIORITY, cache.http_cache());
10936 
10937   c1.Start(&r1, NetLogWithSource());
10938 
10939   r2.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
10940   c2.Start(&r2, NetLogWithSource());
10941 
10942   r3.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
10943   c3.Start(&r3, NetLogWithSource());
10944 
10945   base::RunLoop().Run();
10946 
10947   EXPECT_TRUE(c1.is_done());
10948   EXPECT_TRUE(c2.is_done());
10949   EXPECT_TRUE(c3.is_done());
10950 
10951   EXPECT_THAT(c1.error(), IsOk());
10952   EXPECT_THAT(c2.error(), IsOk());
10953   EXPECT_THAT(c3.error(), IsOk());
10954 }
10955 
TEST_F(HttpCacheTest,ValidationResultsIn200)10956 TEST_F(HttpCacheTest, ValidationResultsIn200) {
10957   MockHttpCache cache;
10958 
10959   // This test ensures that a conditional request, which results in a 200
10960   // instead of a 304, properly truncates the existing response data.
10961 
10962   // write to the cache
10963   RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
10964 
10965   // force this transaction to validate the cache
10966   MockTransaction transaction(kETagGET_Transaction);
10967   transaction.load_flags |= LOAD_VALIDATE_CACHE;
10968   RunTransactionTest(cache.http_cache(), transaction);
10969 
10970   // read from the cache
10971   RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
10972 }
10973 
TEST_F(HttpCacheTest,CachedRedirect)10974 TEST_F(HttpCacheTest, CachedRedirect) {
10975   MockHttpCache cache;
10976 
10977   ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction);
10978   kTestTransaction.status = "HTTP/1.1 301 Moved Permanently";
10979   kTestTransaction.response_headers = "Location: http://www.bar.com/\n";
10980 
10981   MockHttpRequest request(kTestTransaction);
10982   TestCompletionCallback callback;
10983 
10984   // Write to the cache.
10985   {
10986     std::unique_ptr<HttpTransaction> trans;
10987     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
10988 
10989     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
10990     if (rv == ERR_IO_PENDING)
10991       rv = callback.WaitForResult();
10992     ASSERT_THAT(rv, IsOk());
10993 
10994     const HttpResponseInfo* info = trans->GetResponseInfo();
10995     ASSERT_TRUE(info);
10996 
10997     EXPECT_EQ(info->headers->response_code(), 301);
10998 
10999     std::string location;
11000     info->headers->EnumerateHeader(nullptr, "Location", &location);
11001     EXPECT_EQ(location, "http://www.bar.com/");
11002 
11003     // Mark the transaction as completed so it is cached.
11004     trans->DoneReading();
11005 
11006     // Destroy transaction when going out of scope. We have not actually
11007     // read the response body -- want to test that it is still getting cached.
11008   }
11009   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11010   EXPECT_EQ(0, cache.disk_cache()->open_count());
11011   EXPECT_EQ(1, cache.disk_cache()->create_count());
11012 
11013   // Active entries in the cache are not retired synchronously. Make
11014   // sure the next run hits the MockHttpCache and open_count is
11015   // correct.
11016   base::RunLoop().RunUntilIdle();
11017 
11018   // Read from the cache.
11019   {
11020     std::unique_ptr<HttpTransaction> trans;
11021     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11022 
11023     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11024     if (rv == ERR_IO_PENDING)
11025       rv = callback.WaitForResult();
11026     ASSERT_THAT(rv, IsOk());
11027 
11028     const HttpResponseInfo* info = trans->GetResponseInfo();
11029     ASSERT_TRUE(info);
11030 
11031     EXPECT_EQ(info->headers->response_code(), 301);
11032 
11033     std::string location;
11034     info->headers->EnumerateHeader(nullptr, "Location", &location);
11035     EXPECT_EQ(location, "http://www.bar.com/");
11036 
11037     // Mark the transaction as completed so it is cached.
11038     trans->DoneReading();
11039 
11040     // Destroy transaction when going out of scope. We have not actually
11041     // read the response body -- want to test that it is still getting cached.
11042   }
11043   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11044   EXPECT_EQ(1, cache.disk_cache()->open_count());
11045   EXPECT_EQ(1, cache.disk_cache()->create_count());
11046 }
11047 
11048 // Verify that no-cache resources are stored in cache, but are not fetched from
11049 // cache during normal loads.
TEST_F(HttpCacheTest,CacheControlNoCacheNormalLoad)11050 TEST_F(HttpCacheTest, CacheControlNoCacheNormalLoad) {
11051   for (bool use_memory_entry_data : {false, true}) {
11052     MockHttpCache cache;
11053     cache.disk_cache()->set_support_in_memory_entry_data(use_memory_entry_data);
11054 
11055     ScopedMockTransaction transaction(kSimpleGET_Transaction);
11056     transaction.response_headers = "cache-control: no-cache\n";
11057 
11058     // Initial load.
11059     RunTransactionTest(cache.http_cache(), transaction);
11060 
11061     EXPECT_EQ(1, cache.network_layer()->transaction_count());
11062     EXPECT_EQ(0, cache.disk_cache()->open_count());
11063     EXPECT_EQ(1, cache.disk_cache()->create_count());
11064 
11065     // Try loading again; it should result in a network fetch.
11066     RunTransactionTest(cache.http_cache(), transaction);
11067 
11068     EXPECT_EQ(2, cache.network_layer()->transaction_count());
11069     if (use_memory_entry_data) {
11070       EXPECT_EQ(0, cache.disk_cache()->open_count());
11071       EXPECT_EQ(2, cache.disk_cache()->create_count());
11072     } else {
11073       EXPECT_EQ(1, cache.disk_cache()->open_count());
11074       EXPECT_EQ(1, cache.disk_cache()->create_count());
11075     }
11076 
11077     disk_cache::Entry* entry;
11078     MockHttpRequest request(transaction);
11079     EXPECT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &entry));
11080     entry->Close();
11081   }
11082 }
11083 
11084 // Verify that no-cache resources are stored in cache and fetched from cache
11085 // when the LOAD_SKIP_CACHE_VALIDATION flag is set.
TEST_F(HttpCacheTest,CacheControlNoCacheHistoryLoad)11086 TEST_F(HttpCacheTest, CacheControlNoCacheHistoryLoad) {
11087   MockHttpCache cache;
11088 
11089   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11090   transaction.response_headers = "cache-control: no-cache\n";
11091 
11092   // Initial load.
11093   RunTransactionTest(cache.http_cache(), transaction);
11094 
11095   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11096   EXPECT_EQ(0, cache.disk_cache()->open_count());
11097   EXPECT_EQ(1, cache.disk_cache()->create_count());
11098 
11099   // Try loading again with LOAD_SKIP_CACHE_VALIDATION.
11100   transaction.load_flags = LOAD_SKIP_CACHE_VALIDATION;
11101   RunTransactionTest(cache.http_cache(), transaction);
11102 
11103   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11104   EXPECT_EQ(1, cache.disk_cache()->open_count());
11105   EXPECT_EQ(1, cache.disk_cache()->create_count());
11106 
11107   disk_cache::Entry* entry;
11108   MockHttpRequest request(transaction);
11109   EXPECT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &entry));
11110   entry->Close();
11111 }
11112 
TEST_F(HttpCacheTest,CacheControlNoStore)11113 TEST_F(HttpCacheTest, CacheControlNoStore) {
11114   MockHttpCache cache;
11115 
11116   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11117   transaction.response_headers = "cache-control: no-store\n";
11118 
11119   // initial load
11120   RunTransactionTest(cache.http_cache(), transaction);
11121 
11122   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11123   EXPECT_EQ(0, cache.disk_cache()->open_count());
11124   EXPECT_EQ(1, cache.disk_cache()->create_count());
11125 
11126   // try loading again; it should result in a network fetch
11127   RunTransactionTest(cache.http_cache(), transaction);
11128 
11129   EXPECT_EQ(2, cache.network_layer()->transaction_count());
11130   EXPECT_EQ(0, cache.disk_cache()->open_count());
11131   EXPECT_EQ(2, cache.disk_cache()->create_count());
11132 
11133   disk_cache::Entry* entry;
11134   MockHttpRequest request(transaction);
11135   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
11136 }
11137 
TEST_F(HttpCacheTest,CacheControlNoStore2)11138 TEST_F(HttpCacheTest, CacheControlNoStore2) {
11139   // this test is similar to the above test, except that the initial response
11140   // is cachable, but when it is validated, no-store is received causing the
11141   // cached document to be deleted.
11142   MockHttpCache cache;
11143 
11144   ScopedMockTransaction transaction(kETagGET_Transaction);
11145 
11146   // initial load
11147   RunTransactionTest(cache.http_cache(), transaction);
11148 
11149   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11150   EXPECT_EQ(0, cache.disk_cache()->open_count());
11151   EXPECT_EQ(1, cache.disk_cache()->create_count());
11152 
11153   // try loading again; it should result in a network fetch
11154   transaction.load_flags = LOAD_VALIDATE_CACHE;
11155   transaction.response_headers = "cache-control: no-store\n";
11156   RunTransactionTest(cache.http_cache(), transaction);
11157 
11158   EXPECT_EQ(2, cache.network_layer()->transaction_count());
11159   EXPECT_EQ(1, cache.disk_cache()->open_count());
11160   EXPECT_EQ(1, cache.disk_cache()->create_count());
11161 
11162   disk_cache::Entry* entry;
11163   MockHttpRequest request(transaction);
11164   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
11165 }
11166 
TEST_F(HttpCacheTest,CacheControlNoStore3)11167 TEST_F(HttpCacheTest, CacheControlNoStore3) {
11168   // this test is similar to the above test, except that the response is a 304
11169   // instead of a 200.  this should never happen in practice, but it seems like
11170   // a good thing to verify that we still destroy the cache entry.
11171   MockHttpCache cache;
11172 
11173   ScopedMockTransaction transaction(kETagGET_Transaction);
11174 
11175   // initial load
11176   RunTransactionTest(cache.http_cache(), transaction);
11177 
11178   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11179   EXPECT_EQ(0, cache.disk_cache()->open_count());
11180   EXPECT_EQ(1, cache.disk_cache()->create_count());
11181 
11182   // try loading again; it should result in a network fetch
11183   transaction.load_flags = LOAD_VALIDATE_CACHE;
11184   transaction.response_headers = "cache-control: no-store\n";
11185   transaction.status = "HTTP/1.1 304 Not Modified";
11186   RunTransactionTest(cache.http_cache(), transaction);
11187 
11188   EXPECT_EQ(2, cache.network_layer()->transaction_count());
11189   EXPECT_EQ(1, cache.disk_cache()->open_count());
11190   EXPECT_EQ(1, cache.disk_cache()->create_count());
11191 
11192   disk_cache::Entry* entry;
11193   MockHttpRequest request(transaction);
11194   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
11195 }
11196 
11197 // Ensure that we don't cache requests served over bad HTTPS.
TEST_F(HttpCacheTest,SimpleGET_SSLError)11198 TEST_F(HttpCacheTest, SimpleGET_SSLError) {
11199   MockHttpCache cache;
11200 
11201   MockTransaction transaction = kSimpleGET_Transaction;
11202   transaction.cert_status = CERT_STATUS_REVOKED;
11203   ScopedMockTransaction scoped_transaction(transaction);
11204 
11205   // write to the cache
11206   RunTransactionTest(cache.http_cache(), transaction);
11207 
11208   // Test that it was not cached.
11209   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
11210 
11211   MockHttpRequest request(transaction);
11212   TestCompletionCallback callback;
11213 
11214   std::unique_ptr<HttpTransaction> trans;
11215   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11216 
11217   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11218   if (rv == ERR_IO_PENDING)
11219     rv = callback.WaitForResult();
11220   ASSERT_THAT(rv, IsError(ERR_CACHE_MISS));
11221 }
11222 
11223 // Ensure that we don't crash by if left-behind transactions.
TEST_F(HttpCacheTest,OutlivedTransactions)11224 TEST_F(HttpCacheTest, OutlivedTransactions) {
11225   auto cache = std::make_unique<MockHttpCache>();
11226 
11227   std::unique_ptr<HttpTransaction> trans;
11228   EXPECT_THAT(cache->CreateTransaction(&trans), IsOk());
11229 
11230   cache.reset();
11231   trans.reset();
11232 }
11233 
11234 // Test that the disabled mode works.
TEST_F(HttpCacheTest,CacheDisabledMode)11235 TEST_F(HttpCacheTest, CacheDisabledMode) {
11236   MockHttpCache cache;
11237 
11238   // write to the cache
11239   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
11240 
11241   // go into disabled mode
11242   cache.http_cache()->set_mode(HttpCache::DISABLE);
11243 
11244   // force this transaction to write to the cache again
11245   MockTransaction transaction(kSimpleGET_Transaction);
11246 
11247   RunTransactionTest(cache.http_cache(), transaction);
11248 
11249   EXPECT_EQ(2, cache.network_layer()->transaction_count());
11250   EXPECT_EQ(0, cache.disk_cache()->open_count());
11251   EXPECT_EQ(1, cache.disk_cache()->create_count());
11252 }
11253 
11254 // Other tests check that the response headers of the cached response
11255 // get updated on 304. Here we specifically check that the
11256 // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
11257 // fields also gets updated.
11258 // http://crbug.com/20594.
TEST_F(HttpCacheTest,UpdatesRequestResponseTimeOn304)11259 TEST_F(HttpCacheTest, UpdatesRequestResponseTimeOn304) {
11260   MockHttpCache cache;
11261 
11262   const char kUrl[] = "http://foobar";
11263   const char kData[] = "body";
11264 
11265   MockTransaction mock_network_response = {nullptr};
11266   mock_network_response.url = kUrl;
11267 
11268   AddMockTransaction(&mock_network_response);
11269 
11270   // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
11271 
11272   MockTransaction request = {nullptr};
11273   request.url = kUrl;
11274   request.method = "GET";
11275   request.request_headers = "\r\n";
11276   request.data = kData;
11277 
11278   static const Response kNetResponse1 = {
11279     "HTTP/1.1 200 OK",
11280     "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
11281     "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
11282     kData
11283   };
11284 
11285   kNetResponse1.AssignTo(&mock_network_response);
11286 
11287   RunTransactionTest(cache.http_cache(), request);
11288 
11289   // Request |kUrl| again, this time validating the cache and getting
11290   // a 304 back.
11291 
11292   request.load_flags = LOAD_VALIDATE_CACHE;
11293 
11294   static const Response kNetResponse2 = {
11295     "HTTP/1.1 304 Not Modified",
11296     "Date: Wed, 22 Jul 2009 03:15:26 GMT\n",
11297     ""
11298   };
11299 
11300   kNetResponse2.AssignTo(&mock_network_response);
11301 
11302   base::Time request_time = base::Time() + base::Hours(1234);
11303   base::Time response_time = base::Time() + base::Hours(1235);
11304 
11305   mock_network_response.request_time = request_time;
11306   mock_network_response.response_time = response_time;
11307 
11308   HttpResponseInfo response;
11309   RunTransactionTestWithResponseInfo(cache.http_cache(), request, &response);
11310 
11311   // The request and response times should have been updated.
11312   EXPECT_EQ(request_time.ToInternalValue(),
11313             response.request_time.ToInternalValue());
11314   EXPECT_EQ(response_time.ToInternalValue(),
11315             response.response_time.ToInternalValue());
11316 
11317   EXPECT_EQ("HTTP/1.1 200 OK\n"
11318             "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
11319             "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
11320             ToSimpleString(response.headers));
11321 
11322   RemoveMockTransaction(&mock_network_response);
11323 }
11324 
TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,SplitCacheWithNetworkIsolationKey)11325 TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,
11326        SplitCacheWithNetworkIsolationKey) {
11327   MockHttpCache cache;
11328   HttpResponseInfo response;
11329 
11330   SchemefulSite site_a(GURL("http://a.com"));
11331   SchemefulSite site_b(GURL("http://b.com"));
11332   SchemefulSite site_data(GURL("data:text/html,<body>Hello World</body>"));
11333 
11334   MockHttpRequest trans_info = MockHttpRequest(kSimpleGET_Transaction);
11335   // Request with a.com as the top frame and subframe origins. This should
11336   // result in a cache miss.
11337   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11338   trans_info.network_anonymization_key =
11339       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11340   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11341                                 trans_info, &response);
11342   EXPECT_FALSE(response.was_cached);
11343 
11344   // The second request should result in a cache hit.
11345   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11346                                 trans_info, &response);
11347   EXPECT_TRUE(response.was_cached);
11348 
11349   // Now request with b.com as the subframe origin. It should result in a cache
11350   // miss.
11351   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_b);
11352   trans_info.network_anonymization_key =
11353       net::NetworkAnonymizationKey::CreateCrossSite(site_a);
11354   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11355                                 trans_info, &response);
11356   EXPECT_FALSE(response.was_cached);
11357 
11358   // The second request should result in a cache hit.
11359   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11360                                 trans_info, &response);
11361   EXPECT_TRUE(response.was_cached);
11362 
11363   // Another request with a.com as the top frame and subframe origin should
11364   // still result in a cache hit.
11365   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11366   trans_info.network_anonymization_key =
11367       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11368   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11369                                 trans_info, &response);
11370   EXPECT_TRUE(response.was_cached);
11371 
11372   // Now make a request with an opaque subframe site. It shouldn't cause
11373   // anything to be added to the cache when the NIK makes use of the frame site.
11374   // Note that we will use `site_b` as the top-level site so that this resource
11375   // won't be in the cache at first regardless of the NIK partitioning scheme.
11376   trans_info.network_isolation_key = NetworkIsolationKey(site_b, site_data);
11377   trans_info.network_anonymization_key =
11378       net::NetworkAnonymizationKey::CreateCrossSite(site_b);
11379   switch (GetParam()) {
11380     case SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled:
11381       EXPECT_EQ(absl::nullopt,
11382                 trans_info.network_isolation_key.ToCacheKeyString());
11383       break;
11384     case SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled:
11385       EXPECT_EQ("http://b.com _1",
11386                 trans_info.network_isolation_key.ToCacheKeyString().value());
11387       break;
11388     case SplitCacheTestCase::kSplitCacheNikFrameSiteSharedOpaqueEnabled:
11389       EXPECT_EQ("http://b.com _opaque",
11390                 trans_info.network_isolation_key.ToCacheKeyString().value());
11391       break;
11392     case SplitCacheTestCase::kSplitCacheDisabled:
11393       NOTREACHED_NORETURN();
11394   }
11395 
11396   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11397                                 trans_info, &response);
11398   EXPECT_FALSE(response.was_cached);
11399 
11400   // On the second request, expect a cache miss if the NIK uses the frame site.
11401   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11402                                 trans_info, &response);
11403   switch (GetParam()) {
11404     case SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled:
11405       EXPECT_FALSE(response.was_cached);
11406       break;
11407     case SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled:
11408     case SplitCacheTestCase::kSplitCacheNikFrameSiteSharedOpaqueEnabled:
11409       EXPECT_TRUE(response.was_cached);
11410       break;
11411     case SplitCacheTestCase::kSplitCacheDisabled:
11412       NOTREACHED_NORETURN();
11413   }
11414 
11415   // Verify that a post transaction with a data stream uses a separate key.
11416   const int64_t kUploadId = 1;  // Just a dummy value.
11417 
11418   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
11419   element_readers.push_back(
11420       std::make_unique<UploadBytesElementReader>("hello", 5));
11421   ElementsUploadDataStream upload_data_stream(std::move(element_readers),
11422                                               kUploadId);
11423 
11424   MockHttpRequest post_info = MockHttpRequest(kSimplePOST_Transaction);
11425   post_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11426   post_info.network_anonymization_key =
11427       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11428   post_info.upload_data_stream = &upload_data_stream;
11429 
11430   RunTransactionTestWithRequest(cache.http_cache(), kSimplePOST_Transaction,
11431                                 post_info, &response);
11432   EXPECT_FALSE(response.was_cached);
11433 }
11434 
TEST_F(HttpCacheTest,HttpCacheProfileThirdPartyCSS)11435 TEST_F(HttpCacheTest, HttpCacheProfileThirdPartyCSS) {
11436   base::HistogramTester histograms;
11437   MockHttpCache cache;
11438   HttpResponseInfo response;
11439 
11440   url::Origin origin_a = url::Origin::Create(GURL(kSimpleGET_Transaction.url));
11441   url::Origin origin_b = url::Origin::Create(GURL("http://b.com"));
11442   SchemefulSite site_a(origin_a);
11443   SchemefulSite site_b(origin_b);
11444 
11445   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11446   transaction.response_headers = "Content-Type: text/css\n";
11447 
11448   MockHttpRequest trans_info = MockHttpRequest(transaction);
11449 
11450   // Requesting with the same top-frame site should not count as third-party
11451   // but should still be recorded as CSS
11452   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11453   trans_info.network_anonymization_key =
11454       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11455   trans_info.possibly_top_frame_origin = origin_a;
11456 
11457   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11458                                 &response);
11459 
11460   histograms.ExpectTotalCount("HttpCache.Pattern", 1);
11461   histograms.ExpectTotalCount("HttpCache.Pattern.CSS", 1);
11462   histograms.ExpectTotalCount("HttpCache.Pattern.CSSThirdParty", 0);
11463 
11464   // Requesting with a different top-frame site should count as third-party
11465   // and recorded as CSS
11466   trans_info.network_isolation_key = NetworkIsolationKey(site_b, site_b);
11467   trans_info.network_anonymization_key =
11468       net::NetworkAnonymizationKey::CreateSameSite(site_b);
11469   trans_info.possibly_top_frame_origin = origin_b;
11470 
11471   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11472                                 &response);
11473   histograms.ExpectTotalCount("HttpCache.Pattern", 2);
11474   histograms.ExpectTotalCount("HttpCache.Pattern.CSS", 2);
11475   histograms.ExpectTotalCount("HttpCache.Pattern.CSSThirdParty", 1);
11476 }
11477 
TEST_F(HttpCacheTest,HttpCacheProfileThirdPartyJavaScript)11478 TEST_F(HttpCacheTest, HttpCacheProfileThirdPartyJavaScript) {
11479   base::HistogramTester histograms;
11480   MockHttpCache cache;
11481   HttpResponseInfo response;
11482 
11483   url::Origin origin_a = url::Origin::Create(GURL(kSimpleGET_Transaction.url));
11484   url::Origin origin_b = url::Origin::Create(GURL("http://b.com"));
11485   SchemefulSite site_a(origin_a);
11486   SchemefulSite site_b(origin_b);
11487 
11488   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11489   transaction.response_headers = "Content-Type: application/javascript\n";
11490 
11491   MockHttpRequest trans_info = MockHttpRequest(transaction);
11492 
11493   // Requesting with the same top-frame site should not count as third-party
11494   // but should still be recorded as JavaScript
11495   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11496   trans_info.network_anonymization_key =
11497       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11498   trans_info.possibly_top_frame_origin = origin_a;
11499 
11500   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11501                                 &response);
11502 
11503   histograms.ExpectTotalCount("HttpCache.Pattern", 1);
11504   histograms.ExpectTotalCount("HttpCache.Pattern.JavaScript", 1);
11505   histograms.ExpectTotalCount("HttpCache.Pattern.JavaScriptThirdParty", 0);
11506 
11507   // Requesting with a different top-frame site should count as third-party
11508   // and recorded as JavaScript
11509   trans_info.network_isolation_key = NetworkIsolationKey(site_b, site_b);
11510   trans_info.network_anonymization_key =
11511       net::NetworkAnonymizationKey::CreateSameSite(site_b);
11512   trans_info.possibly_top_frame_origin = origin_b;
11513 
11514   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11515                                 &response);
11516   histograms.ExpectTotalCount("HttpCache.Pattern", 2);
11517   histograms.ExpectTotalCount("HttpCache.Pattern.JavaScript", 2);
11518   histograms.ExpectTotalCount("HttpCache.Pattern.JavaScriptThirdParty", 1);
11519 }
11520 
TEST_F(HttpCacheTest,HttpCacheProfileThirdPartyFont)11521 TEST_F(HttpCacheTest, HttpCacheProfileThirdPartyFont) {
11522   base::HistogramTester histograms;
11523   MockHttpCache cache;
11524   HttpResponseInfo response;
11525 
11526   url::Origin origin_a = url::Origin::Create(GURL(kSimpleGET_Transaction.url));
11527   url::Origin origin_b = url::Origin::Create(GURL("http://b.com"));
11528   SchemefulSite site_a(origin_a);
11529   SchemefulSite site_b(origin_b);
11530 
11531   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11532   transaction.response_headers = "Content-Type: font/otf\n";
11533 
11534   MockHttpRequest trans_info = MockHttpRequest(transaction);
11535 
11536   // Requesting with the same top-frame site should not count as third-party
11537   // but should still be recorded as a font
11538   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11539   trans_info.network_anonymization_key =
11540       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11541   trans_info.possibly_top_frame_origin = origin_a;
11542 
11543   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11544                                 &response);
11545 
11546   histograms.ExpectTotalCount("HttpCache.Pattern", 1);
11547   histograms.ExpectTotalCount("HttpCache.Pattern.Font", 1);
11548   histograms.ExpectTotalCount("HttpCache.Pattern.FontThirdParty", 0);
11549 
11550   // Requesting with a different top-frame site should count as third-party
11551   // and recorded as a font
11552   trans_info.network_isolation_key = NetworkIsolationKey(site_b, site_b);
11553   trans_info.network_anonymization_key =
11554       net::NetworkAnonymizationKey::CreateSameSite(site_b);
11555   trans_info.possibly_top_frame_origin = origin_b;
11556 
11557   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11558                                 &response);
11559   histograms.ExpectTotalCount("HttpCache.Pattern", 2);
11560   histograms.ExpectTotalCount("HttpCache.Pattern.Font", 2);
11561   histograms.ExpectTotalCount("HttpCache.Pattern.FontThirdParty", 1);
11562 }
11563 
TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,SplitCache)11564 TEST_P(HttpCacheTest_SplitCacheFeatureEnabled, SplitCache) {
11565   MockHttpCache cache;
11566   HttpResponseInfo response;
11567 
11568   SchemefulSite site_a(GURL("http://a.com"));
11569   SchemefulSite site_b(GURL("http://b.com"));
11570   SchemefulSite site_data(GURL("data:text/html,<body>Hello World</body>"));
11571 
11572   // A request without a top frame origin shouldn't result in anything being
11573   // added to the cache.
11574   MockHttpRequest trans_info = MockHttpRequest(kSimpleGET_Transaction);
11575   trans_info.network_isolation_key = net::NetworkIsolationKey();
11576   trans_info.network_anonymization_key = net::NetworkAnonymizationKey();
11577   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11578                                 trans_info, &response);
11579   EXPECT_FALSE(response.was_cached);
11580 
11581   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11582                                 trans_info, &response);
11583   EXPECT_FALSE(response.was_cached);
11584 
11585   // Now request with a.com as the top frame origin. This should initially
11586   // result in a cache miss since the cached resource has a different top frame
11587   // origin.
11588   net::NetworkIsolationKey key_a(site_a, site_a);
11589   auto nak_a = net::NetworkAnonymizationKey::CreateSameSite(site_a);
11590   trans_info.network_isolation_key = key_a;
11591   trans_info.network_anonymization_key = nak_a;
11592   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11593                                 trans_info, &response);
11594   EXPECT_FALSE(response.was_cached);
11595 
11596   // The second request should result in a cache hit.
11597   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11598                                 trans_info, &response);
11599   EXPECT_TRUE(response.was_cached);
11600 
11601   // If the same resource with the same NIK is for a subframe document resource,
11602   // it should not be a cache hit.
11603   MockHttpRequest subframe_document_trans_info = trans_info;
11604   subframe_document_trans_info.is_subframe_document_resource = true;
11605   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11606                                 subframe_document_trans_info, &response);
11607   EXPECT_FALSE(response.was_cached);
11608 
11609   // Same request again should be a cache hit.
11610   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11611                                 subframe_document_trans_info, &response);
11612   EXPECT_TRUE(response.was_cached);
11613 
11614   // Now request with b.com as the top frame origin. It should be a cache miss.
11615   trans_info.network_isolation_key = NetworkIsolationKey(site_b, site_b);
11616   trans_info.network_anonymization_key =
11617       NetworkAnonymizationKey::CreateSameSite(site_b);
11618   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11619                                 trans_info, &response);
11620   EXPECT_FALSE(response.was_cached);
11621 
11622   // The second request should be a cache hit.
11623   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11624                                 trans_info, &response);
11625   EXPECT_TRUE(response.was_cached);
11626 
11627   // Another request for a.com should still result in a cache hit.
11628   trans_info.network_isolation_key = key_a;
11629   trans_info.network_anonymization_key = nak_a;
11630   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11631                                 trans_info, &response);
11632   EXPECT_TRUE(response.was_cached);
11633 
11634   // Now make a request with an opaque top frame origin. It shouldn't result in
11635   // a cache hit.
11636   trans_info.network_isolation_key = NetworkIsolationKey(site_data, site_data);
11637   trans_info.network_anonymization_key =
11638       NetworkAnonymizationKey::CreateSameSite(site_data);
11639   EXPECT_EQ(absl::nullopt, trans_info.network_isolation_key.ToCacheKeyString());
11640   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11641                                 trans_info, &response);
11642   EXPECT_FALSE(response.was_cached);
11643 
11644   // On the second request, it still shouldn't result in a cache hit.
11645   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11646                                 trans_info, &response);
11647   EXPECT_FALSE(response.was_cached);
11648 
11649   // Verify that a post transaction with a data stream uses a separate key.
11650   const int64_t kUploadId = 1;  // Just a dummy value.
11651 
11652   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
11653   element_readers.push_back(
11654       std::make_unique<UploadBytesElementReader>("hello", 5));
11655   ElementsUploadDataStream upload_data_stream(std::move(element_readers),
11656                                               kUploadId);
11657 
11658   MockHttpRequest post_info = MockHttpRequest(kSimplePOST_Transaction);
11659   post_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11660   post_info.network_anonymization_key =
11661       NetworkAnonymizationKey::CreateSameSite(site_a);
11662   post_info.upload_data_stream = &upload_data_stream;
11663 
11664   RunTransactionTestWithRequest(cache.http_cache(), kSimplePOST_Transaction,
11665                                 post_info, &response);
11666   EXPECT_FALSE(response.was_cached);
11667 }
11668 
TEST_F(HttpCacheTest,SplitCacheEnabledByDefault)11669 TEST_F(HttpCacheTest, SplitCacheEnabledByDefault) {
11670   HttpCache::ClearGlobalsForTesting();
11671   HttpCache::SplitCacheFeatureEnableByDefault();
11672   EXPECT_TRUE(HttpCache::IsSplitCacheEnabled());
11673 
11674   MockHttpCache cache;
11675   HttpResponseInfo response;
11676 
11677   SchemefulSite site_a(GURL("http://a.com"));
11678   SchemefulSite site_b(GURL("http://b.com"));
11679   MockHttpRequest trans_info = MockHttpRequest(kSimpleGET_Transaction);
11680   net::NetworkIsolationKey key_a(site_a, site_a);
11681   auto nak_a = net::NetworkAnonymizationKey::CreateSameSite(site_a);
11682   trans_info.network_isolation_key = key_a;
11683   trans_info.network_anonymization_key = nak_a;
11684   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11685                                 trans_info, &response);
11686   EXPECT_FALSE(response.was_cached);
11687 
11688   // Subsequent requests with the same NIK and different NIK will be a cache hit
11689   // and miss respectively.
11690   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11691                                 trans_info, &response);
11692   EXPECT_TRUE(response.was_cached);
11693 
11694   net::NetworkIsolationKey key_b(site_b, site_b);
11695   auto nak_b = net::NetworkAnonymizationKey::CreateSameSite(site_b);
11696   trans_info.network_isolation_key = key_b;
11697   trans_info.network_anonymization_key = nak_b;
11698   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11699                                 trans_info, &response);
11700   EXPECT_FALSE(response.was_cached);
11701 }
11702 
TEST_F(HttpCacheTest,SplitCacheEnabledByDefaultButOverridden)11703 TEST_F(HttpCacheTest, SplitCacheEnabledByDefaultButOverridden) {
11704   HttpCache::ClearGlobalsForTesting();
11705   base::test::ScopedFeatureList feature_list;
11706   feature_list.InitAndDisableFeature(
11707       net::features::kSplitCacheByNetworkIsolationKey);
11708 
11709   // Enabling it here should have no effect as it is already overridden.
11710   HttpCache::SplitCacheFeatureEnableByDefault();
11711   EXPECT_FALSE(HttpCache::IsSplitCacheEnabled());
11712 }
11713 
TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,SplitCacheUsesRegistrableDomain)11714 TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,
11715        SplitCacheUsesRegistrableDomain) {
11716   MockHttpCache cache;
11717   HttpResponseInfo response;
11718   MockHttpRequest trans_info = MockHttpRequest(kSimpleGET_Transaction);
11719 
11720   SchemefulSite site_a(GURL("http://a.foo.com"));
11721   SchemefulSite site_b(GURL("http://b.foo.com"));
11722 
11723   net::NetworkIsolationKey key_a(site_a, site_a);
11724   auto nak_a = net::NetworkAnonymizationKey::CreateSameSite(site_a);
11725   trans_info.network_isolation_key = key_a;
11726   trans_info.network_anonymization_key = nak_a;
11727   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11728                                 trans_info, &response);
11729   EXPECT_FALSE(response.was_cached);
11730 
11731   // The second request with a different origin but the same registrable domain
11732   // should be a cache hit.
11733   net::NetworkIsolationKey key_b(site_b, site_b);
11734   auto nak_b = net::NetworkAnonymizationKey::CreateSameSite(site_b);
11735   trans_info.network_isolation_key = key_b;
11736   trans_info.network_anonymization_key = nak_b;
11737   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11738                                 trans_info, &response);
11739   EXPECT_TRUE(response.was_cached);
11740 
11741   // Request with a different registrable domain. It should be a cache miss.
11742   SchemefulSite new_site_a(GURL("http://a.bar.com"));
11743   net::NetworkIsolationKey new_key_a(new_site_a, new_site_a);
11744   auto new_nak_a = net::NetworkAnonymizationKey::CreateSameSite(new_site_a);
11745   trans_info.network_isolation_key = new_key_a;
11746   trans_info.network_anonymization_key = new_nak_a;
11747   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11748                                 trans_info, &response);
11749   EXPECT_FALSE(response.was_cached);
11750 }
11751 
TEST_F(HttpCacheTest,NonSplitCache)11752 TEST_F(HttpCacheTest, NonSplitCache) {
11753   base::test::ScopedFeatureList feature_list;
11754   feature_list.InitAndDisableFeature(
11755       net::features::kSplitCacheByNetworkIsolationKey);
11756 
11757   MockHttpCache cache;
11758   HttpResponseInfo response;
11759 
11760   // A request without a top frame is added to the cache normally.
11761   MockHttpRequest trans_info = MockHttpRequest(kSimpleGET_Transaction);
11762   trans_info.network_isolation_key = NetworkIsolationKey();
11763   trans_info.network_anonymization_key = NetworkAnonymizationKey();
11764   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11765                                 trans_info, &response);
11766   EXPECT_FALSE(response.was_cached);
11767 
11768   // The second request should result in a cache hit.
11769   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11770                                 trans_info, &response);
11771   EXPECT_TRUE(response.was_cached);
11772 
11773   // Now request with a.com as the top frame origin. The same cached object
11774   // should be used.
11775   const SchemefulSite kSiteA(GURL("http://a.com/"));
11776   trans_info.network_isolation_key = NetworkIsolationKey(kSiteA, kSiteA);
11777   trans_info.network_anonymization_key =
11778       NetworkAnonymizationKey::CreateSameSite(kSiteA);
11779   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11780                                 trans_info, &response);
11781   EXPECT_TRUE(response.was_cached);
11782 }
11783 
TEST_F(HttpCacheTest,SkipVaryCheck)11784 TEST_F(HttpCacheTest, SkipVaryCheck) {
11785   MockHttpCache cache;
11786 
11787   // Write a simple vary transaction to the cache.
11788   HttpResponseInfo response;
11789   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11790   transaction.request_headers = "accept-encoding: gzip\r\n";
11791   transaction.response_headers =
11792       "Vary: accept-encoding\n"
11793       "Cache-Control: max-age=10000\n";
11794   RunTransactionTest(cache.http_cache(), transaction);
11795 
11796   // Change the request headers so that the request doesn't match due to vary.
11797   // The request should fail.
11798   transaction.load_flags = LOAD_ONLY_FROM_CACHE;
11799   transaction.request_headers = "accept-encoding: foo\r\n";
11800   transaction.start_return_code = ERR_CACHE_MISS;
11801   RunTransactionTest(cache.http_cache(), transaction);
11802 
11803   // Change the load flags to ignore vary checks, the request should now hit.
11804   transaction.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_VARY_CHECK;
11805   transaction.start_return_code = OK;
11806   RunTransactionTest(cache.http_cache(), transaction);
11807 }
11808 
TEST_F(HttpCacheTest,SkipVaryCheckStar)11809 TEST_F(HttpCacheTest, SkipVaryCheckStar) {
11810   MockHttpCache cache;
11811 
11812   // Write a simple vary:* transaction to the cache.
11813   HttpResponseInfo response;
11814   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11815   transaction.request_headers = "accept-encoding: gzip\r\n";
11816   transaction.response_headers =
11817       "Vary: *\n"
11818       "Cache-Control: max-age=10000\n";
11819   RunTransactionTest(cache.http_cache(), transaction);
11820 
11821   // The request shouldn't match even with the same request headers due to the
11822   // Vary: *. The request should fail.
11823   transaction.load_flags = LOAD_ONLY_FROM_CACHE;
11824   transaction.start_return_code = ERR_CACHE_MISS;
11825   RunTransactionTest(cache.http_cache(), transaction);
11826 
11827   // Change the load flags to ignore vary checks, the request should now hit.
11828   transaction.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_VARY_CHECK;
11829   transaction.start_return_code = OK;
11830   RunTransactionTest(cache.http_cache(), transaction);
11831 }
11832 
11833 // Tests that we only return valid entries with LOAD_ONLY_FROM_CACHE
11834 // transactions unless LOAD_SKIP_CACHE_VALIDATION is set.
TEST_F(HttpCacheTest,ValidLoadOnlyFromCache)11835 TEST_F(HttpCacheTest, ValidLoadOnlyFromCache) {
11836   MockHttpCache cache;
11837   base::SimpleTestClock clock;
11838   cache.http_cache()->SetClockForTesting(&clock);
11839   cache.network_layer()->SetClock(&clock);
11840 
11841   // Write a resource that will expire in 100 seconds.
11842   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11843   transaction.response_headers = "Cache-Control: max-age=100\n";
11844   RunTransactionTest(cache.http_cache(), transaction);
11845 
11846   // Move forward in time such that the cached response is no longer valid.
11847   clock.Advance(base::Seconds(101));
11848 
11849   // Skipping cache validation should still return a response.
11850   transaction.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
11851   RunTransactionTest(cache.http_cache(), transaction);
11852 
11853   // If the cache entry is checked for validitiy, it should fail.
11854   transaction.load_flags = LOAD_ONLY_FROM_CACHE;
11855   transaction.start_return_code = ERR_CACHE_MISS;
11856   RunTransactionTest(cache.http_cache(), transaction);
11857 }
11858 
TEST_F(HttpCacheTest,InvalidLoadFlagCombination)11859 TEST_F(HttpCacheTest, InvalidLoadFlagCombination) {
11860   MockHttpCache cache;
11861 
11862   // Put the resource in the cache.
11863   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
11864 
11865   // Now try to fetch it again, but with a flag combination disallowing both
11866   // cache and network access.
11867   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11868   // DevTools relies on this combination of flags for "disable cache" mode
11869   // when a resource is only supposed to be loaded from cache.
11870   transaction.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_BYPASS_CACHE;
11871   transaction.start_return_code = ERR_CACHE_MISS;
11872   RunTransactionTest(cache.http_cache(), transaction);
11873 }
11874 
11875 // Tests that we don't mark entries as truncated when a filter detects the end
11876 // of the stream.
TEST_F(HttpCacheTest,FilterCompletion)11877 TEST_F(HttpCacheTest, FilterCompletion) {
11878   MockHttpCache cache;
11879   TestCompletionCallback callback;
11880 
11881   {
11882     MockHttpRequest request(kSimpleGET_Transaction);
11883     std::unique_ptr<HttpTransaction> trans;
11884     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11885 
11886     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11887     EXPECT_THAT(callback.GetResult(rv), IsOk());
11888 
11889     auto buf = base::MakeRefCounted<IOBufferWithSize>(256);
11890     rv = trans->Read(buf.get(), 256, callback.callback());
11891     EXPECT_GT(callback.GetResult(rv), 0);
11892 
11893     // Now make sure that the entry is preserved.
11894     trans->DoneReading();
11895   }
11896 
11897   // Make sure that the ActiveEntry is gone.
11898   base::RunLoop().RunUntilIdle();
11899 
11900   // Read from the cache.
11901   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
11902 
11903   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11904   EXPECT_EQ(1, cache.disk_cache()->open_count());
11905   EXPECT_EQ(1, cache.disk_cache()->create_count());
11906 }
11907 
11908 // Tests that we don't mark entries as truncated and release the cache
11909 // entry when DoneReading() is called before any Read() calls, such as
11910 // for a redirect.
TEST_F(HttpCacheTest,DoneReading)11911 TEST_F(HttpCacheTest, DoneReading) {
11912   MockHttpCache cache;
11913   TestCompletionCallback callback;
11914 
11915   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11916   transaction.data = "";
11917   MockHttpRequest request(transaction);
11918 
11919   std::unique_ptr<HttpTransaction> trans;
11920   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11921 
11922   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11923   EXPECT_THAT(callback.GetResult(rv), IsOk());
11924 
11925   trans->DoneReading();
11926   // Leave the transaction around.
11927 
11928   // Make sure that the ActiveEntry is gone.
11929   base::RunLoop().RunUntilIdle();
11930 
11931   // Read from the cache. This should not deadlock.
11932   RunTransactionTest(cache.http_cache(), transaction);
11933 
11934   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11935   EXPECT_EQ(1, cache.disk_cache()->open_count());
11936   EXPECT_EQ(1, cache.disk_cache()->create_count());
11937 }
11938 
11939 // Tests that we stop caching when told.
TEST_F(HttpCacheTest,StopCachingDeletesEntry)11940 TEST_F(HttpCacheTest, StopCachingDeletesEntry) {
11941   MockHttpCache cache;
11942   TestCompletionCallback callback;
11943   MockHttpRequest request(kSimpleGET_Transaction);
11944 
11945   {
11946     std::unique_ptr<HttpTransaction> trans;
11947     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11948 
11949     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11950     EXPECT_THAT(callback.GetResult(rv), IsOk());
11951 
11952     auto buf = base::MakeRefCounted<IOBufferWithSize>(256);
11953     rv = trans->Read(buf.get(), 10, callback.callback());
11954     EXPECT_EQ(10, callback.GetResult(rv));
11955 
11956     trans->StopCaching();
11957 
11958     // We should be able to keep reading.
11959     rv = trans->Read(buf.get(), 256, callback.callback());
11960     EXPECT_GT(callback.GetResult(rv), 0);
11961     rv = trans->Read(buf.get(), 256, callback.callback());
11962     EXPECT_EQ(0, callback.GetResult(rv));
11963   }
11964 
11965   // Make sure that the ActiveEntry is gone.
11966   base::RunLoop().RunUntilIdle();
11967 
11968   // Verify that the entry is gone.
11969   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
11970 
11971   EXPECT_EQ(2, cache.network_layer()->transaction_count());
11972   EXPECT_EQ(0, cache.disk_cache()->open_count());
11973   EXPECT_EQ(2, cache.disk_cache()->create_count());
11974 }
11975 
11976 // Tests that we stop caching when told, even if DoneReading is called
11977 // after StopCaching.
TEST_F(HttpCacheTest,StopCachingThenDoneReadingDeletesEntry)11978 TEST_F(HttpCacheTest, StopCachingThenDoneReadingDeletesEntry) {
11979   MockHttpCache cache;
11980   TestCompletionCallback callback;
11981   MockHttpRequest request(kSimpleGET_Transaction);
11982 
11983   {
11984     std::unique_ptr<HttpTransaction> trans;
11985     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11986 
11987     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11988     EXPECT_THAT(callback.GetResult(rv), IsOk());
11989 
11990     auto buf = base::MakeRefCounted<IOBufferWithSize>(256);
11991     rv = trans->Read(buf.get(), 10, callback.callback());
11992     EXPECT_EQ(10, callback.GetResult(rv));
11993 
11994     trans->StopCaching();
11995 
11996     // We should be able to keep reading.
11997     rv = trans->Read(buf.get(), 256, callback.callback());
11998     EXPECT_GT(callback.GetResult(rv), 0);
11999     rv = trans->Read(buf.get(), 256, callback.callback());
12000     EXPECT_EQ(0, callback.GetResult(rv));
12001 
12002     // We should be able to call DoneReading.
12003     trans->DoneReading();
12004   }
12005 
12006   // Make sure that the ActiveEntry is gone.
12007   base::RunLoop().RunUntilIdle();
12008 
12009   // Verify that the entry is gone.
12010   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
12011 
12012   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12013   EXPECT_EQ(0, cache.disk_cache()->open_count());
12014   EXPECT_EQ(2, cache.disk_cache()->create_count());
12015 }
12016 
12017 // Tests that we stop caching when told, when using auth.
TEST_F(HttpCacheTest,StopCachingWithAuthDeletesEntry)12018 TEST_F(HttpCacheTest, StopCachingWithAuthDeletesEntry) {
12019   MockHttpCache cache;
12020   TestCompletionCallback callback;
12021   MockTransaction mock_transaction(kSimpleGET_Transaction);
12022   mock_transaction.status = "HTTP/1.1 401 Unauthorized";
12023   AddMockTransaction(&mock_transaction);
12024   MockHttpRequest request(mock_transaction);
12025 
12026   {
12027     std::unique_ptr<HttpTransaction> trans;
12028     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
12029 
12030     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
12031     EXPECT_THAT(callback.GetResult(rv), IsOk());
12032 
12033     trans->StopCaching();
12034   }
12035   RemoveMockTransaction(&mock_transaction);
12036 
12037   // Make sure that the ActiveEntry is gone.
12038   base::RunLoop().RunUntilIdle();
12039 
12040   // Verify that the entry is gone.
12041   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
12042 
12043   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12044   EXPECT_EQ(0, cache.disk_cache()->open_count());
12045   EXPECT_EQ(2, cache.disk_cache()->create_count());
12046 }
12047 
12048 // Tests that when we are told to stop caching we don't throw away valid data.
TEST_F(HttpCacheTest,StopCachingSavesEntry)12049 TEST_F(HttpCacheTest, StopCachingSavesEntry) {
12050   MockHttpCache cache;
12051   TestCompletionCallback callback;
12052   MockHttpRequest request(kSimpleGET_Transaction);
12053 
12054   {
12055     std::unique_ptr<HttpTransaction> trans;
12056     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
12057 
12058     // Force a response that can be resumed.
12059     ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
12060     AddMockTransaction(&mock_transaction);
12061     mock_transaction.response_headers = "Cache-Control: max-age=10000\n"
12062                                         "Content-Length: 42\n"
12063                                         "Etag: \"foo\"\n";
12064 
12065     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
12066     EXPECT_THAT(callback.GetResult(rv), IsOk());
12067 
12068     auto buf = base::MakeRefCounted<IOBufferWithSize>(256);
12069     rv = trans->Read(buf.get(), 10, callback.callback());
12070     EXPECT_EQ(callback.GetResult(rv), 10);
12071 
12072     trans->StopCaching();
12073 
12074     // We should be able to keep reading.
12075     rv = trans->Read(buf.get(), 256, callback.callback());
12076     EXPECT_GT(callback.GetResult(rv), 0);
12077     rv = trans->Read(buf.get(), 256, callback.callback());
12078     EXPECT_EQ(callback.GetResult(rv), 0);
12079   }
12080 
12081   // Verify that the entry is marked as incomplete.
12082   // VerifyTruncatedFlag(&cache, kSimpleGET_Transaction.url, true, 0);
12083   // Verify that the entry is doomed.
12084   cache.disk_cache()->IsDiskEntryDoomed(request.CacheKey());
12085 }
12086 
12087 // Tests that we handle truncated enries when StopCaching is called.
TEST_F(HttpCacheTest,StopCachingTruncatedEntry)12088 TEST_F(HttpCacheTest, StopCachingTruncatedEntry) {
12089   MockHttpCache cache;
12090   TestCompletionCallback callback;
12091   MockHttpRequest request(kRangeGET_TransactionOK);
12092   request.extra_headers.Clear();
12093   request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE);
12094   AddMockTransaction(&kRangeGET_TransactionOK);
12095 
12096   std::string raw_headers("HTTP/1.1 200 OK\n"
12097                           "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12098                           "ETag: \"foo\"\n"
12099                           "Accept-Ranges: bytes\n"
12100                           "Content-Length: 80\n");
12101   CreateTruncatedEntry(raw_headers, &cache);
12102 
12103   {
12104     // Now make a regular request.
12105     std::unique_ptr<HttpTransaction> trans;
12106     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
12107 
12108     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
12109     EXPECT_THAT(callback.GetResult(rv), IsOk());
12110 
12111     auto buf = base::MakeRefCounted<IOBufferWithSize>(256);
12112     rv = trans->Read(buf.get(), 10, callback.callback());
12113     EXPECT_EQ(callback.GetResult(rv), 10);
12114 
12115     // This is actually going to do nothing.
12116     trans->StopCaching();
12117 
12118     // We should be able to keep reading.
12119     rv = trans->Read(buf.get(), 256, callback.callback());
12120     EXPECT_GT(callback.GetResult(rv), 0);
12121     rv = trans->Read(buf.get(), 256, callback.callback());
12122     EXPECT_GT(callback.GetResult(rv), 0);
12123     rv = trans->Read(buf.get(), 256, callback.callback());
12124     EXPECT_EQ(callback.GetResult(rv), 0);
12125   }
12126 
12127   // Verify that the disk entry was updated.
12128   VerifyTruncatedFlag(&cache, request.CacheKey(), false, 80);
12129   RemoveMockTransaction(&kRangeGET_TransactionOK);
12130 }
12131 
12132 namespace {
12133 
12134 enum class TransactionPhase {
12135   BEFORE_FIRST_READ,
12136   AFTER_FIRST_READ,
12137   AFTER_NETWORK_READ
12138 };
12139 
12140 using CacheInitializer = void (*)(MockHttpCache*);
12141 using HugeCacheTestConfiguration =
12142     std::pair<TransactionPhase, CacheInitializer>;
12143 
12144 class HttpCacheHugeResourceTest
12145     : public ::testing::TestWithParam<HugeCacheTestConfiguration>,
12146       public WithTaskEnvironment {
12147  public:
12148   static std::list<HugeCacheTestConfiguration> GetTestModes();
12149   static std::list<HugeCacheTestConfiguration> kTestModes;
12150 
12151   // CacheInitializer callbacks. These are used to initialize the cache
12152   // depending on the test run configuration.
12153 
12154   // Initializes a cache containing a truncated entry containing the first 20
12155   // bytes of the reponse body.
12156   static void SetupTruncatedCacheEntry(MockHttpCache* cache);
12157 
12158   // Initializes a cache containing a sparse entry. The first 10 bytes are
12159   // present in the cache.
12160   static void SetupPrefixSparseCacheEntry(MockHttpCache* cache);
12161 
12162   // Initializes a cache containing a sparse entry. The 10 bytes at offset
12163   // 99990 are present in the cache.
12164   static void SetupInfixSparseCacheEntry(MockHttpCache* cache);
12165 
12166  protected:
12167   static void LargeResourceTransactionHandler(
12168       const net::HttpRequestInfo* request,
12169       std::string* response_status,
12170       std::string* response_headers,
12171       std::string* response_data);
12172   static int LargeBufferReader(int64_t content_length,
12173                                int64_t offset,
12174                                net::IOBuffer* buf,
12175                                int buf_len);
12176 
12177   static void SetFlagOnBeforeNetworkStart(bool* started, bool* /* defer */);
12178 
12179   // Size of resource to be tested.
12180   static const int64_t kTotalSize = 5000LL * 1000 * 1000;
12181 };
12182 
12183 const int64_t HttpCacheHugeResourceTest::kTotalSize;
12184 
12185 // static
LargeResourceTransactionHandler(const net::HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)12186 void HttpCacheHugeResourceTest::LargeResourceTransactionHandler(
12187     const net::HttpRequestInfo* request,
12188     std::string* response_status,
12189     std::string* response_headers,
12190     std::string* response_data) {
12191   std::string if_range;
12192   if (!request->extra_headers.GetHeader(net::HttpRequestHeaders::kIfRange,
12193                                         &if_range)) {
12194     // If there were no range headers in the request, we are going to just
12195     // return the entire response body.
12196     *response_status = "HTTP/1.1 200 Success";
12197     *response_headers = base::StringPrintf("Content-Length: %" PRId64
12198                                            "\n"
12199                                            "ETag: \"foo\"\n"
12200                                            "Accept-Ranges: bytes\n",
12201                                            kTotalSize);
12202     return;
12203   }
12204 
12205   // From this point on, we should be processing a valid byte-range request.
12206   EXPECT_EQ("\"foo\"", if_range);
12207 
12208   std::string range_header;
12209   EXPECT_TRUE(request->extra_headers.GetHeader(net::HttpRequestHeaders::kRange,
12210                                                &range_header));
12211   std::vector<net::HttpByteRange> ranges;
12212 
12213   EXPECT_TRUE(net::HttpUtil::ParseRangeHeader(range_header, &ranges));
12214   ASSERT_EQ(1u, ranges.size());
12215 
12216   net::HttpByteRange range = ranges[0];
12217   EXPECT_TRUE(range.HasFirstBytePosition());
12218   int64_t last_byte_position =
12219       range.HasLastBytePosition() ? range.last_byte_position() : kTotalSize - 1;
12220 
12221   *response_status = "HTTP/1.1 206 Partial";
12222   *response_headers = base::StringPrintf(
12223       "Content-Range: bytes %" PRId64 "-%" PRId64 "/%" PRId64
12224       "\n"
12225       "Content-Length: %" PRId64 "\n",
12226       range.first_byte_position(), last_byte_position, kTotalSize,
12227       last_byte_position - range.first_byte_position() + 1);
12228 }
12229 
12230 // static
LargeBufferReader(int64_t content_length,int64_t offset,net::IOBuffer * buf,int buf_len)12231 int HttpCacheHugeResourceTest::LargeBufferReader(int64_t content_length,
12232                                                  int64_t offset,
12233                                                  net::IOBuffer* buf,
12234                                                  int buf_len) {
12235   // This test involves reading multiple gigabytes of data. To make it run in a
12236   // reasonable amount of time, we are going to skip filling the buffer with
12237   // data. Instead the test relies on verifying that the count of bytes expected
12238   // at the end is correct.
12239   EXPECT_LT(0, content_length);
12240   EXPECT_LE(offset, content_length);
12241   int num = std::min(static_cast<int64_t>(buf_len), content_length - offset);
12242   return num;
12243 }
12244 
12245 // static
SetFlagOnBeforeNetworkStart(bool * started,bool *)12246 void HttpCacheHugeResourceTest::SetFlagOnBeforeNetworkStart(bool* started,
12247                                                             bool* /* defer */) {
12248   *started = true;
12249 }
12250 
12251 // static
SetupTruncatedCacheEntry(MockHttpCache * cache)12252 void HttpCacheHugeResourceTest::SetupTruncatedCacheEntry(MockHttpCache* cache) {
12253   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
12254   std::string cached_headers = base::StringPrintf(
12255       "HTTP/1.1 200 OK\n"
12256       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12257       "ETag: \"foo\"\n"
12258       "Accept-Ranges: bytes\n"
12259       "Content-Length: %" PRId64 "\n",
12260       kTotalSize);
12261   CreateTruncatedEntry(cached_headers, cache);
12262 }
12263 
12264 // static
SetupPrefixSparseCacheEntry(MockHttpCache * cache)12265 void HttpCacheHugeResourceTest::SetupPrefixSparseCacheEntry(
12266     MockHttpCache* cache) {
12267   MockTransaction transaction(kRangeGET_TransactionOK);
12268   transaction.handler = MockTransactionHandler();
12269   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
12270   transaction.response_headers =
12271       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12272       "ETag: \"foo\"\n"
12273       "Accept-Ranges: bytes\n"
12274       "Content-Range: bytes 0-9/5000000000\n"
12275       "Content-Length: 10\n";
12276   AddMockTransaction(&transaction);
12277   std::string headers;
12278   RunTransactionTestWithResponse(cache->http_cache(), transaction, &headers);
12279   RemoveMockTransaction(&transaction);
12280 }
12281 
12282 // static
SetupInfixSparseCacheEntry(MockHttpCache * cache)12283 void HttpCacheHugeResourceTest::SetupInfixSparseCacheEntry(
12284     MockHttpCache* cache) {
12285   MockTransaction transaction(kRangeGET_TransactionOK);
12286   transaction.handler = MockTransactionHandler();
12287   transaction.request_headers = "Range: bytes = 99990-99999\r\n" EXTRA_HEADER;
12288   transaction.response_headers =
12289       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12290       "ETag: \"foo\"\n"
12291       "Accept-Ranges: bytes\n"
12292       "Content-Range: bytes 99990-99999/5000000000\n"
12293       "Content-Length: 10\n";
12294   AddMockTransaction(&transaction);
12295   std::string headers;
12296   RunTransactionTestWithResponse(cache->http_cache(), transaction, &headers);
12297   RemoveMockTransaction(&transaction);
12298 }
12299 
12300 // static
12301 std::list<HugeCacheTestConfiguration>
GetTestModes()12302 HttpCacheHugeResourceTest::GetTestModes() {
12303   std::list<HugeCacheTestConfiguration> test_modes;
12304   const TransactionPhase kTransactionPhases[] = {
12305       TransactionPhase::BEFORE_FIRST_READ, TransactionPhase::AFTER_FIRST_READ,
12306       TransactionPhase::AFTER_NETWORK_READ};
12307   const CacheInitializer kInitializers[] = {&SetupTruncatedCacheEntry,
12308                                             &SetupPrefixSparseCacheEntry,
12309                                             &SetupInfixSparseCacheEntry};
12310 
12311   for (const auto phase : kTransactionPhases)
12312     for (const auto initializer : kInitializers)
12313       test_modes.emplace_back(phase, initializer);
12314 
12315   return test_modes;
12316 }
12317 
12318 // static
12319 std::list<HugeCacheTestConfiguration> HttpCacheHugeResourceTest::kTestModes =
12320     HttpCacheHugeResourceTest::GetTestModes();
12321 
12322 INSTANTIATE_TEST_SUITE_P(
12323     _,
12324     HttpCacheHugeResourceTest,
12325     ::testing::ValuesIn(HttpCacheHugeResourceTest::kTestModes));
12326 
12327 }  // namespace
12328 
12329 // Test what happens when StopCaching() is called while reading a huge resource
12330 // fetched via GET. Various combinations of cache state and when StopCaching()
12331 // is called is controlled by the parameter passed into the test via the
12332 // INSTANTIATE_TEST_SUITE_P invocation above.
TEST_P(HttpCacheHugeResourceTest,StopCachingFollowedByReadForHugeTruncatedResource)12333 TEST_P(HttpCacheHugeResourceTest,
12334        StopCachingFollowedByReadForHugeTruncatedResource) {
12335   // This test is going to be repeated for all combinations of TransactionPhase
12336   // and CacheInitializers returned by GetTestModes().
12337   const TransactionPhase stop_caching_phase = GetParam().first;
12338   const CacheInitializer cache_initializer = GetParam().second;
12339 
12340   MockHttpCache cache;
12341   (*cache_initializer)(&cache);
12342 
12343   MockTransaction transaction(kSimpleGET_Transaction);
12344   transaction.url = kRangeGET_TransactionOK.url;
12345   transaction.handler = base::BindRepeating(&LargeResourceTransactionHandler);
12346   transaction.read_handler = base::BindRepeating(&LargeBufferReader);
12347   ScopedMockTransaction scoped_transaction(transaction);
12348 
12349   MockHttpRequest request(transaction);
12350   net::TestCompletionCallback callback;
12351   std::unique_ptr<net::HttpTransaction> http_transaction;
12352   int rv = cache.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY,
12353                                                  &http_transaction);
12354   ASSERT_EQ(net::OK, rv);
12355   ASSERT_TRUE(http_transaction.get());
12356 
12357   bool network_transaction_started = false;
12358   if (stop_caching_phase == TransactionPhase::AFTER_NETWORK_READ) {
12359     http_transaction->SetBeforeNetworkStartCallback(base::BindOnce(
12360         &SetFlagOnBeforeNetworkStart, &network_transaction_started));
12361   }
12362 
12363   rv = http_transaction->Start(&request, callback.callback(),
12364                                NetLogWithSource());
12365   rv = callback.GetResult(rv);
12366   ASSERT_EQ(net::OK, rv);
12367 
12368   if (stop_caching_phase == TransactionPhase::BEFORE_FIRST_READ)
12369     http_transaction->StopCaching();
12370 
12371   int64_t total_bytes_received = 0;
12372 
12373   EXPECT_EQ(kTotalSize,
12374             http_transaction->GetResponseInfo()->headers->GetContentLength());
12375   do {
12376     // This test simulates reading gigabytes of data. Buffer size is set to 10MB
12377     // to reduce the number of reads and speed up the test.
12378     const int kBufferSize = 1024 * 1024 * 10;
12379     scoped_refptr<net::IOBuffer> buf =
12380         base::MakeRefCounted<net::IOBufferWithSize>(kBufferSize);
12381     rv = http_transaction->Read(buf.get(), kBufferSize, callback.callback());
12382     rv = callback.GetResult(rv);
12383 
12384     if (stop_caching_phase == TransactionPhase::AFTER_FIRST_READ &&
12385         total_bytes_received == 0) {
12386       http_transaction->StopCaching();
12387     }
12388 
12389     if (rv > 0)
12390       total_bytes_received += rv;
12391 
12392     if (network_transaction_started &&
12393         stop_caching_phase == TransactionPhase::AFTER_NETWORK_READ) {
12394       http_transaction->StopCaching();
12395       network_transaction_started = false;
12396     }
12397   } while (rv > 0);
12398 
12399   // The only verification we are going to do is that the received resource has
12400   // the correct size. This is sufficient to verify that the state machine
12401   // didn't terminate abruptly due to the StopCaching() call.
12402   EXPECT_EQ(kTotalSize, total_bytes_received);
12403 }
12404 
12405 // Tests that we detect truncated resources from the net when there is
12406 // a Content-Length header.
TEST_F(HttpCacheTest,TruncatedByContentLength)12407 TEST_F(HttpCacheTest, TruncatedByContentLength) {
12408   MockHttpCache cache;
12409   TestCompletionCallback callback;
12410 
12411   MockTransaction transaction(kSimpleGET_Transaction);
12412   AddMockTransaction(&transaction);
12413   transaction.response_headers = "Cache-Control: max-age=10000\n"
12414                                  "Content-Length: 100\n";
12415   RunTransactionTest(cache.http_cache(), transaction);
12416   RemoveMockTransaction(&transaction);
12417 
12418   // Read from the cache.
12419   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
12420 
12421   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12422   EXPECT_EQ(0, cache.disk_cache()->open_count());
12423   EXPECT_EQ(2, cache.disk_cache()->create_count());
12424 }
12425 
12426 // Tests that we actually flag entries as truncated when we detect an error
12427 // from the net.
TEST_F(HttpCacheTest,TruncatedByContentLength2)12428 TEST_F(HttpCacheTest, TruncatedByContentLength2) {
12429   MockHttpCache cache;
12430   TestCompletionCallback callback;
12431 
12432   MockTransaction transaction(kSimpleGET_Transaction);
12433   AddMockTransaction(&transaction);
12434   transaction.response_headers = "Cache-Control: max-age=10000\n"
12435                                  "Content-Length: 100\n"
12436                                  "Etag: \"foo\"\n";
12437   RunTransactionTest(cache.http_cache(), transaction);
12438   RemoveMockTransaction(&transaction);
12439 
12440   // Verify that the entry is marked as incomplete.
12441   MockHttpRequest request(transaction);
12442   VerifyTruncatedFlag(&cache, request.CacheKey(), true, 0);
12443 }
12444 
12445 // Make sure that calling SetPriority on a cache transaction passes on
12446 // its priority updates to its underlying network transaction.
TEST_F(HttpCacheTest,SetPriority)12447 TEST_F(HttpCacheTest, SetPriority) {
12448   MockHttpCache cache;
12449 
12450   HttpRequestInfo info;
12451   std::unique_ptr<HttpTransaction> trans;
12452   ASSERT_THAT(cache.http_cache()->CreateTransaction(IDLE, &trans), IsOk());
12453 
12454   // Shouldn't crash, but doesn't do anything either.
12455   trans->SetPriority(LOW);
12456 
12457   EXPECT_FALSE(cache.network_layer()->last_transaction());
12458   EXPECT_EQ(DEFAULT_PRIORITY,
12459             cache.network_layer()->last_create_transaction_priority());
12460 
12461   info.url = GURL(kSimpleGET_Transaction.url);
12462   TestCompletionCallback callback;
12463   EXPECT_EQ(ERR_IO_PENDING,
12464             trans->Start(&info, callback.callback(), NetLogWithSource()));
12465 
12466   EXPECT_TRUE(cache.network_layer()->last_transaction());
12467   if (cache.network_layer()->last_transaction()) {
12468     EXPECT_EQ(LOW, cache.network_layer()->last_create_transaction_priority());
12469     EXPECT_EQ(LOW, cache.network_layer()->last_transaction()->priority());
12470   }
12471 
12472   trans->SetPriority(HIGHEST);
12473 
12474   if (cache.network_layer()->last_transaction()) {
12475     EXPECT_EQ(LOW, cache.network_layer()->last_create_transaction_priority());
12476     EXPECT_EQ(HIGHEST, cache.network_layer()->last_transaction()->priority());
12477   }
12478 
12479   EXPECT_THAT(callback.WaitForResult(), IsOk());
12480 }
12481 
12482 // Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
12483 // transaction passes on its argument to the underlying network transaction.
TEST_F(HttpCacheTest,SetWebSocketHandshakeStreamCreateHelper)12484 TEST_F(HttpCacheTest, SetWebSocketHandshakeStreamCreateHelper) {
12485   MockHttpCache cache;
12486   HttpRequestInfo info;
12487 
12488   FakeWebSocketHandshakeStreamCreateHelper create_helper;
12489   std::unique_ptr<HttpTransaction> trans;
12490   ASSERT_THAT(cache.http_cache()->CreateTransaction(IDLE, &trans), IsOk());
12491 
12492   EXPECT_FALSE(cache.network_layer()->last_transaction());
12493 
12494   info.url = GURL(kSimpleGET_Transaction.url);
12495   TestCompletionCallback callback;
12496   EXPECT_EQ(ERR_IO_PENDING,
12497             trans->Start(&info, callback.callback(), NetLogWithSource()));
12498 
12499   ASSERT_TRUE(cache.network_layer()->last_transaction());
12500   EXPECT_FALSE(cache.network_layer()->last_transaction()->
12501                websocket_handshake_stream_create_helper());
12502   trans->SetWebSocketHandshakeStreamCreateHelper(&create_helper);
12503   EXPECT_EQ(&create_helper,
12504             cache.network_layer()->last_transaction()->
12505             websocket_handshake_stream_create_helper());
12506   EXPECT_THAT(callback.WaitForResult(), IsOk());
12507 }
12508 
12509 // Make sure that a cache transaction passes on its priority to
12510 // newly-created network transactions.
TEST_F(HttpCacheTest,SetPriorityNewTransaction)12511 TEST_F(HttpCacheTest, SetPriorityNewTransaction) {
12512   MockHttpCache cache;
12513   AddMockTransaction(&kRangeGET_TransactionOK);
12514 
12515   std::string raw_headers("HTTP/1.1 200 OK\n"
12516                           "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12517                           "ETag: \"foo\"\n"
12518                           "Accept-Ranges: bytes\n"
12519                           "Content-Length: 80\n");
12520   CreateTruncatedEntry(raw_headers, &cache);
12521 
12522   // Now make a regular request.
12523   std::string headers;
12524   MockTransaction transaction(kRangeGET_TransactionOK);
12525   transaction.request_headers = EXTRA_HEADER;
12526   transaction.data = kFullRangeData;
12527 
12528   std::unique_ptr<HttpTransaction> trans;
12529   ASSERT_THAT(cache.http_cache()->CreateTransaction(MEDIUM, &trans), IsOk());
12530   EXPECT_EQ(DEFAULT_PRIORITY,
12531             cache.network_layer()->last_create_transaction_priority());
12532 
12533   MockHttpRequest info(transaction);
12534   TestCompletionCallback callback;
12535   EXPECT_EQ(ERR_IO_PENDING,
12536             trans->Start(&info, callback.callback(), NetLogWithSource()));
12537   EXPECT_THAT(callback.WaitForResult(), IsOk());
12538 
12539   EXPECT_EQ(MEDIUM, cache.network_layer()->last_create_transaction_priority());
12540 
12541   trans->SetPriority(HIGHEST);
12542   // Should trigger a new network transaction and pick up the new
12543   // priority.
12544   ReadAndVerifyTransaction(trans.get(), transaction);
12545 
12546   EXPECT_EQ(HIGHEST, cache.network_layer()->last_create_transaction_priority());
12547 
12548   RemoveMockTransaction(&kRangeGET_TransactionOK);
12549 }
12550 
12551 namespace {
12552 
RunTransactionAndGetNetworkBytes(MockHttpCache * cache,const MockTransaction & trans_info,int64_t * sent_bytes,int64_t * received_bytes)12553 void RunTransactionAndGetNetworkBytes(MockHttpCache* cache,
12554                                       const MockTransaction& trans_info,
12555                                       int64_t* sent_bytes,
12556                                       int64_t* received_bytes) {
12557   RunTransactionTestBase(
12558       cache->http_cache(), trans_info, MockHttpRequest(trans_info), nullptr,
12559       NetLogWithSource(), nullptr, sent_bytes, received_bytes, nullptr);
12560 }
12561 
12562 }  // namespace
12563 
TEST_F(HttpCacheTest,NetworkBytesCacheMissAndThenHit)12564 TEST_F(HttpCacheTest, NetworkBytesCacheMissAndThenHit) {
12565   MockHttpCache cache;
12566 
12567   MockTransaction transaction(kSimpleGET_Transaction);
12568   int64_t sent, received;
12569   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12570   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12571   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12572 
12573   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12574   EXPECT_EQ(0, sent);
12575   EXPECT_EQ(0, received);
12576 }
12577 
TEST_F(HttpCacheTest,NetworkBytesConditionalRequest304)12578 TEST_F(HttpCacheTest, NetworkBytesConditionalRequest304) {
12579   MockHttpCache cache;
12580 
12581   ScopedMockTransaction transaction(kETagGET_Transaction);
12582   int64_t sent, received;
12583   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12584   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12585   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12586 
12587   transaction.load_flags = LOAD_VALIDATE_CACHE;
12588   transaction.handler = kETagGetConditionalRequestHandler;
12589   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12590   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12591   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12592 }
12593 
TEST_F(HttpCacheTest,NetworkBytesConditionalRequest200)12594 TEST_F(HttpCacheTest, NetworkBytesConditionalRequest200) {
12595   MockHttpCache cache;
12596 
12597   MockTransaction transaction(kTypicalGET_Transaction);
12598   transaction.request_headers = "Foo: bar\r\n";
12599   transaction.response_headers =
12600       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
12601       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
12602       "Etag: \"foopy\"\n"
12603       "Cache-Control: max-age=0\n"
12604       "Vary: Foo\n";
12605   AddMockTransaction(&transaction);
12606   int64_t sent, received;
12607   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12608   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12609   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12610 
12611   RevalidationServer server;
12612   transaction.handler = server.GetHandlerCallback();
12613 
12614   transaction.request_headers = "Foo: none\r\n";
12615   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12616   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12617   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12618 
12619   RemoveMockTransaction(&transaction);
12620 }
12621 
TEST_F(HttpCacheTest,NetworkBytesRange)12622 TEST_F(HttpCacheTest, NetworkBytesRange) {
12623   MockHttpCache cache;
12624   AddMockTransaction(&kRangeGET_TransactionOK);
12625   MockTransaction transaction(kRangeGET_TransactionOK);
12626 
12627   // Read bytes 40-49 from the network.
12628   int64_t sent, received;
12629   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12630   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12631   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12632 
12633   // Read bytes 40-49 from the cache.
12634   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12635   EXPECT_EQ(0, sent);
12636   EXPECT_EQ(0, received);
12637   base::RunLoop().RunUntilIdle();
12638 
12639   // Read bytes 30-39 from the network.
12640   transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
12641   transaction.data = "rg: 30-39 ";
12642   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12643   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12644   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12645   base::RunLoop().RunUntilIdle();
12646 
12647   // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
12648   transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
12649   transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
12650   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12651   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes * 2, sent);
12652   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes * 2, received);
12653 
12654   RemoveMockTransaction(&kRangeGET_TransactionOK);
12655 }
12656 
12657 class HttpCachePrefetchValidationTest : public TestWithTaskEnvironment {
12658  protected:
12659   static const int kNumSecondsPerMinute = 60;
12660   static const int kMaxAgeSecs = 100;
12661   static const int kRequireValidationSecs = kMaxAgeSecs + 1;
12662 
HttpCachePrefetchValidationTest()12663   HttpCachePrefetchValidationTest() : transaction_(kSimpleGET_Transaction) {
12664     DCHECK_LT(kMaxAgeSecs, prefetch_reuse_mins() * kNumSecondsPerMinute);
12665 
12666     cache_.http_cache()->SetClockForTesting(&clock_);
12667     cache_.network_layer()->SetClock(&clock_);
12668 
12669     transaction_.response_headers = "Cache-Control: max-age=100\n";
12670   }
12671 
TransactionRequiredNetwork(int load_flags)12672   bool TransactionRequiredNetwork(int load_flags) {
12673     int pre_transaction_count = transaction_count();
12674     transaction_.load_flags = load_flags;
12675     RunTransactionTest(cache_.http_cache(), transaction_);
12676     return pre_transaction_count != transaction_count();
12677   }
12678 
AdvanceTime(int seconds)12679   void AdvanceTime(int seconds) { clock_.Advance(base::Seconds(seconds)); }
12680 
prefetch_reuse_mins()12681   int prefetch_reuse_mins() { return HttpCache::kPrefetchReuseMins; }
12682 
12683   // How many times this test has sent requests to the (fake) origin
12684   // server. Every test case needs to make at least one request to initialise
12685   // the cache.
transaction_count()12686   int transaction_count() {
12687     return cache_.network_layer()->transaction_count();
12688   }
12689 
12690   MockHttpCache cache_;
12691   ScopedMockTransaction transaction_;
12692   std::string response_headers_;
12693   base::SimpleTestClock clock_;
12694 };
12695 
TEST_F(HttpCachePrefetchValidationTest,SkipValidationShortlyAfterPrefetch)12696 TEST_F(HttpCachePrefetchValidationTest, SkipValidationShortlyAfterPrefetch) {
12697   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12698   AdvanceTime(kRequireValidationSecs);
12699   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12700 }
12701 
TEST_F(HttpCachePrefetchValidationTest,ValidateLongAfterPrefetch)12702 TEST_F(HttpCachePrefetchValidationTest, ValidateLongAfterPrefetch) {
12703   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12704   AdvanceTime(prefetch_reuse_mins() * kNumSecondsPerMinute);
12705   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12706 }
12707 
TEST_F(HttpCachePrefetchValidationTest,SkipValidationOnceOnly)12708 TEST_F(HttpCachePrefetchValidationTest, SkipValidationOnceOnly) {
12709   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12710   AdvanceTime(kRequireValidationSecs);
12711   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12712   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12713 }
12714 
TEST_F(HttpCachePrefetchValidationTest,SkipValidationOnceReadOnly)12715 TEST_F(HttpCachePrefetchValidationTest, SkipValidationOnceReadOnly) {
12716   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12717   AdvanceTime(kRequireValidationSecs);
12718   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_ONLY_FROM_CACHE |
12719                                           LOAD_SKIP_CACHE_VALIDATION));
12720   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12721 }
12722 
TEST_F(HttpCachePrefetchValidationTest,BypassCacheOverwritesPrefetch)12723 TEST_F(HttpCachePrefetchValidationTest, BypassCacheOverwritesPrefetch) {
12724   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12725   AdvanceTime(kRequireValidationSecs);
12726   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_BYPASS_CACHE));
12727   AdvanceTime(kRequireValidationSecs);
12728   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12729 }
12730 
TEST_F(HttpCachePrefetchValidationTest,SkipValidationOnExistingEntryThatNeedsValidation)12731 TEST_F(HttpCachePrefetchValidationTest,
12732        SkipValidationOnExistingEntryThatNeedsValidation) {
12733   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12734   AdvanceTime(kRequireValidationSecs);
12735   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12736   AdvanceTime(kRequireValidationSecs);
12737   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12738   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12739 }
12740 
TEST_F(HttpCachePrefetchValidationTest,SkipValidationOnExistingEntryThatDoesNotNeedValidation)12741 TEST_F(HttpCachePrefetchValidationTest,
12742        SkipValidationOnExistingEntryThatDoesNotNeedValidation) {
12743   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12744   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH));
12745   AdvanceTime(kRequireValidationSecs);
12746   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12747   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12748 }
12749 
TEST_F(HttpCachePrefetchValidationTest,PrefetchMultipleTimes)12750 TEST_F(HttpCachePrefetchValidationTest, PrefetchMultipleTimes) {
12751   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12752   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH));
12753   AdvanceTime(kRequireValidationSecs);
12754   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12755 }
12756 
TEST_F(HttpCachePrefetchValidationTest,ValidateOnDelayedSecondPrefetch)12757 TEST_F(HttpCachePrefetchValidationTest, ValidateOnDelayedSecondPrefetch) {
12758   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12759   AdvanceTime(kRequireValidationSecs);
12760   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12761   AdvanceTime(kRequireValidationSecs);
12762   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12763 }
12764 
TEST_F(HttpCacheTest,StaleContentNotUsedWhenLoadFlagNotSet)12765 TEST_F(HttpCacheTest, StaleContentNotUsedWhenLoadFlagNotSet) {
12766   MockHttpCache cache;
12767 
12768   ScopedMockTransaction stale_while_revalidate_transaction(
12769       kSimpleGET_Transaction);
12770 
12771   stale_while_revalidate_transaction.response_headers =
12772       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12773       "Age: 10801\n"
12774       "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
12775 
12776   // Write to the cache.
12777   RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
12778 
12779   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12780 
12781   // Send the request again and check that it is sent to the network again.
12782   HttpResponseInfo response_info;
12783   RunTransactionTestWithResponseInfo(
12784       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12785 
12786   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12787   EXPECT_FALSE(response_info.async_revalidation_requested);
12788 }
12789 
TEST_F(HttpCacheTest,StaleContentUsedWhenLoadFlagSetAndUsableThenTimesout)12790 TEST_F(HttpCacheTest, StaleContentUsedWhenLoadFlagSetAndUsableThenTimesout) {
12791   MockHttpCache cache;
12792   base::SimpleTestClock clock;
12793   cache.http_cache()->SetClockForTesting(&clock);
12794   cache.network_layer()->SetClock(&clock);
12795   clock.Advance(base::Seconds(10));
12796 
12797   ScopedMockTransaction stale_while_revalidate_transaction(
12798       kSimpleGET_Transaction);
12799   stale_while_revalidate_transaction.load_flags |=
12800       LOAD_SUPPORT_ASYNC_REVALIDATION;
12801   stale_while_revalidate_transaction.response_headers =
12802       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12803       "Age: 10801\n"
12804       "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
12805 
12806   // Write to the cache.
12807   RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
12808 
12809   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12810 
12811   // Send the request again and check that it is not sent to the network again.
12812   HttpResponseInfo response_info;
12813   RunTransactionTestWithResponseInfo(
12814       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12815 
12816   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12817   EXPECT_TRUE(response_info.async_revalidation_requested);
12818   EXPECT_FALSE(response_info.stale_revalidate_timeout.is_null());
12819 
12820   // Move forward in time such that the stale response is no longer valid.
12821   clock.SetNow(response_info.stale_revalidate_timeout);
12822   clock.Advance(base::Seconds(1));
12823 
12824   RunTransactionTestWithResponseInfo(
12825       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12826 
12827   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12828   EXPECT_FALSE(response_info.async_revalidation_requested);
12829 }
12830 
TEST_F(HttpCacheTest,StaleContentUsedWhenLoadFlagSetAndUsable)12831 TEST_F(HttpCacheTest, StaleContentUsedWhenLoadFlagSetAndUsable) {
12832   MockHttpCache cache;
12833   base::SimpleTestClock clock;
12834   cache.http_cache()->SetClockForTesting(&clock);
12835   cache.network_layer()->SetClock(&clock);
12836   clock.Advance(base::Seconds(10));
12837 
12838   ScopedMockTransaction stale_while_revalidate_transaction(
12839       kSimpleGET_Transaction);
12840   stale_while_revalidate_transaction.load_flags |=
12841       LOAD_SUPPORT_ASYNC_REVALIDATION;
12842   stale_while_revalidate_transaction.response_headers =
12843       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12844       "Age: 10801\n"
12845       "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
12846 
12847   // Write to the cache.
12848   RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
12849 
12850   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12851 
12852   // Send the request again and check that it is not sent to the network again.
12853   HttpResponseInfo response_info;
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   base::Time revalidation_timeout = response_info.stale_revalidate_timeout;
12861   clock.Advance(base::Seconds(1));
12862   EXPECT_TRUE(clock.Now() < revalidation_timeout);
12863 
12864   // Fetch the resource again inside the revalidation timeout window.
12865   RunTransactionTestWithResponseInfo(
12866       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12867 
12868   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12869   EXPECT_TRUE(response_info.async_revalidation_requested);
12870   EXPECT_FALSE(response_info.stale_revalidate_timeout.is_null());
12871   // Expect that the original revalidation timeout hasn't changed.
12872   EXPECT_TRUE(revalidation_timeout == response_info.stale_revalidate_timeout);
12873 
12874   // mask of async revalidation flag.
12875   stale_while_revalidate_transaction.load_flags &=
12876       ~LOAD_SUPPORT_ASYNC_REVALIDATION;
12877   stale_while_revalidate_transaction.status = "HTTP/1.1 304 Not Modified";
12878   // Write 304 to the cache.
12879   RunTransactionTestWithResponseInfo(
12880       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12881 
12882   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12883   EXPECT_FALSE(response_info.async_revalidation_requested);
12884   EXPECT_TRUE(response_info.stale_revalidate_timeout.is_null());
12885 }
12886 
TEST_F(HttpCacheTest,StaleContentNotUsedWhenUnusable)12887 TEST_F(HttpCacheTest, StaleContentNotUsedWhenUnusable) {
12888   MockHttpCache cache;
12889 
12890   ScopedMockTransaction stale_while_revalidate_transaction(
12891       kSimpleGET_Transaction);
12892   stale_while_revalidate_transaction.load_flags |=
12893       LOAD_SUPPORT_ASYNC_REVALIDATION;
12894   stale_while_revalidate_transaction.response_headers =
12895       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12896       "Age: 10801\n"
12897       "Cache-Control: max-age=0,stale-while-revalidate=1800\n";
12898 
12899   // Write to the cache.
12900   RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
12901 
12902   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12903 
12904   // Send the request again and check that it is sent to the network again.
12905   HttpResponseInfo response_info;
12906   RunTransactionTestWithResponseInfo(
12907       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12908 
12909   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12910   EXPECT_FALSE(response_info.async_revalidation_requested);
12911 }
12912 
TEST_F(HttpCacheTest,StaleContentWriteError)12913 TEST_F(HttpCacheTest, StaleContentWriteError) {
12914   MockHttpCache cache;
12915   base::SimpleTestClock clock;
12916   cache.http_cache()->SetClockForTesting(&clock);
12917   cache.network_layer()->SetClock(&clock);
12918   clock.Advance(base::Seconds(10));
12919 
12920   ScopedMockTransaction stale_while_revalidate_transaction(
12921       kSimpleGET_Transaction);
12922   stale_while_revalidate_transaction.load_flags |=
12923       LOAD_SUPPORT_ASYNC_REVALIDATION;
12924   stale_while_revalidate_transaction.response_headers =
12925       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12926       "Age: 10801\n"
12927       "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
12928 
12929   // Write to the cache.
12930   RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
12931 
12932   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12933 
12934   // Send the request again but inject a write fault. Should still work
12935   // (and not dereference any null pointers).
12936   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_WRITE);
12937   HttpResponseInfo response_info;
12938   RunTransactionTestWithResponseInfo(
12939       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12940 
12941   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12942 }
12943 
12944 // Tests that we allow multiple simultaneous, non-overlapping transactions to
12945 // take place on a sparse entry.
TEST_F(HttpCacheTest,RangeGET_MultipleRequests)12946 TEST_F(HttpCacheTest, RangeGET_MultipleRequests) {
12947   MockHttpCache cache;
12948 
12949   // Create a transaction for bytes 0-9.
12950   MockHttpRequest request(kRangeGET_TransactionOK);
12951   MockTransaction transaction(kRangeGET_TransactionOK);
12952   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
12953   transaction.data = "rg: 00-09 ";
12954   AddMockTransaction(&transaction);
12955 
12956   TestCompletionCallback callback;
12957   std::unique_ptr<HttpTransaction> trans;
12958   int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
12959   EXPECT_THAT(rv, IsOk());
12960   ASSERT_TRUE(trans.get());
12961 
12962   // Start our transaction.
12963   trans->Start(&request, callback.callback(), NetLogWithSource());
12964 
12965   // A second transaction on a different part of the file (the default
12966   // kRangeGET_TransactionOK requests 40-49) should not be blocked by
12967   // the already pending transaction.
12968   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
12969 
12970   // Let the first transaction complete.
12971   callback.WaitForResult();
12972 
12973   RemoveMockTransaction(&transaction);
12974 }
12975 
12976 // Verify that a range request can be satisfied from a completely cached
12977 // resource with the LOAD_ONLY_FROM_CACHE flag set. Currently it's not
12978 // implemented so it returns ERR_CACHE_MISS. See also
12979 // HttpCacheTest.RangeGET_OK_LoadOnlyFromCache.
12980 // TODO(ricea): Update this test if it is implemented in future.
TEST_F(HttpCacheTest,RangeGET_Previous200_LoadOnlyFromCache)12981 TEST_F(HttpCacheTest, RangeGET_Previous200_LoadOnlyFromCache) {
12982   MockHttpCache cache;
12983 
12984   // Store the whole thing with status 200.
12985   MockTransaction transaction(kETagGET_Transaction);
12986   transaction.url = kRangeGET_TransactionOK.url;
12987   transaction.data = kFullRangeData;
12988   AddMockTransaction(&transaction);
12989   RunTransactionTest(cache.http_cache(), transaction);
12990   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12991   EXPECT_EQ(0, cache.disk_cache()->open_count());
12992   EXPECT_EQ(1, cache.disk_cache()->create_count());
12993 
12994   RemoveMockTransaction(&transaction);
12995   AddMockTransaction(&kRangeGET_TransactionOK);
12996 
12997   // Now see that we use the stored entry.
12998   MockTransaction transaction2(kRangeGET_TransactionOK);
12999   transaction2.load_flags |= LOAD_ONLY_FROM_CACHE;
13000   MockHttpRequest request(transaction2);
13001   TestCompletionCallback callback;
13002 
13003   std::unique_ptr<HttpTransaction> trans;
13004   int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
13005   EXPECT_THAT(rv, IsOk());
13006   ASSERT_TRUE(trans);
13007 
13008   rv = trans->Start(&request, callback.callback(), NetLogWithSource());
13009   if (rv == ERR_IO_PENDING) {
13010     rv = callback.WaitForResult();
13011   }
13012   EXPECT_THAT(rv, IsError(ERR_CACHE_MISS));
13013 
13014   EXPECT_EQ(1, cache.network_layer()->transaction_count());
13015   EXPECT_EQ(1, cache.disk_cache()->open_count());
13016   EXPECT_EQ(1, cache.disk_cache()->create_count());
13017 }
13018 
13019 // Makes sure that a request stops using the cache when the response headers
13020 // with "Cache-Control: no-store" arrives. That means that another request for
13021 // the same URL can be processed before the response body of the original
13022 // request arrives.
TEST_F(HttpCacheTest,NoStoreResponseShouldNotBlockFollowingRequests)13023 TEST_F(HttpCacheTest, NoStoreResponseShouldNotBlockFollowingRequests) {
13024   MockHttpCache cache;
13025   ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
13026   mock_transaction.response_headers = "Cache-Control: no-store\n";
13027   MockHttpRequest request(mock_transaction);
13028 
13029   auto first = std::make_unique<Context>();
13030   first->result = cache.CreateTransaction(&first->trans);
13031   ASSERT_THAT(first->result, IsOk());
13032   EXPECT_EQ(LOAD_STATE_IDLE, first->trans->GetLoadState());
13033   first->result = first->trans->Start(&request, first->callback.callback(),
13034                                       NetLogWithSource());
13035   EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, first->trans->GetLoadState());
13036 
13037   base::RunLoop().RunUntilIdle();
13038   EXPECT_EQ(LOAD_STATE_IDLE, first->trans->GetLoadState());
13039   ASSERT_TRUE(first->trans->GetResponseInfo());
13040   EXPECT_TRUE(first->trans->GetResponseInfo()->headers->HasHeaderValue(
13041       "Cache-Control", "no-store"));
13042   // Here we have read the response header but not read the response body yet.
13043 
13044   // Let us create the second (read) transaction.
13045   auto second = std::make_unique<Context>();
13046   second->result = cache.CreateTransaction(&second->trans);
13047   ASSERT_THAT(second->result, IsOk());
13048   EXPECT_EQ(LOAD_STATE_IDLE, second->trans->GetLoadState());
13049   second->result = second->trans->Start(&request, second->callback.callback(),
13050                                         NetLogWithSource());
13051 
13052   // Here the second transaction proceeds without reading the first body.
13053   EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, second->trans->GetLoadState());
13054   base::RunLoop().RunUntilIdle();
13055   EXPECT_EQ(LOAD_STATE_IDLE, second->trans->GetLoadState());
13056   ASSERT_TRUE(second->trans->GetResponseInfo());
13057   EXPECT_TRUE(second->trans->GetResponseInfo()->headers->HasHeaderValue(
13058       "Cache-Control", "no-store"));
13059   ReadAndVerifyTransaction(second->trans.get(), kSimpleGET_Transaction);
13060 }
13061 
13062 // Tests that serving a response entirely from cache replays the previous
13063 // SSLInfo.
TEST_F(HttpCacheTest,CachePreservesSSLInfo)13064 TEST_F(HttpCacheTest, CachePreservesSSLInfo) {
13065   static const uint16_t kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xc02f;
13066   int status = 0;
13067   SSLConnectionStatusSetCipherSuite(kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
13068                                     &status);
13069   SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2, &status);
13070 
13071   scoped_refptr<X509Certificate> cert =
13072       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
13073 
13074   MockHttpCache cache;
13075 
13076   ScopedMockTransaction transaction(kSimpleGET_Transaction);
13077   transaction.cert = cert;
13078   transaction.ssl_connection_status = status;
13079 
13080   // Fetch the resource.
13081   HttpResponseInfo response_info;
13082   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13083                                      &response_info);
13084 
13085   // The request should have hit the network and a cache entry created.
13086   EXPECT_EQ(1, cache.network_layer()->transaction_count());
13087   EXPECT_EQ(0, cache.disk_cache()->open_count());
13088   EXPECT_EQ(1, cache.disk_cache()->create_count());
13089 
13090   // The expected SSL state was reported.
13091   EXPECT_EQ(transaction.ssl_connection_status,
13092             response_info.ssl_info.connection_status);
13093   EXPECT_TRUE(cert->EqualsIncludingChain(response_info.ssl_info.cert.get()));
13094 
13095   // Fetch the resource again.
13096   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13097                                      &response_info);
13098 
13099   // The request should have been reused without hitting the network.
13100   EXPECT_EQ(1, cache.network_layer()->transaction_count());
13101   EXPECT_EQ(1, cache.disk_cache()->open_count());
13102   EXPECT_EQ(1, cache.disk_cache()->create_count());
13103 
13104   // The SSL state was preserved.
13105   EXPECT_EQ(status, response_info.ssl_info.connection_status);
13106   EXPECT_TRUE(cert->EqualsIncludingChain(response_info.ssl_info.cert.get()));
13107 }
13108 
13109 // Tests that SSLInfo gets updated when revalidating a cached response.
TEST_F(HttpCacheTest,RevalidationUpdatesSSLInfo)13110 TEST_F(HttpCacheTest, RevalidationUpdatesSSLInfo) {
13111   static const uint16_t kTLS_RSA_WITH_RC4_128_MD5 = 0x0004;
13112   static const uint16_t kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xc02f;
13113 
13114   int status1 = 0;
13115   SSLConnectionStatusSetCipherSuite(kTLS_RSA_WITH_RC4_128_MD5, &status1);
13116   SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1, &status1);
13117   int status2 = 0;
13118   SSLConnectionStatusSetCipherSuite(kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
13119                                     &status2);
13120   SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2, &status2);
13121 
13122   scoped_refptr<X509Certificate> cert1 =
13123       ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
13124   scoped_refptr<X509Certificate> cert2 =
13125       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
13126 
13127   MockHttpCache cache;
13128 
13129   ScopedMockTransaction transaction(kTypicalGET_Transaction);
13130   transaction.cert = cert1;
13131   transaction.ssl_connection_status = status1;
13132 
13133   // Fetch the resource.
13134   HttpResponseInfo response_info;
13135   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13136                                      &response_info);
13137 
13138   // The request should have hit the network and a cache entry created.
13139   EXPECT_EQ(1, cache.network_layer()->transaction_count());
13140   EXPECT_EQ(0, cache.disk_cache()->open_count());
13141   EXPECT_EQ(1, cache.disk_cache()->create_count());
13142   EXPECT_FALSE(response_info.was_cached);
13143 
13144   // The expected SSL state was reported.
13145   EXPECT_EQ(status1, response_info.ssl_info.connection_status);
13146   EXPECT_TRUE(cert1->EqualsIncludingChain(response_info.ssl_info.cert.get()));
13147 
13148   // The server deploys a more modern configuration but reports 304 on the
13149   // revalidation attempt.
13150   transaction.status = "HTTP/1.1 304 Not Modified";
13151   transaction.cert = cert2;
13152   transaction.ssl_connection_status = status2;
13153 
13154   // Fetch the resource again, forcing a revalidation.
13155   transaction.request_headers = "Cache-Control: max-age=0\r\n";
13156   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13157                                      &response_info);
13158 
13159   // The request should have been successfully revalidated.
13160   EXPECT_EQ(2, cache.network_layer()->transaction_count());
13161   EXPECT_EQ(1, cache.disk_cache()->open_count());
13162   EXPECT_EQ(1, cache.disk_cache()->create_count());
13163   EXPECT_TRUE(response_info.was_cached);
13164 
13165   // The new SSL state is reported.
13166   EXPECT_EQ(status2, response_info.ssl_info.connection_status);
13167   EXPECT_TRUE(cert2->EqualsIncludingChain(response_info.ssl_info.cert.get()));
13168 }
13169 
TEST_F(HttpCacheTest,CacheEntryStatusOther)13170 TEST_F(HttpCacheTest, CacheEntryStatusOther) {
13171   MockHttpCache cache;
13172 
13173   HttpResponseInfo response_info;
13174   RunTransactionTestWithResponseInfo(cache.http_cache(), kRangeGET_Transaction,
13175                                      &response_info);
13176 
13177   EXPECT_FALSE(response_info.was_cached);
13178   EXPECT_TRUE(response_info.network_accessed);
13179   EXPECT_EQ(CacheEntryStatus::ENTRY_OTHER, response_info.cache_entry_status);
13180 }
13181 
TEST_F(HttpCacheTest,CacheEntryStatusNotInCache)13182 TEST_F(HttpCacheTest, CacheEntryStatusNotInCache) {
13183   MockHttpCache cache;
13184 
13185   HttpResponseInfo response_info;
13186   RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
13187                                      &response_info);
13188 
13189   EXPECT_FALSE(response_info.was_cached);
13190   EXPECT_TRUE(response_info.network_accessed);
13191   EXPECT_EQ(CacheEntryStatus::ENTRY_NOT_IN_CACHE,
13192             response_info.cache_entry_status);
13193 }
13194 
TEST_F(HttpCacheTest,CacheEntryStatusUsed)13195 TEST_F(HttpCacheTest, CacheEntryStatusUsed) {
13196   MockHttpCache cache;
13197   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
13198 
13199   HttpResponseInfo response_info;
13200   RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
13201                                      &response_info);
13202 
13203   EXPECT_TRUE(response_info.was_cached);
13204   EXPECT_FALSE(response_info.network_accessed);
13205   EXPECT_EQ(CacheEntryStatus::ENTRY_USED, response_info.cache_entry_status);
13206 }
13207 
TEST_F(HttpCacheTest,CacheEntryStatusValidated)13208 TEST_F(HttpCacheTest, CacheEntryStatusValidated) {
13209   MockHttpCache cache;
13210   RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
13211 
13212   ScopedMockTransaction still_valid(kETagGET_Transaction);
13213   still_valid.load_flags = LOAD_VALIDATE_CACHE;  // Force a validation.
13214   still_valid.handler = kETagGetConditionalRequestHandler;
13215 
13216   HttpResponseInfo response_info;
13217   RunTransactionTestWithResponseInfo(cache.http_cache(), still_valid,
13218                                      &response_info);
13219 
13220   EXPECT_TRUE(response_info.was_cached);
13221   EXPECT_TRUE(response_info.network_accessed);
13222   EXPECT_EQ(CacheEntryStatus::ENTRY_VALIDATED,
13223             response_info.cache_entry_status);
13224 }
13225 
TEST_F(HttpCacheTest,CacheEntryStatusUpdated)13226 TEST_F(HttpCacheTest, CacheEntryStatusUpdated) {
13227   MockHttpCache cache;
13228   RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
13229 
13230   ScopedMockTransaction update(kETagGET_Transaction);
13231   update.load_flags = LOAD_VALIDATE_CACHE;  // Force a validation.
13232 
13233   HttpResponseInfo response_info;
13234   RunTransactionTestWithResponseInfo(cache.http_cache(), update,
13235                                      &response_info);
13236 
13237   EXPECT_FALSE(response_info.was_cached);
13238   EXPECT_TRUE(response_info.network_accessed);
13239   EXPECT_EQ(CacheEntryStatus::ENTRY_UPDATED, response_info.cache_entry_status);
13240 }
13241 
TEST_F(HttpCacheTest,CacheEntryStatusCantConditionalize)13242 TEST_F(HttpCacheTest, CacheEntryStatusCantConditionalize) {
13243   MockHttpCache cache;
13244   cache.FailConditionalizations();
13245   RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
13246 
13247   HttpResponseInfo response_info;
13248   RunTransactionTestWithResponseInfo(cache.http_cache(),
13249                                      kTypicalGET_Transaction, &response_info);
13250 
13251   EXPECT_FALSE(response_info.was_cached);
13252   EXPECT_TRUE(response_info.network_accessed);
13253   EXPECT_EQ(CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE,
13254             response_info.cache_entry_status);
13255 }
13256 
TEST_F(HttpSplitCacheKeyTest,GetResourceURLFromHttpCacheKey)13257 TEST_F(HttpSplitCacheKeyTest, GetResourceURLFromHttpCacheKey) {
13258   base::test::ScopedFeatureList feature_list;
13259   feature_list.InitAndEnableFeature(
13260       net::features::kSplitCacheByNetworkIsolationKey);
13261   MockHttpCache cache;
13262   std::string urls[] = {"http://www.a.com/", "https://b.com/example.html",
13263                         "http://example.com/Some Path/Some Leaf?some query"};
13264 
13265   for (const std::string& url : urls) {
13266     std::string key = ComputeCacheKey(url);
13267     EXPECT_EQ(GURL(url).spec(), HttpCache::GetResourceURLFromHttpCacheKey(key));
13268   }
13269 }
13270 
TEST_F(HttpCacheTest,GetResourceURLFromHttpCacheKey)13271 TEST_F(HttpCacheTest, GetResourceURLFromHttpCacheKey) {
13272   const struct {
13273     std::string input;
13274     std::string output;
13275   } kTestCase[] = {
13276       // Valid input:
13277       {"0/0/https://a.com/", "https://a.com/"},
13278       {"0/0/https://a.com/path", "https://a.com/path"},
13279       {"0/0/https://a.com/?query", "https://a.com/?query"},
13280       {"0/0/https://a.com/#fragment", "https://a.com/#fragment"},
13281       {"0/0/_dk_s_ https://a.com/", "https://a.com/"},
13282       {"0/0/_dk_https://a.com https://b.com https://c.com/", "https://c.com/"},
13283       {"0/0/_dk_shttps://a.com https://b.com https://c.com/", "https://c.com/"},
13284 
13285       // Invalid input, producing garbage, without crashing.
13286       {"", ""},
13287       {"0/a.com", "0/a.com"},
13288       {"https://a.com/", "a.com/"},
13289       {"0/https://a.com/", "/a.com/"},
13290   };
13291 
13292   for (const auto& test : kTestCase) {
13293     EXPECT_EQ(test.output,
13294               HttpCache::GetResourceURLFromHttpCacheKey(test.input));
13295   }
13296 }
13297 
13298 class TestCompletionCallbackForHttpCache : public TestCompletionCallbackBase {
13299  public:
13300   TestCompletionCallbackForHttpCache() = default;
13301   ~TestCompletionCallbackForHttpCache() override = default;
13302 
callback()13303   CompletionRepeatingCallback callback() {
13304     return base::BindRepeating(&TestCompletionCallbackForHttpCache::SetResult,
13305                                base::Unretained(this));
13306   }
13307 
results()13308   const std::vector<int>& results() { return results_; }
13309 
13310  private:
13311   std::vector<int> results_;
13312 
13313  protected:
SetResult(int result)13314   void SetResult(int result) override {
13315     results_.push_back(result);
13316     DidSetResult();
13317   }
13318 };
13319 
TEST_F(HttpCacheIOCallbackTest,FailedDoomFollowedByOpen)13320 TEST_F(HttpCacheIOCallbackTest, FailedDoomFollowedByOpen) {
13321   MockHttpCache cache;
13322   TestCompletionCallbackForHttpCache cb;
13323   std::unique_ptr<Transaction> transaction =
13324       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13325 
13326   transaction->SetIOCallBackForTest(cb.callback());
13327   transaction->SetCacheIOCallBackForTest(cb.callback());
13328 
13329   // Create the backend here as our direct calls to DoomEntry and OpenEntry
13330   // below require that it exists.
13331   cache.backend();
13332 
13333   // Need a mock transaction in order to use some of MockHttpCache's
13334   // functions.
13335   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13336 
13337   ActiveEntry* entry1 = nullptr;
13338 
13339   cache.disk_cache()->set_force_fail_callback_later(true);
13340 
13341   // Queue up our operations.
13342   int rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get());
13343   ASSERT_EQ(rv, ERR_IO_PENDING);
13344   cache.disk_cache()->set_force_fail_callback_later(false);
13345   rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry1,
13346                  transaction.get());
13347   ASSERT_EQ(rv, ERR_IO_PENDING);
13348 
13349   // Wait for all the results to arrive.
13350   cb.GetResult(rv);
13351   ASSERT_EQ(cb.results().size(), 2u);
13352 
13353   // Verify that DoomEntry failed correctly.
13354   ASSERT_EQ(cb.results()[0], ERR_CACHE_DOOM_FAILURE);
13355   // Verify that OpenEntry fails with the same code.
13356   ASSERT_EQ(cb.results()[1], ERR_CACHE_DOOM_FAILURE);
13357   ASSERT_EQ(entry1, nullptr);
13358 }
13359 
TEST_F(HttpCacheIOCallbackTest,FailedDoomFollowedByCreate)13360 TEST_F(HttpCacheIOCallbackTest, FailedDoomFollowedByCreate) {
13361   MockHttpCache cache;
13362   TestCompletionCallbackForHttpCache cb;
13363   std::unique_ptr<Transaction> transaction =
13364       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13365 
13366   transaction->SetIOCallBackForTest(cb.callback());
13367   transaction->SetCacheIOCallBackForTest(cb.callback());
13368 
13369   // Create the backend here as our direct calls to DoomEntry and CreateEntry
13370   // below require that it exists.
13371   cache.backend();
13372 
13373   // Need a mock transaction in order to use some of MockHttpCache's
13374   // functions.
13375   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13376 
13377   ActiveEntry* entry1 = nullptr;
13378 
13379   cache.disk_cache()->set_force_fail_callback_later(true);
13380 
13381   // Queue up our operations.
13382   int rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get());
13383   ASSERT_EQ(rv, ERR_IO_PENDING);
13384   cache.disk_cache()->set_force_fail_callback_later(false);
13385   rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13386                    transaction.get());
13387   ASSERT_EQ(rv, ERR_IO_PENDING);
13388 
13389   // Wait for all the results to arrive.
13390   cb.GetResult(rv);
13391   ASSERT_EQ(cb.results().size(), 2u);
13392 
13393   // Verify that DoomEntry failed correctly.
13394   ASSERT_EQ(cb.results()[0], ERR_CACHE_DOOM_FAILURE);
13395   // Verify that CreateEntry requests a restart (CACHE_RACE).
13396   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13397   ASSERT_EQ(entry1, nullptr);
13398 }
13399 
TEST_F(HttpCacheIOCallbackTest,FailedDoomFollowedByDoom)13400 TEST_F(HttpCacheIOCallbackTest, FailedDoomFollowedByDoom) {
13401   MockHttpCache cache;
13402   TestCompletionCallbackForHttpCache cb;
13403   std::unique_ptr<Transaction> transaction =
13404       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13405 
13406   transaction->SetIOCallBackForTest(cb.callback());
13407   transaction->SetCacheIOCallBackForTest(cb.callback());
13408 
13409   // Create the backend here as our direct calls to DoomEntry below require that
13410   // it exists.
13411   cache.backend();
13412 
13413   // Need a mock transaction in order to use some of MockHttpCache's
13414   // functions.
13415   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13416 
13417   cache.disk_cache()->set_force_fail_callback_later(true);
13418 
13419   // Queue up our operations.
13420   int rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get());
13421   ASSERT_EQ(rv, ERR_IO_PENDING);
13422   cache.disk_cache()->set_force_fail_callback_later(false);
13423   rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get());
13424   ASSERT_EQ(rv, ERR_IO_PENDING);
13425 
13426   // Wait for all the results to arrive.
13427   cb.GetResult(rv);
13428   ASSERT_EQ(cb.results().size(), 2u);
13429 
13430   // Verify that DoomEntry failed correctly.
13431   ASSERT_EQ(cb.results()[0], ERR_CACHE_DOOM_FAILURE);
13432   // Verify that the second DoomEntry requests a restart (CACHE_RACE).
13433   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13434 }
13435 
TEST_F(HttpCacheIOCallbackTest,FailedOpenFollowedByCreate)13436 TEST_F(HttpCacheIOCallbackTest, FailedOpenFollowedByCreate) {
13437   MockHttpCache cache;
13438   TestCompletionCallbackForHttpCache cb;
13439   std::unique_ptr<Transaction> transaction =
13440       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13441 
13442   transaction->SetIOCallBackForTest(cb.callback());
13443   transaction->SetCacheIOCallBackForTest(cb.callback());
13444 
13445   // Create the backend here as our direct calls to OpenEntry and CreateEntry
13446   // below require that it exists.
13447   cache.backend();
13448 
13449   // Need a mock transaction in order to use some of MockHttpCache's
13450   // functions.
13451   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13452 
13453   ActiveEntry* entry1 = nullptr;
13454   ActiveEntry* entry2 = nullptr;
13455 
13456   cache.disk_cache()->set_force_fail_callback_later(true);
13457 
13458   // Queue up our operations.
13459   int rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry1,
13460                      transaction.get());
13461   ASSERT_EQ(rv, ERR_IO_PENDING);
13462   cache.disk_cache()->set_force_fail_callback_later(false);
13463   rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13464                    transaction.get());
13465   ASSERT_EQ(rv, ERR_IO_PENDING);
13466 
13467   // Wait for all the results to arrive.
13468   cb.GetResult(rv);
13469   ASSERT_EQ(cb.results().size(), 2u);
13470 
13471   // Verify that OpenEntry failed correctly.
13472   ASSERT_EQ(cb.results()[0], ERR_CACHE_OPEN_FAILURE);
13473   ASSERT_EQ(entry1, nullptr);
13474   // Verify that the CreateEntry requests a restart (CACHE_RACE).
13475   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13476   ASSERT_EQ(entry2, nullptr);
13477 }
13478 
TEST_F(HttpCacheIOCallbackTest,FailedCreateFollowedByOpen)13479 TEST_F(HttpCacheIOCallbackTest, FailedCreateFollowedByOpen) {
13480   MockHttpCache cache;
13481   TestCompletionCallbackForHttpCache cb;
13482   std::unique_ptr<Transaction> transaction =
13483       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13484 
13485   transaction->SetIOCallBackForTest(cb.callback());
13486   transaction->SetCacheIOCallBackForTest(cb.callback());
13487 
13488   // Create the backend here as our direct calls to CreateEntry and OpenEntry
13489   // below require that it exists.
13490   cache.backend();
13491 
13492   // Need a mock transaction in order to use some of MockHttpCache's
13493   // functions.
13494   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13495 
13496   ActiveEntry* entry1 = nullptr;
13497   ActiveEntry* entry2 = nullptr;
13498 
13499   cache.disk_cache()->set_force_fail_callback_later(true);
13500 
13501   // Queue up our operations.
13502   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13503                        transaction.get());
13504   ASSERT_EQ(rv, ERR_IO_PENDING);
13505   cache.disk_cache()->set_force_fail_callback_later(false);
13506   rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry2,
13507                  transaction.get());
13508   ASSERT_EQ(rv, ERR_IO_PENDING);
13509 
13510   // Wait for all the results to arrive.
13511   cb.GetResult(rv);
13512   ASSERT_EQ(cb.results().size(), 2u);
13513 
13514   // Verify that CreateEntry failed correctly.
13515   ASSERT_EQ(cb.results()[0], ERR_CACHE_CREATE_FAILURE);
13516   ASSERT_EQ(entry1, nullptr);
13517   // Verify that the OpenEntry requests a restart (CACHE_RACE).
13518   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13519   ASSERT_EQ(entry2, nullptr);
13520 }
13521 
TEST_F(HttpCacheIOCallbackTest,FailedCreateFollowedByCreate)13522 TEST_F(HttpCacheIOCallbackTest, FailedCreateFollowedByCreate) {
13523   MockHttpCache cache;
13524   TestCompletionCallbackForHttpCache cb;
13525   std::unique_ptr<Transaction> transaction =
13526       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13527 
13528   transaction->SetIOCallBackForTest(cb.callback());
13529   transaction->SetCacheIOCallBackForTest(cb.callback());
13530 
13531   // Create the backend here as our direct calls to CreateEntry below require
13532   // that it exists.
13533   cache.backend();
13534 
13535   // Need a mock transaction in order to use some of MockHttpCache's
13536   // functions.
13537   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13538 
13539   ActiveEntry* entry1 = nullptr;
13540   ActiveEntry* entry2 = nullptr;
13541 
13542   cache.disk_cache()->set_force_fail_callback_later(true);
13543 
13544   // Queue up our operations.
13545   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13546                        transaction.get());
13547   ASSERT_EQ(rv, ERR_IO_PENDING);
13548   cache.disk_cache()->set_force_fail_callback_later(false);
13549   rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13550                    transaction.get());
13551   ASSERT_EQ(rv, ERR_IO_PENDING);
13552 
13553   // Wait for all the results to arrive.
13554   cb.GetResult(rv);
13555   ASSERT_EQ(cb.results().size(), 2u);
13556 
13557   // Verify the CreateEntry(s) failed.
13558   ASSERT_EQ(cb.results()[0], ERR_CACHE_CREATE_FAILURE);
13559   ASSERT_EQ(entry1, nullptr);
13560   ASSERT_EQ(cb.results()[1], ERR_CACHE_CREATE_FAILURE);
13561   ASSERT_EQ(entry2, nullptr);
13562 }
13563 
TEST_F(HttpCacheIOCallbackTest,CreateFollowedByCreate)13564 TEST_F(HttpCacheIOCallbackTest, CreateFollowedByCreate) {
13565   MockHttpCache cache;
13566   TestCompletionCallbackForHttpCache cb;
13567   std::unique_ptr<Transaction> transaction =
13568       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13569 
13570   transaction->SetIOCallBackForTest(cb.callback());
13571   transaction->SetCacheIOCallBackForTest(cb.callback());
13572 
13573   // Create the backend here as our direct calls to CreateEntry below require
13574   // that it exists.
13575   cache.backend();
13576 
13577   // Need a mock transaction in order to use some of MockHttpCache's
13578   // functions.
13579   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13580 
13581   ActiveEntry* entry1 = nullptr;
13582   ActiveEntry* entry2 = nullptr;
13583 
13584   // Queue up our operations.
13585   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13586                        transaction.get());
13587   ASSERT_EQ(rv, ERR_IO_PENDING);
13588   rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13589                    transaction.get());
13590   ASSERT_EQ(rv, ERR_IO_PENDING);
13591 
13592   // Wait for all the results to arrive.
13593   cb.GetResult(rv);
13594   ASSERT_EQ(cb.results().size(), 2u);
13595 
13596   // Verify that the first CreateEntry succeeded.
13597   ASSERT_EQ(cb.results()[0], OK);
13598   ASSERT_NE(entry1, nullptr);
13599   // Verify that the second CreateEntry failed.
13600   ASSERT_EQ(cb.results()[1], ERR_CACHE_CREATE_FAILURE);
13601   ASSERT_EQ(entry2, nullptr);
13602 }
13603 
TEST_F(HttpCacheIOCallbackTest,OperationFollowedByDoom)13604 TEST_F(HttpCacheIOCallbackTest, OperationFollowedByDoom) {
13605   MockHttpCache cache;
13606   TestCompletionCallbackForHttpCache cb;
13607   std::unique_ptr<Transaction> transaction =
13608       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13609 
13610   transaction->SetIOCallBackForTest(cb.callback());
13611   transaction->SetCacheIOCallBackForTest(cb.callback());
13612 
13613   // Create the backend here as our direct calls to CreateEntry and DoomEntry
13614   // below require that it exists.
13615   cache.backend();
13616 
13617   // Need a mock transaction in order to use some of MockHttpCache's
13618   // functions.
13619   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13620 
13621   ActiveEntry* entry1 = nullptr;
13622 
13623   // Queue up our operations.
13624   // For this test all we need is some operation followed by a doom, a create
13625   // fulfills that requirement.
13626   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13627                        transaction.get());
13628   ASSERT_EQ(rv, ERR_IO_PENDING);
13629   rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get());
13630   ASSERT_EQ(rv, ERR_IO_PENDING);
13631 
13632   // Wait for all the results to arrive.
13633   cb.GetResult(rv);
13634   ASSERT_EQ(cb.results().size(), 2u);
13635 
13636   // Verify that the CreateEntry succeeded.
13637   ASSERT_EQ(cb.results()[0], OK);
13638   // Verify that the DoomEntry requests a restart (CACHE_RACE).
13639   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13640 }
13641 
TEST_F(HttpCacheIOCallbackTest,CreateFollowedByOpenOrCreate)13642 TEST_F(HttpCacheIOCallbackTest, CreateFollowedByOpenOrCreate) {
13643   MockHttpCache cache;
13644   TestCompletionCallbackForHttpCache cb;
13645   std::unique_ptr<Transaction> transaction =
13646       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13647 
13648   transaction->SetIOCallBackForTest(cb.callback());
13649   transaction->SetCacheIOCallBackForTest(cb.callback());
13650 
13651   // Create the backend here as our direct calls to CreateEntry and
13652   // OpenOrCreateEntry below require that it exists.
13653   cache.backend();
13654 
13655   // Need a mock transaction in order to use some of MockHttpCache's
13656   // functions.
13657   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13658 
13659   ActiveEntry* entry1 = nullptr;
13660   ActiveEntry* entry2 = nullptr;
13661 
13662   // Queue up our operations.
13663   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13664                        transaction.get());
13665   ASSERT_EQ(rv, ERR_IO_PENDING);
13666   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13667                          transaction.get());
13668   ASSERT_EQ(rv, ERR_IO_PENDING);
13669 
13670   // Wait for all the results to arrive.
13671   cb.GetResult(rv);
13672   ASSERT_EQ(cb.results().size(), 2u);
13673 
13674   // Verify that the CreateEntry succeeded.
13675   ASSERT_EQ(cb.results()[0], OK);
13676   ASSERT_NE(entry1, nullptr);
13677   // Verify that OpenOrCreateEntry succeeded.
13678   ASSERT_EQ(cb.results()[1], OK);
13679   ASSERT_NE(entry2, nullptr);
13680   ASSERT_EQ(entry1->disk_entry, entry2->disk_entry);
13681 }
13682 
TEST_F(HttpCacheIOCallbackTest,FailedCreateFollowedByOpenOrCreate)13683 TEST_F(HttpCacheIOCallbackTest, FailedCreateFollowedByOpenOrCreate) {
13684   MockHttpCache cache;
13685   TestCompletionCallbackForHttpCache cb;
13686   std::unique_ptr<Transaction> transaction =
13687       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13688 
13689   transaction->SetIOCallBackForTest(cb.callback());
13690   transaction->SetCacheIOCallBackForTest(cb.callback());
13691 
13692   // Create the backend here as our direct calls to CreateEntry and
13693   // OpenOrCreateEntry below require that it exists.
13694   cache.backend();
13695 
13696   // Need a mock transaction in order to use some of MockHttpCache's
13697   // functions.
13698   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13699 
13700   ActiveEntry* entry1 = nullptr;
13701   ActiveEntry* entry2 = nullptr;
13702 
13703   cache.disk_cache()->set_force_fail_callback_later(true);
13704 
13705   // Queue up our operations.
13706   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13707                        transaction.get());
13708   ASSERT_EQ(rv, ERR_IO_PENDING);
13709   cache.disk_cache()->set_force_fail_callback_later(false);
13710   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13711                          transaction.get());
13712   ASSERT_EQ(rv, ERR_IO_PENDING);
13713 
13714   // Wait for all the results to arrive.
13715   cb.GetResult(rv);
13716   ASSERT_EQ(cb.results().size(), 2u);
13717 
13718   // Verify that CreateEntry failed correctly.
13719   ASSERT_EQ(cb.results()[0], ERR_CACHE_CREATE_FAILURE);
13720   ASSERT_EQ(entry1, nullptr);
13721   // Verify that the OpenOrCreateEntry requests a restart (CACHE_RACE).
13722   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13723   ASSERT_EQ(entry2, nullptr);
13724 }
13725 
TEST_F(HttpCacheIOCallbackTest,OpenFollowedByOpenOrCreate)13726 TEST_F(HttpCacheIOCallbackTest, OpenFollowedByOpenOrCreate) {
13727   MockHttpCache cache;
13728   TestCompletionCallbackForHttpCache cb;
13729   std::unique_ptr<Transaction> transaction =
13730       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13731 
13732   transaction->SetIOCallBackForTest(cb.callback());
13733   transaction->SetCacheIOCallBackForTest(cb.callback());
13734 
13735   // Create the backend here as our direct calls to OpenEntry and
13736   // OpenOrCreateEntry below require that it exists.
13737   cache.backend();
13738 
13739   // Need a mock transaction in order to use some of MockHttpCache's
13740   // functions.
13741   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13742 
13743   ActiveEntry* entry0 = nullptr;
13744   ActiveEntry* entry1 = nullptr;
13745   ActiveEntry* entry2 = nullptr;
13746 
13747   // First need to create and entry so we can open it.
13748   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry0,
13749                        transaction.get());
13750   ASSERT_EQ(rv, ERR_IO_PENDING);
13751   cb.GetResult(rv);
13752   ASSERT_EQ(cb.results().size(), static_cast<size_t>(1));
13753   ASSERT_EQ(cb.results()[0], OK);
13754   ASSERT_NE(entry0, nullptr);
13755   // Manually DeactivateEntry() because OpenEntry() fails if there is an
13756   // existing active entry.
13757   DeactivateEntry(cache.http_cache(), entry0);
13758 
13759   // Queue up our operations.
13760   rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry1,
13761                  transaction.get());
13762   ASSERT_EQ(rv, ERR_IO_PENDING);
13763   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13764                          transaction.get());
13765   ASSERT_EQ(rv, ERR_IO_PENDING);
13766 
13767   // Wait for all the results to arrive.
13768   cb.GetResult(rv);
13769   ASSERT_EQ(cb.results().size(), 3u);
13770 
13771   // Verify that the OpenEntry succeeded.
13772   ASSERT_EQ(cb.results()[1], OK);
13773   ASSERT_NE(entry1, nullptr);
13774   // Verify that OpenOrCreateEntry succeeded.
13775   ASSERT_EQ(cb.results()[2], OK);
13776   ASSERT_NE(entry2, nullptr);
13777   ASSERT_EQ(entry1->disk_entry, entry2->disk_entry);
13778 }
13779 
TEST_F(HttpCacheIOCallbackTest,FailedOpenFollowedByOpenOrCreate)13780 TEST_F(HttpCacheIOCallbackTest, FailedOpenFollowedByOpenOrCreate) {
13781   MockHttpCache cache;
13782   TestCompletionCallbackForHttpCache cb;
13783   std::unique_ptr<Transaction> transaction =
13784       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13785 
13786   transaction->SetIOCallBackForTest(cb.callback());
13787   transaction->SetCacheIOCallBackForTest(cb.callback());
13788 
13789   // Create the backend here as our direct calls to OpenEntry and
13790   // OpenOrCreateEntry below require that it exists.
13791   cache.backend();
13792 
13793   // Need a mock transaction in order to use some of MockHttpCache's
13794   // functions.
13795   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13796 
13797   ActiveEntry* entry1 = nullptr;
13798   ActiveEntry* entry2 = nullptr;
13799 
13800   cache.disk_cache()->set_force_fail_callback_later(true);
13801 
13802   // Queue up our operations.
13803   int rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry1,
13804                      transaction.get());
13805   ASSERT_EQ(rv, ERR_IO_PENDING);
13806   cache.disk_cache()->set_force_fail_callback_later(false);
13807   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13808                          transaction.get());
13809   ASSERT_EQ(rv, ERR_IO_PENDING);
13810 
13811   // Wait for all the results to arrive.
13812   cb.GetResult(rv);
13813   ASSERT_EQ(cb.results().size(), 2u);
13814 
13815   // Verify that OpenEntry failed correctly.
13816   ASSERT_EQ(cb.results()[0], ERR_CACHE_OPEN_FAILURE);
13817   ASSERT_EQ(entry1, nullptr);
13818   // Verify that the OpenOrCreateEntry requests a restart (CACHE_RACE).
13819   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13820   ASSERT_EQ(entry2, nullptr);
13821 }
13822 
TEST_F(HttpCacheIOCallbackTest,OpenOrCreateFollowedByCreate)13823 TEST_F(HttpCacheIOCallbackTest, OpenOrCreateFollowedByCreate) {
13824   MockHttpCache cache;
13825   TestCompletionCallbackForHttpCache cb;
13826   std::unique_ptr<Transaction> transaction =
13827       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13828 
13829   transaction->SetIOCallBackForTest(cb.callback());
13830   transaction->SetCacheIOCallBackForTest(cb.callback());
13831 
13832   // Create the backend here as our direct calls to OpenOrCreateEntry and
13833   // CreateEntry below require that it exists.
13834   cache.backend();
13835 
13836   // Need a mock transaction in order to use some of MockHttpCache's
13837   // functions.
13838   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13839 
13840   ActiveEntry* entry1 = nullptr;
13841   ActiveEntry* entry2 = nullptr;
13842 
13843   // Queue up our operations.
13844   int rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13845                              transaction.get());
13846   ASSERT_EQ(rv, ERR_IO_PENDING);
13847   rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13848                    transaction.get());
13849   ASSERT_EQ(rv, ERR_IO_PENDING);
13850 
13851   // Wait for all the results to arrive.
13852   cb.GetResult(rv);
13853   ASSERT_EQ(cb.results().size(), 2u);
13854 
13855   // Verify that the OpenOrCreateEntry succeeded.
13856   ASSERT_EQ(cb.results()[0], OK);
13857   ASSERT_NE(entry1, nullptr);
13858   // Verify that CreateEntry failed.
13859   ASSERT_EQ(cb.results()[1], ERR_CACHE_CREATE_FAILURE);
13860   ASSERT_EQ(entry2, nullptr);
13861 }
13862 
TEST_F(HttpCacheIOCallbackTest,OpenOrCreateFollowedByOpenOrCreate)13863 TEST_F(HttpCacheIOCallbackTest, OpenOrCreateFollowedByOpenOrCreate) {
13864   MockHttpCache cache;
13865   TestCompletionCallbackForHttpCache cb;
13866   std::unique_ptr<Transaction> transaction =
13867       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13868 
13869   transaction->SetIOCallBackForTest(cb.callback());
13870   transaction->SetCacheIOCallBackForTest(cb.callback());
13871 
13872   // Create the backend here as our direct calls to OpenOrCreateEntry below
13873   // require that it exists.
13874   cache.backend();
13875 
13876   // Need a mock transaction in order to use some of MockHttpCache's
13877   // functions.
13878   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13879 
13880   ActiveEntry* entry1 = nullptr;
13881   ActiveEntry* entry2 = nullptr;
13882 
13883   // Queue up our operations.
13884   int rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13885                              transaction.get());
13886   ASSERT_EQ(rv, ERR_IO_PENDING);
13887   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13888                          transaction.get());
13889   ASSERT_EQ(rv, ERR_IO_PENDING);
13890 
13891   // Wait for all the results to arrive.
13892   cb.GetResult(rv);
13893   ASSERT_EQ(cb.results().size(), 2u);
13894 
13895   // Verify that the OpenOrCreateEntry succeeded.
13896   ASSERT_EQ(cb.results()[0], OK);
13897   ASSERT_NE(entry1, nullptr);
13898   // Verify that the other succeeded.
13899   ASSERT_EQ(cb.results()[1], OK);
13900   ASSERT_NE(entry2, nullptr);
13901 }
13902 
TEST_F(HttpCacheIOCallbackTest,FailedOpenOrCreateFollowedByOpenOrCreate)13903 TEST_F(HttpCacheIOCallbackTest, FailedOpenOrCreateFollowedByOpenOrCreate) {
13904   MockHttpCache cache;
13905   TestCompletionCallbackForHttpCache cb;
13906   std::unique_ptr<Transaction> transaction =
13907       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13908 
13909   transaction->SetIOCallBackForTest(cb.callback());
13910   transaction->SetCacheIOCallBackForTest(cb.callback());
13911 
13912   // Create the backend here as our direct calls to OpenOrCreateEntry below
13913   // require that it exists.
13914   cache.backend();
13915 
13916   // Need a mock transaction in order to use some of MockHttpCache's
13917   // functions.
13918   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13919 
13920   ActiveEntry* entry1 = nullptr;
13921   ActiveEntry* entry2 = nullptr;
13922 
13923   cache.disk_cache()->set_force_fail_callback_later(true);
13924 
13925   // Queue up our operations.
13926   int rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13927                              transaction.get());
13928   ASSERT_EQ(rv, ERR_IO_PENDING);
13929   cache.disk_cache()->set_force_fail_callback_later(false);
13930   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13931                          transaction.get());
13932   ASSERT_EQ(rv, ERR_IO_PENDING);
13933 
13934   // Wait for all the results to arrive.
13935   cb.GetResult(rv);
13936   ASSERT_EQ(cb.results().size(), 2u);
13937 
13938   // Verify that the OpenOrCreateEntry failed.
13939   ASSERT_EQ(cb.results()[0], ERR_CACHE_OPEN_OR_CREATE_FAILURE);
13940   ASSERT_EQ(entry1, nullptr);
13941   // Verify that the other failed.
13942   ASSERT_EQ(cb.results()[1], ERR_CACHE_OPEN_OR_CREATE_FAILURE);
13943   ASSERT_EQ(entry2, nullptr);
13944 }
13945 
TEST_F(HttpCacheTest,DnsAliasesNoRevalidation)13946 TEST_F(HttpCacheTest, DnsAliasesNoRevalidation) {
13947   MockHttpCache cache;
13948   HttpResponseInfo response;
13949   ScopedMockTransaction transaction(kSimpleGET_Transaction);
13950   transaction.dns_aliases = {"alias1", "alias2"};
13951 
13952   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13953                                      &response);
13954   EXPECT_FALSE(response.was_cached);
13955   EXPECT_THAT(response.dns_aliases, testing::ElementsAre("alias1", "alias2"));
13956 
13957   // The second request result in a cache hit and the response used without
13958   // revalidation. Set the transaction alias list to empty to verify that the
13959   // cached aliases are being used.
13960   transaction.dns_aliases = {};
13961   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13962                                      &response);
13963   EXPECT_TRUE(response.was_cached);
13964   EXPECT_THAT(response.dns_aliases, testing::ElementsAre("alias1", "alias2"));
13965 }
13966 
TEST_F(HttpCacheTest,NoDnsAliasesNoRevalidation)13967 TEST_F(HttpCacheTest, NoDnsAliasesNoRevalidation) {
13968   MockHttpCache cache;
13969   HttpResponseInfo response;
13970   ScopedMockTransaction transaction(kSimpleGET_Transaction);
13971   transaction.dns_aliases = {};
13972 
13973   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13974                                      &response);
13975   EXPECT_FALSE(response.was_cached);
13976   EXPECT_TRUE(response.dns_aliases.empty());
13977 
13978   // The second request should result in a cache hit and the response used
13979   // without revalidation. Set the transaction alias list to nonempty to verify
13980   // that the cached aliases are being used.
13981   transaction.dns_aliases = {"alias"};
13982   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13983                                      &response);
13984   EXPECT_TRUE(response.was_cached);
13985   EXPECT_TRUE(response.dns_aliases.empty());
13986 }
13987 
TEST_F(HttpCacheTest,DnsAliasesRevalidation)13988 TEST_F(HttpCacheTest, DnsAliasesRevalidation) {
13989   MockHttpCache cache;
13990   HttpResponseInfo response;
13991   ScopedMockTransaction transaction(kTypicalGET_Transaction);
13992   transaction.response_headers =
13993       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
13994       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
13995       "Cache-Control: max-age=0\n";
13996   transaction.dns_aliases = {"alias1", "alias2"};
13997 
13998   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13999                                      &response);
14000   EXPECT_FALSE(response.was_cached);
14001   EXPECT_THAT(response.dns_aliases, testing::ElementsAre("alias1", "alias2"));
14002 
14003   // On the second request, the cache should be revalidated. Change the aliases
14004   // to be sure that the new aliases are being used, and have the response be
14005   // cached for next time.
14006   transaction.response_headers = "Cache-Control: max-age=10000\n";
14007   transaction.dns_aliases = {"alias3", "alias4"};
14008   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
14009                                      &response);
14010   EXPECT_FALSE(response.was_cached);
14011   EXPECT_THAT(response.dns_aliases, testing::ElementsAre("alias3", "alias4"));
14012 
14013   transaction.dns_aliases = {"alias5", "alias6"};
14014   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
14015                                      &response);
14016   EXPECT_TRUE(response.was_cached);
14017   EXPECT_THAT(response.dns_aliases, testing::ElementsAre("alias3", "alias4"));
14018 }
14019 
TEST_F(HttpCacheTest,FirstPartySetsBypassCache_ShouldBypass_NoId)14020 TEST_F(HttpCacheTest, FirstPartySetsBypassCache_ShouldBypass_NoId) {
14021   MockHttpCache cache;
14022   HttpResponseInfo response;
14023   ScopedMockTransaction transaction(kSimpleGET_Transaction);
14024 
14025   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
14026                                      &response);
14027   EXPECT_FALSE(response.was_cached);
14028 
14029   transaction.fps_cache_filter = {5};
14030   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
14031                                      &response);
14032   EXPECT_FALSE(response.was_cached);
14033 }
14034 
TEST_F(HttpCacheTest,FirstPartySetsBypassCache_ShouldBypass_IdTooSmall)14035 TEST_F(HttpCacheTest, FirstPartySetsBypassCache_ShouldBypass_IdTooSmall) {
14036   MockHttpCache cache;
14037   HttpResponseInfo response;
14038   ScopedMockTransaction transaction(kSimpleGET_Transaction);
14039   const int64_t kBrowserRunId = 4;
14040   transaction.browser_run_id = {kBrowserRunId};
14041   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
14042                                      &response);
14043   EXPECT_FALSE(response.was_cached);
14044   EXPECT_TRUE(response.browser_run_id.has_value());
14045   EXPECT_EQ(kBrowserRunId, response.browser_run_id.value());
14046 
14047   transaction.fps_cache_filter = {5};
14048   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
14049                                      &response);
14050   EXPECT_FALSE(response.was_cached);
14051 }
14052 
TEST_F(HttpCacheTest,FirstPartySetsBypassCache_ShouldNotBypass)14053 TEST_F(HttpCacheTest, FirstPartySetsBypassCache_ShouldNotBypass) {
14054   MockHttpCache cache;
14055   HttpResponseInfo response;
14056   ScopedMockTransaction transaction(kSimpleGET_Transaction);
14057   const int64_t kBrowserRunId = 5;
14058   transaction.browser_run_id = {kBrowserRunId};
14059   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
14060                                      &response);
14061   EXPECT_FALSE(response.was_cached);
14062   EXPECT_TRUE(response.browser_run_id.has_value());
14063   EXPECT_EQ(kBrowserRunId, response.browser_run_id.value());
14064 
14065   transaction.fps_cache_filter = {5};
14066   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
14067                                      &response);
14068   EXPECT_TRUE(response.was_cached);
14069 }
14070 
TEST_F(HttpCacheTest,FirstPartySetsBypassCache_ShouldNotBypass_NoFilter)14071 TEST_F(HttpCacheTest, FirstPartySetsBypassCache_ShouldNotBypass_NoFilter) {
14072   MockHttpCache cache;
14073   HttpResponseInfo response;
14074   ScopedMockTransaction transaction(kSimpleGET_Transaction);
14075 
14076   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
14077                                      &response);
14078   EXPECT_FALSE(response.was_cached);
14079 
14080   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
14081                                      &response);
14082   EXPECT_TRUE(response.was_cached);
14083 }
14084 
TEST_F(HttpCacheTest,SecurityHeadersAreCopiedToConditionalizedResponse)14085 TEST_F(HttpCacheTest, SecurityHeadersAreCopiedToConditionalizedResponse) {
14086   MockHttpCache cache;
14087   HttpResponseInfo response;
14088   ScopedMockTransaction transaction(kSimpleGET_Transaction);
14089 
14090   static const Response kNetResponse1 = {
14091       "HTTP/1.1 200 OK",
14092       "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
14093       "Server: server1\n"
14094       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n"
14095       "Cross-Origin-Resource-Policy: cross-origin\n",
14096       "body1"};
14097 
14098   static const Response kNetResponse2 = {
14099       "HTTP/1.1 304 Not Modified",
14100       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
14101       "Server: server2\n"
14102       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
14103       ""};
14104 
14105   kNetResponse1.AssignTo(&transaction);
14106   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
14107                                      &response);
14108 
14109   // On the second request, the cache is revalidated.
14110   const char kExtraRequestHeaders[] =
14111       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
14112   transaction.request_headers = kExtraRequestHeaders;
14113   kNetResponse2.AssignTo(&transaction);
14114   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
14115                                      &response);
14116 
14117   // Verify that the CORP header was carried over to the response.
14118   std::string response_corp_header;
14119   response.headers->GetNormalizedHeader("Cross-Origin-Resource-Policy",
14120                                         &response_corp_header);
14121 
14122   EXPECT_EQ(304, response.headers->response_code());
14123   EXPECT_EQ("cross-origin", response_corp_header);
14124 }
14125 
14126 }  // namespace net
14127