xref: /aosp_15_r20/external/cronet/net/http/http_cache_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 <optional>
12 #include <set>
13 #include <utility>
14 #include <vector>
15 
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 "url/origin.h"
79 
80 using net::test::IsError;
81 using net::test::IsOk;
82 using testing::AllOf;
83 using testing::ByRef;
84 using testing::Contains;
85 using testing::ElementsAre;
86 using testing::Eq;
87 using testing::Field;
88 using testing::Gt;
89 using testing::IsEmpty;
90 using testing::NotNull;
91 
92 using base::Time;
93 
94 namespace net {
95 
96 using CacheEntryStatus = HttpResponseInfo::CacheEntryStatus;
97 
98 class WebSocketEndpointLockManager;
99 
100 namespace {
101 
102 constexpr auto ToSimpleString = test::HttpResponseHeadersToSimpleString;
103 
104 // Tests the load timing values of a request that goes through a
105 // MockNetworkTransaction.
TestLoadTimingNetworkRequest(const LoadTimingInfo & load_timing_info)106 void TestLoadTimingNetworkRequest(const LoadTimingInfo& load_timing_info) {
107   EXPECT_FALSE(load_timing_info.socket_reused);
108   EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
109 
110   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
111   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
112 
113   ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
114                               CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
115   EXPECT_LE(load_timing_info.connect_timing.connect_end,
116             load_timing_info.send_start);
117 
118   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
119 
120   // Set by URLRequest / URLRequestHttpJob, at a higher level.
121   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
122   EXPECT_TRUE(load_timing_info.request_start.is_null());
123   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
124 }
125 
126 // Tests the load timing values of a request that receives a cached response.
TestLoadTimingCachedResponse(const LoadTimingInfo & load_timing_info)127 void TestLoadTimingCachedResponse(const LoadTimingInfo& load_timing_info) {
128   EXPECT_FALSE(load_timing_info.socket_reused);
129   EXPECT_EQ(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
130 
131   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
132   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
133 
134   ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
135 
136   // Only the send start / end times should be sent, and they should have the
137   // same value.
138   EXPECT_FALSE(load_timing_info.send_start.is_null());
139   EXPECT_EQ(load_timing_info.send_start, load_timing_info.send_end);
140 
141   // Set by URLRequest / URLRequestHttpJob, at a higher level.
142   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
143   EXPECT_TRUE(load_timing_info.request_start.is_null());
144   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
145 }
146 
DeferCallback(bool * defer)147 void DeferCallback(bool* defer) {
148   *defer = true;
149 }
150 
151 class DeleteCacheCompletionCallback : public TestCompletionCallbackBase {
152  public:
DeleteCacheCompletionCallback(std::unique_ptr<MockHttpCache> cache)153   explicit DeleteCacheCompletionCallback(std::unique_ptr<MockHttpCache> cache)
154       : cache_(std::move(cache)) {}
155 
156   DeleteCacheCompletionCallback(const DeleteCacheCompletionCallback&) = delete;
157   DeleteCacheCompletionCallback& operator=(
158       const DeleteCacheCompletionCallback&) = delete;
159 
callback()160   CompletionOnceCallback callback() {
161     return base::BindOnce(&DeleteCacheCompletionCallback::OnComplete,
162                           base::Unretained(this));
163   }
164 
165  private:
OnComplete(int result)166   void OnComplete(int result) {
167     cache_.reset();
168     SetResult(result);
169   }
170 
171   std::unique_ptr<MockHttpCache> cache_;
172 };
173 
174 //-----------------------------------------------------------------------------
175 // helpers
176 
ReadAndVerifyTransaction(HttpTransaction * trans,const MockTransaction & trans_info)177 void ReadAndVerifyTransaction(HttpTransaction* trans,
178                               const MockTransaction& trans_info) {
179   std::string content;
180   int rv = ReadTransaction(trans, &content);
181 
182   EXPECT_THAT(rv, IsOk());
183   std::string expected(trans_info.data);
184   EXPECT_EQ(expected, content);
185 }
186 
ReadRemainingAndVerifyTransaction(HttpTransaction * trans,const std::string & already_read,const MockTransaction & trans_info)187 void ReadRemainingAndVerifyTransaction(HttpTransaction* trans,
188                                        const std::string& already_read,
189                                        const MockTransaction& trans_info) {
190   std::string content;
191   int rv = ReadTransaction(trans, &content);
192   EXPECT_THAT(rv, IsOk());
193 
194   std::string expected(trans_info.data);
195   EXPECT_EQ(expected, already_read + content);
196 }
197 
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)198 void RunTransactionTestBase(HttpCache* cache,
199                             const MockTransaction& trans_info,
200                             const MockHttpRequest& request,
201                             HttpResponseInfo* response_info,
202                             const NetLogWithSource& net_log,
203                             LoadTimingInfo* load_timing_info,
204                             int64_t* sent_bytes,
205                             int64_t* received_bytes,
206                             IPEndPoint* remote_endpoint) {
207   TestCompletionCallback callback;
208 
209   // write to the cache
210 
211   std::unique_ptr<HttpTransaction> trans;
212   int rv = cache->CreateTransaction(DEFAULT_PRIORITY, &trans);
213   EXPECT_THAT(rv, IsOk());
214   ASSERT_TRUE(trans.get());
215 
216   rv = trans->Start(&request, callback.callback(), net_log);
217   if (rv == ERR_IO_PENDING) {
218     rv = callback.WaitForResult();
219   }
220   ASSERT_EQ(trans_info.start_return_code, rv);
221 
222   if (OK != rv) {
223     return;
224   }
225 
226   const HttpResponseInfo* response = trans->GetResponseInfo();
227   ASSERT_TRUE(response);
228 
229   if (response_info) {
230     *response_info = *response;
231   }
232 
233   if (load_timing_info) {
234     // If a fake network connection is used, need a NetLog to get a fake socket
235     // ID.
236     EXPECT_TRUE(net_log.net_log());
237     *load_timing_info = LoadTimingInfo();
238     trans->GetLoadTimingInfo(load_timing_info);
239   }
240 
241   if (remote_endpoint) {
242     ASSERT_TRUE(trans->GetRemoteEndpoint(remote_endpoint));
243   }
244 
245   ReadAndVerifyTransaction(trans.get(), trans_info);
246 
247   if (sent_bytes) {
248     *sent_bytes = trans->GetTotalSentBytes();
249   }
250   if (received_bytes) {
251     *received_bytes = trans->GetTotalReceivedBytes();
252   }
253 }
254 
RunTransactionTestWithRequest(HttpCache * cache,const MockTransaction & trans_info,const MockHttpRequest & request,HttpResponseInfo * response_info)255 void RunTransactionTestWithRequest(HttpCache* cache,
256                                    const MockTransaction& trans_info,
257                                    const MockHttpRequest& request,
258                                    HttpResponseInfo* response_info) {
259   RunTransactionTestBase(cache, trans_info, request, response_info,
260                          NetLogWithSource(), nullptr, nullptr, nullptr,
261                          nullptr);
262 }
263 
RunTransactionTestAndGetTiming(HttpCache * cache,const MockTransaction & trans_info,const NetLogWithSource & log,LoadTimingInfo * load_timing_info)264 void RunTransactionTestAndGetTiming(HttpCache* cache,
265                                     const MockTransaction& trans_info,
266                                     const NetLogWithSource& log,
267                                     LoadTimingInfo* load_timing_info) {
268   RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
269                          nullptr, log, load_timing_info, nullptr, nullptr,
270                          nullptr);
271 }
272 
RunTransactionTestAndGetTimingAndConnectedSocketAddress(HttpCache * cache,const MockTransaction & trans_info,const NetLogWithSource & log,LoadTimingInfo * load_timing_info,IPEndPoint * remote_endpoint)273 void RunTransactionTestAndGetTimingAndConnectedSocketAddress(
274     HttpCache* cache,
275     const MockTransaction& trans_info,
276     const NetLogWithSource& log,
277     LoadTimingInfo* load_timing_info,
278     IPEndPoint* remote_endpoint) {
279   RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
280                          nullptr, log, load_timing_info, nullptr, nullptr,
281                          remote_endpoint);
282 }
283 
RunTransactionTest(HttpCache * cache,const MockTransaction & trans_info)284 void RunTransactionTest(HttpCache* cache, const MockTransaction& trans_info) {
285   RunTransactionTestAndGetTiming(cache, trans_info, NetLogWithSource(),
286                                  nullptr);
287 }
288 
RunTransactionTestWithLog(HttpCache * cache,const MockTransaction & trans_info,const NetLogWithSource & log)289 void RunTransactionTestWithLog(HttpCache* cache,
290                                const MockTransaction& trans_info,
291                                const NetLogWithSource& log) {
292   RunTransactionTestAndGetTiming(cache, trans_info, log, nullptr);
293 }
294 
RunTransactionTestWithResponseInfo(HttpCache * cache,const MockTransaction & trans_info,HttpResponseInfo * response)295 void RunTransactionTestWithResponseInfo(HttpCache* cache,
296                                         const MockTransaction& trans_info,
297                                         HttpResponseInfo* response) {
298   RunTransactionTestWithRequest(cache, trans_info, MockHttpRequest(trans_info),
299                                 response);
300 }
301 
RunTransactionTestWithResponseInfoAndGetTiming(HttpCache * cache,const MockTransaction & trans_info,HttpResponseInfo * response,const NetLogWithSource & log,LoadTimingInfo * load_timing_info)302 void RunTransactionTestWithResponseInfoAndGetTiming(
303     HttpCache* cache,
304     const MockTransaction& trans_info,
305     HttpResponseInfo* response,
306     const NetLogWithSource& log,
307     LoadTimingInfo* load_timing_info) {
308   RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
309                          response, log, load_timing_info, nullptr, nullptr,
310                          nullptr);
311 }
312 
RunTransactionTestWithResponse(HttpCache * cache,const MockTransaction & trans_info,std::string * response_headers)313 void RunTransactionTestWithResponse(HttpCache* cache,
314                                     const MockTransaction& trans_info,
315                                     std::string* response_headers) {
316   HttpResponseInfo response;
317   RunTransactionTestWithResponseInfo(cache, trans_info, &response);
318   *response_headers = ToSimpleString(response.headers);
319 }
320 
RunTransactionTestWithResponseAndGetTiming(HttpCache * cache,const MockTransaction & trans_info,std::string * response_headers,const NetLogWithSource & log,LoadTimingInfo * load_timing_info)321 void RunTransactionTestWithResponseAndGetTiming(
322     HttpCache* cache,
323     const MockTransaction& trans_info,
324     std::string* response_headers,
325     const NetLogWithSource& log,
326     LoadTimingInfo* load_timing_info) {
327   HttpResponseInfo response;
328   RunTransactionTestBase(cache, trans_info, MockHttpRequest(trans_info),
329                          &response, log, load_timing_info, nullptr, nullptr,
330                          nullptr);
331   *response_headers = ToSimpleString(response.headers);
332 }
333 
334 // This class provides a handler for kFastNoStoreGET_Transaction so that the
335 // no-store header can be included on demand.
336 class FastTransactionServer {
337  public:
FastTransactionServer()338   FastTransactionServer() { no_store = false; }
339 
340   FastTransactionServer(const FastTransactionServer&) = delete;
341   FastTransactionServer& operator=(const FastTransactionServer&) = delete;
342 
343   ~FastTransactionServer() = default;
344 
set_no_store(bool value)345   void set_no_store(bool value) { no_store = value; }
346 
FastNoStoreHandler(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)347   static void FastNoStoreHandler(const HttpRequestInfo* request,
348                                  std::string* response_status,
349                                  std::string* response_headers,
350                                  std::string* response_data) {
351     if (no_store) {
352       *response_headers = "Cache-Control: no-store\n";
353     }
354   }
355 
356  private:
357   static bool no_store;
358 };
359 bool FastTransactionServer::no_store;
360 
361 const MockTransaction kFastNoStoreGET_Transaction = {
362     "http://www.google.com/nostore",
363     "GET",
364     base::Time(),
365     "",
366     LOAD_VALIDATE_CACHE,
367     DefaultTransportInfo(),
368     "HTTP/1.1 200 OK",
369     "Cache-Control: max-age=10000\n",
370     base::Time(),
371     "<html><body>Google Blah Blah</body></html>",
372     {},
373     std::nullopt,
374     std::nullopt,
375     TEST_MODE_SYNC_NET_START,
376     base::BindRepeating(&FastTransactionServer::FastNoStoreHandler),
377     MockTransactionReadHandler(),
378     nullptr,
379     0,
380     0,
381     OK,
382 };
383 
384 // This class provides a handler for kRangeGET_TransactionOK so that the range
385 // request can be served on demand.
386 class RangeTransactionServer {
387  public:
RangeTransactionServer()388   RangeTransactionServer() {
389     not_modified_ = false;
390     modified_ = false;
391     bad_200_ = false;
392     redirect_ = false;
393     length_ = 80;
394   }
395 
396   RangeTransactionServer(const RangeTransactionServer&) = delete;
397   RangeTransactionServer& operator=(const RangeTransactionServer&) = delete;
398 
~RangeTransactionServer()399   ~RangeTransactionServer() {
400     not_modified_ = false;
401     modified_ = false;
402     bad_200_ = false;
403     redirect_ = false;
404     length_ = 80;
405   }
406 
407   // Returns only 416 or 304 when set.
set_not_modified(bool value)408   void set_not_modified(bool value) { not_modified_ = value; }
409 
410   // Returns 206 when revalidating a range (instead of 304).
set_modified(bool value)411   void set_modified(bool value) { modified_ = value; }
412 
413   // Returns 200 instead of 206 (a malformed response overall).
set_bad_200(bool value)414   void set_bad_200(bool value) { bad_200_ = value; }
415 
416   // Sets how long the resource is. (Default is 80)
set_length(int64_t length)417   void set_length(int64_t length) { length_ = length; }
418 
419   // Sets whether to return a 301 instead of normal return.
set_redirect(bool redirect)420   void set_redirect(bool redirect) { redirect_ = redirect; }
421 
422   // Other than regular range related behavior (and the flags mentioned above),
423   // the server reacts to requests headers like so:
424   //   X-Require-Mock-Auth -> return 401.
425   //   X-Require-Mock-Auth-Alt -> return 401.
426   //   X-Return-Default-Range -> assume 40-49 was requested.
427   // The -Alt variant doesn't cause the MockNetworkTransaction to
428   // report that it IsReadyToRestartForAuth().
429   static void RangeHandler(const HttpRequestInfo* request,
430                            std::string* response_status,
431                            std::string* response_headers,
432                            std::string* response_data);
433 
434  private:
435   static bool not_modified_;
436   static bool modified_;
437   static bool bad_200_;
438   static bool redirect_;
439   static int64_t length_;
440 };
441 bool RangeTransactionServer::not_modified_ = false;
442 bool RangeTransactionServer::modified_ = false;
443 bool RangeTransactionServer::bad_200_ = false;
444 bool RangeTransactionServer::redirect_ = false;
445 int64_t RangeTransactionServer::length_ = 80;
446 
447 // A dummy extra header that must be preserved on a given request.
448 
449 // EXTRA_HEADER_LINE doesn't include a line terminator because it
450 // will be passed to AddHeaderFromString() which doesn't accept them.
451 #define EXTRA_HEADER_LINE "Extra: header"
452 
453 // EXTRA_HEADER contains a line terminator, as expected by
454 // AddHeadersFromString() (_not_ AddHeaderFromString()).
455 #define EXTRA_HEADER EXTRA_HEADER_LINE "\r\n"
456 
457 static const char kExtraHeaderKey[] = "Extra";
458 
459 // Static.
RangeHandler(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)460 void RangeTransactionServer::RangeHandler(const HttpRequestInfo* request,
461                                           std::string* response_status,
462                                           std::string* response_headers,
463                                           std::string* response_data) {
464   if (request->extra_headers.IsEmpty()) {
465     response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
466     response_data->clear();
467     return;
468   }
469 
470   // We want to make sure we don't delete extra headers.
471   EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
472 
473   bool require_auth =
474       request->extra_headers.HasHeader("X-Require-Mock-Auth") ||
475       request->extra_headers.HasHeader("X-Require-Mock-Auth-Alt");
476 
477   if (require_auth && !request->extra_headers.HasHeader("Authorization")) {
478     response_status->assign("HTTP/1.1 401 Unauthorized");
479     response_data->assign("WWW-Authenticate: Foo\n");
480     return;
481   }
482 
483   if (redirect_) {
484     response_status->assign("HTTP/1.1 301 Moved Permanently");
485     response_headers->assign("Location: /elsewhere\nContent-Length: 5");
486     response_data->assign("12345");
487     return;
488   }
489 
490   if (not_modified_) {
491     response_status->assign("HTTP/1.1 304 Not Modified");
492     response_data->clear();
493     return;
494   }
495 
496   std::vector<HttpByteRange> ranges;
497   std::string range_header;
498   if (!request->extra_headers.GetHeader(HttpRequestHeaders::kRange,
499                                         &range_header) ||
500       !HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ ||
501       ranges.size() != 1 ||
502       (modified_ && request->extra_headers.HasHeader("If-Range"))) {
503     // This is not a byte range request, or a failed If-Range. We return 200.
504     response_status->assign("HTTP/1.1 200 OK");
505     response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT");
506     response_data->assign("Not a range");
507     return;
508   }
509 
510   // We can handle this range request.
511   HttpByteRange byte_range = ranges[0];
512 
513   if (request->extra_headers.HasHeader("X-Return-Default-Range")) {
514     byte_range.set_first_byte_position(40);
515     byte_range.set_last_byte_position(49);
516   }
517 
518   if (byte_range.first_byte_position() >= length_) {
519     response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable");
520     response_data->clear();
521     return;
522   }
523 
524   EXPECT_TRUE(byte_range.ComputeBounds(length_));
525   int64_t start = byte_range.first_byte_position();
526   int64_t end = byte_range.last_byte_position();
527 
528   EXPECT_LT(end, length_);
529 
530   std::string content_range = base::StringPrintf("Content-Range: bytes %" PRId64
531                                                  "-%" PRId64 "/%" PRId64 "\n",
532                                                  start, end, length_);
533   response_headers->append(content_range);
534 
535   if (!request->extra_headers.HasHeader("If-None-Match") || modified_) {
536     std::string data;
537     if (end == start) {
538       EXPECT_EQ(0, end % 10);
539       data = "r";
540     } else {
541       EXPECT_EQ(9, (end - start) % 10);
542       for (int64_t block_start = start; block_start < end; block_start += 10) {
543         base::StringAppendF(&data, "rg: %02" PRId64 "-%02" PRId64 " ",
544                             block_start % 100, (block_start + 9) % 100);
545       }
546     }
547     *response_data = data;
548 
549     if (end - start != 9) {
550       // We also have to fix content-length.
551       int64_t len = end - start + 1;
552       std::string content_length =
553           base::StringPrintf("Content-Length: %" PRId64 "\n", len);
554       response_headers->replace(response_headers->find("Content-Length:"),
555                                 content_length.size(), content_length);
556     }
557   } else {
558     response_status->assign("HTTP/1.1 304 Not Modified");
559     response_data->clear();
560   }
561 }
562 
563 const MockTransaction kRangeGET_TransactionOK = {
564     "http://www.google.com/range",
565     "GET",
566     base::Time(),
567     "Range: bytes = 40-49\r\n" EXTRA_HEADER,
568     LOAD_NORMAL,
569     DefaultTransportInfo(),
570     "HTTP/1.1 206 Partial Content",
571     "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
572     "ETag: \"foo\"\n"
573     "Accept-Ranges: bytes\n"
574     "Content-Length: 10\n",
575     base::Time(),
576     "rg: 40-49 ",
577     {},
578     std::nullopt,
579     std::nullopt,
580     TEST_MODE_NORMAL,
581     base::BindRepeating(&RangeTransactionServer::RangeHandler),
582     MockTransactionReadHandler(),
583     nullptr,
584     0,
585     0,
586     OK,
587 };
588 
589 const char kFullRangeData[] =
590     "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 "
591     "rg: 40-49 rg: 50-59 rg: 60-69 rg: 70-79 ";
592 
593 // Verifies the response headers (|response|) match a partial content
594 // response for the range starting at |start| and ending at |end|.
Verify206Response(const std::string & response,int start,int end)595 void Verify206Response(const std::string& response, int start, int end) {
596   auto headers = base::MakeRefCounted<HttpResponseHeaders>(
597       HttpUtil::AssembleRawHeaders(response));
598 
599   ASSERT_EQ(206, headers->response_code());
600 
601   int64_t range_start, range_end, object_size;
602   ASSERT_TRUE(
603       headers->GetContentRangeFor206(&range_start, &range_end, &object_size));
604   int64_t content_length = headers->GetContentLength();
605 
606   int length = end - start + 1;
607   ASSERT_EQ(length, content_length);
608   ASSERT_EQ(start, range_start);
609   ASSERT_EQ(end, range_end);
610 }
611 
612 // Creates a truncated entry that can be resumed using byte ranges.
CreateTruncatedEntry(std::string raw_headers,MockHttpCache * cache)613 void CreateTruncatedEntry(std::string raw_headers, MockHttpCache* cache) {
614   // Create a disk cache entry that stores an incomplete resource.
615   disk_cache::Entry* entry;
616   MockHttpRequest request(kRangeGET_TransactionOK);
617   ASSERT_TRUE(cache->CreateBackendEntry(request.CacheKey(), &entry, nullptr));
618 
619   HttpResponseInfo response;
620   response.response_time = base::Time::Now();
621   response.request_time = base::Time::Now();
622   response.headers = base::MakeRefCounted<HttpResponseHeaders>(
623       HttpUtil::AssembleRawHeaders(raw_headers));
624   // Set the last argument for this to be an incomplete request.
625   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
626 
627   auto buf = base::MakeRefCounted<IOBufferWithSize>(100);
628   int len =
629       static_cast<int>(base::strlcpy(buf->data(), "rg: 00-09 rg: 10-19 ", 100));
630   TestCompletionCallback cb;
631   int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
632   EXPECT_EQ(len, cb.GetResult(rv));
633   entry->Close();
634 }
635 
636 // Verifies that there's an entry with this |key| with the truncated flag set to
637 // |flag_value|, and with an optional |data_size| (if not zero).
VerifyTruncatedFlag(MockHttpCache * cache,const std::string & key,bool flag_value,int data_size)638 void VerifyTruncatedFlag(MockHttpCache* cache,
639                          const std::string& key,
640                          bool flag_value,
641                          int data_size) {
642   disk_cache::Entry* entry;
643   ASSERT_TRUE(cache->OpenBackendEntry(key, &entry));
644   disk_cache::ScopedEntryPtr closer(entry);
645 
646   HttpResponseInfo response;
647   bool truncated = !flag_value;
648   EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
649   EXPECT_EQ(flag_value, truncated);
650   if (data_size) {
651     EXPECT_EQ(data_size, entry->GetDataSize(1));
652   }
653 }
654 
655 // Helper to represent a network HTTP response.
656 struct Response {
657   // Set this response into |trans|.
AssignTonet::__anone6acdaec0111::Response658   void AssignTo(MockTransaction* trans) const {
659     trans->status = status;
660     trans->response_headers = headers;
661     trans->data = body;
662   }
663 
status_and_headersnet::__anone6acdaec0111::Response664   std::string status_and_headers() const {
665     return std::string(status) + "\n" + std::string(headers);
666   }
667 
668   const char* status;
669   const char* headers;
670   const char* body;
671 };
672 
673 struct Context {
674   Context() = default;
675 
676   int result = ERR_IO_PENDING;
677   TestCompletionCallback callback;
678   std::unique_ptr<HttpTransaction> trans;
679 };
680 
681 class FakeWebSocketHandshakeStreamCreateHelper
682     : public WebSocketHandshakeStreamBase::CreateHelper {
683  public:
684   ~FakeWebSocketHandshakeStreamCreateHelper() override = default;
CreateBasicStream(std::unique_ptr<ClientSocketHandle> connect,bool using_proxy,WebSocketEndpointLockManager * websocket_endpoint_lock_manager)685   std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
686       std::unique_ptr<ClientSocketHandle> connect,
687       bool using_proxy,
688       WebSocketEndpointLockManager* websocket_endpoint_lock_manager) override {
689     return nullptr;
690   }
CreateHttp2Stream(base::WeakPtr<SpdySession> session,std::set<std::string> dns_aliases)691   std::unique_ptr<WebSocketHandshakeStreamBase> CreateHttp2Stream(
692       base::WeakPtr<SpdySession> session,
693       std::set<std::string> dns_aliases) override {
694     NOTREACHED();
695     return nullptr;
696   }
CreateHttp3Stream(std::unique_ptr<QuicChromiumClientSession::Handle> session,std::set<std::string> dns_aliases)697   std::unique_ptr<WebSocketHandshakeStreamBase> CreateHttp3Stream(
698       std::unique_ptr<QuicChromiumClientSession::Handle> session,
699       std::set<std::string> dns_aliases) override {
700     NOTREACHED();
701     return nullptr;
702   }
703 };
704 
705 // Returns true if |entry| is not one of the log types paid attention to in this
706 // test. Note that HTTP_CACHE_WRITE_INFO and HTTP_CACHE_*_DATA are
707 // ignored.
ShouldIgnoreLogEntry(const NetLogEntry & entry)708 bool ShouldIgnoreLogEntry(const NetLogEntry& entry) {
709   switch (entry.type) {
710     case NetLogEventType::HTTP_CACHE_GET_BACKEND:
711     case NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY:
712     case NetLogEventType::HTTP_CACHE_OPEN_ENTRY:
713     case NetLogEventType::HTTP_CACHE_CREATE_ENTRY:
714     case NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY:
715     case NetLogEventType::HTTP_CACHE_DOOM_ENTRY:
716     case NetLogEventType::HTTP_CACHE_READ_INFO:
717       return false;
718     default:
719       return true;
720   }
721 }
722 
723 // Gets the entries from |net_log| created by the cache layer and asserted on in
724 // these tests.
GetFilteredNetLogEntries(const RecordingNetLogObserver & net_log_observer)725 std::vector<NetLogEntry> GetFilteredNetLogEntries(
726     const RecordingNetLogObserver& net_log_observer) {
727   auto entries = net_log_observer.GetEntries();
728   std::erase_if(entries, ShouldIgnoreLogEntry);
729   return entries;
730 }
731 
LogContainsEventType(const RecordingNetLogObserver & net_log_observer,NetLogEventType expected)732 bool LogContainsEventType(const RecordingNetLogObserver& net_log_observer,
733                           NetLogEventType expected) {
734   return !net_log_observer.GetEntriesWithType(expected).empty();
735 }
736 
737 // Returns a TransportInfo distinct from the default for mock transactions,
738 // with the given port number.
TestTransportInfoWithPort(uint16_t port)739 TransportInfo TestTransportInfoWithPort(uint16_t port) {
740   TransportInfo result;
741   result.endpoint = IPEndPoint(IPAddress(42, 0, 1, 2), port);
742   return result;
743 }
744 
745 // Returns a TransportInfo distinct from the default for mock transactions.
TestTransportInfo()746 TransportInfo TestTransportInfo() {
747   return TestTransportInfoWithPort(1337);
748 }
749 
CachedTestTransportInfo()750 TransportInfo CachedTestTransportInfo() {
751   TransportInfo result = TestTransportInfo();
752   result.type = TransportType::kCached;
753   return result;
754 }
755 
756 // Helper function, generating valid HTTP cache key from `url`.
757 // See also: HttpCache::GenerateCacheKey(..)
GenerateCacheKey(const std::string & url)758 std::string GenerateCacheKey(const std::string& url) {
759   return "1/0/" + url;
760 }
761 
762 }  // namespace
763 
764 using HttpCacheTest = TestWithTaskEnvironment;
765 
766 class HttpCacheIOCallbackTest : public HttpCacheTest {
767  public:
768   HttpCacheIOCallbackTest() = default;
769   ~HttpCacheIOCallbackTest() override = default;
770 
771   // HttpCache::ActiveEntry is private, doing this allows tests to use it
772   using ActiveEntry = HttpCache::ActiveEntry;
773   using Transaction = HttpCache::Transaction;
774 
775   // The below functions are forwarding calls to the HttpCache class.
OpenEntry(HttpCache * cache,const std::string & url,scoped_refptr<ActiveEntry> * entry,HttpCache::Transaction * trans)776   int OpenEntry(HttpCache* cache,
777                 const std::string& url,
778                 scoped_refptr<ActiveEntry>* entry,
779                 HttpCache::Transaction* trans) {
780     return cache->OpenEntry(GenerateCacheKey(url), entry, trans);
781   }
782 
OpenOrCreateEntry(HttpCache * cache,const std::string & url,scoped_refptr<ActiveEntry> * entry,HttpCache::Transaction * trans)783   int OpenOrCreateEntry(HttpCache* cache,
784                         const std::string& url,
785                         scoped_refptr<ActiveEntry>* entry,
786                         HttpCache::Transaction* trans) {
787     return cache->OpenOrCreateEntry(GenerateCacheKey(url), entry, trans);
788   }
789 
CreateEntry(HttpCache * cache,const std::string & url,scoped_refptr<ActiveEntry> * entry,HttpCache::Transaction * trans)790   int CreateEntry(HttpCache* cache,
791                   const std::string& url,
792                   scoped_refptr<ActiveEntry>* entry,
793                   HttpCache::Transaction* trans) {
794     return cache->CreateEntry(GenerateCacheKey(url), entry, trans);
795   }
796 
DoomEntry(HttpCache * cache,const std::string & url,HttpCache::Transaction * trans)797   int DoomEntry(HttpCache* cache,
798                 const std::string& url,
799                 HttpCache::Transaction* trans) {
800     return cache->DoomEntry(GenerateCacheKey(url), trans);
801   }
802 };
803 
804 class HttpSplitCacheKeyTest : public HttpCacheTest {
805  public:
806   HttpSplitCacheKeyTest() = default;
807   ~HttpSplitCacheKeyTest() override = default;
808 
ComputeCacheKey(const std::string & url_string)809   std::string ComputeCacheKey(const std::string& url_string) {
810     GURL url(url_string);
811     SchemefulSite site(url);
812     net::HttpRequestInfo request_info;
813     request_info.url = url;
814     request_info.method = "GET";
815     request_info.network_isolation_key = net::NetworkIsolationKey(site, site);
816     request_info.network_anonymization_key =
817         net::NetworkAnonymizationKey::CreateSameSite(site);
818     MockHttpCache cache;
819     return *cache.http_cache()->GenerateCacheKeyForRequest(&request_info);
820   }
821 };
822 
823 //-----------------------------------------------------------------------------
824 // Tests.
825 
TEST_F(HttpCacheTest,CreateThenDestroy)826 TEST_F(HttpCacheTest, CreateThenDestroy) {
827   MockHttpCache cache;
828 
829   std::unique_ptr<HttpTransaction> trans;
830   EXPECT_THAT(cache.CreateTransaction(&trans), IsOk());
831   ASSERT_TRUE(trans.get());
832 }
833 
TEST_F(HttpCacheTest,GetBackend)834 TEST_F(HttpCacheTest, GetBackend) {
835   MockHttpCache cache(HttpCache::DefaultBackend::InMemory(0));
836 
837   disk_cache::Backend* backend;
838   TestCompletionCallback cb;
839   // This will lazily initialize the backend.
840   int rv = cache.http_cache()->GetBackend(&backend, cb.callback());
841   EXPECT_THAT(cb.GetResult(rv), IsOk());
842 }
843 
TEST_F(HttpCacheTest,SimpleGET)844 TEST_F(HttpCacheTest, SimpleGET) {
845   MockHttpCache cache;
846   LoadTimingInfo load_timing_info;
847 
848   // Write to the cache.
849   RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
850                                  NetLogWithSource::Make(NetLogSourceType::NONE),
851                                  &load_timing_info);
852 
853   EXPECT_EQ(1, cache.network_layer()->transaction_count());
854   EXPECT_EQ(0, cache.disk_cache()->open_count());
855   EXPECT_EQ(1, cache.disk_cache()->create_count());
856   TestLoadTimingNetworkRequest(load_timing_info);
857 }
858 
859 // This test verifies that the callback passed to SetConnectedCallback() is
860 // called once for simple GET calls that traverse the cache.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallback)861 TEST_F(HttpCacheTest, SimpleGET_ConnectedCallback) {
862   MockHttpCache cache;
863 
864   ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
865   mock_transaction.transport_info = TestTransportInfo();
866   MockHttpRequest request(mock_transaction);
867 
868   ConnectedHandler connected_handler;
869 
870   std::unique_ptr<HttpTransaction> transaction;
871   EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
872   ASSERT_THAT(transaction, NotNull());
873 
874   transaction->SetConnectedCallback(connected_handler.Callback());
875 
876   TestCompletionCallback callback;
877   ASSERT_THAT(
878       transaction->Start(&request, callback.callback(), NetLogWithSource()),
879       IsError(ERR_IO_PENDING));
880   EXPECT_THAT(callback.WaitForResult(), IsOk());
881 
882   EXPECT_THAT(connected_handler.transports(), ElementsAre(TestTransportInfo()));
883 }
884 
885 // This test verifies that when the callback passed to SetConnectedCallback()
886 // returns an error, the transaction fails with that error.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackReturnError)887 TEST_F(HttpCacheTest, SimpleGET_ConnectedCallbackReturnError) {
888   MockHttpCache cache;
889   MockHttpRequest request(kSimpleGET_Transaction);
890   ConnectedHandler connected_handler;
891 
892   std::unique_ptr<HttpTransaction> transaction;
893   EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
894   ASSERT_THAT(transaction, NotNull());
895 
896   // The exact error code does not matter. We only care that it is passed to
897   // the transaction's completion callback unmodified.
898   connected_handler.set_result(ERR_NOT_IMPLEMENTED);
899   transaction->SetConnectedCallback(connected_handler.Callback());
900 
901   TestCompletionCallback callback;
902   ASSERT_THAT(
903       transaction->Start(&request, callback.callback(), NetLogWithSource()),
904       IsError(ERR_IO_PENDING));
905   EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NOT_IMPLEMENTED));
906 }
907 
908 // This test verifies that the callback passed to SetConnectedCallback() is
909 // called once for requests that hit the cache.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackOnCacheHit)910 TEST_F(HttpCacheTest, SimpleGET_ConnectedCallbackOnCacheHit) {
911   MockHttpCache cache;
912 
913   {
914     // Populate the cache.
915     ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
916     mock_transaction.transport_info = TestTransportInfo();
917     RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
918   }
919 
920   // Establish a baseline.
921   EXPECT_EQ(1, cache.network_layer()->transaction_count());
922 
923   // Load from the cache (only), observe the callback being called.
924 
925   ConnectedHandler connected_handler;
926   MockHttpRequest request(kSimpleGET_Transaction);
927 
928   std::unique_ptr<HttpTransaction> transaction;
929   EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
930   ASSERT_THAT(transaction, NotNull());
931 
932   transaction->SetConnectedCallback(connected_handler.Callback());
933 
934   TestCompletionCallback callback;
935   ASSERT_THAT(
936       transaction->Start(&request, callback.callback(), NetLogWithSource()),
937       IsError(ERR_IO_PENDING));
938   EXPECT_THAT(callback.WaitForResult(), IsOk());
939 
940   // Still only 1 transaction for the previous request. The connected callback
941   // was not called by a second network transaction.
942   EXPECT_EQ(1, cache.network_layer()->transaction_count());
943 
944   EXPECT_THAT(connected_handler.transports(),
945               ElementsAre(CachedTestTransportInfo()));
946 }
947 
948 // This test verifies that when the callback passed to SetConnectedCallback()
949 // is called for a request that hit the cache and returns an error, the cache
950 // entry is reusable.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackOnCacheHitReturnError)951 TEST_F(HttpCacheTest, SimpleGET_ConnectedCallbackOnCacheHitReturnError) {
952   MockHttpCache cache;
953 
954   {
955     // Populate the cache.
956     ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
957     mock_transaction.transport_info = TestTransportInfo();
958     RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
959   }
960 
961   MockHttpRequest request(kSimpleGET_Transaction);
962 
963   {
964     // Attempt to read from cache entry, but abort transaction due to a
965     // connected callback error.
966     ConnectedHandler connected_handler;
967     connected_handler.set_result(ERR_FAILED);
968 
969     std::unique_ptr<HttpTransaction> transaction;
970     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
971     ASSERT_THAT(transaction, NotNull());
972 
973     transaction->SetConnectedCallback(connected_handler.Callback());
974 
975     TestCompletionCallback callback;
976     ASSERT_THAT(
977         transaction->Start(&request, callback.callback(), NetLogWithSource()),
978         IsError(ERR_IO_PENDING));
979     EXPECT_THAT(callback.WaitForResult(), IsError(ERR_FAILED));
980 
981     // Used the cache entry only.
982     EXPECT_THAT(connected_handler.transports(),
983                 ElementsAre(CachedTestTransportInfo()));
984   }
985 
986   {
987     // Request the same resource once more, observe that it is read from cache.
988     ConnectedHandler connected_handler;
989 
990     std::unique_ptr<HttpTransaction> transaction;
991     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
992     ASSERT_THAT(transaction, NotNull());
993 
994     transaction->SetConnectedCallback(connected_handler.Callback());
995 
996     TestCompletionCallback callback;
997     ASSERT_THAT(
998         transaction->Start(&request, callback.callback(), NetLogWithSource()),
999         IsError(ERR_IO_PENDING));
1000     EXPECT_THAT(callback.WaitForResult(), IsOk());
1001 
1002     // Used the cache entry only.
1003     EXPECT_THAT(connected_handler.transports(),
1004                 ElementsAre(CachedTestTransportInfo()));
1005   }
1006 }
1007 
1008 // This test verifies that when the callback passed to SetConnectedCallback()
1009 // returns `ERR_INCONSISTENT_IP_ADDRESS_SPACE`, the cache entry is invalidated.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackOnCacheHitReturnInconsistentIpError)1010 TEST_F(HttpCacheTest,
1011        SimpleGET_ConnectedCallbackOnCacheHitReturnInconsistentIpError) {
1012   MockHttpCache cache;
1013 
1014   ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
1015   mock_transaction.transport_info = TestTransportInfo();
1016 
1017   // Populate the cache.
1018   RunTransactionTest(cache.http_cache(), mock_transaction);
1019 
1020   MockHttpRequest request(kSimpleGET_Transaction);
1021 
1022   {
1023     // Attempt to read from cache entry, but abort transaction due to a
1024     // connected callback error.
1025     ConnectedHandler connected_handler;
1026     connected_handler.set_result(ERR_INCONSISTENT_IP_ADDRESS_SPACE);
1027 
1028     std::unique_ptr<HttpTransaction> transaction;
1029     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
1030     ASSERT_THAT(transaction, NotNull());
1031 
1032     transaction->SetConnectedCallback(connected_handler.Callback());
1033 
1034     TestCompletionCallback callback;
1035     ASSERT_THAT(
1036         transaction->Start(&request, callback.callback(), NetLogWithSource()),
1037         IsError(ERR_IO_PENDING));
1038     EXPECT_THAT(callback.WaitForResult(),
1039                 IsError(ERR_INCONSISTENT_IP_ADDRESS_SPACE));
1040 
1041     // Used the cache entry only.
1042     EXPECT_THAT(connected_handler.transports(),
1043                 ElementsAre(CachedTestTransportInfo()));
1044   }
1045 
1046   {
1047     // Request the same resource once more, observe that it is not read from
1048     // cache.
1049     ConnectedHandler connected_handler;
1050 
1051     std::unique_ptr<HttpTransaction> transaction;
1052     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
1053     ASSERT_THAT(transaction, NotNull());
1054 
1055     transaction->SetConnectedCallback(connected_handler.Callback());
1056 
1057     TestCompletionCallback callback;
1058     ASSERT_THAT(
1059         transaction->Start(&request, callback.callback(), NetLogWithSource()),
1060         IsError(ERR_IO_PENDING));
1061     EXPECT_THAT(callback.WaitForResult(), IsOk());
1062 
1063     // Used the network only.
1064     EXPECT_THAT(connected_handler.transports(),
1065                 ElementsAre(TestTransportInfo()));
1066   }
1067 }
1068 
1069 // This test verifies that when the callback passed to SetConnectedCallback()
1070 // returns
1071 // `ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_PRIVATE_NETWORK_ACCESS_POLICY`, the
1072 // cache entry is invalidated, and we'll retry the connection from the network.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackOnCacheHitReturnPrivateNetworkAccessBlockedError)1073 TEST_F(
1074     HttpCacheTest,
1075     SimpleGET_ConnectedCallbackOnCacheHitReturnPrivateNetworkAccessBlockedError) {
1076   MockHttpCache cache;
1077 
1078   ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
1079   mock_transaction.transport_info = TestTransportInfo();
1080 
1081   // Populate the cache.
1082   RunTransactionTest(cache.http_cache(), mock_transaction);
1083 
1084   MockHttpRequest request(kSimpleGET_Transaction);
1085 
1086   {
1087     // Attempt to read from cache entry, but abort transaction due to a
1088     // connected callback error.
1089     ConnectedHandler connected_handler;
1090     connected_handler.set_result(
1091         ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_PRIVATE_NETWORK_ACCESS_POLICY);
1092 
1093     std::unique_ptr<HttpTransaction> transaction;
1094     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
1095     ASSERT_THAT(transaction, NotNull());
1096 
1097     transaction->SetConnectedCallback(connected_handler.Callback());
1098 
1099     TestCompletionCallback callback;
1100     ASSERT_THAT(
1101         transaction->Start(&request, callback.callback(), NetLogWithSource()),
1102         IsError(ERR_IO_PENDING));
1103     EXPECT_THAT(
1104         callback.WaitForResult(),
1105         IsError(
1106             ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_PRIVATE_NETWORK_ACCESS_POLICY));
1107 
1108     // Used the cache entry only.
1109     EXPECT_THAT(connected_handler.transports(),
1110                 ElementsAre(CachedTestTransportInfo(), TestTransportInfo()));
1111   }
1112 
1113   {
1114     // Request the same resource once more, observe that it is not read from
1115     // cache.
1116     ConnectedHandler connected_handler;
1117 
1118     std::unique_ptr<HttpTransaction> transaction;
1119     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
1120     ASSERT_THAT(transaction, NotNull());
1121 
1122     transaction->SetConnectedCallback(connected_handler.Callback());
1123 
1124     TestCompletionCallback callback;
1125     ASSERT_THAT(
1126         transaction->Start(&request, callback.callback(), NetLogWithSource()),
1127         IsError(ERR_IO_PENDING));
1128     EXPECT_THAT(callback.WaitForResult(), IsOk());
1129 
1130     // Used the network only.
1131     EXPECT_THAT(connected_handler.transports(),
1132                 ElementsAre(TestTransportInfo()));
1133   }
1134 }
1135 
1136 // This test verifies that the callback passed to SetConnectedCallback() is
1137 // called with the right transport type when the cached entry was originally
1138 // fetched via proxy.
TEST_F(HttpCacheTest,SimpleGET_ConnectedCallbackOnCacheHitFromProxy)1139 TEST_F(HttpCacheTest, SimpleGET_ConnectedCallbackOnCacheHitFromProxy) {
1140   MockHttpCache cache;
1141 
1142   TransportInfo proxied_transport_info = TestTransportInfo();
1143   proxied_transport_info.type = TransportType::kProxied;
1144 
1145   {
1146     // Populate the cache.
1147     ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
1148     mock_transaction.transport_info = proxied_transport_info;
1149     RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1150   }
1151 
1152   // Establish a baseline.
1153   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1154 
1155   // Load from the cache (only), observe the callback being called.
1156 
1157   ConnectedHandler connected_handler;
1158   MockHttpRequest request(kSimpleGET_Transaction);
1159 
1160   std::unique_ptr<HttpTransaction> transaction;
1161   EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
1162   ASSERT_THAT(transaction, NotNull());
1163 
1164   transaction->SetConnectedCallback(connected_handler.Callback());
1165 
1166   TestCompletionCallback callback;
1167   ASSERT_THAT(
1168       transaction->Start(&request, callback.callback(), NetLogWithSource()),
1169       IsError(ERR_IO_PENDING));
1170   EXPECT_THAT(callback.WaitForResult(), IsOk());
1171 
1172   // Still only 1 transaction for the previous request. The connected callback
1173   // was not called by a second network transaction.
1174   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1175 
1176   // The transport info mentions both the cache and the original proxy.
1177   TransportInfo expected_transport_info = TestTransportInfo();
1178   expected_transport_info.type = TransportType::kCachedFromProxy;
1179 
1180   EXPECT_THAT(connected_handler.transports(),
1181               ElementsAre(expected_transport_info));
1182 }
1183 
TEST_F(HttpCacheTest,SimpleGET_DelayedCacheLock)1184 TEST_F(HttpCacheTest, SimpleGET_DelayedCacheLock) {
1185   MockHttpCache cache;
1186   LoadTimingInfo load_timing_info;
1187 
1188   // Configure the cache to delay the response for AddTransactionToEntry so it
1189   // gets sequenced behind any other tasks that get generated when starting the
1190   // transaction (i.e. network activity when run in parallel with the cache
1191   // lock).
1192   cache.http_cache()->DelayAddTransactionToEntryForTesting();
1193 
1194   // Write to the cache.
1195   RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
1196                                  NetLogWithSource::Make(NetLogSourceType::NONE),
1197                                  &load_timing_info);
1198 
1199   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1200   EXPECT_EQ(0, cache.disk_cache()->open_count());
1201   EXPECT_EQ(1, cache.disk_cache()->create_count());
1202   TestLoadTimingNetworkRequest(load_timing_info);
1203 }
1204 
1205 enum class SplitCacheTestCase {
1206   kSplitCacheDisabled,
1207   kSplitCacheNikFrameSiteEnabled,
1208   kSplitCacheNikCrossSiteFlagEnabled,
1209   kSplitCacheNikFrameSiteSharedOpaqueEnabled,
1210 };
1211 
InitializeSplitCacheScopedFeatureList(base::test::ScopedFeatureList & scoped_feature_list,SplitCacheTestCase test_case)1212 void InitializeSplitCacheScopedFeatureList(
1213     base::test::ScopedFeatureList& scoped_feature_list,
1214     SplitCacheTestCase test_case) {
1215   std::vector<base::test::FeatureRef> enabled_features;
1216   std::vector<base::test::FeatureRef> disabled_features;
1217 
1218   if (test_case == SplitCacheTestCase::kSplitCacheDisabled) {
1219     disabled_features.push_back(
1220         net::features::kSplitCacheByNetworkIsolationKey);
1221   } else {
1222     enabled_features.push_back(net::features::kSplitCacheByNetworkIsolationKey);
1223   }
1224 
1225   if (test_case == SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled) {
1226     enabled_features.push_back(
1227         net::features::kEnableCrossSiteFlagNetworkIsolationKey);
1228   } else {
1229     disabled_features.push_back(
1230         net::features::kEnableCrossSiteFlagNetworkIsolationKey);
1231   }
1232 
1233   if (test_case ==
1234       SplitCacheTestCase::kSplitCacheNikFrameSiteSharedOpaqueEnabled) {
1235     enabled_features.push_back(
1236         net::features::kEnableFrameSiteSharedOpaqueNetworkIsolationKey);
1237   } else {
1238     disabled_features.push_back(
1239         net::features::kEnableFrameSiteSharedOpaqueNetworkIsolationKey);
1240   }
1241   scoped_feature_list.InitWithFeatures(enabled_features, disabled_features);
1242 }
1243 
1244 class HttpCacheTest_SplitCacheFeature
1245     : public HttpCacheTest,
1246       public ::testing::WithParamInterface<SplitCacheTestCase> {
1247  public:
HttpCacheTest_SplitCacheFeature()1248   HttpCacheTest_SplitCacheFeature() {
1249     InitializeSplitCacheScopedFeatureList(feature_list_, GetParam());
1250   }
1251 
IsSplitCacheEnabled() const1252   bool IsSplitCacheEnabled() const {
1253     return GetParam() != SplitCacheTestCase::kSplitCacheDisabled;
1254   }
1255 
1256  private:
1257   base::test::ScopedFeatureList feature_list_;
1258 };
1259 
TEST_P(HttpCacheTest_SplitCacheFeature,SimpleGETVerifyGoogleFontMetrics)1260 TEST_P(HttpCacheTest_SplitCacheFeature, SimpleGETVerifyGoogleFontMetrics) {
1261   SchemefulSite site_a(GURL("http://www.a.com"));
1262 
1263   MockHttpCache cache;
1264 
1265   ScopedMockTransaction transaction(
1266       kSimpleGET_Transaction,
1267       "http://themes.googleusercontent.com/static/fonts/roboto");
1268   MockHttpRequest request(transaction);
1269   request.network_isolation_key = NetworkIsolationKey(site_a, site_a);
1270   request.network_anonymization_key =
1271       net::NetworkAnonymizationKey::CreateSameSite(site_a);
1272 
1273   // Attempt to populate the cache.
1274   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
1275                                 nullptr);
1276 
1277   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
1278                                 nullptr);
1279 }
1280 
1281 INSTANTIATE_TEST_SUITE_P(
1282     All,
1283     HttpCacheTest_SplitCacheFeature,
1284     testing::ValuesIn(
1285         {SplitCacheTestCase::kSplitCacheDisabled,
1286          SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled,
1287          SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled,
1288          SplitCacheTestCase::kSplitCacheNikFrameSiteSharedOpaqueEnabled}),
__anone6acdaec0202(const testing::TestParamInfo<SplitCacheTestCase>& info) 1289     [](const testing::TestParamInfo<SplitCacheTestCase>& info) {
1290       switch (info.param) {
1291         case (SplitCacheTestCase::kSplitCacheDisabled):
1292           return "SplitCacheDisabled";
1293         case (SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled):
1294           return "SplitCacheNikFrameSiteEnabled";
1295         case (SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled):
1296           return "SplitCacheNikCrossSiteFlagEnabled";
1297         case (SplitCacheTestCase::kSplitCacheNikFrameSiteSharedOpaqueEnabled):
1298           return "SplitCacheNikFrameSiteSharedOpaqueEnabled";
1299       }
1300     });
1301 
1302 class HttpCacheTest_SplitCacheFeatureEnabled
1303     : public HttpCacheTest_SplitCacheFeature {
1304  public:
HttpCacheTest_SplitCacheFeatureEnabled()1305   HttpCacheTest_SplitCacheFeatureEnabled() {
1306     CHECK(base::FeatureList::IsEnabled(
1307         net::features::kSplitCacheByNetworkIsolationKey));
1308   }
1309 };
1310 
1311 INSTANTIATE_TEST_SUITE_P(
1312     All,
1313     HttpCacheTest_SplitCacheFeatureEnabled,
1314     testing::ValuesIn(
1315         {SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled,
1316          SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled,
1317          SplitCacheTestCase::kSplitCacheNikFrameSiteSharedOpaqueEnabled}),
__anone6acdaec0302(const testing::TestParamInfo<SplitCacheTestCase>& info) 1318     [](const testing::TestParamInfo<SplitCacheTestCase>& info) {
1319       switch (info.param) {
1320         case (SplitCacheTestCase::kSplitCacheDisabled):
1321           return "NotUsedForThisTestSuite";
1322         case (SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled):
1323           return "SplitCacheNikFrameSiteEnabled";
1324         case (SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled):
1325           return "SplitCacheNikCrossSiteFlagEnabled";
1326         case (SplitCacheTestCase::kSplitCacheNikFrameSiteSharedOpaqueEnabled):
1327           return "SplitCacheNikFrameSiteSharedOpaqueEnabled";
1328       }
1329     });
1330 
TEST_F(HttpCacheTest,SimpleGETNoDiskCache)1331 TEST_F(HttpCacheTest, SimpleGETNoDiskCache) {
1332   MockHttpCache cache;
1333 
1334   cache.disk_cache()->set_fail_requests(true);
1335 
1336   RecordingNetLogObserver net_log_observer;
1337   LoadTimingInfo load_timing_info;
1338 
1339   // Read from the network, and don't use the cache.
1340   RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
1341                                  NetLogWithSource::Make(NetLogSourceType::NONE),
1342                                  &load_timing_info);
1343 
1344   // Check that the NetLog was filled as expected.
1345   // (We attempted to OpenOrCreate entries, but fail).
1346   auto entries = GetFilteredNetLogEntries(net_log_observer);
1347 
1348   EXPECT_EQ(4u, entries.size());
1349   EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
1350                                     NetLogEventType::HTTP_CACHE_GET_BACKEND));
1351   EXPECT_TRUE(
1352       LogContainsEndEvent(entries, 1, NetLogEventType::HTTP_CACHE_GET_BACKEND));
1353   EXPECT_TRUE(LogContainsBeginEvent(
1354       entries, 2, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1355   EXPECT_TRUE(LogContainsEndEvent(
1356       entries, 3, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1357 
1358   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1359   EXPECT_EQ(0, cache.disk_cache()->open_count());
1360   EXPECT_EQ(0, cache.disk_cache()->create_count());
1361   TestLoadTimingNetworkRequest(load_timing_info);
1362 }
1363 
TEST_F(HttpCacheTest,SimpleGETNoDiskCache2)1364 TEST_F(HttpCacheTest, SimpleGETNoDiskCache2) {
1365   // This will initialize a cache object with NULL backend.
1366   auto factory = std::make_unique<MockBlockingBackendFactory>();
1367   factory->set_fail(true);
1368   factory->FinishCreation();  // We'll complete synchronously.
1369   MockHttpCache cache(std::move(factory));
1370 
1371   // Read from the network, and don't use the cache.
1372   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1373 
1374   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1375   EXPECT_FALSE(cache.http_cache()->GetCurrentBackend());
1376 }
1377 
1378 // Tests that IOBuffers are not referenced after IO completes.
TEST_F(HttpCacheTest,ReleaseBuffer)1379 TEST_F(HttpCacheTest, ReleaseBuffer) {
1380   MockHttpCache cache;
1381 
1382   // Write to the cache.
1383   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1384 
1385   MockHttpRequest request(kSimpleGET_Transaction);
1386   std::unique_ptr<HttpTransaction> trans;
1387   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
1388 
1389   const int kBufferSize = 10;
1390   auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
1391   ReleaseBufferCompletionCallback cb(buffer.get());
1392 
1393   int rv = trans->Start(&request, cb.callback(), NetLogWithSource());
1394   EXPECT_THAT(cb.GetResult(rv), IsOk());
1395 
1396   rv = trans->Read(buffer.get(), kBufferSize, cb.callback());
1397   EXPECT_EQ(kBufferSize, cb.GetResult(rv));
1398 }
1399 
TEST_F(HttpCacheTest,SimpleGETWithDiskFailures)1400 TEST_F(HttpCacheTest, SimpleGETWithDiskFailures) {
1401   MockHttpCache cache;
1402 
1403   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_ALL);
1404 
1405   // Read from the network, and fail to write to the cache.
1406   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1407 
1408   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1409   EXPECT_EQ(0, cache.disk_cache()->open_count());
1410   EXPECT_EQ(1, cache.disk_cache()->create_count());
1411 
1412   // This one should see an empty cache again.
1413   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1414 
1415   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1416   EXPECT_EQ(0, cache.disk_cache()->open_count());
1417   EXPECT_EQ(2, cache.disk_cache()->create_count());
1418 }
1419 
1420 // Tests that disk failures after the transaction has started don't cause the
1421 // request to fail.
TEST_F(HttpCacheTest,SimpleGETWithDiskFailures2)1422 TEST_F(HttpCacheTest, SimpleGETWithDiskFailures2) {
1423   MockHttpCache cache;
1424 
1425   MockHttpRequest request(kSimpleGET_Transaction);
1426 
1427   auto c = std::make_unique<Context>();
1428   int rv = cache.CreateTransaction(&c->trans);
1429   ASSERT_THAT(rv, IsOk());
1430 
1431   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1432   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1433   rv = c->callback.WaitForResult();
1434 
1435   // Start failing request now.
1436   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_ALL);
1437 
1438   // We have to open the entry again to propagate the failure flag.
1439   disk_cache::Entry* en;
1440   ASSERT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &en));
1441   en->Close();
1442 
1443   ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
1444   c.reset();
1445 
1446   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1447   EXPECT_EQ(1, cache.disk_cache()->open_count());
1448   EXPECT_EQ(1, cache.disk_cache()->create_count());
1449 
1450   // This one should see an empty cache again.
1451   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1452 
1453   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1454   EXPECT_EQ(1, cache.disk_cache()->open_count());
1455   EXPECT_EQ(2, cache.disk_cache()->create_count());
1456 }
1457 
1458 // Tests that we handle failures to read from the cache.
TEST_F(HttpCacheTest,SimpleGETWithDiskFailures3)1459 TEST_F(HttpCacheTest, SimpleGETWithDiskFailures3) {
1460   MockHttpCache cache;
1461 
1462   // Read from the network, and write to the cache.
1463   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1464 
1465   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1466   EXPECT_EQ(0, cache.disk_cache()->open_count());
1467   EXPECT_EQ(1, cache.disk_cache()->create_count());
1468 
1469   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_ALL);
1470 
1471   MockHttpRequest request(kSimpleGET_Transaction);
1472 
1473   // Now fail to read from the cache.
1474   auto c = std::make_unique<Context>();
1475   int rv = cache.CreateTransaction(&c->trans);
1476   ASSERT_THAT(rv, IsOk());
1477 
1478   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
1479   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
1480 
1481   // Now verify that the entry was removed from the cache.
1482   cache.disk_cache()->set_soft_failures_mask(0);
1483 
1484   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1485   EXPECT_EQ(1, cache.disk_cache()->open_count());
1486   EXPECT_EQ(2, cache.disk_cache()->create_count());
1487 
1488   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1489 
1490   EXPECT_EQ(3, cache.network_layer()->transaction_count());
1491   EXPECT_EQ(1, cache.disk_cache()->open_count());
1492   EXPECT_EQ(3, cache.disk_cache()->create_count());
1493 }
1494 
TEST_F(HttpCacheTest,SimpleGET_LoadOnlyFromCache_Hit)1495 TEST_F(HttpCacheTest, SimpleGET_LoadOnlyFromCache_Hit) {
1496   MockHttpCache cache;
1497 
1498   RecordingNetLogObserver net_log_observer;
1499   NetLogWithSource net_log_with_source =
1500       NetLogWithSource::Make(NetLogSourceType::NONE);
1501   LoadTimingInfo load_timing_info;
1502 
1503   // Write to the cache.
1504   RunTransactionTestAndGetTiming(cache.http_cache(), kSimpleGET_Transaction,
1505                                  net_log_with_source, &load_timing_info);
1506 
1507   // Check that the NetLog was filled as expected.
1508   auto entries = GetFilteredNetLogEntries(net_log_observer);
1509 
1510   EXPECT_EQ(6u, entries.size());
1511   EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
1512                                     NetLogEventType::HTTP_CACHE_GET_BACKEND));
1513   EXPECT_TRUE(
1514       LogContainsEndEvent(entries, 1, NetLogEventType::HTTP_CACHE_GET_BACKEND));
1515   EXPECT_TRUE(LogContainsBeginEvent(
1516       entries, 2, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1517   EXPECT_TRUE(LogContainsEndEvent(
1518       entries, 3, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1519   EXPECT_TRUE(LogContainsBeginEvent(entries, 4,
1520                                     NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1521   EXPECT_TRUE(LogContainsEndEvent(entries, 5,
1522                                   NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1523 
1524   TestLoadTimingNetworkRequest(load_timing_info);
1525 
1526   // Force this transaction to read from the cache.
1527   MockTransaction transaction(kSimpleGET_Transaction);
1528   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
1529 
1530   net_log_observer.Clear();
1531 
1532   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
1533                                  net_log_with_source, &load_timing_info);
1534 
1535   // Check that the NetLog was filled as expected.
1536   entries = GetFilteredNetLogEntries(net_log_observer);
1537 
1538   EXPECT_EQ(8u, entries.size());
1539   EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
1540                                     NetLogEventType::HTTP_CACHE_GET_BACKEND));
1541   EXPECT_TRUE(
1542       LogContainsEndEvent(entries, 1, NetLogEventType::HTTP_CACHE_GET_BACKEND));
1543   EXPECT_TRUE(LogContainsBeginEvent(
1544       entries, 2, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1545   EXPECT_TRUE(LogContainsEndEvent(
1546       entries, 3, NetLogEventType::HTTP_CACHE_OPEN_OR_CREATE_ENTRY));
1547   EXPECT_TRUE(LogContainsBeginEvent(entries, 4,
1548                                     NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1549   EXPECT_TRUE(LogContainsEndEvent(entries, 5,
1550                                   NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1551   EXPECT_TRUE(
1552       LogContainsBeginEvent(entries, 6, NetLogEventType::HTTP_CACHE_READ_INFO));
1553   EXPECT_TRUE(
1554       LogContainsEndEvent(entries, 7, NetLogEventType::HTTP_CACHE_READ_INFO));
1555 
1556   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1557   EXPECT_EQ(1, cache.disk_cache()->open_count());
1558   EXPECT_EQ(1, cache.disk_cache()->create_count());
1559   TestLoadTimingCachedResponse(load_timing_info);
1560 }
1561 
TEST_F(HttpCacheTest,SimpleGET_LoadOnlyFromCache_Miss)1562 TEST_F(HttpCacheTest, SimpleGET_LoadOnlyFromCache_Miss) {
1563   MockHttpCache cache;
1564 
1565   // force this transaction to read from the cache
1566   MockTransaction transaction(kSimpleGET_Transaction);
1567   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
1568 
1569   MockHttpRequest request(transaction);
1570   TestCompletionCallback callback;
1571 
1572   std::unique_ptr<HttpTransaction> trans;
1573   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
1574 
1575   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
1576   if (rv == ERR_IO_PENDING) {
1577     rv = callback.WaitForResult();
1578   }
1579   ASSERT_THAT(rv, IsError(ERR_CACHE_MISS));
1580 
1581   trans.reset();
1582 
1583   EXPECT_EQ(0, cache.network_layer()->transaction_count());
1584   EXPECT_EQ(0, cache.disk_cache()->open_count());
1585   EXPECT_EQ(0, cache.disk_cache()->create_count());
1586 }
1587 
TEST_F(HttpCacheTest,SimpleGET_LoadPreferringCache_Hit)1588 TEST_F(HttpCacheTest, SimpleGET_LoadPreferringCache_Hit) {
1589   MockHttpCache cache;
1590 
1591   // write to the cache
1592   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1593 
1594   // force this transaction to read from the cache if valid
1595   MockTransaction transaction(kSimpleGET_Transaction);
1596   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
1597 
1598   RunTransactionTest(cache.http_cache(), transaction);
1599 
1600   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1601   EXPECT_EQ(1, cache.disk_cache()->open_count());
1602   EXPECT_EQ(1, cache.disk_cache()->create_count());
1603 }
1604 
TEST_F(HttpCacheTest,SimpleGET_LoadPreferringCache_Miss)1605 TEST_F(HttpCacheTest, SimpleGET_LoadPreferringCache_Miss) {
1606   MockHttpCache cache;
1607 
1608   // force this transaction to read from the cache if valid
1609   MockTransaction transaction(kSimpleGET_Transaction);
1610   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
1611 
1612   RunTransactionTest(cache.http_cache(), transaction);
1613 
1614   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1615   EXPECT_EQ(0, cache.disk_cache()->open_count());
1616   EXPECT_EQ(1, cache.disk_cache()->create_count());
1617 }
1618 
1619 // Tests LOAD_SKIP_CACHE_VALIDATION in the presence of vary headers.
TEST_F(HttpCacheTest,SimpleGET_LoadPreferringCache_VaryMatch)1620 TEST_F(HttpCacheTest, SimpleGET_LoadPreferringCache_VaryMatch) {
1621   MockHttpCache cache;
1622 
1623   // Write to the cache.
1624   ScopedMockTransaction transaction(kSimpleGET_Transaction);
1625   transaction.request_headers = "Foo: bar\r\n";
1626   transaction.response_headers =
1627       "Cache-Control: max-age=10000\n"
1628       "Vary: Foo\n";
1629   RunTransactionTest(cache.http_cache(), transaction);
1630 
1631   // Read from the cache.
1632   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
1633   RunTransactionTest(cache.http_cache(), transaction);
1634 
1635   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1636   EXPECT_EQ(1, cache.disk_cache()->open_count());
1637   EXPECT_EQ(1, cache.disk_cache()->create_count());
1638 }
1639 
1640 // Tests LOAD_SKIP_CACHE_VALIDATION in the presence of vary headers.
TEST_F(HttpCacheTest,SimpleGET_LoadPreferringCache_VaryMismatch)1641 TEST_F(HttpCacheTest, SimpleGET_LoadPreferringCache_VaryMismatch) {
1642   MockHttpCache cache;
1643 
1644   // Write to the cache.
1645   ScopedMockTransaction transaction(kSimpleGET_Transaction);
1646   transaction.request_headers = "Foo: bar\r\n";
1647   transaction.response_headers =
1648       "Cache-Control: max-age=10000\n"
1649       "Vary: Foo\n";
1650   RunTransactionTest(cache.http_cache(), transaction);
1651 
1652   // Attempt to read from the cache... this is a vary mismatch that must reach
1653   // the network again.
1654   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
1655   transaction.request_headers = "Foo: none\r\n";
1656   LoadTimingInfo load_timing_info;
1657   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
1658                                  NetLogWithSource::Make(NetLogSourceType::NONE),
1659                                  &load_timing_info);
1660 
1661   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1662   EXPECT_EQ(1, cache.disk_cache()->open_count());
1663   EXPECT_EQ(1, cache.disk_cache()->create_count());
1664   TestLoadTimingNetworkRequest(load_timing_info);
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   ScopedMockTransaction transaction(kSimpleGET_Transaction);
1673   transaction.response_headers =
1674       "Cache-Control: max-age=10000\n"
1675       "Vary: *\n";
1676   RunTransactionTest(cache.http_cache(), transaction);
1677 
1678   // Attempt to read from the cache... we will still load it from network,
1679   // since Vary: * doesn't match.
1680   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
1681   LoadTimingInfo load_timing_info;
1682   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
1683                                  NetLogWithSource::Make(NetLogSourceType::NONE),
1684                                  &load_timing_info);
1685 
1686   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1687   EXPECT_EQ(1, cache.disk_cache()->open_count());
1688   EXPECT_EQ(1, cache.disk_cache()->create_count());
1689 }
1690 
1691 // Tests that was_cached was set properly on a failure, even if the cached
1692 // response wasn't returned.
TEST_F(HttpCacheTest,SimpleGET_CacheSignal_Failure)1693 TEST_F(HttpCacheTest, SimpleGET_CacheSignal_Failure) {
1694   for (bool use_memory_entry_data : {false, true}) {
1695     MockHttpCache cache;
1696     cache.disk_cache()->set_support_in_memory_entry_data(use_memory_entry_data);
1697 
1698     // Prime cache.
1699     ScopedMockTransaction transaction(kSimpleGET_Transaction);
1700     transaction.response_headers = "Cache-Control: no-cache\n";
1701 
1702     RunTransactionTest(cache.http_cache(), transaction);
1703     EXPECT_EQ(1, cache.network_layer()->transaction_count());
1704     EXPECT_EQ(1, cache.disk_cache()->create_count());
1705     EXPECT_EQ(0, cache.disk_cache()->open_count());
1706 
1707     // Network failure with error; should fail but have was_cached set.
1708     transaction.start_return_code = ERR_FAILED;
1709 
1710     MockHttpRequest request(transaction);
1711     TestCompletionCallback callback;
1712     std::unique_ptr<HttpTransaction> trans;
1713     int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
1714     EXPECT_THAT(rv, IsOk());
1715     ASSERT_TRUE(trans.get());
1716     rv = trans->Start(&request, callback.callback(), NetLogWithSource());
1717     EXPECT_THAT(callback.GetResult(rv), IsError(ERR_FAILED));
1718 
1719     const HttpResponseInfo* response_info = trans->GetResponseInfo();
1720     ASSERT_TRUE(response_info);
1721     // If use_memory_entry_data is true, we will not bother opening the entry,
1722     // and just kick it out, so was_cached will end up false.
1723     EXPECT_EQ(2, cache.network_layer()->transaction_count());
1724     if (use_memory_entry_data) {
1725       EXPECT_EQ(false, response_info->was_cached);
1726       EXPECT_EQ(2, cache.disk_cache()->create_count());
1727       EXPECT_EQ(0, cache.disk_cache()->open_count());
1728     } else {
1729       EXPECT_EQ(true, response_info->was_cached);
1730       EXPECT_EQ(1, cache.disk_cache()->create_count());
1731       EXPECT_EQ(1, cache.disk_cache()->open_count());
1732     }
1733   }
1734 }
1735 
1736 // Tests that if the transaction is destroyed right after setting the
1737 // cache_entry_status_ as CANT_CONDITIONALIZE, then RecordHistograms should not
1738 // hit a dcheck.
TEST_F(HttpCacheTest,RecordHistogramsCantConditionalize)1739 TEST_F(HttpCacheTest, RecordHistogramsCantConditionalize) {
1740   MockHttpCache cache;
1741   cache.disk_cache()->set_support_in_memory_entry_data(true);
1742 
1743   {
1744     // Prime cache.
1745     ScopedMockTransaction transaction(kSimpleGET_Transaction);
1746     transaction.response_headers = "Cache-Control: no-cache\n";
1747     RunTransactionTest(cache.http_cache(), transaction);
1748     EXPECT_EQ(1, cache.network_layer()->transaction_count());
1749     EXPECT_EQ(1, cache.disk_cache()->create_count());
1750     EXPECT_EQ(0, cache.disk_cache()->open_count());
1751   }
1752 
1753   {
1754     ScopedMockTransaction transaction(kSimpleGET_Transaction);
1755     MockHttpRequest request(transaction);
1756     TestCompletionCallback callback;
1757     std::unique_ptr<HttpTransaction> trans;
1758     int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
1759     EXPECT_THAT(rv, IsOk());
1760     ASSERT_TRUE(trans.get());
1761     rv = trans->Start(&request, callback.callback(), NetLogWithSource());
1762     // Now destroy the transaction so that RecordHistograms gets invoked.
1763     trans.reset();
1764   }
1765 }
1766 
1767 // Confirm if we have an empty cache, a read is marked as network verified.
TEST_F(HttpCacheTest,SimpleGET_NetworkAccessed_Network)1768 TEST_F(HttpCacheTest, SimpleGET_NetworkAccessed_Network) {
1769   MockHttpCache cache;
1770 
1771   // write to the cache
1772   HttpResponseInfo response_info;
1773   RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
1774                                      &response_info);
1775 
1776   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1777   EXPECT_EQ(0, cache.disk_cache()->open_count());
1778   EXPECT_EQ(1, cache.disk_cache()->create_count());
1779   EXPECT_TRUE(response_info.network_accessed);
1780   EXPECT_EQ(CacheEntryStatus::ENTRY_NOT_IN_CACHE,
1781             response_info.cache_entry_status);
1782 }
1783 
1784 // Confirm if we have a fresh entry in cache, it isn't marked as
1785 // network verified.
TEST_F(HttpCacheTest,SimpleGET_NetworkAccessed_Cache)1786 TEST_F(HttpCacheTest, SimpleGET_NetworkAccessed_Cache) {
1787   MockHttpCache cache;
1788 
1789   // Prime cache.
1790   MockTransaction transaction(kSimpleGET_Transaction);
1791 
1792   RunTransactionTest(cache.http_cache(), transaction);
1793   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1794   EXPECT_EQ(1, cache.disk_cache()->create_count());
1795 
1796   // Re-run transaction; make sure we don't mark the network as accessed.
1797   HttpResponseInfo response_info;
1798   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
1799                                      &response_info);
1800 
1801   EXPECT_EQ(1, cache.network_layer()->transaction_count());
1802   EXPECT_FALSE(response_info.network_accessed);
1803   EXPECT_EQ(CacheEntryStatus::ENTRY_USED, response_info.cache_entry_status);
1804 }
1805 
TEST_F(HttpCacheTest,SimpleGET_LoadBypassCache)1806 TEST_F(HttpCacheTest, SimpleGET_LoadBypassCache) {
1807   MockHttpCache cache;
1808 
1809   // Write to the cache.
1810   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1811 
1812   // Force this transaction to write to the cache again.
1813   MockTransaction transaction(kSimpleGET_Transaction);
1814   transaction.load_flags |= LOAD_BYPASS_CACHE;
1815 
1816   RecordingNetLogObserver net_log_observer;
1817   LoadTimingInfo load_timing_info;
1818 
1819   // Write to the cache.
1820   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
1821                                  NetLogWithSource::Make(NetLogSourceType::NONE),
1822                                  &load_timing_info);
1823 
1824   // Check that the NetLog was filled as expected.
1825   auto entries = GetFilteredNetLogEntries(net_log_observer);
1826 
1827   EXPECT_EQ(8u, entries.size());
1828   EXPECT_TRUE(LogContainsBeginEvent(entries, 0,
1829                                     NetLogEventType::HTTP_CACHE_GET_BACKEND));
1830   EXPECT_TRUE(
1831       LogContainsEndEvent(entries, 1, NetLogEventType::HTTP_CACHE_GET_BACKEND));
1832   EXPECT_TRUE(LogContainsBeginEvent(entries, 2,
1833                                     NetLogEventType::HTTP_CACHE_DOOM_ENTRY));
1834   EXPECT_TRUE(
1835       LogContainsEndEvent(entries, 3, NetLogEventType::HTTP_CACHE_DOOM_ENTRY));
1836   EXPECT_TRUE(LogContainsBeginEvent(entries, 4,
1837                                     NetLogEventType::HTTP_CACHE_CREATE_ENTRY));
1838   EXPECT_TRUE(LogContainsEndEvent(entries, 5,
1839                                   NetLogEventType::HTTP_CACHE_CREATE_ENTRY));
1840   EXPECT_TRUE(LogContainsBeginEvent(entries, 6,
1841                                     NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1842   EXPECT_TRUE(LogContainsEndEvent(entries, 7,
1843                                   NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY));
1844 
1845   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1846   EXPECT_EQ(0, cache.disk_cache()->open_count());
1847   EXPECT_EQ(2, cache.disk_cache()->create_count());
1848   TestLoadTimingNetworkRequest(load_timing_info);
1849 }
1850 
TEST_F(HttpCacheTest,SimpleGET_LoadBypassCache_Implicit)1851 TEST_F(HttpCacheTest, SimpleGET_LoadBypassCache_Implicit) {
1852   MockHttpCache cache;
1853 
1854   // write to the cache
1855   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1856 
1857   // force this transaction to write to the cache again
1858   MockTransaction transaction(kSimpleGET_Transaction);
1859   transaction.request_headers = "pragma: no-cache\r\n";
1860 
1861   RunTransactionTest(cache.http_cache(), transaction);
1862 
1863   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1864   EXPECT_EQ(0, cache.disk_cache()->open_count());
1865   EXPECT_EQ(2, cache.disk_cache()->create_count());
1866 }
1867 
TEST_F(HttpCacheTest,SimpleGET_LoadBypassCache_Implicit2)1868 TEST_F(HttpCacheTest, SimpleGET_LoadBypassCache_Implicit2) {
1869   MockHttpCache cache;
1870 
1871   // write to the cache
1872   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1873 
1874   // force this transaction to write to the cache again
1875   MockTransaction transaction(kSimpleGET_Transaction);
1876   transaction.request_headers = "cache-control: no-cache\r\n";
1877 
1878   RunTransactionTest(cache.http_cache(), transaction);
1879 
1880   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1881   EXPECT_EQ(0, cache.disk_cache()->open_count());
1882   EXPECT_EQ(2, cache.disk_cache()->create_count());
1883 }
1884 
TEST_F(HttpCacheTest,SimpleGET_LoadValidateCache)1885 TEST_F(HttpCacheTest, SimpleGET_LoadValidateCache) {
1886   MockHttpCache cache;
1887 
1888   // Write to the cache.
1889   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1890 
1891   // Read from the cache.
1892   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1893 
1894   // Force this transaction to validate the cache.
1895   MockTransaction transaction(kSimpleGET_Transaction);
1896   transaction.load_flags |= LOAD_VALIDATE_CACHE;
1897 
1898   HttpResponseInfo response_info;
1899   LoadTimingInfo load_timing_info;
1900   RunTransactionTestWithResponseInfoAndGetTiming(
1901       cache.http_cache(), transaction, &response_info,
1902       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info);
1903 
1904   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1905   EXPECT_EQ(1, cache.disk_cache()->open_count());
1906   EXPECT_EQ(1, cache.disk_cache()->create_count());
1907   EXPECT_TRUE(response_info.network_accessed);
1908   TestLoadTimingNetworkRequest(load_timing_info);
1909 }
1910 
TEST_F(HttpCacheTest,SimpleGET_LoadValidateCache_Implicit)1911 TEST_F(HttpCacheTest, SimpleGET_LoadValidateCache_Implicit) {
1912   MockHttpCache cache;
1913 
1914   // write to the cache
1915   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1916 
1917   // read from the cache
1918   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
1919 
1920   // force this transaction to validate the cache
1921   MockTransaction transaction(kSimpleGET_Transaction);
1922   transaction.request_headers = "cache-control: max-age=0\r\n";
1923 
1924   RunTransactionTest(cache.http_cache(), transaction);
1925 
1926   EXPECT_EQ(2, cache.network_layer()->transaction_count());
1927   EXPECT_EQ(1, cache.disk_cache()->open_count());
1928   EXPECT_EQ(1, cache.disk_cache()->create_count());
1929 }
1930 
1931 // Tests that |unused_since_prefetch| is updated accordingly (e.g. it is set to
1932 // true after a prefetch and set back to false when the prefetch is used).
TEST_F(HttpCacheTest,SimpleGET_UnusedSincePrefetch)1933 TEST_F(HttpCacheTest, SimpleGET_UnusedSincePrefetch) {
1934   MockHttpCache cache;
1935   HttpResponseInfo response_info;
1936 
1937   // A normal load does not have |unused_since_prefetch| set.
1938   RunTransactionTestWithResponseInfoAndGetTiming(
1939       cache.http_cache(), kSimpleGET_Transaction, &response_info,
1940       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1941   EXPECT_FALSE(response_info.unused_since_prefetch);
1942   EXPECT_FALSE(response_info.was_cached);
1943 
1944   // The prefetch itself does not have |unused_since_prefetch| set.
1945   MockTransaction prefetch_transaction(kSimpleGET_Transaction);
1946   prefetch_transaction.load_flags |= LOAD_PREFETCH;
1947   RunTransactionTestWithResponseInfoAndGetTiming(
1948       cache.http_cache(), prefetch_transaction, &response_info,
1949       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1950   EXPECT_FALSE(response_info.unused_since_prefetch);
1951   EXPECT_TRUE(response_info.was_cached);
1952 
1953   // A duplicated prefetch has |unused_since_prefetch| set.
1954   RunTransactionTestWithResponseInfoAndGetTiming(
1955       cache.http_cache(), prefetch_transaction, &response_info,
1956       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1957   EXPECT_TRUE(response_info.unused_since_prefetch);
1958   EXPECT_TRUE(response_info.was_cached);
1959 
1960   // |unused_since_prefetch| is still true after two prefetches in a row.
1961   RunTransactionTestWithResponseInfoAndGetTiming(
1962       cache.http_cache(), kSimpleGET_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   // The resource has now been used, back to normal behavior.
1968   RunTransactionTestWithResponseInfoAndGetTiming(
1969       cache.http_cache(), kSimpleGET_Transaction, &response_info,
1970       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1971   EXPECT_FALSE(response_info.unused_since_prefetch);
1972   EXPECT_TRUE(response_info.was_cached);
1973 }
1974 
1975 // Tests that requests made with the LOAD_RESTRICTED_PREFETCH load flag result
1976 // in HttpResponseInfo entries with the |restricted_prefetch| flag set. Also
1977 // tests that responses with |restricted_prefetch| flag set can only be used by
1978 // requests that have the LOAD_CAN_USE_RESTRICTED_PREFETCH load flag.
TEST_F(HttpCacheTest,SimpleGET_RestrictedPrefetchIsRestrictedUntilReuse)1979 TEST_F(HttpCacheTest, SimpleGET_RestrictedPrefetchIsRestrictedUntilReuse) {
1980   MockHttpCache cache;
1981   HttpResponseInfo response_info;
1982 
1983   // A normal load does not have |restricted_prefetch| set.
1984   RunTransactionTestWithResponseInfoAndGetTiming(
1985       cache.http_cache(), kTypicalGET_Transaction, &response_info,
1986       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1987   EXPECT_FALSE(response_info.restricted_prefetch);
1988   EXPECT_FALSE(response_info.was_cached);
1989   EXPECT_TRUE(response_info.network_accessed);
1990 
1991   // A restricted prefetch is marked as |restricted_prefetch|.
1992   MockTransaction prefetch_transaction(kSimpleGET_Transaction);
1993   prefetch_transaction.load_flags |= LOAD_PREFETCH;
1994   prefetch_transaction.load_flags |= LOAD_RESTRICTED_PREFETCH;
1995   RunTransactionTestWithResponseInfoAndGetTiming(
1996       cache.http_cache(), prefetch_transaction, &response_info,
1997       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
1998   EXPECT_TRUE(response_info.restricted_prefetch);
1999   EXPECT_FALSE(response_info.was_cached);
2000   EXPECT_TRUE(response_info.network_accessed);
2001 
2002   // Requests that are marked as able to reuse restricted prefetches can do so
2003   // correctly. Once it is reused, it is no longer considered as or marked
2004   // restricted.
2005   MockTransaction can_use_restricted_prefetch_transaction(
2006       kSimpleGET_Transaction);
2007   can_use_restricted_prefetch_transaction.load_flags |=
2008       LOAD_CAN_USE_RESTRICTED_PREFETCH;
2009   RunTransactionTestWithResponseInfoAndGetTiming(
2010       cache.http_cache(), can_use_restricted_prefetch_transaction,
2011       &response_info, NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2012   EXPECT_TRUE(response_info.restricted_prefetch);
2013   EXPECT_TRUE(response_info.was_cached);
2014   EXPECT_FALSE(response_info.network_accessed);
2015 
2016   // Later reuse is still no longer marked restricted.
2017   RunTransactionTestWithResponseInfoAndGetTiming(
2018       cache.http_cache(), kSimpleGET_Transaction, &response_info,
2019       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2020   EXPECT_FALSE(response_info.restricted_prefetch);
2021   EXPECT_TRUE(response_info.was_cached);
2022   EXPECT_FALSE(response_info.network_accessed);
2023 }
2024 
TEST_F(HttpCacheTest,SimpleGET_RestrictedPrefetchReuseIsLimited)2025 TEST_F(HttpCacheTest, SimpleGET_RestrictedPrefetchReuseIsLimited) {
2026   MockHttpCache cache;
2027   HttpResponseInfo response_info;
2028 
2029   // A restricted prefetch is marked as |restricted_prefetch|.
2030   MockTransaction prefetch_transaction(kSimpleGET_Transaction);
2031   prefetch_transaction.load_flags |= LOAD_PREFETCH;
2032   prefetch_transaction.load_flags |= LOAD_RESTRICTED_PREFETCH;
2033   RunTransactionTestWithResponseInfoAndGetTiming(
2034       cache.http_cache(), prefetch_transaction, &response_info,
2035       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2036   EXPECT_TRUE(response_info.restricted_prefetch);
2037   EXPECT_FALSE(response_info.was_cached);
2038   EXPECT_TRUE(response_info.network_accessed);
2039 
2040   // Requests that cannot reuse restricted prefetches fail to do so. The network
2041   // is accessed and the resulting response is not marked as
2042   // |restricted_prefetch|.
2043   RunTransactionTestWithResponseInfoAndGetTiming(
2044       cache.http_cache(), kSimpleGET_Transaction, &response_info,
2045       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2046   EXPECT_FALSE(response_info.restricted_prefetch);
2047   EXPECT_FALSE(response_info.was_cached);
2048   EXPECT_TRUE(response_info.network_accessed);
2049 
2050   // Future requests that are not marked as able to reuse restricted prefetches
2051   // can use the entry in the cache now, since it has been evicted in favor of
2052   // an unrestricted one.
2053   RunTransactionTestWithResponseInfoAndGetTiming(
2054       cache.http_cache(), kSimpleGET_Transaction, &response_info,
2055       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2056   EXPECT_FALSE(response_info.restricted_prefetch);
2057   EXPECT_TRUE(response_info.was_cached);
2058   EXPECT_FALSE(response_info.network_accessed);
2059 }
2060 
TEST_F(HttpCacheTest,SimpleGET_UnusedSincePrefetchWriteError)2061 TEST_F(HttpCacheTest, SimpleGET_UnusedSincePrefetchWriteError) {
2062   MockHttpCache cache;
2063   HttpResponseInfo response_info;
2064 
2065   // Do a prefetch.
2066   MockTransaction prefetch_transaction(kSimpleGET_Transaction);
2067   prefetch_transaction.load_flags |= LOAD_PREFETCH;
2068   RunTransactionTestWithResponseInfoAndGetTiming(
2069       cache.http_cache(), prefetch_transaction, &response_info,
2070       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2071   EXPECT_TRUE(response_info.unused_since_prefetch);
2072   EXPECT_FALSE(response_info.was_cached);
2073 
2074   // Try to use it while injecting a failure on write.
2075   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_WRITE);
2076   RunTransactionTestWithResponseInfoAndGetTiming(
2077       cache.http_cache(), kSimpleGET_Transaction, &response_info,
2078       NetLogWithSource::Make(NetLogSourceType::NONE), nullptr);
2079 }
2080 
2081 // Make sure that if a prefetch entry is truncated, then an attempt to re-use it
2082 // gets aborted in connected handler that truncated bit is not lost.
TEST_F(HttpCacheTest,PrefetchTruncateCancelInConnectedCallback)2083 TEST_F(HttpCacheTest, PrefetchTruncateCancelInConnectedCallback) {
2084   MockHttpCache cache;
2085 
2086   ScopedMockTransaction transaction(kSimpleGET_Transaction);
2087   transaction.response_headers =
2088       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2089       "Content-Length: 20\n"
2090       "Etag: \"foopy\"\n";
2091   transaction.data = "01234567890123456789";
2092   transaction.load_flags |= LOAD_PREFETCH | LOAD_CAN_USE_RESTRICTED_PREFETCH;
2093 
2094   // Do a truncated read of a prefetch request.
2095   {
2096     MockHttpRequest request(transaction);
2097     Context c;
2098 
2099     int rv = cache.CreateTransaction(&c.trans);
2100     ASSERT_THAT(rv, IsOk());
2101 
2102     rv = c.callback.GetResult(
2103         c.trans->Start(&request, c.callback.callback(), NetLogWithSource()));
2104     ASSERT_THAT(rv, IsOk());
2105 
2106     // Read less than the whole thing.
2107     scoped_refptr<IOBufferWithSize> buf =
2108         base::MakeRefCounted<IOBufferWithSize>(10);
2109     rv = c.callback.GetResult(
2110         c.trans->Read(buf.get(), buf->size(), c.callback.callback()));
2111     EXPECT_EQ(buf->size(), rv);
2112 
2113     // Destroy the transaction.
2114     c.trans.reset();
2115     base::RunLoop().RunUntilIdle();
2116 
2117     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/true,
2118                         /*data_size=*/10);
2119   }
2120 
2121   // Do a fetch that can use prefetch that aborts in connected handler.
2122   transaction.load_flags &= ~LOAD_PREFETCH;
2123   {
2124     MockHttpRequest request(transaction);
2125     Context c;
2126 
2127     int rv = cache.CreateTransaction(&c.trans);
2128     ASSERT_THAT(rv, IsOk());
2129     c.trans->SetConnectedCallback(base::BindRepeating(
2130         [](const TransportInfo& info, CompletionOnceCallback callback) -> int {
2131           return net::ERR_ABORTED;
2132         }));
2133     rv = c.callback.GetResult(
2134         c.trans->Start(&request, c.callback.callback(), NetLogWithSource()));
2135     EXPECT_EQ(net::ERR_ABORTED, rv);
2136 
2137     // Destroy the transaction.
2138     c.trans.reset();
2139     base::RunLoop().RunUntilIdle();
2140 
2141     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/true,
2142                         /*data_size=*/10);
2143   }
2144 
2145   // Now try again without abort.
2146   {
2147     MockHttpRequest request(transaction);
2148     RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
2149                                   /*response_info=*/nullptr);
2150     base::RunLoop().RunUntilIdle();
2151 
2152     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/false,
2153                         /*data_size=*/20);
2154   }
2155 }
2156 
2157 // Make sure that if a stale-while-revalidate entry is truncated, then an
2158 // attempt to re-use it gets aborted in connected handler that truncated bit is
2159 // not lost.
TEST_F(HttpCacheTest,StaleWhiteRevalidateTruncateCancelInConnectedCallback)2160 TEST_F(HttpCacheTest, StaleWhiteRevalidateTruncateCancelInConnectedCallback) {
2161   MockHttpCache cache;
2162 
2163   ScopedMockTransaction transaction(kSimpleGET_Transaction);
2164   transaction.response_headers =
2165       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
2166       "Content-Length: 20\n"
2167       "Cache-Control: max-age=0, stale-while-revalidate=60\n"
2168       "Etag: \"foopy\"\n";
2169   transaction.data = "01234567890123456789";
2170   transaction.load_flags |= LOAD_SUPPORT_ASYNC_REVALIDATION;
2171 
2172   // Do a truncated read of a stale-while-revalidate resource.
2173   {
2174     MockHttpRequest request(transaction);
2175     Context c;
2176 
2177     int rv = cache.CreateTransaction(&c.trans);
2178     ASSERT_THAT(rv, IsOk());
2179 
2180     rv = c.callback.GetResult(
2181         c.trans->Start(&request, c.callback.callback(), NetLogWithSource()));
2182     ASSERT_THAT(rv, IsOk());
2183 
2184     // Read less than the whole thing.
2185     scoped_refptr<IOBufferWithSize> buf =
2186         base::MakeRefCounted<IOBufferWithSize>(10);
2187     rv = c.callback.GetResult(
2188         c.trans->Read(buf.get(), buf->size(), c.callback.callback()));
2189     EXPECT_EQ(buf->size(), rv);
2190 
2191     // Destroy the transaction.
2192     c.trans.reset();
2193     base::RunLoop().RunUntilIdle();
2194 
2195     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/true,
2196                         /*data_size=*/10);
2197   }
2198 
2199   // Do a fetch that uses that resource that aborts in connected handler.
2200   {
2201     MockHttpRequest request(transaction);
2202     Context c;
2203 
2204     int rv = cache.CreateTransaction(&c.trans);
2205     ASSERT_THAT(rv, IsOk());
2206     c.trans->SetConnectedCallback(base::BindRepeating(
2207         [](const TransportInfo& info, CompletionOnceCallback callback) -> int {
2208           return net::ERR_ABORTED;
2209         }));
2210     rv = c.callback.GetResult(
2211         c.trans->Start(&request, c.callback.callback(), NetLogWithSource()));
2212     EXPECT_EQ(net::ERR_ABORTED, rv);
2213 
2214     // Destroy the transaction.
2215     c.trans.reset();
2216     base::RunLoop().RunUntilIdle();
2217 
2218     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/true,
2219                         /*data_size=*/10);
2220   }
2221 
2222   // Now try again without abort.
2223   {
2224     MockHttpRequest request(transaction);
2225     RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
2226                                   /*response_info=*/nullptr);
2227     base::RunLoop().RunUntilIdle();
2228 
2229     VerifyTruncatedFlag(&cache, request.CacheKey(), /*flag_value=*/false,
2230                         /*data_size=*/20);
2231   }
2232 }
2233 
2234 static const auto kPreserveRequestHeaders =
2235     base::BindRepeating([](const net::HttpRequestInfo* request,
2236                            std::string* response_status,
2237                            std::string* response_headers,
__anone6acdaec0602(const net::HttpRequestInfo* request, std::string* response_status, std::string* response_headers, std::string* response_data) 2238                            std::string* response_data) {
2239       EXPECT_TRUE(request->extra_headers.HasHeader(kExtraHeaderKey));
2240     });
2241 
2242 // Tests that we don't remove extra headers for simple requests.
TEST_F(HttpCacheTest,SimpleGET_PreserveRequestHeaders)2243 TEST_F(HttpCacheTest, SimpleGET_PreserveRequestHeaders) {
2244   for (bool use_memory_entry_data : {false, true}) {
2245     MockHttpCache cache;
2246     cache.disk_cache()->set_support_in_memory_entry_data(use_memory_entry_data);
2247 
2248     ScopedMockTransaction transaction(kSimpleGET_Transaction);
2249     transaction.handler = kPreserveRequestHeaders;
2250     transaction.request_headers = EXTRA_HEADER;
2251     transaction.response_headers = "Cache-Control: max-age=0\n";
2252 
2253     // Write, then revalidate the entry.
2254     RunTransactionTest(cache.http_cache(), transaction);
2255     RunTransactionTest(cache.http_cache(), transaction);
2256 
2257     EXPECT_EQ(2, cache.network_layer()->transaction_count());
2258 
2259     // If the backend supports memory entry data, we can figure out that the
2260     // entry has caching-hostile headers w/o opening it.
2261     if (use_memory_entry_data) {
2262       EXPECT_EQ(0, cache.disk_cache()->open_count());
2263       EXPECT_EQ(2, cache.disk_cache()->create_count());
2264     } else {
2265       EXPECT_EQ(1, cache.disk_cache()->open_count());
2266       EXPECT_EQ(1, cache.disk_cache()->create_count());
2267     }
2268   }
2269 }
2270 
2271 // Tests that we don't remove extra headers for conditionalized requests.
TEST_F(HttpCacheTest,ConditionalizedGET_PreserveRequestHeaders)2272 TEST_F(HttpCacheTest, ConditionalizedGET_PreserveRequestHeaders) {
2273   for (bool use_memory_entry_data : {false, true}) {
2274     MockHttpCache cache;
2275     // Unlike in SimpleGET_PreserveRequestHeaders, this entry can be
2276     // conditionalized, so memory hints don't affect behavior.
2277     cache.disk_cache()->set_support_in_memory_entry_data(use_memory_entry_data);
2278 
2279     // Write to the cache.
2280     RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
2281 
2282     ScopedMockTransaction transaction(kETagGET_Transaction);
2283     transaction.handler = kPreserveRequestHeaders;
2284     transaction.request_headers = "If-None-Match: \"foopy\"\r\n" EXTRA_HEADER;
2285 
2286     RunTransactionTest(cache.http_cache(), transaction);
2287 
2288     EXPECT_EQ(2, cache.network_layer()->transaction_count());
2289     EXPECT_EQ(1, cache.disk_cache()->open_count());
2290     EXPECT_EQ(1, cache.disk_cache()->create_count());
2291   }
2292 }
2293 
TEST_F(HttpCacheTest,SimpleGET_ManyReaders)2294 TEST_F(HttpCacheTest, SimpleGET_ManyReaders) {
2295   MockHttpCache cache;
2296 
2297   MockHttpRequest request(kSimpleGET_Transaction);
2298 
2299   std::vector<std::unique_ptr<Context>> context_list;
2300   const int kNumTransactions = 5;
2301 
2302   for (int i = 0; i < kNumTransactions; ++i) {
2303     context_list.push_back(std::make_unique<Context>());
2304     auto& c = context_list[i];
2305 
2306     c->result = cache.CreateTransaction(&c->trans);
2307     ASSERT_THAT(c->result, IsOk());
2308     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
2309 
2310     c->result =
2311         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
2312   }
2313 
2314   // All requests are waiting for the active entry.
2315   for (auto& context : context_list) {
2316     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
2317   }
2318 
2319   // Allow all requests to move from the Create queue to the active entry.
2320   base::RunLoop().RunUntilIdle();
2321 
2322   // All requests are added to writers.
2323   std::string cache_key = request.CacheKey();
2324   EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
2325 
2326   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2327   EXPECT_EQ(0, cache.disk_cache()->open_count());
2328   EXPECT_EQ(1, cache.disk_cache()->create_count());
2329 
2330   // All requests are between Start and Read, i.e. idle.
2331   for (auto& context : context_list) {
2332     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
2333   }
2334 
2335   for (int i = 0; i < kNumTransactions; ++i) {
2336     auto& c = context_list[i];
2337     if (c->result == ERR_IO_PENDING) {
2338       c->result = c->callback.WaitForResult();
2339     }
2340 
2341     // After the 1st transaction has completed the response, all transactions
2342     // get added to readers.
2343     if (i > 0) {
2344       EXPECT_FALSE(cache.IsWriterPresent(cache_key));
2345       EXPECT_EQ(kNumTransactions - i, cache.GetCountReaders(cache_key));
2346     }
2347 
2348     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
2349   }
2350 
2351   // We should not have had to re-open the disk entry
2352   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2353   EXPECT_EQ(0, cache.disk_cache()->open_count());
2354   EXPECT_EQ(1, cache.disk_cache()->create_count());
2355 }
2356 
TEST_F(HttpCacheTest,RangeGET_FullAfterPartial)2357 TEST_F(HttpCacheTest, RangeGET_FullAfterPartial) {
2358   MockHttpCache cache;
2359 
2360   // Request a prefix.
2361   {
2362     ScopedMockTransaction transaction_pre(kRangeGET_TransactionOK);
2363     transaction_pre.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
2364     transaction_pre.data = "rg: 00-09 ";
2365     MockHttpRequest request_pre(transaction_pre);
2366 
2367     HttpResponseInfo response_pre;
2368     RunTransactionTestWithRequest(cache.http_cache(), transaction_pre,
2369                                   request_pre, &response_pre);
2370     ASSERT_TRUE(response_pre.headers != nullptr);
2371     EXPECT_EQ(206, response_pre.headers->response_code());
2372     EXPECT_EQ(1, cache.network_layer()->transaction_count());
2373     EXPECT_EQ(0, cache.disk_cache()->open_count());
2374     EXPECT_EQ(1, cache.disk_cache()->create_count());
2375   }
2376 
2377   {
2378     // Now request the full thing, but set validation to fail. This would
2379     // previously fail in the middle of data and truncate it; current behavior
2380     // restarts it, somewhat wastefully but gets the data back.
2381     RangeTransactionServer handler;
2382     handler.set_modified(true);
2383 
2384     ScopedMockTransaction transaction_all(kRangeGET_TransactionOK);
2385     transaction_all.request_headers = EXTRA_HEADER;
2386     transaction_all.data = "Not a range";
2387     MockHttpRequest request_all(transaction_all);
2388 
2389     HttpResponseInfo response_all;
2390     RunTransactionTestWithRequest(cache.http_cache(), transaction_all,
2391                                   request_all, &response_all);
2392     ASSERT_TRUE(response_all.headers != nullptr);
2393     EXPECT_EQ(200, response_all.headers->response_code());
2394     // 1 from previous test, failed validation, and re-try.
2395     EXPECT_EQ(3, cache.network_layer()->transaction_count());
2396     EXPECT_EQ(1, cache.disk_cache()->open_count());
2397     EXPECT_EQ(1, cache.disk_cache()->create_count());
2398   }
2399 }
2400 
2401 // Tests that when a range request transaction becomes a writer for the first
2402 // range and then fails conditionalization for the next range and decides to
2403 // doom the entry, then there should not be a dcheck assertion hit.
TEST_F(HttpCacheTest,RangeGET_OverlappingRangesCouldntConditionalize)2404 TEST_F(HttpCacheTest, RangeGET_OverlappingRangesCouldntConditionalize) {
2405   MockHttpCache cache;
2406 
2407   {
2408     ScopedMockTransaction transaction_pre(kRangeGET_TransactionOK);
2409     transaction_pre.request_headers = "Range: bytes = 10-19\r\n" EXTRA_HEADER;
2410     transaction_pre.data = "rg: 10-19 ";
2411     MockHttpRequest request_pre(transaction_pre);
2412 
2413     HttpResponseInfo response_pre;
2414     RunTransactionTestWithRequest(cache.http_cache(), transaction_pre,
2415                                   request_pre, &response_pre);
2416     ASSERT_TRUE(response_pre.headers != nullptr);
2417     EXPECT_EQ(206, response_pre.headers->response_code());
2418     EXPECT_EQ(1, cache.network_layer()->transaction_count());
2419     EXPECT_EQ(0, cache.disk_cache()->open_count());
2420     EXPECT_EQ(1, cache.disk_cache()->create_count());
2421   }
2422 
2423   {
2424     // First range skips validation because the response is fresh while the
2425     // second range requires validation since that range is not present in the
2426     // cache and during validation it fails conditionalization.
2427     cache.FailConditionalizations();
2428     ScopedMockTransaction transaction_pre(kRangeGET_TransactionOK);
2429     transaction_pre.request_headers = "Range: bytes = 10-29\r\n" EXTRA_HEADER;
2430 
2431     // TODO(crbug.com/992521): Fix this scenario to not return the cached bytes
2432     // repeatedly.
2433     transaction_pre.data = "rg: 10-19 rg: 10-19 rg: 20-29 ";
2434     MockHttpRequest request_pre(transaction_pre);
2435     HttpResponseInfo response_pre;
2436     RunTransactionTestWithRequest(cache.http_cache(), transaction_pre,
2437                                   request_pre, &response_pre);
2438     ASSERT_TRUE(response_pre.headers != nullptr);
2439     EXPECT_EQ(2, cache.network_layer()->transaction_count());
2440     EXPECT_EQ(1, cache.disk_cache()->open_count());
2441     EXPECT_EQ(2, cache.disk_cache()->create_count());
2442   }
2443 }
2444 
TEST_F(HttpCacheTest,RangeGET_FullAfterPartialReuse)2445 TEST_F(HttpCacheTest, RangeGET_FullAfterPartialReuse) {
2446   MockHttpCache cache;
2447 
2448   // Request a prefix.
2449   {
2450     ScopedMockTransaction transaction_pre(kRangeGET_TransactionOK);
2451     transaction_pre.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
2452     transaction_pre.data = "rg: 00-09 ";
2453     MockHttpRequest request_pre(transaction_pre);
2454 
2455     HttpResponseInfo response_pre;
2456     RunTransactionTestWithRequest(cache.http_cache(), transaction_pre,
2457                                   request_pre, &response_pre);
2458     ASSERT_TRUE(response_pre.headers != nullptr);
2459     EXPECT_EQ(206, response_pre.headers->response_code());
2460     EXPECT_EQ(1, cache.network_layer()->transaction_count());
2461     EXPECT_EQ(0, cache.disk_cache()->open_count());
2462     EXPECT_EQ(1, cache.disk_cache()->create_count());
2463   }
2464 
2465   {
2466     // Now request the full thing, revalidating successfully, so the full
2467     // file gets stored via a sparse-entry.
2468     ScopedMockTransaction transaction_all(kRangeGET_TransactionOK);
2469     transaction_all.request_headers = EXTRA_HEADER;
2470     transaction_all.data =
2471         "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49"
2472         " rg: 50-59 rg: 60-69 rg: 70-79 ";
2473     MockHttpRequest request_all(transaction_all);
2474 
2475     HttpResponseInfo response_all;
2476     RunTransactionTestWithRequest(cache.http_cache(), transaction_all,
2477                                   request_all, &response_all);
2478     ASSERT_TRUE(response_all.headers != nullptr);
2479     EXPECT_EQ(200, response_all.headers->response_code());
2480     // 1 from previous test, validation, and second chunk
2481     EXPECT_EQ(3, cache.network_layer()->transaction_count());
2482     EXPECT_EQ(1, cache.disk_cache()->open_count());
2483     EXPECT_EQ(1, cache.disk_cache()->create_count());
2484   }
2485 
2486   {
2487     // Grab it again, should not need re-validation.
2488     ScopedMockTransaction transaction_all2(kRangeGET_TransactionOK);
2489     transaction_all2.request_headers = EXTRA_HEADER;
2490     transaction_all2.data =
2491         "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49"
2492         " rg: 50-59 rg: 60-69 rg: 70-79 ";
2493     MockHttpRequest request_all2(transaction_all2);
2494 
2495     HttpResponseInfo response_all2;
2496     RunTransactionTestWithRequest(cache.http_cache(), transaction_all2,
2497                                   request_all2, &response_all2);
2498     ASSERT_TRUE(response_all2.headers != nullptr);
2499     EXPECT_EQ(200, response_all2.headers->response_code());
2500 
2501     // Only one more cache open, no new network traffic.
2502     EXPECT_EQ(3, cache.network_layer()->transaction_count());
2503     EXPECT_EQ(2, cache.disk_cache()->open_count());
2504     EXPECT_EQ(1, cache.disk_cache()->create_count());
2505   }
2506 }
2507 
2508 // This test verifies that the ConnectedCallback passed to a cache transaction
2509 // is called once per subrange in the case of a range request with a partial
2510 // cache hit.
TEST_F(HttpCacheTest,RangeGET_ConnectedCallbackCalledForEachRange)2511 TEST_F(HttpCacheTest, RangeGET_ConnectedCallbackCalledForEachRange) {
2512   MockHttpCache cache;
2513 
2514   // Request an infix range and populate the cache with it.
2515   {
2516     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2517     mock_transaction.request_headers = "Range: bytes = 20-29\r\n" EXTRA_HEADER;
2518     mock_transaction.data = "rg: 20-29 ";
2519     mock_transaction.transport_info = TestTransportInfo();
2520 
2521     RunTransactionTest(cache.http_cache(), mock_transaction);
2522   }
2523 
2524   // Request a surrounding range and observe that the callback is called once
2525   // per subrange, as split up by cache hits.
2526   {
2527     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2528     mock_transaction.request_headers = "Range: bytes = 10-39\r\n" EXTRA_HEADER;
2529     mock_transaction.data = "rg: 10-19 rg: 20-29 rg: 30-39 ";
2530     mock_transaction.transport_info = TestTransportInfo();
2531     MockHttpRequest request(mock_transaction);
2532 
2533     ConnectedHandler connected_handler;
2534 
2535     std::unique_ptr<HttpTransaction> transaction;
2536     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2537     ASSERT_THAT(transaction, NotNull());
2538 
2539     transaction->SetConnectedCallback(connected_handler.Callback());
2540 
2541     TestCompletionCallback callback;
2542     ASSERT_THAT(
2543         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2544         IsError(ERR_IO_PENDING));
2545     EXPECT_THAT(callback.WaitForResult(), IsOk());
2546 
2547     // 1 call for the first range's network transaction.
2548     EXPECT_THAT(connected_handler.transports(),
2549                 ElementsAre(TestTransportInfo()));
2550 
2551     // Switch the endpoint for the next network transaction to observe.
2552     // For ease, we just switch the port number.
2553     //
2554     // NOTE: This works because only the mock transaction struct's address is
2555     // registered with the mocking framework - the pointee data is consulted
2556     // each time it is read.
2557     mock_transaction.transport_info = TestTransportInfoWithPort(123);
2558 
2559     ReadAndVerifyTransaction(transaction.get(), mock_transaction);
2560 
2561     // A second call for the cached range, reported as coming from the original
2562     // endpoint it was cached from. A third call for the last range's network
2563     // transaction.
2564     EXPECT_THAT(connected_handler.transports(),
2565                 ElementsAre(TestTransportInfo(), CachedTestTransportInfo(),
2566                             TestTransportInfoWithPort(123)));
2567   }
2568 }
2569 
2570 // This test verifies that when the ConnectedCallback passed to a cache range
2571 // transaction returns an `ERR_INCONSISTENT_IP_ADDRESS_SPACE` error during a
2572 // partial read from cache, then the cache entry is invalidated.
TEST_F(HttpCacheTest,RangeGET_ConnectedCallbackReturnInconsistentIpError)2573 TEST_F(HttpCacheTest, RangeGET_ConnectedCallbackReturnInconsistentIpError) {
2574   MockHttpCache cache;
2575 
2576   // Request an infix range and populate the cache with it.
2577   {
2578     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2579     mock_transaction.request_headers = "Range: bytes = 20-29\r\n" EXTRA_HEADER;
2580     mock_transaction.data = "rg: 20-29 ";
2581     mock_transaction.transport_info = TestTransportInfo();
2582 
2583     RunTransactionTest(cache.http_cache(), mock_transaction);
2584   }
2585 
2586   ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2587   mock_transaction.request_headers = "Range: bytes = 10-39\r\n" EXTRA_HEADER;
2588   mock_transaction.data = "rg: 10-19 rg: 20-29 rg: 30-39 ";
2589   mock_transaction.transport_info = TestTransportInfo();
2590   MockHttpRequest request(mock_transaction);
2591 
2592   // Request a surrounding range. This *should* be read in three parts:
2593   //
2594   // 1. for the prefix: from the network
2595   // 2. for the cached infix: from the cache
2596   // 3. for the suffix: from the network
2597   //
2598   // The connected callback returns OK for 1), but fails during 2). As a result,
2599   // the transaction fails partway and 3) is never created. The cache entry is
2600   // invalidated as a result of the specific error code.
2601   {
2602     ConnectedHandler connected_handler;
2603 
2604     std::unique_ptr<HttpTransaction> transaction;
2605     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2606     ASSERT_THAT(transaction, NotNull());
2607 
2608     transaction->SetConnectedCallback(connected_handler.Callback());
2609 
2610     TestCompletionCallback callback;
2611     ASSERT_THAT(
2612         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2613         IsError(ERR_IO_PENDING));
2614     EXPECT_THAT(callback.WaitForResult(), IsOk());
2615 
2616     // 1 call for the first range's network transaction.
2617     EXPECT_THAT(connected_handler.transports(),
2618                 ElementsAre(TestTransportInfo()));
2619 
2620     // Set the callback to return an error the next time it is called.
2621     connected_handler.set_result(ERR_INCONSISTENT_IP_ADDRESS_SPACE);
2622 
2623     std::string content;
2624     EXPECT_THAT(ReadTransaction(transaction.get(), &content),
2625                 IsError(ERR_INCONSISTENT_IP_ADDRESS_SPACE));
2626 
2627     // A second call that failed.
2628     EXPECT_THAT(connected_handler.transports(),
2629                 ElementsAre(TestTransportInfo(), CachedTestTransportInfo()));
2630   }
2631 
2632   // Request the same range again, observe that nothing is read from cache.
2633   {
2634     ConnectedHandler connected_handler;
2635 
2636     std::unique_ptr<HttpTransaction> transaction;
2637     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2638     ASSERT_THAT(transaction, NotNull());
2639 
2640     transaction->SetConnectedCallback(connected_handler.Callback());
2641 
2642     TestCompletionCallback callback;
2643     ASSERT_THAT(
2644         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2645         IsError(ERR_IO_PENDING));
2646     EXPECT_THAT(callback.WaitForResult(), IsOk());
2647 
2648     std::string content;
2649     EXPECT_THAT(ReadTransaction(transaction.get(), &content), IsOk());
2650     EXPECT_EQ(content, mock_transaction.data);
2651 
2652     // 1 call for the network transaction from which the whole response was
2653     // read. The first 20 bytes were cached by the previous two requests, but
2654     // the cache entry was doomed during the last transaction so they are not
2655     // used here.
2656     EXPECT_THAT(connected_handler.transports(),
2657                 ElementsAre(TestTransportInfo()));
2658   }
2659 }
2660 
2661 // This test verifies that when the ConnectedCallback passed to a cache range
2662 // transaction returns an `ERR_INCONSISTENT_IP_ADDRESS_SPACE` error during a
2663 // network transaction, then the cache entry is invalidated.
TEST_F(HttpCacheTest,RangeGET_ConnectedCallbackReturnInconsistentIpErrorForNetwork)2664 TEST_F(HttpCacheTest,
2665        RangeGET_ConnectedCallbackReturnInconsistentIpErrorForNetwork) {
2666   MockHttpCache cache;
2667 
2668   // Request a prefix range and populate the cache with it.
2669   {
2670     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2671     mock_transaction.request_headers = "Range: bytes = 10-19\r\n" EXTRA_HEADER;
2672     mock_transaction.data = "rg: 10-19 ";
2673     mock_transaction.transport_info = TestTransportInfo();
2674 
2675     RunTransactionTest(cache.http_cache(), mock_transaction);
2676   }
2677 
2678   ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2679   mock_transaction.request_headers = "Range: bytes = 10-29\r\n" EXTRA_HEADER;
2680   mock_transaction.data = "rg: 10-19 rg: 20-29 ";
2681   mock_transaction.transport_info = TestTransportInfo();
2682   MockHttpRequest request(mock_transaction);
2683 
2684   // Request a longer range. This *should* be read in two parts:
2685   //
2686   // 1. for the prefix: from the cache
2687   // 2. for the suffix: from the network
2688   {
2689     ConnectedHandler connected_handler;
2690 
2691     std::unique_ptr<HttpTransaction> transaction;
2692     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2693     ASSERT_THAT(transaction, NotNull());
2694 
2695     transaction->SetConnectedCallback(connected_handler.Callback());
2696 
2697     TestCompletionCallback callback;
2698     ASSERT_THAT(
2699         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2700         IsError(ERR_IO_PENDING));
2701     EXPECT_THAT(callback.WaitForResult(), IsOk());
2702 
2703     // 1 call for the first range's network transaction.
2704     EXPECT_THAT(connected_handler.transports(),
2705                 ElementsAre(CachedTestTransportInfo()));
2706 
2707     // Set the callback to return an error the next time it is called.
2708     connected_handler.set_result(ERR_INCONSISTENT_IP_ADDRESS_SPACE);
2709 
2710     std::string content;
2711     EXPECT_THAT(ReadTransaction(transaction.get(), &content),
2712                 IsError(ERR_INCONSISTENT_IP_ADDRESS_SPACE));
2713 
2714     // A second call that failed.
2715     EXPECT_THAT(connected_handler.transports(),
2716                 ElementsAre(CachedTestTransportInfo(), TestTransportInfo()));
2717   }
2718 
2719   // Request the same range again, observe that nothing is read from cache.
2720   {
2721     ConnectedHandler connected_handler;
2722 
2723     std::unique_ptr<HttpTransaction> transaction;
2724     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2725     ASSERT_THAT(transaction, NotNull());
2726 
2727     transaction->SetConnectedCallback(connected_handler.Callback());
2728 
2729     TestCompletionCallback callback;
2730     ASSERT_THAT(
2731         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2732         IsError(ERR_IO_PENDING));
2733     EXPECT_THAT(callback.WaitForResult(), IsOk());
2734 
2735     std::string content;
2736     EXPECT_THAT(ReadTransaction(transaction.get(), &content), IsOk());
2737     EXPECT_EQ(content, mock_transaction.data);
2738 
2739     // 1 call for the network transaction from which the whole response was
2740     // read. The first 20 bytes were cached by the previous two requests, but
2741     // the cache entry was doomed during the last transaction so they are not
2742     // used here.
2743     EXPECT_THAT(connected_handler.transports(),
2744                 ElementsAre(TestTransportInfo()));
2745   }
2746 }
2747 
2748 // This test verifies that when the ConnectedCallback passed to a cache
2749 // transaction returns an error for the second (or third) subrange transaction,
2750 // the overall cache transaction fails with that error. The cache entry is still
2751 // usable after that.
TEST_F(HttpCacheTest,RangeGET_ConnectedCallbackReturnErrorSecondTime)2752 TEST_F(HttpCacheTest, RangeGET_ConnectedCallbackReturnErrorSecondTime) {
2753   MockHttpCache cache;
2754 
2755   // Request an infix range and populate the cache with it.
2756   {
2757     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2758     mock_transaction.request_headers = "Range: bytes = 20-29\r\n" EXTRA_HEADER;
2759     mock_transaction.data = "rg: 20-29 ";
2760     mock_transaction.transport_info = TestTransportInfo();
2761 
2762     RunTransactionTest(cache.http_cache(), mock_transaction);
2763   }
2764 
2765   ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2766   mock_transaction.request_headers = "Range: bytes = 10-39\r\n" EXTRA_HEADER;
2767   mock_transaction.data = "rg: 10-19 rg: 20-29 rg: 30-39 ";
2768   mock_transaction.transport_info = TestTransportInfo();
2769   MockHttpRequest request(mock_transaction);
2770 
2771   // Request a surrounding range. This *should* be read in three parts:
2772   //
2773   // 1. for the prefix: from the network
2774   // 2. for the cached infix: from the cache
2775   // 3. for the suffix: from the network
2776   //
2777   // The connected callback returns OK for 1), but fails during 2). As a result,
2778   // the transaction fails partway and 3) is never created. The prefix is still
2779   // cached, such that the cache entry ends up with both the prefix and infix.
2780   {
2781     ConnectedHandler connected_handler;
2782 
2783     std::unique_ptr<HttpTransaction> transaction;
2784     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2785     ASSERT_THAT(transaction, NotNull());
2786 
2787     transaction->SetConnectedCallback(connected_handler.Callback());
2788 
2789     TestCompletionCallback callback;
2790     ASSERT_THAT(
2791         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2792         IsError(ERR_IO_PENDING));
2793     EXPECT_THAT(callback.WaitForResult(), IsOk());
2794 
2795     // 1 call for the first range's network transaction.
2796     EXPECT_THAT(connected_handler.transports(),
2797                 ElementsAre(TestTransportInfo()));
2798 
2799     // Set the callback to return an error the next time it is called. The exact
2800     // error code is irrelevant, what matters is that it is reflected in the
2801     // overall status of the transaction.
2802     connected_handler.set_result(ERR_NOT_IMPLEMENTED);
2803 
2804     std::string content;
2805     EXPECT_THAT(ReadTransaction(transaction.get(), &content),
2806                 IsError(ERR_NOT_IMPLEMENTED));
2807 
2808     // A second call that failed.
2809     EXPECT_THAT(connected_handler.transports(),
2810                 ElementsAre(TestTransportInfo(), CachedTestTransportInfo()));
2811   }
2812 
2813   // Request the same range again, observe that the prefix and infix are both
2814   // read from cache. Only the suffix is fetched from the network.
2815   {
2816     ConnectedHandler connected_handler;
2817 
2818     std::unique_ptr<HttpTransaction> transaction;
2819     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2820     ASSERT_THAT(transaction, NotNull());
2821 
2822     transaction->SetConnectedCallback(connected_handler.Callback());
2823 
2824     TestCompletionCallback callback;
2825     ASSERT_THAT(
2826         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2827         IsError(ERR_IO_PENDING));
2828     EXPECT_THAT(callback.WaitForResult(), IsOk());
2829 
2830     // 1 call for the first range's cache transaction: the first 20 bytes were
2831     // cached by the previous two requests.
2832     EXPECT_THAT(connected_handler.transports(),
2833                 ElementsAre(CachedTestTransportInfo()));
2834 
2835     std::string content;
2836     EXPECT_THAT(ReadTransaction(transaction.get(), &content), IsOk());
2837     EXPECT_EQ(content, mock_transaction.data);
2838 
2839     // A second call from the network transaction for the last 10 bytes.
2840     EXPECT_THAT(connected_handler.transports(),
2841                 ElementsAre(CachedTestTransportInfo(), TestTransportInfo()));
2842   }
2843 }
2844 
2845 // This test verifies that the ConnectedCallback passed to a cache transaction
2846 // is called once per subrange in the case of a range request with a partial
2847 // cache hit, even when a prefix of the range is cached.
TEST_F(HttpCacheTest,RangeGET_ConnectedCallbackCalledForEachRangeWithPrefix)2848 TEST_F(HttpCacheTest, RangeGET_ConnectedCallbackCalledForEachRangeWithPrefix) {
2849   MockHttpCache cache;
2850 
2851   // Request a prefix range and populate the cache with it.
2852   {
2853     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2854     mock_transaction.request_headers = "Range: bytes = 10-19\r\n" EXTRA_HEADER;
2855     mock_transaction.data = "rg: 10-19 ";
2856     mock_transaction.transport_info = TestTransportInfo();
2857 
2858     RunTransactionTest(cache.http_cache(), mock_transaction);
2859   }
2860 
2861   // Request a surrounding range and observe that the callback is called once
2862   // per subrange, as split up by cache hits.
2863   {
2864     ScopedMockTransaction mock_transaction(kRangeGET_TransactionOK);
2865     mock_transaction.request_headers = "Range: bytes = 10-39\r\n" EXTRA_HEADER;
2866     mock_transaction.data = "rg: 10-19 rg: 20-29 rg: 30-39 ";
2867     mock_transaction.transport_info = TestTransportInfoWithPort(123);
2868     MockHttpRequest request(mock_transaction);
2869 
2870     ConnectedHandler connected_handler;
2871 
2872     std::unique_ptr<HttpTransaction> transaction;
2873     EXPECT_THAT(cache.CreateTransaction(&transaction), IsOk());
2874     ASSERT_THAT(transaction, NotNull());
2875 
2876     transaction->SetConnectedCallback(connected_handler.Callback());
2877 
2878     TestCompletionCallback callback;
2879     ASSERT_THAT(
2880         transaction->Start(&request, callback.callback(), NetLogWithSource()),
2881         IsError(ERR_IO_PENDING));
2882     EXPECT_THAT(callback.WaitForResult(), IsOk());
2883 
2884     // 1 call for the first range from the cache, reported as coming from the
2885     // endpoint which initially served the cached range.
2886     EXPECT_THAT(connected_handler.transports(),
2887                 ElementsAre(CachedTestTransportInfo()));
2888 
2889     ReadAndVerifyTransaction(transaction.get(), mock_transaction);
2890 
2891     // A second call for the last range's network transaction.
2892     EXPECT_THAT(
2893         connected_handler.transports(),
2894         ElementsAre(CachedTestTransportInfo(), TestTransportInfoWithPort(123)));
2895   }
2896 }
2897 
2898 // Tests that a range transaction is still usable even if it's unable to access
2899 // the cache.
TEST_F(HttpCacheTest,RangeGET_FailedCacheAccess)2900 TEST_F(HttpCacheTest, RangeGET_FailedCacheAccess) {
2901   MockHttpCache cache;
2902 
2903   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
2904   MockHttpRequest request(transaction);
2905 
2906   auto c = std::make_unique<Context>();
2907   c->result = cache.CreateTransaction(&c->trans);
2908   ASSERT_THAT(c->result, IsOk());
2909   EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
2910 
2911   cache.disk_cache()->set_fail_requests(true);
2912 
2913   c->result =
2914       c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
2915 
2916   base::RunLoop().RunUntilIdle();
2917 
2918   EXPECT_FALSE(cache.IsWriterPresent(kRangeGET_TransactionOK.url));
2919 
2920   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2921   EXPECT_EQ(0, cache.disk_cache()->open_count());
2922   EXPECT_EQ(0, cache.disk_cache()->create_count());
2923 
2924   c->result = c->callback.WaitForResult();
2925 
2926   ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK);
2927 
2928   EXPECT_EQ(1, cache.network_layer()->transaction_count());
2929   EXPECT_EQ(0, cache.disk_cache()->open_count());
2930   EXPECT_EQ(0, cache.disk_cache()->create_count());
2931 }
2932 
2933 // Tests that we can have parallel validation on range requests.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationNoMatch)2934 TEST_F(HttpCacheTest, RangeGET_ParallelValidationNoMatch) {
2935   MockHttpCache cache;
2936 
2937   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
2938   MockHttpRequest request(transaction);
2939 
2940   std::vector<std::unique_ptr<Context>> context_list;
2941   const int kNumTransactions = 5;
2942 
2943   for (int i = 0; i < kNumTransactions; ++i) {
2944     context_list.push_back(std::make_unique<Context>());
2945     auto& c = context_list[i];
2946 
2947     c->result = cache.CreateTransaction(&c->trans);
2948     ASSERT_THAT(c->result, IsOk());
2949     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
2950 
2951     c->result =
2952         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
2953   }
2954 
2955   // All requests are waiting for the active entry.
2956   for (auto& context : context_list) {
2957     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
2958   }
2959 
2960   // Allow all requests to move from the Create queue to the active entry.
2961   base::RunLoop().RunUntilIdle();
2962 
2963   // First entry created is doomed due to 2nd transaction's validation leading
2964   // to restarting of the queued transactions.
2965   EXPECT_TRUE(cache.IsWriterPresent(request.CacheKey()));
2966 
2967   // TODO(shivanisha): The restarted transactions race for creating the entry
2968   // and thus instead of all 4 succeeding, 2 of them succeed. This is very
2969   // implementation specific and happens because the queued transactions get
2970   // restarted synchronously and get to the queue of creating the entry before
2971   // the transaction that is restarting them. Fix the test to make it less
2972   // vulnerable to any scheduling changes in the code.
2973   EXPECT_EQ(5, cache.network_layer()->transaction_count());
2974   EXPECT_EQ(0, cache.disk_cache()->open_count());
2975   EXPECT_EQ(3, cache.disk_cache()->create_count());
2976 
2977   for (auto& context : context_list) {
2978     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
2979   }
2980 
2981   for (int i = 0; i < kNumTransactions; ++i) {
2982     auto& c = context_list[i];
2983     if (c->result == ERR_IO_PENDING) {
2984       c->result = c->callback.WaitForResult();
2985     }
2986 
2987     ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK);
2988   }
2989 
2990   EXPECT_EQ(5, cache.network_layer()->transaction_count());
2991   EXPECT_EQ(0, cache.disk_cache()->open_count());
2992   EXPECT_EQ(3, cache.disk_cache()->create_count());
2993 }
2994 
2995 // Tests that if a transaction is dooming the entry and the entry was doomed by
2996 // another transaction that was not part of the entry and created a new entry,
2997 // the new entry should not be incorrectly doomed. (crbug.com/736993)
TEST_F(HttpCacheTest,RangeGET_ParallelValidationNoMatchDoomEntry)2998 TEST_F(HttpCacheTest, RangeGET_ParallelValidationNoMatchDoomEntry) {
2999   MockHttpCache cache;
3000 
3001   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3002   MockHttpRequest request(transaction);
3003 
3004   MockTransaction dooming_transaction(kRangeGET_TransactionOK);
3005   dooming_transaction.load_flags |= LOAD_BYPASS_CACHE;
3006   MockHttpRequest dooming_request(dooming_transaction);
3007 
3008   std::vector<std::unique_ptr<Context>> context_list;
3009   const int kNumTransactions = 3;
3010 
3011   scoped_refptr<MockDiskEntry> first_entry;
3012   scoped_refptr<MockDiskEntry> second_entry;
3013   for (int i = 0; i < kNumTransactions; ++i) {
3014     context_list.push_back(std::make_unique<Context>());
3015     auto& c = context_list[i];
3016 
3017     c->result = cache.CreateTransaction(&c->trans);
3018     ASSERT_THAT(c->result, IsOk());
3019     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3020 
3021     MockHttpRequest* this_request = &request;
3022 
3023     if (i == 2) {
3024       this_request = &dooming_request;
3025     }
3026 
3027     if (i == 1) {
3028       ASSERT_TRUE(first_entry);
3029       first_entry->SetDefer(MockDiskEntry::DEFER_READ);
3030     }
3031 
3032     c->result = c->trans->Start(this_request, c->callback.callback(),
3033                                 NetLogWithSource());
3034 
3035     // Continue the transactions. 2nd will pause at the cache reading state and
3036     // 3rd transaction will doom the entry.
3037     base::RunLoop().RunUntilIdle();
3038 
3039     std::string cache_key = request.CacheKey();
3040     // Check status of the first and second entries after every transaction.
3041     switch (i) {
3042       case 0:
3043         first_entry = cache.disk_cache()->GetDiskEntryRef(cache_key);
3044         break;
3045       case 1:
3046         EXPECT_FALSE(first_entry->is_doomed());
3047         break;
3048       case 2:
3049         EXPECT_TRUE(first_entry->is_doomed());
3050         second_entry = cache.disk_cache()->GetDiskEntryRef(cache_key);
3051         EXPECT_FALSE(second_entry->is_doomed());
3052         break;
3053     }
3054   }
3055   // Resume cache read by 1st transaction which will lead to dooming the entry
3056   // as well since the entry cannot be validated. This double dooming should not
3057   // lead to an assertion.
3058   first_entry->ResumeDiskEntryOperation();
3059   base::RunLoop().RunUntilIdle();
3060 
3061   // Since second_entry is already created, when 1st transaction goes on to
3062   // create an entry, it will get ERR_CACHE_RACE leading to dooming of
3063   // second_entry and creation of a third entry.
3064   EXPECT_TRUE(second_entry->is_doomed());
3065 
3066   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3067   EXPECT_EQ(0, cache.disk_cache()->open_count());
3068   EXPECT_EQ(3, cache.disk_cache()->create_count());
3069 
3070   for (auto& context : context_list) {
3071     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
3072   }
3073 
3074   for (auto& c : context_list) {
3075     ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK);
3076   }
3077 
3078   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3079   EXPECT_EQ(0, cache.disk_cache()->open_count());
3080   EXPECT_EQ(3, cache.disk_cache()->create_count());
3081 }
3082 
3083 // Same as above but tests that the 2nd transaction does not do anything if
3084 // there is nothing to doom. (crbug.com/736993)
TEST_F(HttpCacheTest,RangeGET_ParallelValidationNoMatchDoomEntry1)3085 TEST_F(HttpCacheTest, RangeGET_ParallelValidationNoMatchDoomEntry1) {
3086   MockHttpCache cache;
3087 
3088   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3089   MockHttpRequest request(transaction);
3090 
3091   MockTransaction dooming_transaction(kRangeGET_TransactionOK);
3092   dooming_transaction.load_flags |= LOAD_BYPASS_CACHE;
3093   MockHttpRequest dooming_request(dooming_transaction);
3094 
3095   std::vector<std::unique_ptr<Context>> context_list;
3096   const int kNumTransactions = 3;
3097 
3098   scoped_refptr<MockDiskEntry> first_entry;
3099   for (int i = 0; i < kNumTransactions; ++i) {
3100     context_list.push_back(std::make_unique<Context>());
3101     auto& c = context_list[i];
3102 
3103     c->result = cache.CreateTransaction(&c->trans);
3104     ASSERT_THAT(c->result, IsOk());
3105     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3106 
3107     MockHttpRequest* this_request = &request;
3108 
3109     if (i == 2) {
3110       this_request = &dooming_request;
3111       cache.disk_cache()->SetDefer(MockDiskEntry::DEFER_CREATE);
3112     }
3113 
3114     if (i == 1) {
3115       ASSERT_TRUE(first_entry);
3116       first_entry->SetDefer(MockDiskEntry::DEFER_READ);
3117     }
3118 
3119     c->result = c->trans->Start(this_request, c->callback.callback(),
3120                                 NetLogWithSource());
3121 
3122     // Continue the transactions. 2nd will pause at the cache reading state and
3123     // 3rd transaction will doom the entry and pause before creating a new
3124     // entry.
3125     base::RunLoop().RunUntilIdle();
3126 
3127     // Check status of the entry after every transaction.
3128     switch (i) {
3129       case 0:
3130         first_entry = cache.disk_cache()->GetDiskEntryRef(request.CacheKey());
3131         break;
3132       case 1:
3133         EXPECT_FALSE(first_entry->is_doomed());
3134         break;
3135       case 2:
3136         EXPECT_TRUE(first_entry->is_doomed());
3137         break;
3138     }
3139   }
3140   // Resume cache read by 2nd transaction which will lead to dooming the entry
3141   // as well since the entry cannot be validated. This double dooming should not
3142   // lead to an assertion.
3143   first_entry->ResumeDiskEntryOperation();
3144   base::RunLoop().RunUntilIdle();
3145 
3146   // Resume creation of entry by 3rd transaction.
3147   cache.disk_cache()->ResumeCacheOperation();
3148   base::RunLoop().RunUntilIdle();
3149 
3150   // Note that since 3rd transaction's entry is already created but its
3151   // callback is deferred, MockDiskCache's implementation returns
3152   // ERR_CACHE_CREATE_FAILURE when 2nd transaction tries to create an entry
3153   // during that time, leading to it switching over to pass-through mode.
3154   // Thus the number of entries is 2 below.
3155   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3156   EXPECT_EQ(0, cache.disk_cache()->open_count());
3157   EXPECT_EQ(2, cache.disk_cache()->create_count());
3158 
3159   for (auto& context : context_list) {
3160     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
3161   }
3162 
3163   for (auto& c : context_list) {
3164     ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK);
3165   }
3166 
3167   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3168   EXPECT_EQ(0, cache.disk_cache()->open_count());
3169   EXPECT_EQ(2, cache.disk_cache()->create_count());
3170 }
3171 
3172 // Tests parallel validation on range requests with non-overlapping ranges.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationDifferentRanges)3173 TEST_F(HttpCacheTest, RangeGET_ParallelValidationDifferentRanges) {
3174   MockHttpCache cache;
3175 
3176   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3177 
3178   std::vector<std::unique_ptr<Context>> context_list;
3179   const int kNumTransactions = 2;
3180 
3181   for (int i = 0; i < kNumTransactions; ++i) {
3182     context_list.push_back(std::make_unique<Context>());
3183   }
3184 
3185   // Let 1st transaction complete headers phase for ranges 40-49.
3186   std::string first_read;
3187   MockHttpRequest request1(transaction);
3188   {
3189     auto& c = context_list[0];
3190     c->result = cache.CreateTransaction(&c->trans);
3191     ASSERT_THAT(c->result, IsOk());
3192     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3193 
3194     c->result =
3195         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3196     base::RunLoop().RunUntilIdle();
3197 
3198     // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns
3199     // true.
3200     const int kBufferSize = 5;
3201     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
3202     ReleaseBufferCompletionCallback cb(buffer.get());
3203     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3204     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3205 
3206     std::string data_read(buffer->data(), kBufferSize);
3207     first_read = data_read;
3208 
3209     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3210   }
3211 
3212   // 2nd transaction requests ranges 30-39.
3213   transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3214   MockHttpRequest request2(transaction);
3215   {
3216     auto& c = context_list[1];
3217     c->result = cache.CreateTransaction(&c->trans);
3218     ASSERT_THAT(c->result, IsOk());
3219     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3220 
3221     c->result =
3222         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3223     base::RunLoop().RunUntilIdle();
3224 
3225     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3226   }
3227 
3228   std::string cache_key = request2.CacheKey();
3229   EXPECT_TRUE(cache.IsWriterPresent(cache_key));
3230   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
3231 
3232   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3233   EXPECT_EQ(0, cache.disk_cache()->open_count());
3234   EXPECT_EQ(1, cache.disk_cache()->create_count());
3235 
3236   for (int i = 0; i < kNumTransactions; ++i) {
3237     auto& c = context_list[i];
3238     if (c->result == ERR_IO_PENDING) {
3239       c->result = c->callback.WaitForResult();
3240     }
3241 
3242     if (i == 0) {
3243       ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
3244                                         transaction);
3245       continue;
3246     }
3247 
3248     transaction.data = "rg: 30-39 ";
3249     ReadAndVerifyTransaction(c->trans.get(), transaction);
3250   }
3251 
3252   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3253   EXPECT_EQ(0, cache.disk_cache()->open_count());
3254   EXPECT_EQ(1, cache.disk_cache()->create_count());
3255 
3256   // Fetch from the cache to check that ranges 30-49 have been successfully
3257   // cached.
3258   {
3259     MockTransaction range_transaction(kRangeGET_TransactionOK);
3260     range_transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
3261     range_transaction.data = "rg: 30-39 rg: 40-49 ";
3262     std::string headers;
3263     RunTransactionTestWithResponse(cache.http_cache(), range_transaction,
3264                                    &headers);
3265     Verify206Response(headers, 30, 49);
3266   }
3267 
3268   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3269   EXPECT_EQ(1, cache.disk_cache()->open_count());
3270   EXPECT_EQ(1, cache.disk_cache()->create_count());
3271 
3272   context_list.clear();
3273 }
3274 
3275 // Tests that a request does not create Writers when readers is not empty.
TEST_F(HttpCacheTest,RangeGET_DoNotCreateWritersWhenReaderExists)3276 TEST_F(HttpCacheTest, RangeGET_DoNotCreateWritersWhenReaderExists) {
3277   MockHttpCache cache;
3278 
3279   // Save a request in the cache so that the next request can become a
3280   // reader.
3281   ScopedMockTransaction transaction(kRangeGET_Transaction);
3282   transaction.request_headers = EXTRA_HEADER;
3283   RunTransactionTest(cache.http_cache(), transaction);
3284 
3285   // Let this request be a reader since it doesn't need validation as per its
3286   // load flag.
3287   transaction.load_flags |= LOAD_SKIP_CACHE_VALIDATION;
3288   MockHttpRequest request(transaction);
3289   Context context;
3290   context.result = cache.CreateTransaction(&context.trans);
3291   ASSERT_THAT(context.result, IsOk());
3292   context.result = context.trans->Start(&request, context.callback.callback(),
3293                                         NetLogWithSource());
3294   base::RunLoop().RunUntilIdle();
3295   std::string cache_key = request.CacheKey();
3296   EXPECT_EQ(1, cache.GetCountReaders(cache_key));
3297 
3298   // A range request should now "not" create Writers while readers is still
3299   // non-empty.
3300   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
3301   MockHttpRequest range_request(transaction);
3302   Context range_context;
3303   range_context.result = cache.CreateTransaction(&range_context.trans);
3304   ASSERT_THAT(range_context.result, IsOk());
3305   range_context.result = range_context.trans->Start(
3306       &range_request, range_context.callback.callback(), NetLogWithSource());
3307   base::RunLoop().RunUntilIdle();
3308 
3309   EXPECT_EQ(1, cache.GetCountReaders(cache_key));
3310   EXPECT_FALSE(cache.IsWriterPresent(cache_key));
3311   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
3312 }
3313 
3314 // Tests parallel validation on range requests can be successfully restarted
3315 // when there is a cache lock timeout.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationCacheLockTimeout)3316 TEST_F(HttpCacheTest, RangeGET_ParallelValidationCacheLockTimeout) {
3317   MockHttpCache cache;
3318 
3319   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3320 
3321   std::vector<std::unique_ptr<Context>> context_list;
3322   const int kNumTransactions = 2;
3323 
3324   for (int i = 0; i < kNumTransactions; ++i) {
3325     context_list.push_back(std::make_unique<Context>());
3326   }
3327 
3328   // Let 1st transaction complete headers phase for ranges 40-49.
3329   std::string first_read;
3330   MockHttpRequest request1(transaction);
3331   {
3332     auto& c = context_list[0];
3333     c->result = cache.CreateTransaction(&c->trans);
3334     ASSERT_THAT(c->result, IsOk());
3335     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3336 
3337     c->result =
3338         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3339     base::RunLoop().RunUntilIdle();
3340 
3341     // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns
3342     // true.
3343     const int kBufferSize = 5;
3344     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
3345     ReleaseBufferCompletionCallback cb(buffer.get());
3346     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3347     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3348 
3349     std::string data_read(buffer->data(), kBufferSize);
3350     first_read = data_read;
3351 
3352     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3353   }
3354 
3355   // Cache lock timeout will lead to dooming the entry since the transaction may
3356   // have already written the headers.
3357   cache.SimulateCacheLockTimeoutAfterHeaders();
3358 
3359   // 2nd transaction requests ranges 30-39.
3360   transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
3361   MockHttpRequest request2(transaction);
3362   {
3363     auto& c = context_list[1];
3364     c->result = cache.CreateTransaction(&c->trans);
3365     ASSERT_THAT(c->result, IsOk());
3366     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3367 
3368     c->result =
3369         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3370     base::RunLoop().RunUntilIdle();
3371 
3372     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3373   }
3374 
3375   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(request1.CacheKey()));
3376 
3377   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3378   EXPECT_EQ(0, cache.disk_cache()->open_count());
3379   EXPECT_EQ(1, cache.disk_cache()->create_count());
3380 
3381   for (int i = 0; i < kNumTransactions; ++i) {
3382     auto& c = context_list[i];
3383     if (c->result == ERR_IO_PENDING) {
3384       c->result = c->callback.WaitForResult();
3385     }
3386 
3387     if (i == 0) {
3388       ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
3389                                         transaction);
3390       continue;
3391     }
3392 
3393     transaction.data = "rg: 30-39 ";
3394     ReadAndVerifyTransaction(c->trans.get(), transaction);
3395   }
3396 
3397   EXPECT_EQ(3, cache.network_layer()->transaction_count());
3398   EXPECT_EQ(0, cache.disk_cache()->open_count());
3399   EXPECT_EQ(1, cache.disk_cache()->create_count());
3400 }
3401 
3402 // Tests a full request and a simultaneous range request and the range request
3403 // dooms the entry created by the full request due to not being able to
3404 // conditionalize.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationCouldntConditionalize)3405 TEST_F(HttpCacheTest, RangeGET_ParallelValidationCouldntConditionalize) {
3406   MockHttpCache cache;
3407 
3408   MockTransaction mock_transaction(kSimpleGET_Transaction);
3409   mock_transaction.url = kRangeGET_TransactionOK.url;
3410   // Remove the cache-control and other headers so that the response cannot be
3411   // conditionalized.
3412   mock_transaction.response_headers = "";
3413   MockHttpRequest request1(mock_transaction);
3414 
3415   std::vector<std::unique_ptr<Context>> context_list;
3416   const int kNumTransactions = 2;
3417 
3418   for (int i = 0; i < kNumTransactions; ++i) {
3419     context_list.push_back(std::make_unique<Context>());
3420   }
3421 
3422   // Let 1st transaction complete headers phase for no range and read some part
3423   // of the response and write in the cache.
3424   std::string first_read;
3425   {
3426     ScopedMockTransaction transaction(mock_transaction);
3427     request1.url = GURL(kRangeGET_TransactionOK.url);
3428     auto& c = context_list[0];
3429     c->result = cache.CreateTransaction(&c->trans);
3430     ASSERT_THAT(c->result, IsOk());
3431     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3432 
3433     c->result =
3434         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3435     base::RunLoop().RunUntilIdle();
3436 
3437     const int kBufferSize = 5;
3438     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
3439     ReleaseBufferCompletionCallback cb(buffer.get());
3440     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3441     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3442 
3443     std::string data_read(buffer->data(), kBufferSize);
3444     first_read = data_read;
3445 
3446     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3447   }
3448 
3449   // 2nd transaction requests a range.
3450   ScopedMockTransaction range_transaction(kRangeGET_TransactionOK);
3451   range_transaction.request_headers = "Range: bytes = 0-29\r\n" EXTRA_HEADER;
3452   MockHttpRequest request2(range_transaction);
3453   {
3454     auto& c = context_list[1];
3455     c->result = cache.CreateTransaction(&c->trans);
3456     ASSERT_THAT(c->result, IsOk());
3457     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3458 
3459     c->result =
3460         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3461     base::RunLoop().RunUntilIdle();
3462 
3463     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3464   }
3465 
3466   // The second request would have doomed the 1st entry and created a new entry.
3467   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3468   EXPECT_EQ(0, cache.disk_cache()->open_count());
3469   EXPECT_EQ(2, cache.disk_cache()->create_count());
3470 
3471   for (int i = 0; i < kNumTransactions; ++i) {
3472     auto& c = context_list[i];
3473     if (c->result == ERR_IO_PENDING) {
3474       c->result = c->callback.WaitForResult();
3475     }
3476 
3477     if (i == 0) {
3478       ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
3479                                         mock_transaction);
3480       continue;
3481     }
3482     range_transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 ";
3483     ReadAndVerifyTransaction(c->trans.get(), range_transaction);
3484   }
3485   context_list.clear();
3486 }
3487 
3488 // Tests a 200 request and a simultaneous range request where conditionalization
3489 // is possible.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationCouldConditionalize)3490 TEST_F(HttpCacheTest, RangeGET_ParallelValidationCouldConditionalize) {
3491   MockHttpCache cache;
3492 
3493   MockTransaction mock_transaction(kSimpleGET_Transaction);
3494   mock_transaction.url = kRangeGET_TransactionOK.url;
3495   mock_transaction.data = kFullRangeData;
3496   std::string response_headers_str = base::StrCat(
3497       {"ETag: StrongOne\n",
3498        "Content-Length:", base::NumberToString(strlen(kFullRangeData)), "\n"});
3499   mock_transaction.response_headers = response_headers_str.c_str();
3500 
3501   std::vector<std::unique_ptr<Context>> context_list;
3502   const int kNumTransactions = 2;
3503 
3504   for (int i = 0; i < kNumTransactions; ++i) {
3505     context_list.push_back(std::make_unique<Context>());
3506   }
3507 
3508   // Let 1st transaction complete headers phase for no range and read some part
3509   // of the response and write in the cache.
3510   std::string first_read;
3511   MockHttpRequest request1(mock_transaction);
3512   {
3513     ScopedMockTransaction transaction(mock_transaction);
3514     request1.url = GURL(kRangeGET_TransactionOK.url);
3515     auto& c = context_list[0];
3516     c->result = cache.CreateTransaction(&c->trans);
3517     ASSERT_THAT(c->result, IsOk());
3518     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3519 
3520     c->result =
3521         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3522     base::RunLoop().RunUntilIdle();
3523 
3524     const int kBufferSize = 5;
3525     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
3526     ReleaseBufferCompletionCallback cb(buffer.get());
3527     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3528     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3529 
3530     std::string data_read(buffer->data(), kBufferSize);
3531     first_read = data_read;
3532 
3533     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3534   }
3535 
3536   // 2nd transaction requests a range.
3537   ScopedMockTransaction range_transaction(kRangeGET_TransactionOK);
3538   range_transaction.request_headers = "Range: bytes = 0-29\r\n" EXTRA_HEADER;
3539   MockHttpRequest request2(range_transaction);
3540   {
3541     auto& c = context_list[1];
3542     c->result = cache.CreateTransaction(&c->trans);
3543     ASSERT_THAT(c->result, IsOk());
3544     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3545 
3546     c->result =
3547         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3548     base::RunLoop().RunUntilIdle();
3549 
3550     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3551   }
3552 
3553   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3554   EXPECT_EQ(0, cache.disk_cache()->open_count());
3555   EXPECT_EQ(1, cache.disk_cache()->create_count());
3556 
3557   // Finish and verify the first request.
3558   auto& c0 = context_list[0];
3559   c0->result = c0->callback.WaitForResult();
3560   ReadRemainingAndVerifyTransaction(c0->trans.get(), first_read,
3561                                     mock_transaction);
3562 
3563   // And the second.
3564   auto& c1 = context_list[1];
3565   c1->result = c1->callback.WaitForResult();
3566 
3567   range_transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 ";
3568   ReadAndVerifyTransaction(c1->trans.get(), range_transaction);
3569   context_list.clear();
3570 }
3571 
3572 // Tests parallel validation on range requests with overlapping ranges.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationOverlappingRanges)3573 TEST_F(HttpCacheTest, RangeGET_ParallelValidationOverlappingRanges) {
3574   MockHttpCache cache;
3575 
3576   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3577 
3578   std::vector<std::unique_ptr<Context>> context_list;
3579   const int kNumTransactions = 2;
3580 
3581   for (int i = 0; i < kNumTransactions; ++i) {
3582     context_list.push_back(std::make_unique<Context>());
3583   }
3584 
3585   // Let 1st transaction complete headers phase for ranges 40-49.
3586   std::string first_read;
3587   MockHttpRequest request1(transaction);
3588   {
3589     auto& c = context_list[0];
3590     c->result = cache.CreateTransaction(&c->trans);
3591     ASSERT_THAT(c->result, IsOk());
3592     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3593 
3594     c->result =
3595         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3596     base::RunLoop().RunUntilIdle();
3597 
3598     // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns
3599     // true.
3600     const int kBufferSize = 5;
3601     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
3602     ReleaseBufferCompletionCallback cb(buffer.get());
3603     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3604     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3605 
3606     std::string data_read(buffer->data(), kBufferSize);
3607     first_read = data_read;
3608 
3609     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3610   }
3611 
3612   // 2nd transaction requests ranges 30-49.
3613   transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
3614   MockHttpRequest request2(transaction);
3615   {
3616     auto& c = context_list[1];
3617     c->result = cache.CreateTransaction(&c->trans);
3618     ASSERT_THAT(c->result, IsOk());
3619     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3620 
3621     c->result =
3622         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3623     base::RunLoop().RunUntilIdle();
3624 
3625     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3626   }
3627 
3628   std::string cache_key = request1.CacheKey();
3629   EXPECT_TRUE(cache.IsWriterPresent(cache_key));
3630   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
3631 
3632   // Should have created another transaction for the uncached range.
3633   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3634   EXPECT_EQ(0, cache.disk_cache()->open_count());
3635   EXPECT_EQ(1, cache.disk_cache()->create_count());
3636 
3637   for (int i = 0; i < kNumTransactions; ++i) {
3638     auto& c = context_list[i];
3639     if (c->result == ERR_IO_PENDING) {
3640       c->result = c->callback.WaitForResult();
3641     }
3642 
3643     if (i == 0) {
3644       ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
3645                                         transaction);
3646       continue;
3647     }
3648 
3649     transaction.data = "rg: 30-39 rg: 40-49 ";
3650     ReadAndVerifyTransaction(c->trans.get(), transaction);
3651   }
3652 
3653   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3654   EXPECT_EQ(0, cache.disk_cache()->open_count());
3655   EXPECT_EQ(1, cache.disk_cache()->create_count());
3656 
3657   // Fetch from the cache to check that ranges 30-49 have been successfully
3658   // cached.
3659   {
3660     MockTransaction range_transaction(kRangeGET_TransactionOK);
3661     range_transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
3662     range_transaction.data = "rg: 30-39 rg: 40-49 ";
3663     std::string headers;
3664     RunTransactionTestWithResponse(cache.http_cache(), range_transaction,
3665                                    &headers);
3666     Verify206Response(headers, 30, 49);
3667   }
3668 
3669   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3670   EXPECT_EQ(0, cache.disk_cache()->open_count());
3671   EXPECT_EQ(1, cache.disk_cache()->create_count());
3672 }
3673 
3674 // Tests parallel validation on range requests with overlapping ranges and the
3675 // impact of deleting the writer on transactions that have validated.
TEST_F(HttpCacheTest,RangeGET_ParallelValidationRestartDoneHeaders)3676 TEST_F(HttpCacheTest, RangeGET_ParallelValidationRestartDoneHeaders) {
3677   MockHttpCache cache;
3678 
3679   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3680 
3681   std::vector<std::unique_ptr<Context>> context_list;
3682   const int kNumTransactions = 2;
3683 
3684   for (int i = 0; i < kNumTransactions; ++i) {
3685     context_list.push_back(std::make_unique<Context>());
3686   }
3687 
3688   // Let 1st transaction complete headers phase for ranges 40-59.
3689   std::string first_read;
3690   transaction.request_headers = "Range: bytes = 40-59\r\n" EXTRA_HEADER;
3691   MockHttpRequest request1(transaction);
3692   {
3693     auto& c = context_list[0];
3694     c->result = cache.CreateTransaction(&c->trans);
3695     ASSERT_THAT(c->result, IsOk());
3696     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3697 
3698     c->result =
3699         c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
3700     base::RunLoop().RunUntilIdle();
3701 
3702     // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns
3703     // true.
3704     const int kBufferSize = 10;
3705     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
3706     ReleaseBufferCompletionCallback cb(buffer.get());
3707     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
3708     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
3709 
3710     std::string data_read(buffer->data(), kBufferSize);
3711     first_read = data_read;
3712 
3713     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3714   }
3715 
3716   // 2nd transaction requests ranges 30-59.
3717   transaction.request_headers = "Range: bytes = 30-59\r\n" EXTRA_HEADER;
3718   MockHttpRequest request2(transaction);
3719   {
3720     auto& c = context_list[1];
3721     c->result = cache.CreateTransaction(&c->trans);
3722     ASSERT_THAT(c->result, IsOk());
3723     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3724 
3725     c->result =
3726         c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
3727     base::RunLoop().RunUntilIdle();
3728 
3729     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3730   }
3731 
3732   std::string cache_key = request1.CacheKey();
3733   EXPECT_TRUE(cache.IsWriterPresent(cache_key));
3734   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
3735 
3736   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3737   EXPECT_EQ(0, cache.disk_cache()->open_count());
3738   EXPECT_EQ(1, cache.disk_cache()->create_count());
3739 
3740   // Delete the writer transaction.
3741   context_list[0].reset();
3742 
3743   base::RunLoop().RunUntilIdle();
3744 
3745   transaction.data = "rg: 30-39 rg: 40-49 rg: 50-59 ";
3746   ReadAndVerifyTransaction(context_list[1]->trans.get(), transaction);
3747 
3748   // Create another network transaction since the 2nd transaction is restarted.
3749   // 30-39 will be read from network, 40-49 from the cache and 50-59 from the
3750   // network.
3751   EXPECT_EQ(4, cache.network_layer()->transaction_count());
3752   EXPECT_EQ(0, cache.disk_cache()->open_count());
3753   EXPECT_EQ(1, cache.disk_cache()->create_count());
3754 
3755   // Fetch from the cache to check that ranges 30-49 have been successfully
3756   // cached.
3757   {
3758     MockTransaction range_transaction(kRangeGET_TransactionOK);
3759     range_transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
3760     range_transaction.data = "rg: 30-39 rg: 40-49 ";
3761     std::string headers;
3762     RunTransactionTestWithResponse(cache.http_cache(), range_transaction,
3763                                    &headers);
3764     Verify206Response(headers, 30, 49);
3765   }
3766 
3767   EXPECT_EQ(4, cache.network_layer()->transaction_count());
3768   EXPECT_EQ(1, cache.disk_cache()->open_count());
3769   EXPECT_EQ(1, cache.disk_cache()->create_count());
3770 }
3771 
3772 // A test of doing a range request to a cached 301 response
TEST_F(HttpCacheTest,RangeGET_CachedRedirect)3773 TEST_F(HttpCacheTest, RangeGET_CachedRedirect) {
3774   RangeTransactionServer handler;
3775   handler.set_redirect(true);
3776 
3777   MockHttpCache cache;
3778   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
3779   transaction.request_headers = "Range: bytes = 0-\r\n" EXTRA_HEADER;
3780   transaction.status = "HTTP/1.1 301 Moved Permanently";
3781   transaction.response_headers = "Location: /elsewhere\nContent-Length:5";
3782   transaction.data = "12345";
3783   MockHttpRequest request(transaction);
3784 
3785   TestCompletionCallback callback;
3786 
3787   // Write to the cache.
3788   {
3789     std::unique_ptr<HttpTransaction> trans;
3790     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
3791 
3792     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
3793     if (rv == ERR_IO_PENDING) {
3794       rv = callback.WaitForResult();
3795     }
3796     ASSERT_THAT(rv, IsOk());
3797 
3798     const HttpResponseInfo* info = trans->GetResponseInfo();
3799     ASSERT_TRUE(info);
3800 
3801     EXPECT_EQ(info->headers->response_code(), 301);
3802 
3803     std::string location;
3804     info->headers->EnumerateHeader(nullptr, "Location", &location);
3805     EXPECT_EQ(location, "/elsewhere");
3806 
3807     ReadAndVerifyTransaction(trans.get(), transaction);
3808   }
3809   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3810   EXPECT_EQ(0, cache.disk_cache()->open_count());
3811   EXPECT_EQ(1, cache.disk_cache()->create_count());
3812 
3813   // Active entries in the cache are not retired synchronously. Make
3814   // sure the next run hits the MockHttpCache and open_count is
3815   // correct.
3816   base::RunLoop().RunUntilIdle();
3817 
3818   // Read from the cache.
3819   {
3820     std::unique_ptr<HttpTransaction> trans;
3821     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
3822 
3823     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
3824     if (rv == ERR_IO_PENDING) {
3825       rv = callback.WaitForResult();
3826     }
3827     ASSERT_THAT(rv, IsOk());
3828 
3829     const HttpResponseInfo* info = trans->GetResponseInfo();
3830     ASSERT_TRUE(info);
3831 
3832     EXPECT_EQ(info->headers->response_code(), 301);
3833 
3834     std::string location;
3835     info->headers->EnumerateHeader(nullptr, "Location", &location);
3836     EXPECT_EQ(location, "/elsewhere");
3837 
3838     trans->DoneReading();
3839   }
3840   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3841   EXPECT_EQ(1, cache.disk_cache()->open_count());
3842   EXPECT_EQ(1, cache.disk_cache()->create_count());
3843 
3844   // Now read the full body. This normally would not be done for a 301 by
3845   // higher layers, but e.g. a 500 could hit a further bug here.
3846   {
3847     std::unique_ptr<HttpTransaction> trans;
3848     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
3849 
3850     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
3851     if (rv == ERR_IO_PENDING) {
3852       rv = callback.WaitForResult();
3853     }
3854     ASSERT_THAT(rv, IsOk());
3855 
3856     const HttpResponseInfo* info = trans->GetResponseInfo();
3857     ASSERT_TRUE(info);
3858 
3859     EXPECT_EQ(info->headers->response_code(), 301);
3860 
3861     std::string location;
3862     info->headers->EnumerateHeader(nullptr, "Location", &location);
3863     EXPECT_EQ(location, "/elsewhere");
3864 
3865     ReadAndVerifyTransaction(trans.get(), transaction);
3866   }
3867   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3868   // No extra open since it picks up a previous ActiveEntry.
3869   EXPECT_EQ(1, cache.disk_cache()->open_count());
3870   EXPECT_EQ(1, cache.disk_cache()->create_count());
3871 }
3872 
3873 // A transaction that fails to validate an entry, while attempting to write
3874 // the response, should still get data to its consumer even if the attempt to
3875 // create a new entry fails.
TEST_F(HttpCacheTest,SimpleGET_ValidationFailureWithCreateFailure)3876 TEST_F(HttpCacheTest, SimpleGET_ValidationFailureWithCreateFailure) {
3877   MockHttpCache cache;
3878   MockHttpRequest request(kSimpleGET_Transaction);
3879   request.load_flags |= LOAD_VALIDATE_CACHE;
3880   std::vector<std::unique_ptr<Context>> context_list;
3881 
3882   // Create and run the first, successful, transaction to prime the cache.
3883   context_list.push_back(std::make_unique<Context>());
3884   auto& c1 = context_list.back();
3885   c1->result = cache.CreateTransaction(&c1->trans);
3886   ASSERT_THAT(c1->result, IsOk());
3887   EXPECT_EQ(LOAD_STATE_IDLE, c1->trans->GetLoadState());
3888   c1->result =
3889       c1->trans->Start(&request, c1->callback.callback(), NetLogWithSource());
3890   EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, c1->trans->GetLoadState());
3891   base::RunLoop().RunUntilIdle();
3892 
3893   EXPECT_TRUE(cache.IsWriterPresent(request.CacheKey()));
3894   EXPECT_EQ(1, cache.network_layer()->transaction_count());
3895   EXPECT_EQ(0, cache.disk_cache()->open_count());
3896   EXPECT_EQ(1, cache.disk_cache()->create_count());
3897 
3898   // Create and start the second transaction, which will fail its validation
3899   // during the call to RunUntilIdle().
3900   context_list.push_back(std::make_unique<Context>());
3901   auto& c2 = context_list.back();
3902   c2->result = cache.CreateTransaction(&c2->trans);
3903   ASSERT_THAT(c2->result, IsOk());
3904   EXPECT_EQ(LOAD_STATE_IDLE, c2->trans->GetLoadState());
3905   c2->result =
3906       c2->trans->Start(&request, c2->callback.callback(), NetLogWithSource());
3907   // Expect idle at this point because we should be able to find and use the
3908   // Active Entry that c1 created instead of waiting on the cache to open the
3909   // entry.
3910   EXPECT_EQ(LOAD_STATE_IDLE, c2->trans->GetLoadState());
3911 
3912   cache.disk_cache()->set_fail_requests(true);
3913   // The transaction, c2, should now attempt to validate the entry, fail when it
3914   // receives a 200 OK response, attempt to create a new entry, fail to create,
3915   // and then continue onward without an entry.
3916   base::RunLoop().RunUntilIdle();
3917 
3918   // All requests depend on the writer, and the writer is between Start and
3919   // Read, i.e. idle.
3920   for (auto& context : context_list) {
3921     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
3922   }
3923 
3924   // Confirm that both transactions correctly Read() the data.
3925   for (auto& context : context_list) {
3926     if (context->result == ERR_IO_PENDING) {
3927       context->result = context->callback.WaitForResult();
3928     }
3929     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
3930   }
3931 
3932   EXPECT_EQ(2, cache.network_layer()->transaction_count());
3933   EXPECT_EQ(0, cache.disk_cache()->open_count());
3934   EXPECT_EQ(1, cache.disk_cache()->create_count());
3935 }
3936 
3937 // Parallel validation results in 200.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationNoMatch)3938 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationNoMatch) {
3939   MockHttpCache cache;
3940   MockHttpRequest request(kSimpleGET_Transaction);
3941   request.load_flags |= LOAD_VALIDATE_CACHE;
3942   std::vector<std::unique_ptr<Context>> context_list;
3943   const int kNumTransactions = 5;
3944   for (int i = 0; i < kNumTransactions; ++i) {
3945     context_list.push_back(std::make_unique<Context>());
3946     auto& c = context_list[i];
3947     c->result = cache.CreateTransaction(&c->trans);
3948     ASSERT_THAT(c->result, IsOk());
3949     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
3950     c->result =
3951         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
3952   }
3953 
3954   // All requests are waiting for the active entry.
3955   for (auto& context : context_list) {
3956     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
3957   }
3958 
3959   // Allow all requests to move from the Create queue to the active entry.
3960   base::RunLoop().RunUntilIdle();
3961 
3962   // The first request should be a writer at this point, and the subsequent
3963   // requests should have passed the validation phase and created their own
3964   // entries since none of them matched the headers of the earlier one.
3965   EXPECT_TRUE(cache.IsWriterPresent(request.CacheKey()));
3966 
3967   EXPECT_EQ(5, cache.network_layer()->transaction_count());
3968   EXPECT_EQ(0, cache.disk_cache()->open_count());
3969   EXPECT_EQ(5, cache.disk_cache()->create_count());
3970 
3971   // All requests depend on the writer, and the writer is between Start and
3972   // Read, i.e. idle.
3973   for (auto& context : context_list) {
3974     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
3975   }
3976 
3977   for (auto& context : context_list) {
3978     if (context->result == ERR_IO_PENDING) {
3979       context->result = context->callback.WaitForResult();
3980     }
3981     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
3982   }
3983 
3984   EXPECT_EQ(5, cache.network_layer()->transaction_count());
3985   EXPECT_EQ(0, cache.disk_cache()->open_count());
3986   EXPECT_EQ(5, cache.disk_cache()->create_count());
3987 }
3988 
TEST_F(HttpCacheTest,RangeGET_Enormous)3989 TEST_F(HttpCacheTest, RangeGET_Enormous) {
3990   // Test for how blockfile's limit on range namespace interacts with
3991   // HttpCache::Transaction.
3992   // See https://crbug.com/770694
3993   base::ScopedTempDir temp_dir;
3994   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
3995 
3996   auto backend_factory = std::make_unique<HttpCache::DefaultBackend>(
3997       DISK_CACHE, CACHE_BACKEND_BLOCKFILE,
3998       /*file_operations_factory=*/nullptr, temp_dir.GetPath(), 1024 * 1024,
3999       false);
4000   MockHttpCache cache(std::move(backend_factory));
4001 
4002   RangeTransactionServer handler;
4003   handler.set_length(2305843009213693962);
4004 
4005   // Prime with a range it can store.
4006   {
4007     ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4008     transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
4009     transaction.data = "rg: 00-09 ";
4010     MockHttpRequest request(transaction);
4011 
4012     HttpResponseInfo response;
4013     RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
4014                                   &response);
4015     ASSERT_TRUE(response.headers != nullptr);
4016     EXPECT_EQ(206, response.headers->response_code());
4017     EXPECT_EQ(1, cache.network_layer()->transaction_count());
4018   }
4019 
4020   // Try with a range it can't. Should still work.
4021   {
4022     ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4023     transaction.request_headers =
4024         "Range: bytes = "
4025         "2305843009213693952-2305843009213693961\r\n" EXTRA_HEADER;
4026     transaction.data = "rg: 52-61 ";
4027     MockHttpRequest request(transaction);
4028 
4029     HttpResponseInfo response;
4030     RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
4031                                   &response);
4032     ASSERT_TRUE(response.headers != nullptr);
4033     EXPECT_EQ(206, response.headers->response_code());
4034     EXPECT_EQ(2, cache.network_layer()->transaction_count());
4035   }
4036 
4037   // Can't actually cache it due to backend limitations. If the network
4038   // transaction count is 2, this test isn't covering what it needs to.
4039   {
4040     ScopedMockTransaction transaction(kRangeGET_TransactionOK);
4041     transaction.request_headers =
4042         "Range: bytes = "
4043         "2305843009213693952-2305843009213693961\r\n" EXTRA_HEADER;
4044     transaction.data = "rg: 52-61 ";
4045     MockHttpRequest request(transaction);
4046 
4047     HttpResponseInfo response;
4048     RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
4049                                   &response);
4050     ASSERT_TRUE(response.headers != nullptr);
4051     EXPECT_EQ(206, response.headers->response_code());
4052     EXPECT_EQ(3, cache.network_layer()->transaction_count());
4053   }
4054 }
4055 
4056 // Parallel validation results in 200 for 1 transaction and validation matches
4057 // for subsequent transactions.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationNoMatch1)4058 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationNoMatch1) {
4059   MockHttpCache cache;
4060   MockHttpRequest request(kSimpleGET_Transaction);
4061 
4062   MockTransaction transaction(kSimpleGET_Transaction);
4063   transaction.load_flags |= LOAD_VALIDATE_CACHE;
4064   MockHttpRequest validate_request(transaction);
4065   std::vector<std::unique_ptr<Context>> context_list;
4066   const int kNumTransactions = 5;
4067   for (int i = 0; i < kNumTransactions; ++i) {
4068     context_list.push_back(std::make_unique<Context>());
4069     auto& c = context_list[i];
4070     c->result = cache.CreateTransaction(&c->trans);
4071     ASSERT_THAT(c->result, IsOk());
4072     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
4073 
4074     MockHttpRequest* this_request = &request;
4075     if (i == 1) {
4076       this_request = &validate_request;
4077     }
4078 
4079     c->result = c->trans->Start(this_request, c->callback.callback(),
4080                                 NetLogWithSource());
4081   }
4082 
4083   // All requests are waiting for the active entry.
4084   for (auto& context : context_list) {
4085     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
4086   }
4087 
4088   // Allow all requests to move from the Create queue to the active entry.
4089   base::RunLoop().RunUntilIdle();
4090 
4091   // The new entry will have all the transactions except the first one which
4092   // will continue in the doomed entry.
4093   EXPECT_EQ(kNumTransactions - 1,
4094             cache.GetCountWriterTransactions(validate_request.CacheKey()));
4095 
4096   EXPECT_EQ(1, cache.disk_cache()->doomed_count());
4097 
4098   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4099   EXPECT_EQ(0, cache.disk_cache()->open_count());
4100   EXPECT_EQ(2, cache.disk_cache()->create_count());
4101 
4102   for (auto& context : context_list) {
4103     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
4104   }
4105 
4106   for (auto& context : context_list) {
4107     if (context->result == ERR_IO_PENDING) {
4108       context->result = context->callback.WaitForResult();
4109     }
4110 
4111     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
4112   }
4113 
4114   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4115   EXPECT_EQ(0, cache.disk_cache()->open_count());
4116   EXPECT_EQ(2, cache.disk_cache()->create_count());
4117 }
4118 
4119 // Tests that a GET followed by a DELETE results in DELETE immediately starting
4120 // the headers phase and the entry is doomed.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationDelete)4121 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationDelete) {
4122   MockHttpCache cache;
4123 
4124   MockHttpRequest request(kSimpleGET_Transaction);
4125   request.load_flags |= LOAD_VALIDATE_CACHE;
4126 
4127   MockHttpRequest delete_request(kSimpleGET_Transaction);
4128   delete_request.method = "DELETE";
4129 
4130   std::vector<std::unique_ptr<Context>> context_list;
4131   const int kNumTransactions = 2;
4132 
4133   for (int i = 0; i < kNumTransactions; ++i) {
4134     context_list.push_back(std::make_unique<Context>());
4135     auto& c = context_list[i];
4136 
4137     MockHttpRequest* this_request = &request;
4138     if (i == 1) {
4139       this_request = &delete_request;
4140     }
4141 
4142     c->result = cache.CreateTransaction(&c->trans);
4143     ASSERT_THAT(c->result, IsOk());
4144     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
4145 
4146     c->result = c->trans->Start(this_request, c->callback.callback(),
4147                                 NetLogWithSource());
4148   }
4149 
4150   // All requests are waiting for the active entry.
4151   for (auto& context : context_list) {
4152     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
4153   }
4154 
4155   // Allow all requests to move from the Create queue to the active entry.
4156   base::RunLoop().RunUntilIdle();
4157 
4158   // The first request should be a writer at this point, and the subsequent
4159   // request should have passed the validation phase and doomed the existing
4160   // entry.
4161   EXPECT_TRUE(cache.disk_cache()->IsDiskEntryDoomed(request.CacheKey()));
4162 
4163   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4164   EXPECT_EQ(0, cache.disk_cache()->open_count());
4165   EXPECT_EQ(1, cache.disk_cache()->create_count());
4166 
4167   // All requests depend on the writer, and the writer is between Start and
4168   // Read, i.e. idle.
4169   for (auto& context : context_list) {
4170     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
4171   }
4172 
4173   for (auto& context : context_list) {
4174     if (context->result == ERR_IO_PENDING) {
4175       context->result = context->callback.WaitForResult();
4176     }
4177     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
4178   }
4179 
4180   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4181   EXPECT_EQ(0, cache.disk_cache()->open_count());
4182   EXPECT_EQ(1, cache.disk_cache()->create_count());
4183 }
4184 
4185 // Tests that a transaction which is in validated queue can be destroyed without
4186 // any impact to other transactions.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationCancelValidated)4187 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationCancelValidated) {
4188   MockHttpCache cache;
4189 
4190   MockHttpRequest request(kSimpleGET_Transaction);
4191 
4192   MockTransaction transaction(kSimpleGET_Transaction);
4193   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
4194   MockHttpRequest read_only_request(transaction);
4195 
4196   std::vector<std::unique_ptr<Context>> context_list;
4197   const int kNumTransactions = 2;
4198 
4199   for (int i = 0; i < kNumTransactions; ++i) {
4200     context_list.push_back(std::make_unique<Context>());
4201     auto& c = context_list[i];
4202 
4203     c->result = cache.CreateTransaction(&c->trans);
4204     ASSERT_THAT(c->result, IsOk());
4205 
4206     MockHttpRequest* current_request = i == 1 ? &read_only_request : &request;
4207 
4208     c->result = c->trans->Start(current_request, c->callback.callback(),
4209                                 NetLogWithSource());
4210   }
4211 
4212   // Allow all requests to move from the Create queue to the active entry.
4213   base::RunLoop().RunUntilIdle();
4214 
4215   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4216   EXPECT_EQ(0, cache.disk_cache()->open_count());
4217   EXPECT_EQ(1, cache.disk_cache()->create_count());
4218 
4219   std::string cache_key = request.CacheKey();
4220   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
4221   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
4222 
4223   context_list[1].reset();
4224 
4225   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(cache_key));
4226 
4227   // Complete the rest of the transactions.
4228   for (auto& context : context_list) {
4229     if (!context) {
4230       continue;
4231     }
4232     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
4233   }
4234 
4235   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4236   EXPECT_EQ(0, cache.disk_cache()->open_count());
4237   EXPECT_EQ(1, cache.disk_cache()->create_count());
4238 }
4239 
4240 // Tests that an idle writer transaction can be deleted without impacting the
4241 // existing writers.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingCancelIdleTransaction)4242 TEST_F(HttpCacheTest, SimpleGET_ParallelWritingCancelIdleTransaction) {
4243   MockHttpCache cache;
4244 
4245   MockHttpRequest request(kSimpleGET_Transaction);
4246 
4247   std::vector<std::unique_ptr<Context>> context_list;
4248   const int kNumTransactions = 2;
4249 
4250   for (int i = 0; i < kNumTransactions; ++i) {
4251     context_list.push_back(std::make_unique<Context>());
4252     auto& c = context_list[i];
4253 
4254     c->result = cache.CreateTransaction(&c->trans);
4255     ASSERT_THAT(c->result, IsOk());
4256 
4257     c->result =
4258         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
4259   }
4260 
4261   // Allow all requests to move from the Create queue to the active entry.
4262   base::RunLoop().RunUntilIdle();
4263 
4264   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4265   EXPECT_EQ(0, cache.disk_cache()->open_count());
4266   EXPECT_EQ(1, cache.disk_cache()->create_count());
4267 
4268   // Both transactions would be added to writers.
4269   std::string cache_key = request.CacheKey();
4270   EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
4271 
4272   context_list[1].reset();
4273 
4274   EXPECT_EQ(kNumTransactions - 1, cache.GetCountWriterTransactions(cache_key));
4275 
4276   // Complete the rest of the transactions.
4277   for (auto& context : context_list) {
4278     if (!context) {
4279       continue;
4280     }
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   auto buffer2 = base::MakeRefCounted<IOBufferWithSize>(1);
4469   ReleaseBufferCompletionCallback buffer_callback2(buffer2.get());
4470   result = transaction->Read(buffer2.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     }
4561     if (i == 1) {
4562       ReadRemainingAndVerifyTransaction(context->trans.get(), first_read,
4563                                         kSimpleGET_Transaction);
4564     } else {
4565       ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
4566     }
4567   }
4568 
4569   EXPECT_EQ(2, cache.network_layer()->transaction_count());
4570   EXPECT_EQ(0, cache.disk_cache()->open_count());
4571   EXPECT_EQ(2, cache.disk_cache()->create_count());
4572 }
4573 
4574 // Tests the case when network read failure happens. Idle and waiting
4575 // transactions should fail and headers transaction should be restarted.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingNetworkReadFailed)4576 TEST_F(HttpCacheTest, SimpleGET_ParallelWritingNetworkReadFailed) {
4577   MockHttpCache cache;
4578 
4579   ScopedMockTransaction fail_transaction(kSimpleGET_Transaction);
4580   fail_transaction.read_return_code = ERR_INTERNET_DISCONNECTED;
4581   MockHttpRequest failing_request(fail_transaction);
4582 
4583   MockHttpRequest request(kSimpleGET_Transaction);
4584 
4585   MockTransaction transaction(kSimpleGET_Transaction);
4586   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
4587   MockHttpRequest read_request(transaction);
4588 
4589   const int kNumTransactions = 4;
4590   std::vector<std::unique_ptr<Context>> context_list;
4591 
4592   for (int i = 0; i < kNumTransactions; ++i) {
4593     context_list.push_back(std::make_unique<Context>());
4594     auto& c = context_list[i];
4595 
4596     c->result = cache.CreateTransaction(&c->trans);
4597     ASSERT_THAT(c->result, IsOk());
4598 
4599     MockHttpRequest* this_request = &request;
4600     if (i == 0) {
4601       this_request = &failing_request;
4602     }
4603     if (i == 3) {
4604       this_request = &read_request;
4605     }
4606 
4607     c->result = c->trans->Start(this_request, c->callback.callback(),
4608                                 NetLogWithSource());
4609   }
4610 
4611   // Allow all requests to move from the Create queue to the active entry.
4612   base::RunLoop().RunUntilIdle();
4613 
4614   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4615   EXPECT_EQ(0, cache.disk_cache()->open_count());
4616   EXPECT_EQ(1, cache.disk_cache()->create_count());
4617 
4618   std::string cache_key = read_request.CacheKey();
4619   EXPECT_EQ(3, cache.GetCountWriterTransactions(cache_key));
4620   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
4621 
4622   // Initiate Read from two writers and let the first get a network failure.
4623   for (int i = 0; i < 2; i++) {
4624     auto& c = context_list[i];
4625     const int kBufferSize = 5;
4626     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
4627     c->result =
4628         c->trans->Read(buffer.get(), kBufferSize, c->callback.callback());
4629     EXPECT_EQ(ERR_IO_PENDING, c->result);
4630   }
4631 
4632   base::RunLoop().RunUntilIdle();
4633   for (int i = 0; i < 2; i++) {
4634     auto& c = context_list[i];
4635     c->result = c->callback.WaitForResult();
4636     EXPECT_EQ(ERR_INTERNET_DISCONNECTED, c->result);
4637   }
4638 
4639   // The entry should have been doomed and destroyed and the headers transaction
4640   // restarted. Since headers transaction is read-only it will error out.
4641   auto& read_only = context_list[3];
4642   read_only->result = read_only->callback.WaitForResult();
4643   EXPECT_EQ(ERR_CACHE_MISS, read_only->result);
4644 
4645   EXPECT_FALSE(cache.IsWriterPresent(cache_key));
4646 
4647   // Invoke Read on the 3rd transaction and it should get the error code back.
4648   auto& c = context_list[2];
4649   const int kBufferSize = 5;
4650   auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
4651   c->result = c->trans->Read(buffer.get(), kBufferSize, c->callback.callback());
4652   EXPECT_EQ(ERR_INTERNET_DISCONNECTED, c->result);
4653 }
4654 
4655 // Tests the case when cache write failure happens. Idle and waiting
4656 // transactions should fail and headers transaction should be restarted.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingCacheWriteFailed)4657 TEST_F(HttpCacheTest, SimpleGET_ParallelWritingCacheWriteFailed) {
4658   MockHttpCache cache;
4659 
4660   MockHttpRequest request(kSimpleGET_Transaction);
4661 
4662   MockTransaction transaction(kSimpleGET_Transaction);
4663   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
4664   MockHttpRequest read_request(transaction);
4665 
4666   const int kNumTransactions = 4;
4667   std::vector<std::unique_ptr<Context>> context_list;
4668 
4669   for (int i = 0; i < kNumTransactions; ++i) {
4670     context_list.push_back(std::make_unique<Context>());
4671     auto& c = context_list[i];
4672 
4673     c->result = cache.CreateTransaction(&c->trans);
4674     ASSERT_THAT(c->result, IsOk());
4675 
4676     MockHttpRequest* this_request = &request;
4677     if (i == 3) {
4678       this_request = &read_request;
4679     }
4680 
4681     c->result = c->trans->Start(this_request, c->callback.callback(),
4682                                 NetLogWithSource());
4683   }
4684 
4685   // Allow all requests to move from the Create queue to the active entry.
4686   base::RunLoop().RunUntilIdle();
4687 
4688   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4689   EXPECT_EQ(0, cache.disk_cache()->open_count());
4690   EXPECT_EQ(1, cache.disk_cache()->create_count());
4691 
4692   std::string cache_key = read_request.CacheKey();
4693   EXPECT_EQ(3, cache.GetCountWriterTransactions(cache_key));
4694   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
4695 
4696   // Initiate Read from two writers and let the first get a cache write failure.
4697   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_ALL);
4698   // We have to open the entry again to propagate the failure flag.
4699   disk_cache::Entry* en;
4700   cache.OpenBackendEntry(cache_key, &en);
4701   en->Close();
4702   const int kBufferSize = 5;
4703   std::vector<scoped_refptr<IOBuffer>> buffer(
4704       3, base::MakeRefCounted<IOBufferWithSize>(kBufferSize));
4705   for (int i = 0; i < 2; i++) {
4706     auto& c = context_list[i];
4707     c->result =
4708         c->trans->Read(buffer[i].get(), kBufferSize, c->callback.callback());
4709     EXPECT_EQ(ERR_IO_PENDING, c->result);
4710   }
4711 
4712   std::string first_read;
4713   base::RunLoop().RunUntilIdle();
4714   for (int i = 0; i < 2; i++) {
4715     auto& c = context_list[i];
4716     c->result = c->callback.WaitForResult();
4717     if (i == 0) {
4718       EXPECT_EQ(5, c->result);
4719       std::string data_read(buffer[i]->data(), kBufferSize);
4720       first_read = data_read;
4721     } else {
4722       EXPECT_EQ(ERR_CACHE_WRITE_FAILURE, c->result);
4723     }
4724   }
4725 
4726   // The entry should have been doomed and destroyed and the headers transaction
4727   // restarted. Since headers transaction is read-only it will error out.
4728   auto& read_only = context_list[3];
4729   read_only->result = read_only->callback.WaitForResult();
4730   EXPECT_EQ(ERR_CACHE_MISS, read_only->result);
4731 
4732   EXPECT_FALSE(cache.IsWriterPresent(cache_key));
4733 
4734   // Invoke Read on the 3rd transaction and it should get the error code back.
4735   auto& c = context_list[2];
4736   c->result =
4737       c->trans->Read(buffer[2].get(), kBufferSize, c->callback.callback());
4738   EXPECT_EQ(ERR_CACHE_WRITE_FAILURE, c->result);
4739 
4740   // The first transaction should be able to continue to read from the network
4741   // without writing to the cache.
4742   auto& succ_read = context_list[0];
4743   ReadRemainingAndVerifyTransaction(succ_read->trans.get(), first_read,
4744                                     kSimpleGET_Transaction);
4745 }
4746 
4747 // Tests that POST requests do not join existing transactions for parallel
4748 // writing to the cache. Note that two POSTs only map to the same entry if their
4749 // upload data identifier is same and that should happen for back-forward case
4750 // (LOAD_ONLY_FROM_CACHE). But this test tests without LOAD_ONLY_FROM_CACHE
4751 // because read-only transactions anyways do not join parallel writing.
4752 // TODO(shivanisha) Testing this because it is allowed by the code but looks
4753 // like the code should disallow two POSTs without LOAD_ONLY_FROM_CACHE with the
4754 // same upload data identifier to map to the same entry.
TEST_F(HttpCacheTest,SimplePOST_ParallelWritingDisallowed)4755 TEST_F(HttpCacheTest, SimplePOST_ParallelWritingDisallowed) {
4756   MockHttpCache cache;
4757 
4758   MockTransaction transaction(kSimplePOST_Transaction);
4759 
4760   const int64_t kUploadId = 1;  // Just a dummy value.
4761 
4762   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
4763   element_readers.push_back(
4764       std::make_unique<UploadBytesElementReader>("hello", 5));
4765   ElementsUploadDataStream upload_data_stream(std::move(element_readers),
4766                                               kUploadId);
4767 
4768   // Note that both transactions should have the same upload_data_stream
4769   // identifier to map to the same entry.
4770   transaction.load_flags = LOAD_SKIP_CACHE_VALIDATION;
4771   MockHttpRequest request(transaction);
4772   request.upload_data_stream = &upload_data_stream;
4773 
4774   const int kNumTransactions = 2;
4775   std::vector<std::unique_ptr<Context>> context_list;
4776 
4777   for (int i = 0; i < kNumTransactions; ++i) {
4778     context_list.push_back(std::make_unique<Context>());
4779     auto& c = context_list[i];
4780 
4781     c->result = cache.CreateTransaction(&c->trans);
4782     ASSERT_THAT(c->result, IsOk());
4783 
4784     c->result =
4785         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
4786 
4787     // Complete the headers phase request.
4788     base::RunLoop().RunUntilIdle();
4789   }
4790 
4791   std::string cache_key = request.CacheKey();
4792   // Only the 1st transaction gets added to writers.
4793   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
4794   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
4795 
4796   // Read the 1st transaction.
4797   ReadAndVerifyTransaction(context_list[0]->trans.get(),
4798                            kSimplePOST_Transaction);
4799 
4800   // 2nd transaction should now become a reader.
4801   base::RunLoop().RunUntilIdle();
4802   EXPECT_EQ(1, cache.GetCountReaders(cache_key));
4803   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(cache_key));
4804   ReadAndVerifyTransaction(context_list[1]->trans.get(),
4805                            kSimplePOST_Transaction);
4806 
4807   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4808   EXPECT_EQ(0, cache.disk_cache()->open_count());
4809   EXPECT_EQ(1, cache.disk_cache()->create_count());
4810 
4811   context_list.clear();
4812 }
4813 
4814 // Tests the case when parallel writing succeeds. Tests both idle and waiting
4815 // transactions.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingSuccess)4816 TEST_F(HttpCacheTest, SimpleGET_ParallelWritingSuccess) {
4817   MockHttpCache cache;
4818 
4819   MockHttpRequest request(kSimpleGET_Transaction);
4820 
4821   MockTransaction transaction(kSimpleGET_Transaction);
4822   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
4823   MockHttpRequest read_request(transaction);
4824 
4825   const int kNumTransactions = 4;
4826   std::vector<std::unique_ptr<Context>> context_list;
4827 
4828   for (int i = 0; i < kNumTransactions; ++i) {
4829     context_list.push_back(std::make_unique<Context>());
4830     auto& c = context_list[i];
4831 
4832     c->result = cache.CreateTransaction(&c->trans);
4833     ASSERT_THAT(c->result, IsOk());
4834 
4835     MockHttpRequest* this_request = &request;
4836     if (i == 3) {
4837       this_request = &read_request;
4838     }
4839 
4840     c->result = c->trans->Start(this_request, c->callback.callback(),
4841                                 NetLogWithSource());
4842   }
4843 
4844   // Allow all requests to move from the Create queue to the active entry.
4845   base::RunLoop().RunUntilIdle();
4846 
4847   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4848   EXPECT_EQ(0, cache.disk_cache()->open_count());
4849   EXPECT_EQ(1, cache.disk_cache()->create_count());
4850 
4851   std::string cache_key = request.CacheKey();
4852   EXPECT_EQ(3, cache.GetCountWriterTransactions(cache_key));
4853   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
4854 
4855   // Initiate Read from two writers.
4856   const int kBufferSize = 5;
4857   std::vector<scoped_refptr<IOBuffer>> buffer(
4858       3, base::MakeRefCounted<IOBufferWithSize>(kBufferSize));
4859   for (int i = 0; i < 2; i++) {
4860     auto& c = context_list[i];
4861     c->result =
4862         c->trans->Read(buffer[i].get(), kBufferSize, c->callback.callback());
4863     EXPECT_EQ(ERR_IO_PENDING, c->result);
4864   }
4865 
4866   std::vector<std::string> first_read(2);
4867   base::RunLoop().RunUntilIdle();
4868   for (int i = 0; i < 2; i++) {
4869     auto& c = context_list[i];
4870     c->result = c->callback.WaitForResult();
4871     EXPECT_EQ(5, c->result);
4872     std::string data_read(buffer[i]->data(), kBufferSize);
4873     first_read[i] = data_read;
4874   }
4875   EXPECT_EQ(first_read[0], first_read[1]);
4876 
4877   // The first transaction should be able to continue to read from the network
4878   // without writing to the cache.
4879   for (int i = 0; i < 2; i++) {
4880     auto& c = context_list[i];
4881     ReadRemainingAndVerifyTransaction(c->trans.get(), first_read[i],
4882                                       kSimpleGET_Transaction);
4883     if (i == 0) {
4884       // Remaining transactions should now be readers.
4885       EXPECT_EQ(3, cache.GetCountReaders(cache_key));
4886     }
4887   }
4888 
4889   // Verify the rest of the transactions.
4890   for (int i = 2; i < kNumTransactions; i++) {
4891     auto& c = context_list[i];
4892     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
4893   }
4894 
4895   context_list.clear();
4896 }
4897 
4898 // Tests the case when parallel writing involves things bigger than what cache
4899 // can store. In this case, the best we can do is re-fetch it.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingHuge)4900 TEST_F(HttpCacheTest, SimpleGET_ParallelWritingHuge) {
4901   MockHttpCache cache;
4902   cache.disk_cache()->set_max_file_size(10);
4903 
4904   ScopedMockTransaction transaction(kSimpleGET_Transaction);
4905   std::string response_headers = base::StrCat(
4906       {kSimpleGET_Transaction.response_headers, "Content-Length: ",
4907        base::NumberToString(strlen(kSimpleGET_Transaction.data)), "\n"});
4908   transaction.response_headers = response_headers.c_str();
4909   MockHttpRequest request(transaction);
4910 
4911   const int kNumTransactions = 4;
4912   std::vector<std::unique_ptr<Context>> context_list;
4913 
4914   for (int i = 0; i < kNumTransactions; ++i) {
4915     context_list.push_back(std::make_unique<Context>());
4916     auto& c = context_list[i];
4917 
4918     c->result = cache.CreateTransaction(&c->trans);
4919     ASSERT_THAT(c->result, IsOk());
4920 
4921     MockHttpRequest* this_request = &request;
4922     c->result = c->trans->Start(this_request, c->callback.callback(),
4923                                 NetLogWithSource());
4924   }
4925 
4926   // Start them up.
4927   base::RunLoop().RunUntilIdle();
4928 
4929   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4930   EXPECT_EQ(0, cache.disk_cache()->open_count());
4931   EXPECT_EQ(1, cache.disk_cache()->create_count());
4932 
4933   std::string cache_key = request.CacheKey();
4934   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
4935   EXPECT_EQ(kNumTransactions - 1, cache.GetCountDoneHeadersQueue(cache_key));
4936 
4937   // Initiate Read from first transaction.
4938   const int kBufferSize = 5;
4939   std::vector<scoped_refptr<IOBuffer>> buffer(
4940       kNumTransactions, base::MakeRefCounted<IOBufferWithSize>(kBufferSize));
4941   auto& c = context_list[0];
4942   c->result =
4943       c->trans->Read(buffer[0].get(), kBufferSize, c->callback.callback());
4944   EXPECT_EQ(ERR_IO_PENDING, c->result);
4945 
4946   // ... and complete it.
4947   std::vector<std::string> first_read(kNumTransactions);
4948   base::RunLoop().RunUntilIdle();
4949   c->result = c->callback.WaitForResult();
4950   EXPECT_EQ(kBufferSize, c->result);
4951   std::string data_read(buffer[0]->data(), kBufferSize);
4952   first_read[0] = data_read;
4953   EXPECT_EQ("<html", first_read[0]);
4954 
4955   // Complete all of them.
4956   for (int i = 0; i < kNumTransactions; i++) {
4957     ReadRemainingAndVerifyTransaction(context_list[i]->trans.get(),
4958                                       first_read[i], kSimpleGET_Transaction);
4959   }
4960 
4961   // Sadly all of them have to hit the network
4962   EXPECT_EQ(kNumTransactions, cache.network_layer()->transaction_count());
4963 
4964   context_list.clear();
4965 }
4966 
4967 // Tests that network transaction's info is saved correctly when a writer
4968 // transaction that created the network transaction becomes a reader. Also
4969 // verifies that the network bytes are only attributed to the transaction that
4970 // created the network transaction.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritingVerifyNetworkBytes)4971 TEST_F(HttpCacheTest, SimpleGET_ParallelWritingVerifyNetworkBytes) {
4972   MockHttpCache cache;
4973 
4974   MockHttpRequest request(kSimpleGET_Transaction);
4975 
4976   const int kNumTransactions = 2;
4977   std::vector<std::unique_ptr<Context>> context_list;
4978 
4979   for (int i = 0; i < kNumTransactions; ++i) {
4980     context_list.push_back(std::make_unique<Context>());
4981     auto& c = context_list[i];
4982 
4983     c->result = cache.CreateTransaction(&c->trans);
4984     ASSERT_THAT(c->result, IsOk());
4985 
4986     c->result =
4987         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
4988   }
4989 
4990   // Allow all requests to move from the Create queue to the active entry.
4991   base::RunLoop().RunUntilIdle();
4992 
4993   EXPECT_EQ(1, cache.network_layer()->transaction_count());
4994   EXPECT_EQ(0, cache.disk_cache()->open_count());
4995   EXPECT_EQ(1, cache.disk_cache()->create_count());
4996 
4997   std::string cache_key = request.CacheKey();
4998   EXPECT_EQ(2, cache.GetCountWriterTransactions(cache_key));
4999   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(cache_key));
5000 
5001   // Get the network bytes read by the first transaction.
5002   int total_received_bytes = context_list[0]->trans->GetTotalReceivedBytes();
5003   EXPECT_GT(total_received_bytes, 0);
5004 
5005   // Complete Read by the 2nd transaction so that the 1st transaction that
5006   // created the network transaction is now a reader.
5007   ReadAndVerifyTransaction(context_list[1]->trans.get(),
5008                            kSimpleGET_Transaction);
5009 
5010   EXPECT_EQ(1, cache.GetCountReaders(cache_key));
5011 
5012   // Verify that the network bytes read are not attributed to the 2nd
5013   // transaction but to the 1st.
5014   EXPECT_EQ(0, context_list[1]->trans->GetTotalReceivedBytes());
5015 
5016   EXPECT_GE(total_received_bytes,
5017             context_list[0]->trans->GetTotalReceivedBytes());
5018 
5019   ReadAndVerifyTransaction(context_list[0]->trans.get(),
5020                            kSimpleGET_Transaction);
5021 }
5022 
5023 // Tests than extra Read from the consumer should not hang/crash the browser.
TEST_F(HttpCacheTest,SimpleGET_ExtraRead)5024 TEST_F(HttpCacheTest, SimpleGET_ExtraRead) {
5025   MockHttpCache cache;
5026   MockHttpRequest request(kSimpleGET_Transaction);
5027   Context c;
5028 
5029   c.result = cache.CreateTransaction(&c.trans);
5030   ASSERT_THAT(c.result, IsOk());
5031 
5032   c.result =
5033       c.trans->Start(&request, c.callback.callback(), NetLogWithSource());
5034 
5035   base::RunLoop().RunUntilIdle();
5036 
5037   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5038   EXPECT_EQ(0, cache.disk_cache()->open_count());
5039   EXPECT_EQ(1, cache.disk_cache()->create_count());
5040 
5041   std::string cache_key = request.CacheKey();
5042   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
5043   EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(cache_key));
5044 
5045   ReadAndVerifyTransaction(c.trans.get(), kSimpleGET_Transaction);
5046 
5047   // Perform an extra Read.
5048   const int kBufferSize = 10;
5049   auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
5050   c.result = c.trans->Read(buffer.get(), kBufferSize, c.callback.callback());
5051   EXPECT_EQ(0, c.result);
5052 }
5053 
5054 // Tests when a writer is destroyed mid-read, all the other writer transactions
5055 // can continue writing to the entry.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationCancelWriter)5056 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationCancelWriter) {
5057   MockHttpCache cache;
5058 
5059   ScopedMockTransaction transaction(kSimpleGET_Transaction);
5060   transaction.response_headers =
5061       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
5062       "Content-Length: 22\n"
5063       "Etag: \"foopy\"\n";
5064   MockHttpRequest request(transaction);
5065 
5066   const int kNumTransactions = 3;
5067   std::vector<std::unique_ptr<Context>> context_list;
5068 
5069   for (int i = 0; i < kNumTransactions; ++i) {
5070     context_list.push_back(std::make_unique<Context>());
5071     auto& c = context_list[i];
5072 
5073     c->result = cache.CreateTransaction(&c->trans);
5074     ASSERT_THAT(c->result, IsOk());
5075 
5076     c->result =
5077         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5078   }
5079 
5080   // Allow all requests to move from the Create queue to the active entry.
5081   base::RunLoop().RunUntilIdle();
5082 
5083   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5084   EXPECT_EQ(0, cache.disk_cache()->open_count());
5085   EXPECT_EQ(1, cache.disk_cache()->create_count());
5086 
5087   std::string cache_key = request.CacheKey();
5088   EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
5089 
5090   // Let first transaction read some bytes.
5091   {
5092     auto& c = context_list[0];
5093     const int kBufferSize = 5;
5094     auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
5095     ReleaseBufferCompletionCallback cb(buffer.get());
5096     c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
5097     EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
5098   }
5099 
5100   // Deleting the active transaction at this point will not impact the other
5101   // transactions since there are other transactions in writers.
5102   context_list[0].reset();
5103 
5104   base::RunLoop().RunUntilIdle();
5105 
5106   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5107   EXPECT_EQ(0, cache.disk_cache()->open_count());
5108   EXPECT_EQ(1, cache.disk_cache()->create_count());
5109 
5110   // Complete the rest of the transactions.
5111   for (auto& context : context_list) {
5112     if (!context) {
5113       continue;
5114     }
5115     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
5116   }
5117 }
5118 
5119 // Tests that when StopCaching is invoked on a writer, dependent transactions
5120 // are restarted.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationStopCaching)5121 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationStopCaching) {
5122   MockHttpCache cache;
5123 
5124   MockHttpRequest request(kSimpleGET_Transaction);
5125 
5126   MockTransaction transaction(kSimpleGET_Transaction);
5127   transaction.load_flags |= LOAD_ONLY_FROM_CACHE;
5128   MockHttpRequest read_only_request(transaction);
5129 
5130   const int kNumTransactions = 2;
5131   std::vector<std::unique_ptr<Context>> context_list;
5132 
5133   for (int i = 0; i < kNumTransactions; ++i) {
5134     context_list.push_back(std::make_unique<Context>());
5135     auto& c = context_list[i];
5136 
5137     c->result = cache.CreateTransaction(&c->trans);
5138     ASSERT_THAT(c->result, IsOk());
5139 
5140     MockHttpRequest* this_request = &request;
5141     if (i == 1) {
5142       this_request = &read_only_request;
5143     }
5144 
5145     c->result = c->trans->Start(this_request, c->callback.callback(),
5146                                 NetLogWithSource());
5147   }
5148 
5149   // Allow all requests to move from the Create queue to the active entry.
5150   base::RunLoop().RunUntilIdle();
5151 
5152   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5153   EXPECT_EQ(0, cache.disk_cache()->open_count());
5154   EXPECT_EQ(1, cache.disk_cache()->create_count());
5155 
5156   std::string cache_key = request.CacheKey();
5157   EXPECT_EQ(kNumTransactions - 1, cache.GetCountWriterTransactions(cache_key));
5158   EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(cache_key));
5159 
5160   // Invoking StopCaching on the writer will lead to dooming the entry and
5161   // restarting the validated transactions. Since it is a read-only transaction
5162   // it will error out.
5163   context_list[0]->trans->StopCaching();
5164 
5165   base::RunLoop().RunUntilIdle();
5166 
5167   int rv = context_list[1]->callback.WaitForResult();
5168   EXPECT_EQ(ERR_CACHE_MISS, rv);
5169 
5170   ReadAndVerifyTransaction(context_list[0]->trans.get(),
5171                            kSimpleGET_Transaction);
5172 }
5173 
5174 // Tests that when StopCaching is invoked on a writer transaction, it is a
5175 // no-op if there are other writer transactions.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritersStopCachingNoOp)5176 TEST_F(HttpCacheTest, SimpleGET_ParallelWritersStopCachingNoOp) {
5177   MockHttpCache cache;
5178 
5179   MockHttpRequest request(kSimpleGET_Transaction);
5180 
5181   MockTransaction transaction(kSimpleGET_Transaction);
5182   transaction.load_flags |= LOAD_VALIDATE_CACHE;
5183   MockHttpRequest validate_request(transaction);
5184 
5185   const int kNumTransactions = 3;
5186   std::vector<std::unique_ptr<Context>> context_list;
5187 
5188   for (int i = 0; i < kNumTransactions; ++i) {
5189     context_list.push_back(std::make_unique<Context>());
5190     auto& c = context_list[i];
5191 
5192     c->result = cache.CreateTransaction(&c->trans);
5193     ASSERT_THAT(c->result, IsOk());
5194 
5195     MockHttpRequest* this_request = &request;
5196     if (i == 2) {
5197       this_request = &validate_request;
5198       c->trans->SetBeforeNetworkStartCallback(base::BindOnce(&DeferCallback));
5199     }
5200 
5201     c->result = c->trans->Start(this_request, c->callback.callback(),
5202                                 NetLogWithSource());
5203   }
5204 
5205   // Allow all requests to move from the Create queue to the active entry.
5206   base::RunLoop().RunUntilIdle();
5207 
5208   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5209   EXPECT_EQ(0, cache.disk_cache()->open_count());
5210   EXPECT_EQ(1, cache.disk_cache()->create_count());
5211 
5212   std::string cache_key = request.CacheKey();
5213   EXPECT_TRUE(cache.IsHeadersTransactionPresent(cache_key));
5214   EXPECT_EQ(kNumTransactions - 1, cache.GetCountWriterTransactions(cache_key));
5215 
5216   // Invoking StopCaching on the writer will be a no-op since there are multiple
5217   // transaction in writers.
5218   context_list[0]->trans->StopCaching();
5219 
5220   // Resume network start for headers_transaction.
5221   auto& c = context_list[2];
5222   c->trans->ResumeNetworkStart();
5223   base::RunLoop().RunUntilIdle();
5224   // After validation old entry will be doomed and headers_transaction will be
5225   // added to the new entry.
5226   EXPECT_EQ(1, cache.GetCountWriterTransactions(cache_key));
5227 
5228   // Complete the rest of the transactions.
5229   for (auto& context : context_list) {
5230     if (!context) {
5231       continue;
5232     }
5233     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
5234   }
5235 
5236   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5237   EXPECT_EQ(0, cache.disk_cache()->open_count());
5238   EXPECT_EQ(2, cache.disk_cache()->create_count());
5239 }
5240 
5241 // Tests that a transaction is currently in headers phase and is destroyed
5242 // leading to destroying the entry.
TEST_F(HttpCacheTest,SimpleGET_ParallelValidationCancelHeaders)5243 TEST_F(HttpCacheTest, SimpleGET_ParallelValidationCancelHeaders) {
5244   MockHttpCache cache;
5245 
5246   MockHttpRequest request(kSimpleGET_Transaction);
5247 
5248   const int kNumTransactions = 2;
5249   std::vector<std::unique_ptr<Context>> context_list;
5250 
5251   for (int i = 0; i < kNumTransactions; ++i) {
5252     context_list.push_back(std::make_unique<Context>());
5253     auto& c = context_list[i];
5254 
5255     c->result = cache.CreateTransaction(&c->trans);
5256     ASSERT_THAT(c->result, IsOk());
5257 
5258     if (i == 0) {
5259       c->trans->SetBeforeNetworkStartCallback(base::BindOnce(&DeferCallback));
5260     }
5261 
5262     c->result =
5263         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5264   }
5265 
5266   base::RunLoop().RunUntilIdle();
5267 
5268   std::string cache_key = request.CacheKey();
5269   EXPECT_TRUE(cache.IsHeadersTransactionPresent(cache_key));
5270   EXPECT_EQ(1, cache.GetCountAddToEntryQueue(cache_key));
5271 
5272   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5273   EXPECT_EQ(0, cache.disk_cache()->open_count());
5274   EXPECT_EQ(1, cache.disk_cache()->create_count());
5275 
5276   // Delete the headers transaction.
5277   context_list[0].reset();
5278 
5279   base::RunLoop().RunUntilIdle();
5280 
5281   // Complete the rest of the transactions.
5282   for (auto& context : context_list) {
5283     if (!context) {
5284       continue;
5285     }
5286     ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
5287   }
5288 
5289   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5290   EXPECT_EQ(0, cache.disk_cache()->open_count());
5291   EXPECT_EQ(2, cache.disk_cache()->create_count());
5292 }
5293 
5294 // Similar to the above test, except here cache write fails and the
5295 // validated transactions should be restarted.
TEST_F(HttpCacheTest,SimpleGET_ParallelWritersFailWrite)5296 TEST_F(HttpCacheTest, SimpleGET_ParallelWritersFailWrite) {
5297   MockHttpCache cache;
5298 
5299   MockHttpRequest request(kSimpleGET_Transaction);
5300 
5301   const int kNumTransactions = 5;
5302   std::vector<std::unique_ptr<Context>> context_list;
5303 
5304   for (int i = 0; i < kNumTransactions; ++i) {
5305     context_list.push_back(std::make_unique<Context>());
5306     auto& c = context_list[i];
5307 
5308     c->result = cache.CreateTransaction(&c->trans);
5309     ASSERT_THAT(c->result, IsOk());
5310     EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
5311 
5312     c->result =
5313         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5314   }
5315 
5316   // All requests are waiting for the active entry.
5317   for (auto& context : context_list) {
5318     EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState());
5319   }
5320 
5321   // Allow all requests to move from the Create queue to the active entry.
5322   base::RunLoop().RunUntilIdle();
5323 
5324   // All transactions become writers.
5325   std::string cache_key = request.CacheKey();
5326   EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
5327 
5328   // All requests depend on the writer, and the writer is between Start and
5329   // Read, i.e. idle.
5330   for (auto& context : context_list) {
5331     EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
5332   }
5333 
5334   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5335   EXPECT_EQ(0, cache.disk_cache()->open_count());
5336   EXPECT_EQ(1, cache.disk_cache()->create_count());
5337 
5338   // Fail the request.
5339   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_ALL);
5340   // We have to open the entry again to propagate the failure flag.
5341   disk_cache::Entry* en;
5342   cache.OpenBackendEntry(cache_key, &en);
5343   en->Close();
5344 
5345   for (int i = 0; i < kNumTransactions; ++i) {
5346     auto& c = context_list[i];
5347     if (c->result == ERR_IO_PENDING) {
5348       c->result = c->callback.WaitForResult();
5349     }
5350     if (i == 1) {
5351       // The earlier entry must be destroyed and its disk entry doomed.
5352       EXPECT_TRUE(cache.disk_cache()->IsDiskEntryDoomed(cache_key));
5353     }
5354 
5355     if (i == 0) {
5356       // Consumer gets the response even if cache write failed.
5357       ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5358     } else {
5359       // Read should lead to a failure being returned.
5360       const int kBufferSize = 5;
5361       auto buffer = base::MakeRefCounted<IOBufferWithSize>(kBufferSize);
5362       ReleaseBufferCompletionCallback cb(buffer.get());
5363       c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
5364       EXPECT_EQ(ERR_CACHE_WRITE_FAILURE, cb.GetResult(c->result));
5365     }
5366   }
5367 }
5368 
5369 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769.
5370 // If cancelling a request is racing with another request for the same resource
5371 // finishing, we have to make sure that we remove both transactions from the
5372 // entry.
TEST_F(HttpCacheTest,SimpleGET_RacingReaders)5373 TEST_F(HttpCacheTest, SimpleGET_RacingReaders) {
5374   MockHttpCache cache;
5375 
5376   MockHttpRequest request(kSimpleGET_Transaction);
5377   MockHttpRequest reader_request(kSimpleGET_Transaction);
5378   reader_request.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
5379 
5380   std::vector<std::unique_ptr<Context>> context_list;
5381   const int kNumTransactions = 5;
5382 
5383   for (int i = 0; i < kNumTransactions; ++i) {
5384     context_list.push_back(std::make_unique<Context>());
5385     Context* c = context_list[i].get();
5386 
5387     c->result = cache.CreateTransaction(&c->trans);
5388     ASSERT_THAT(c->result, IsOk());
5389 
5390     MockHttpRequest* this_request = &request;
5391     if (i == 1 || i == 2) {
5392       this_request = &reader_request;
5393     }
5394 
5395     c->result = c->trans->Start(this_request, c->callback.callback(),
5396                                 NetLogWithSource());
5397   }
5398 
5399   // Allow all requests to move from the Create queue to the active entry.
5400   base::RunLoop().RunUntilIdle();
5401 
5402   // The first request should be a writer at this point, and the subsequent
5403   // requests should be pending.
5404 
5405   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5406   EXPECT_EQ(0, cache.disk_cache()->open_count());
5407   EXPECT_EQ(1, cache.disk_cache()->create_count());
5408 
5409   Context* c = context_list[0].get();
5410   ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
5411   c->result = c->callback.WaitForResult();
5412   ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5413 
5414   // Now all transactions should be waiting for read to be invoked. Two readers
5415   // are because of the load flags and remaining two transactions were converted
5416   // to readers after skipping validation. Note that the remaining two went on
5417   // to process the headers in parallel with readers present on the entry.
5418   EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState());
5419   EXPECT_EQ(LOAD_STATE_IDLE, context_list[3]->trans->GetLoadState());
5420 
5421   c = context_list[1].get();
5422   ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
5423   c->result = c->callback.WaitForResult();
5424   if (c->result == OK) {
5425     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5426   }
5427 
5428   // At this point we have one reader, two pending transactions and a task on
5429   // the queue to move to the next transaction. Now we cancel the request that
5430   // is the current reader, and expect the queued task to be able to start the
5431   // next request.
5432 
5433   c = context_list[2].get();
5434   c->trans.reset();
5435 
5436   for (int i = 3; i < kNumTransactions; ++i) {
5437     c = context_list[i].get();
5438     if (c->result == ERR_IO_PENDING) {
5439       c->result = c->callback.WaitForResult();
5440     }
5441     if (c->result == OK) {
5442       ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5443     }
5444   }
5445 
5446   // We should not have had to re-open the disk entry.
5447 
5448   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5449   EXPECT_EQ(0, cache.disk_cache()->open_count());
5450   EXPECT_EQ(1, cache.disk_cache()->create_count());
5451 }
5452 
5453 // Tests that we can doom an entry with pending transactions and delete one of
5454 // the pending transactions before the first one completes.
5455 // See http://code.google.com/p/chromium/issues/detail?id=25588
TEST_F(HttpCacheTest,SimpleGET_DoomWithPending)5456 TEST_F(HttpCacheTest, SimpleGET_DoomWithPending) {
5457   // We need simultaneous doomed / not_doomed entries so let's use a real cache.
5458   MockHttpCache cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
5459 
5460   MockHttpRequest request(kSimpleGET_Transaction);
5461   MockHttpRequest writer_request(kSimpleGET_Transaction);
5462   writer_request.load_flags = LOAD_BYPASS_CACHE;
5463 
5464   std::vector<std::unique_ptr<Context>> context_list;
5465   const int kNumTransactions = 4;
5466 
5467   for (int i = 0; i < kNumTransactions; ++i) {
5468     context_list.push_back(std::make_unique<Context>());
5469     Context* c = context_list[i].get();
5470 
5471     c->result = cache.CreateTransaction(&c->trans);
5472     ASSERT_THAT(c->result, IsOk());
5473 
5474     MockHttpRequest* this_request = &request;
5475     if (i == 3) {
5476       this_request = &writer_request;
5477     }
5478 
5479     c->result = c->trans->Start(this_request, c->callback.callback(),
5480                                 NetLogWithSource());
5481   }
5482 
5483   base::RunLoop().RunUntilIdle();
5484 
5485   // The first request should be a writer at this point, and the two subsequent
5486   // requests should be pending. The last request doomed the first entry.
5487 
5488   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5489 
5490   // Cancel the second transaction. Note that this and the 3rd transactions
5491   // would have completed their headers phase and would be waiting in the
5492   // done_headers_queue when the 2nd transaction is cancelled.
5493   context_list[1].reset();
5494 
5495   for (int i = 0; i < kNumTransactions; ++i) {
5496     if (i == 1) {
5497       continue;
5498     }
5499     Context* c = context_list[i].get();
5500     ASSERT_THAT(c->result, IsError(ERR_IO_PENDING));
5501     c->result = c->callback.WaitForResult();
5502     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5503   }
5504 }
5505 
TEST_F(HttpCacheTest,DoomDoesNotSetHints)5506 TEST_F(HttpCacheTest, DoomDoesNotSetHints) {
5507   // Test that a doomed writer doesn't set in-memory index hints.
5508   MockHttpCache cache;
5509   cache.disk_cache()->set_support_in_memory_entry_data(true);
5510 
5511   // Request 1 is a normal one to a no-cache/no-etag resource, to potentially
5512   // set a "this is unvalidatable" hint in the cache. We also need it to
5513   // actually write out to the doomed entry after request 2 does its thing,
5514   // so its transaction is paused.
5515   ScopedMockTransaction transaction(kSimpleGET_Transaction);
5516   transaction.response_headers = "Cache-Control: no-cache\n";
5517   MockHttpRequest request1(transaction);
5518 
5519   Context c1;
5520   c1.result = cache.CreateTransaction(&c1.trans);
5521   ASSERT_THAT(c1.result, IsOk());
5522   c1.trans->SetBeforeNetworkStartCallback(
5523       base::BindOnce([](bool* defer) { *defer = true; }));
5524   c1.result =
5525       c1.trans->Start(&request1, c1.callback.callback(), NetLogWithSource());
5526   ASSERT_THAT(c1.result, IsError(ERR_IO_PENDING));
5527 
5528   // It starts, copies over headers info, but doesn't get to proceed.
5529   base::RunLoop().RunUntilIdle();
5530 
5531   // Request 2 sets LOAD_BYPASS_CACHE to force the first one to be doomed ---
5532   // it'll want to be a writer.
5533   transaction.response_headers = kSimpleGET_Transaction.response_headers;
5534   MockHttpRequest request2(transaction);
5535   request2.load_flags = LOAD_BYPASS_CACHE;
5536 
5537   Context c2;
5538   c2.result = cache.CreateTransaction(&c2.trans);
5539   ASSERT_THAT(c2.result, IsOk());
5540   c2.result =
5541       c2.trans->Start(&request2, c2.callback.callback(), NetLogWithSource());
5542   ASSERT_THAT(c2.result, IsError(ERR_IO_PENDING));
5543 
5544   // Run Request2, then let the first one wrap up.
5545   base::RunLoop().RunUntilIdle();
5546   c2.callback.WaitForResult();
5547   ReadAndVerifyTransaction(c2.trans.get(), kSimpleGET_Transaction);
5548 
5549   c1.trans->ResumeNetworkStart();
5550   c1.callback.WaitForResult();
5551   ReadAndVerifyTransaction(c1.trans.get(), kSimpleGET_Transaction);
5552 
5553   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5554   EXPECT_EQ(0, cache.disk_cache()->open_count());
5555   EXPECT_EQ(2, cache.disk_cache()->create_count());
5556 
5557   // Request 3 tries to read from cache, and it should successfully do so. It's
5558   // run after the previous two transactions finish so it doesn't try to
5559   // cooperate with them, and is entirely driven by the state of the cache.
5560   MockHttpRequest request3(kSimpleGET_Transaction);
5561   Context context3;
5562   context3.result = cache.CreateTransaction(&context3.trans);
5563   ASSERT_THAT(context3.result, IsOk());
5564   context3.result = context3.trans->Start(
5565       &request3, context3.callback.callback(), NetLogWithSource());
5566   base::RunLoop().RunUntilIdle();
5567   ASSERT_THAT(context3.result, IsError(ERR_IO_PENDING));
5568   context3.result = context3.callback.WaitForResult();
5569   ReadAndVerifyTransaction(context3.trans.get(), kSimpleGET_Transaction);
5570 
5571   EXPECT_EQ(2, cache.network_layer()->transaction_count());
5572   EXPECT_EQ(1, cache.disk_cache()->open_count());
5573   EXPECT_EQ(2, cache.disk_cache()->create_count());
5574 }
5575 
5576 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4731.
5577 // We may attempt to delete an entry synchronously with the act of adding a new
5578 // transaction to said entry.
TEST_F(HttpCacheTest,FastNoStoreGET_DoneWithPending)5579 TEST_F(HttpCacheTest, FastNoStoreGET_DoneWithPending) {
5580   MockHttpCache cache;
5581 
5582   ScopedMockTransaction transaction(kFastNoStoreGET_Transaction);
5583   // The headers will be served right from the call to Start() the request.
5584   MockHttpRequest request(transaction);
5585   FastTransactionServer request_handler;
5586 
5587   std::vector<std::unique_ptr<Context>> context_list;
5588   const int kNumTransactions = 3;
5589 
5590   for (int i = 0; i < kNumTransactions; ++i) {
5591     context_list.push_back(std::make_unique<Context>());
5592     Context* c = context_list[i].get();
5593 
5594     c->result = cache.CreateTransaction(&c->trans);
5595     ASSERT_THAT(c->result, IsOk());
5596 
5597     c->result =
5598         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5599   }
5600 
5601   // Allow all requests to move from the Create queue to the active entry.
5602   base::RunLoop().RunUntilIdle();
5603 
5604   // The first request should be a writer at this point, and the subsequent
5605   // requests should have completed validation. Since the validation does not
5606   // result in a match, a new entry would be created.
5607 
5608   EXPECT_EQ(3, cache.network_layer()->transaction_count());
5609   EXPECT_EQ(0, cache.disk_cache()->open_count());
5610   EXPECT_EQ(3, cache.disk_cache()->create_count());
5611 
5612   // Now, make sure that the second request asks for the entry not to be stored.
5613   request_handler.set_no_store(true);
5614 
5615   for (int i = 0; i < kNumTransactions; ++i) {
5616     Context* c = context_list[i].get();
5617     if (c->result == ERR_IO_PENDING) {
5618       c->result = c->callback.WaitForResult();
5619     }
5620     ReadAndVerifyTransaction(c->trans.get(), transaction);
5621     context_list[i].reset();
5622   }
5623 
5624   EXPECT_EQ(3, cache.network_layer()->transaction_count());
5625   EXPECT_EQ(0, cache.disk_cache()->open_count());
5626   EXPECT_EQ(3, cache.disk_cache()->create_count());
5627 }
5628 
TEST_F(HttpCacheTest,SimpleGET_ManyWriters_CancelFirst)5629 TEST_F(HttpCacheTest, SimpleGET_ManyWriters_CancelFirst) {
5630   MockHttpCache cache;
5631 
5632   MockHttpRequest request(kSimpleGET_Transaction);
5633 
5634   std::vector<std::unique_ptr<Context>> context_list;
5635   const int kNumTransactions = 2;
5636 
5637   for (int i = 0; i < kNumTransactions; ++i) {
5638     context_list.push_back(std::make_unique<Context>());
5639     Context* c = context_list[i].get();
5640 
5641     c->result = cache.CreateTransaction(&c->trans);
5642     ASSERT_THAT(c->result, IsOk());
5643 
5644     c->result =
5645         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5646   }
5647 
5648   // Allow all requests to move from the Create queue to the active entry.
5649   // All would have been added to writers.
5650   base::RunLoop().RunUntilIdle();
5651   std::string cache_key =
5652       *cache.http_cache()->GenerateCacheKeyForRequest(&request);
5653   EXPECT_EQ(kNumTransactions, cache.GetCountWriterTransactions(cache_key));
5654 
5655   // The second transaction skipped validation, thus only one network
5656   // transaction is created.
5657   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5658   EXPECT_EQ(0, cache.disk_cache()->open_count());
5659   EXPECT_EQ(1, cache.disk_cache()->create_count());
5660 
5661   for (int i = 0; i < kNumTransactions; ++i) {
5662     Context* c = context_list[i].get();
5663     if (c->result == ERR_IO_PENDING) {
5664       c->result = c->callback.WaitForResult();
5665     }
5666     // Destroy only the first transaction.
5667     // This should not impact the other writer transaction and the network
5668     // transaction will continue to be used by that transaction.
5669     if (i == 0) {
5670       context_list[i].reset();
5671     }
5672   }
5673 
5674   // Complete the rest of the transactions.
5675   for (int i = 1; i < kNumTransactions; ++i) {
5676     Context* c = context_list[i].get();
5677     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5678   }
5679 
5680   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5681   EXPECT_EQ(0, cache.disk_cache()->open_count());
5682   EXPECT_EQ(1, cache.disk_cache()->create_count());
5683 }
5684 
5685 // Tests that we can cancel requests that are queued waiting to open the disk
5686 // cache entry.
TEST_F(HttpCacheTest,SimpleGET_ManyWriters_CancelCreate)5687 TEST_F(HttpCacheTest, SimpleGET_ManyWriters_CancelCreate) {
5688   MockHttpCache cache;
5689 
5690   MockHttpRequest request(kSimpleGET_Transaction);
5691 
5692   std::vector<std::unique_ptr<Context>> context_list;
5693   const int kNumTransactions = 5;
5694 
5695   for (int i = 0; i < kNumTransactions; i++) {
5696     context_list.push_back(std::make_unique<Context>());
5697     Context* c = context_list[i].get();
5698 
5699     c->result = cache.CreateTransaction(&c->trans);
5700     ASSERT_THAT(c->result, IsOk());
5701 
5702     c->result =
5703         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5704   }
5705 
5706   // The first request should be creating the disk cache entry and the others
5707   // should be pending.
5708 
5709   EXPECT_EQ(0, cache.network_layer()->transaction_count());
5710   EXPECT_EQ(0, cache.disk_cache()->open_count());
5711   EXPECT_EQ(1, cache.disk_cache()->create_count());
5712 
5713   // Cancel a request from the pending queue.
5714   context_list[3].reset();
5715 
5716   // Cancel the request that is creating the entry. This will force the pending
5717   // operations to restart.
5718   context_list[0].reset();
5719 
5720   // Complete the rest of the transactions.
5721   for (int i = 1; i < kNumTransactions; i++) {
5722     Context* c = context_list[i].get();
5723     if (c) {
5724       c->result = c->callback.GetResult(c->result);
5725       ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5726     }
5727   }
5728 
5729   // We should have had to re-create the disk entry.
5730 
5731   EXPECT_EQ(1, cache.network_layer()->transaction_count());
5732   EXPECT_EQ(0, cache.disk_cache()->open_count());
5733   EXPECT_EQ(2, cache.disk_cache()->create_count());
5734 }
5735 
5736 // Tests that we can cancel a single request to open a disk cache entry.
TEST_F(HttpCacheTest,SimpleGET_CancelCreate)5737 TEST_F(HttpCacheTest, SimpleGET_CancelCreate) {
5738   MockHttpCache cache;
5739 
5740   MockHttpRequest request(kSimpleGET_Transaction);
5741 
5742   auto c = std::make_unique<Context>();
5743 
5744   c->result = cache.CreateTransaction(&c->trans);
5745   ASSERT_THAT(c->result, IsOk());
5746 
5747   c->result =
5748       c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5749   EXPECT_THAT(c->result, IsError(ERR_IO_PENDING));
5750 
5751   // Release the reference that the mock disk cache keeps for this entry, so
5752   // that we test that the http cache handles the cancellation correctly.
5753   cache.disk_cache()->ReleaseAll();
5754   c.reset();
5755 
5756   base::RunLoop().RunUntilIdle();
5757   EXPECT_EQ(1, cache.disk_cache()->create_count());
5758 }
5759 
5760 // Tests that we delete/create entries even if multiple requests are queued.
TEST_F(HttpCacheTest,SimpleGET_ManyWriters_BypassCache)5761 TEST_F(HttpCacheTest, SimpleGET_ManyWriters_BypassCache) {
5762   MockHttpCache cache;
5763 
5764   MockHttpRequest request(kSimpleGET_Transaction);
5765   request.load_flags = LOAD_BYPASS_CACHE;
5766 
5767   std::vector<std::unique_ptr<Context>> context_list;
5768   const int kNumTransactions = 5;
5769 
5770   for (int i = 0; i < kNumTransactions; i++) {
5771     context_list.push_back(std::make_unique<Context>());
5772     Context* c = context_list[i].get();
5773 
5774     c->result = cache.CreateTransaction(&c->trans);
5775     ASSERT_THAT(c->result, IsOk());
5776 
5777     c->result =
5778         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5779   }
5780 
5781   // The first request should be deleting the disk cache entry and the others
5782   // should be pending.
5783 
5784   EXPECT_EQ(0, cache.network_layer()->transaction_count());
5785   EXPECT_EQ(0, cache.disk_cache()->open_count());
5786   EXPECT_EQ(0, cache.disk_cache()->create_count());
5787 
5788   // Complete the transactions.
5789   for (int i = 0; i < kNumTransactions; i++) {
5790     Context* c = context_list[i].get();
5791     c->result = c->callback.GetResult(c->result);
5792     ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction);
5793   }
5794 
5795   // We should have had to re-create the disk entry multiple times.
5796 
5797   EXPECT_EQ(5, cache.network_layer()->transaction_count());
5798   EXPECT_EQ(0, cache.disk_cache()->open_count());
5799   EXPECT_EQ(5, cache.disk_cache()->create_count());
5800 }
5801 
5802 // Tests that a (simulated) timeout allows transactions waiting on the cache
5803 // lock to continue.
TEST_F(HttpCacheTest,SimpleGET_WriterTimeout)5804 TEST_F(HttpCacheTest, SimpleGET_WriterTimeout) {
5805   MockHttpCache cache;
5806   cache.SimulateCacheLockTimeout();
5807 
5808   MockHttpRequest request(kSimpleGET_Transaction);
5809   Context c1, c2;
5810   ASSERT_THAT(cache.CreateTransaction(&c1.trans), IsOk());
5811   ASSERT_EQ(ERR_IO_PENDING, c1.trans->Start(&request, c1.callback.callback(),
5812                                             NetLogWithSource()));
5813   ASSERT_THAT(cache.CreateTransaction(&c2.trans), IsOk());
5814   ASSERT_EQ(ERR_IO_PENDING, c2.trans->Start(&request, c2.callback.callback(),
5815                                             NetLogWithSource()));
5816 
5817   // The second request is queued after the first one.
5818 
5819   c2.callback.WaitForResult();
5820   ReadAndVerifyTransaction(c2.trans.get(), kSimpleGET_Transaction);
5821 
5822   // Complete the first transaction.
5823   c1.callback.WaitForResult();
5824   ReadAndVerifyTransaction(c1.trans.get(), kSimpleGET_Transaction);
5825 }
5826 
5827 // Tests that a (simulated) timeout allows transactions waiting on the cache
5828 // lock to continue but read only transactions to error out.
TEST_F(HttpCacheTest,SimpleGET_WriterTimeoutReadOnlyError)5829 TEST_F(HttpCacheTest, SimpleGET_WriterTimeoutReadOnlyError) {
5830   MockHttpCache cache;
5831 
5832   // Simulate timeout.
5833   cache.SimulateCacheLockTimeout();
5834 
5835   MockHttpRequest request(kSimpleGET_Transaction);
5836   Context c1, c2;
5837   ASSERT_THAT(cache.CreateTransaction(&c1.trans), IsOk());
5838   ASSERT_EQ(ERR_IO_PENDING, c1.trans->Start(&request, c1.callback.callback(),
5839                                             NetLogWithSource()));
5840 
5841   request.load_flags = LOAD_ONLY_FROM_CACHE;
5842   ASSERT_THAT(cache.CreateTransaction(&c2.trans), IsOk());
5843   ASSERT_EQ(ERR_IO_PENDING, c2.trans->Start(&request, c2.callback.callback(),
5844                                             NetLogWithSource()));
5845 
5846   // The second request is queued after the first one.
5847   int res = c2.callback.WaitForResult();
5848   ASSERT_EQ(ERR_CACHE_MISS, res);
5849 
5850   // Complete the first transaction.
5851   c1.callback.WaitForResult();
5852   ReadAndVerifyTransaction(c1.trans.get(), kSimpleGET_Transaction);
5853 }
5854 
TEST_F(HttpCacheTest,SimpleGET_AbandonedCacheRead)5855 TEST_F(HttpCacheTest, SimpleGET_AbandonedCacheRead) {
5856   MockHttpCache cache;
5857 
5858   // write to the cache
5859   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
5860 
5861   MockHttpRequest request(kSimpleGET_Transaction);
5862   TestCompletionCallback callback;
5863 
5864   std::unique_ptr<HttpTransaction> trans;
5865   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
5866   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5867   if (rv == ERR_IO_PENDING) {
5868     rv = callback.WaitForResult();
5869   }
5870   ASSERT_THAT(rv, IsOk());
5871 
5872   auto buf = base::MakeRefCounted<IOBufferWithSize>(256);
5873   rv = trans->Read(buf.get(), 256, callback.callback());
5874   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5875 
5876   // Test that destroying the transaction while it is reading from the cache
5877   // works properly.
5878   trans.reset();
5879 
5880   // Make sure we pump any pending events, which should include a call to
5881   // HttpCache::Transaction::OnCacheReadCompleted.
5882   base::RunLoop().RunUntilIdle();
5883 }
5884 
5885 // Tests that we can delete the HttpCache and deal with queued transactions
5886 // ("waiting for the backend" as opposed to Active or Doomed entries).
TEST_F(HttpCacheTest,SimpleGET_ManyWriters_DeleteCache)5887 TEST_F(HttpCacheTest, SimpleGET_ManyWriters_DeleteCache) {
5888   auto cache = std::make_unique<MockHttpCache>(
5889       std::make_unique<MockBackendNoCbFactory>());
5890 
5891   MockHttpRequest request(kSimpleGET_Transaction);
5892 
5893   std::vector<std::unique_ptr<Context>> context_list;
5894   const int kNumTransactions = 5;
5895 
5896   for (int i = 0; i < kNumTransactions; i++) {
5897     context_list.push_back(std::make_unique<Context>());
5898     Context* c = context_list[i].get();
5899 
5900     c->result = cache->CreateTransaction(&c->trans);
5901     ASSERT_THAT(c->result, IsOk());
5902 
5903     c->result =
5904         c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
5905   }
5906 
5907   // The first request should be creating the disk cache entry and the others
5908   // should be pending.
5909 
5910   EXPECT_EQ(0, cache->network_layer()->transaction_count());
5911   EXPECT_EQ(0, cache->disk_cache()->open_count());
5912   EXPECT_EQ(0, cache->disk_cache()->create_count());
5913 
5914   cache.reset();
5915 }
5916 
5917 // Tests that we queue requests when initializing the backend.
TEST_F(HttpCacheTest,SimpleGET_WaitForBackend)5918 TEST_F(HttpCacheTest, SimpleGET_WaitForBackend) {
5919   auto factory = std::make_unique<MockBlockingBackendFactory>();
5920   MockBlockingBackendFactory* factory_ptr = factory.get();
5921   MockHttpCache cache(std::move(factory));
5922 
5923   MockHttpRequest request0(kSimpleGET_Transaction);
5924   MockHttpRequest request1(kTypicalGET_Transaction);
5925   MockHttpRequest request2(kETagGET_Transaction);
5926 
5927   std::vector<std::unique_ptr<Context>> context_list;
5928   const int kNumTransactions = 3;
5929 
5930   for (int i = 0; i < kNumTransactions; i++) {
5931     context_list.push_back(std::make_unique<Context>());
5932     Context* c = context_list[i].get();
5933 
5934     c->result = cache.CreateTransaction(&c->trans);
5935     ASSERT_THAT(c->result, IsOk());
5936   }
5937 
5938   context_list[0]->result = context_list[0]->trans->Start(
5939       &request0, context_list[0]->callback.callback(), NetLogWithSource());
5940   context_list[1]->result = context_list[1]->trans->Start(
5941       &request1, context_list[1]->callback.callback(), NetLogWithSource());
5942   context_list[2]->result = context_list[2]->trans->Start(
5943       &request2, context_list[2]->callback.callback(), NetLogWithSource());
5944 
5945   // Just to make sure that everything is still pending.
5946   base::RunLoop().RunUntilIdle();
5947 
5948   // The first request should be creating the disk cache.
5949   EXPECT_FALSE(context_list[0]->callback.have_result());
5950 
5951   factory_ptr->FinishCreation();
5952 
5953   base::RunLoop().RunUntilIdle();
5954   EXPECT_EQ(3, cache.network_layer()->transaction_count());
5955   EXPECT_EQ(3, cache.disk_cache()->create_count());
5956 
5957   for (int i = 0; i < kNumTransactions; ++i) {
5958     EXPECT_TRUE(context_list[i]->callback.have_result());
5959     context_list[i].reset();
5960   }
5961 }
5962 
5963 // Tests that we can cancel requests that are queued waiting for the backend
5964 // to be initialized.
TEST_F(HttpCacheTest,SimpleGET_WaitForBackend_CancelCreate)5965 TEST_F(HttpCacheTest, SimpleGET_WaitForBackend_CancelCreate) {
5966   auto factory = std::make_unique<MockBlockingBackendFactory>();
5967   MockBlockingBackendFactory* factory_ptr = factory.get();
5968   MockHttpCache cache(std::move(factory));
5969 
5970   MockHttpRequest request0(kSimpleGET_Transaction);
5971   MockHttpRequest request1(kTypicalGET_Transaction);
5972   MockHttpRequest request2(kETagGET_Transaction);
5973 
5974   std::vector<std::unique_ptr<Context>> context_list;
5975   const int kNumTransactions = 3;
5976 
5977   for (int i = 0; i < kNumTransactions; i++) {
5978     context_list.push_back(std::make_unique<Context>());
5979     Context* c = context_list[i].get();
5980 
5981     c->result = cache.CreateTransaction(&c->trans);
5982     ASSERT_THAT(c->result, IsOk());
5983   }
5984 
5985   context_list[0]->result = context_list[0]->trans->Start(
5986       &request0, context_list[0]->callback.callback(), NetLogWithSource());
5987   context_list[1]->result = context_list[1]->trans->Start(
5988       &request1, context_list[1]->callback.callback(), NetLogWithSource());
5989   context_list[2]->result = context_list[2]->trans->Start(
5990       &request2, context_list[2]->callback.callback(), NetLogWithSource());
5991 
5992   // Just to make sure that everything is still pending.
5993   base::RunLoop().RunUntilIdle();
5994 
5995   // The first request should be creating the disk cache.
5996   EXPECT_FALSE(context_list[0]->callback.have_result());
5997 
5998   // Cancel a request from the pending queue.
5999   context_list[1].reset();
6000 
6001   // Cancel the request that is creating the entry.
6002   context_list[0].reset();
6003 
6004   // Complete the last transaction.
6005   factory_ptr->FinishCreation();
6006 
6007   context_list[2]->result =
6008       context_list[2]->callback.GetResult(context_list[2]->result);
6009   ReadAndVerifyTransaction(context_list[2]->trans.get(), kETagGET_Transaction);
6010 
6011   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6012   EXPECT_EQ(1, cache.disk_cache()->create_count());
6013 }
6014 
6015 // Tests that we can delete the HttpCache while creating the backend.
TEST_F(HttpCacheTest,DeleteCacheWaitingForBackend)6016 TEST_F(HttpCacheTest, DeleteCacheWaitingForBackend) {
6017   auto factory = std::make_unique<MockBlockingBackendFactory>();
6018   MockBlockingBackendFactory* factory_ptr = factory.get();
6019   auto cache = std::make_unique<MockHttpCache>(std::move(factory));
6020 
6021   MockHttpRequest request(kSimpleGET_Transaction);
6022 
6023   auto c = std::make_unique<Context>();
6024   c->result = cache->CreateTransaction(&c->trans);
6025   ASSERT_THAT(c->result, IsOk());
6026 
6027   c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
6028 
6029   // Just to make sure that everything is still pending.
6030   base::RunLoop().RunUntilIdle();
6031 
6032   // The request should be creating the disk cache.
6033   EXPECT_FALSE(c->callback.have_result());
6034 
6035   // Manually arrange for completion to happen after ~HttpCache.
6036   // This can't be done via FinishCreation() since that's in `factory`, and
6037   // that's owned by `cache`.
6038   disk_cache::BackendResultCallback callback = factory_ptr->ReleaseCallback();
6039 
6040   cache.reset();
6041   base::RunLoop().RunUntilIdle();
6042 
6043   // Simulate the backend completion callback running now the HttpCache is gone.
6044   std::move(callback).Run(disk_cache::BackendResult::MakeError(ERR_ABORTED));
6045 }
6046 
6047 // Tests that we can delete the cache while creating the backend, from within
6048 // one of the callbacks.
TEST_F(HttpCacheTest,DeleteCacheWaitingForBackend2)6049 TEST_F(HttpCacheTest, DeleteCacheWaitingForBackend2) {
6050   auto factory = std::make_unique<MockBlockingBackendFactory>();
6051   MockBlockingBackendFactory* factory_ptr = factory.get();
6052   auto cache = std::make_unique<MockHttpCache>(std::move(factory));
6053   auto* cache_ptr = cache.get();
6054 
6055   DeleteCacheCompletionCallback cb(std::move(cache));
6056   disk_cache::Backend* backend;
6057   int rv = cache_ptr->http_cache()->GetBackend(&backend, cb.callback());
6058   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6059 
6060   // Now let's queue a regular transaction
6061   MockHttpRequest request(kSimpleGET_Transaction);
6062 
6063   auto c = std::make_unique<Context>();
6064   c->result = cache_ptr->CreateTransaction(&c->trans);
6065   ASSERT_THAT(c->result, IsOk());
6066 
6067   c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
6068 
6069   // And another direct backend request.
6070   TestCompletionCallback cb2;
6071   rv = cache_ptr->http_cache()->GetBackend(&backend, cb2.callback());
6072   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6073 
6074   // Just to make sure that everything is still pending.
6075   base::RunLoop().RunUntilIdle();
6076 
6077   // The request should be queued.
6078   EXPECT_FALSE(c->callback.have_result());
6079 
6080   // Generate the callback.
6081   factory_ptr->FinishCreation();
6082   rv = cb.WaitForResult();
6083 
6084   // The cache should be gone by now.
6085   base::RunLoop().RunUntilIdle();
6086   EXPECT_THAT(c->callback.GetResult(c->result), IsOk());
6087   EXPECT_FALSE(cb2.have_result());
6088 }
6089 
TEST_F(HttpCacheTest,TypicalGET_ConditionalRequest)6090 TEST_F(HttpCacheTest, TypicalGET_ConditionalRequest) {
6091   MockHttpCache cache;
6092 
6093   // write to the cache
6094   RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
6095 
6096   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6097   EXPECT_EQ(0, cache.disk_cache()->open_count());
6098   EXPECT_EQ(1, cache.disk_cache()->create_count());
6099 
6100   // Get the same URL again, but this time we expect it to result
6101   // in a conditional request.
6102   LoadTimingInfo load_timing_info;
6103   RunTransactionTestAndGetTiming(cache.http_cache(), kTypicalGET_Transaction,
6104                                  NetLogWithSource::Make(NetLogSourceType::NONE),
6105                                  &load_timing_info);
6106 
6107   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6108   EXPECT_EQ(1, cache.disk_cache()->open_count());
6109   EXPECT_EQ(1, cache.disk_cache()->create_count());
6110   TestLoadTimingNetworkRequest(load_timing_info);
6111 }
6112 
6113 static const auto kETagGetConditionalRequestHandler =
6114     base::BindRepeating([](const HttpRequestInfo* request,
6115                            std::string* response_status,
6116                            std::string* response_headers,
__anone6acdaec0802(const HttpRequestInfo* request, std::string* response_status, std::string* response_headers, std::string* response_data) 6117                            std::string* response_data) {
6118       EXPECT_TRUE(
6119           request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
6120       response_status->assign("HTTP/1.1 304 Not Modified");
6121       response_headers->assign(kETagGET_Transaction.response_headers);
6122       response_data->clear();
6123     });
6124 
TEST_F(HttpCacheTest,ETagGET_ConditionalRequest_304)6125 TEST_F(HttpCacheTest, ETagGET_ConditionalRequest_304) {
6126   MockHttpCache cache;
6127 
6128   ScopedMockTransaction transaction(kETagGET_Transaction);
6129 
6130   // write to the cache
6131   RunTransactionTest(cache.http_cache(), transaction);
6132 
6133   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6134   EXPECT_EQ(0, cache.disk_cache()->open_count());
6135   EXPECT_EQ(1, cache.disk_cache()->create_count());
6136 
6137   // Get the same URL again, but this time we expect it to result
6138   // in a conditional request.
6139   transaction.load_flags = LOAD_VALIDATE_CACHE;
6140   transaction.handler = kETagGetConditionalRequestHandler;
6141   LoadTimingInfo load_timing_info;
6142   IPEndPoint remote_endpoint;
6143   RunTransactionTestAndGetTimingAndConnectedSocketAddress(
6144       cache.http_cache(), transaction,
6145       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info,
6146       &remote_endpoint);
6147 
6148   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6149   EXPECT_EQ(1, cache.disk_cache()->open_count());
6150   EXPECT_EQ(1, cache.disk_cache()->create_count());
6151   TestLoadTimingNetworkRequest(load_timing_info);
6152 
6153   EXPECT_FALSE(remote_endpoint.address().empty());
6154 }
6155 
6156 class RevalidationServer {
6157  public:
6158   RevalidationServer() = default;
6159 
EtagUsed()6160   bool EtagUsed() { return etag_used_; }
LastModifiedUsed()6161   bool LastModifiedUsed() { return last_modified_used_; }
6162 
GetHandlerCallback()6163   MockTransactionHandler GetHandlerCallback() {
6164     return base::BindLambdaForTesting([this](const HttpRequestInfo* request,
6165                                              std::string* response_status,
6166                                              std::string* response_headers,
6167                                              std::string* response_data) {
6168       if (request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch)) {
6169         etag_used_ = true;
6170       }
6171 
6172       if (request->extra_headers.HasHeader(
6173               HttpRequestHeaders::kIfModifiedSince)) {
6174         last_modified_used_ = true;
6175       }
6176 
6177       if (etag_used_ || last_modified_used_) {
6178         response_status->assign("HTTP/1.1 304 Not Modified");
6179         response_headers->assign(kTypicalGET_Transaction.response_headers);
6180         response_data->clear();
6181       } else {
6182         response_status->assign(kTypicalGET_Transaction.status);
6183         response_headers->assign(kTypicalGET_Transaction.response_headers);
6184         response_data->assign(kTypicalGET_Transaction.data);
6185       }
6186     });
6187   }
6188 
6189  private:
6190   bool etag_used_ = false;
6191   bool last_modified_used_ = false;
6192 };
6193 
6194 // Tests revalidation after a vary match.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMatch)6195 TEST_F(HttpCacheTest, GET_ValidateCache_VaryMatch) {
6196   MockHttpCache cache;
6197 
6198   // Write to the cache.
6199   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6200   transaction.request_headers = "Foo: bar\r\n";
6201   transaction.response_headers =
6202       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6203       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6204       "Etag: \"foopy\"\n"
6205       "Cache-Control: max-age=0\n"
6206       "Vary: Foo\n";
6207   RunTransactionTest(cache.http_cache(), transaction);
6208 
6209   // Read from the cache.
6210   RevalidationServer server;
6211   transaction.handler = server.GetHandlerCallback();
6212   LoadTimingInfo load_timing_info;
6213   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
6214                                  NetLogWithSource::Make(NetLogSourceType::NONE),
6215                                  &load_timing_info);
6216 
6217   EXPECT_TRUE(server.EtagUsed());
6218   EXPECT_TRUE(server.LastModifiedUsed());
6219   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6220   EXPECT_EQ(1, cache.disk_cache()->open_count());
6221   EXPECT_EQ(1, cache.disk_cache()->create_count());
6222   TestLoadTimingNetworkRequest(load_timing_info);
6223 }
6224 
6225 // Tests revalidation after a vary mismatch if etag is present.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMismatch)6226 TEST_F(HttpCacheTest, GET_ValidateCache_VaryMismatch) {
6227   MockHttpCache cache;
6228 
6229   // Write to the cache.
6230   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6231   transaction.request_headers = "Foo: bar\r\n";
6232   transaction.response_headers =
6233       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6234       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6235       "Etag: \"foopy\"\n"
6236       "Cache-Control: max-age=0\n"
6237       "Vary: Foo\n";
6238   RunTransactionTest(cache.http_cache(), transaction);
6239 
6240   // Read from the cache and revalidate the entry.
6241   RevalidationServer server;
6242   transaction.handler = server.GetHandlerCallback();
6243   transaction.request_headers = "Foo: none\r\n";
6244   LoadTimingInfo load_timing_info;
6245   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
6246                                  NetLogWithSource::Make(NetLogSourceType::NONE),
6247                                  &load_timing_info);
6248 
6249   EXPECT_TRUE(server.EtagUsed());
6250   EXPECT_FALSE(server.LastModifiedUsed());
6251   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6252   EXPECT_EQ(1, cache.disk_cache()->open_count());
6253   EXPECT_EQ(1, cache.disk_cache()->create_count());
6254   TestLoadTimingNetworkRequest(load_timing_info);
6255 }
6256 
6257 // Tests revalidation after a vary mismatch due to vary: * if etag is present.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMismatchStar)6258 TEST_F(HttpCacheTest, GET_ValidateCache_VaryMismatchStar) {
6259   MockHttpCache cache;
6260 
6261   // Write to the cache.
6262   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6263   transaction.response_headers =
6264       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6265       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6266       "Etag: \"foopy\"\n"
6267       "Cache-Control: max-age=0\n"
6268       "Vary: *\n";
6269   RunTransactionTest(cache.http_cache(), transaction);
6270 
6271   // Read from the cache and revalidate the entry.
6272   RevalidationServer server;
6273   transaction.handler = server.GetHandlerCallback();
6274   LoadTimingInfo load_timing_info;
6275   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
6276                                  NetLogWithSource::Make(NetLogSourceType::NONE),
6277                                  &load_timing_info);
6278 
6279   EXPECT_TRUE(server.EtagUsed());
6280   EXPECT_FALSE(server.LastModifiedUsed());
6281   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6282   EXPECT_EQ(1, cache.disk_cache()->open_count());
6283   EXPECT_EQ(1, cache.disk_cache()->create_count());
6284   TestLoadTimingNetworkRequest(load_timing_info);
6285 }
6286 
6287 // Tests lack of revalidation after a vary mismatch and no etag.
TEST_F(HttpCacheTest,GET_DontValidateCache_VaryMismatch)6288 TEST_F(HttpCacheTest, GET_DontValidateCache_VaryMismatch) {
6289   MockHttpCache cache;
6290 
6291   // Write to the cache.
6292   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6293   transaction.request_headers = "Foo: bar\r\n";
6294   transaction.response_headers =
6295       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
6296       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
6297       "Cache-Control: max-age=0\n"
6298       "Vary: Foo\n";
6299   RunTransactionTest(cache.http_cache(), transaction);
6300 
6301   // Read from the cache and don't revalidate the entry.
6302   RevalidationServer server;
6303   transaction.handler = server.GetHandlerCallback();
6304   transaction.request_headers = "Foo: none\r\n";
6305   LoadTimingInfo load_timing_info;
6306   RunTransactionTestAndGetTiming(cache.http_cache(), transaction,
6307                                  NetLogWithSource::Make(NetLogSourceType::NONE),
6308                                  &load_timing_info);
6309 
6310   EXPECT_FALSE(server.EtagUsed());
6311   EXPECT_FALSE(server.LastModifiedUsed());
6312   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6313   EXPECT_EQ(1, cache.disk_cache()->open_count());
6314   EXPECT_EQ(1, cache.disk_cache()->create_count());
6315   TestLoadTimingNetworkRequest(load_timing_info);
6316 }
6317 
6318 // Tests that a new vary header provided when revalidating an entry is saved.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMatch_UpdateVary)6319 TEST_F(HttpCacheTest, GET_ValidateCache_VaryMatch_UpdateVary) {
6320   MockHttpCache cache;
6321 
6322   // Write to the cache.
6323   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6324   transaction.request_headers = "Foo: bar\r\n Name: bar\r\n";
6325   transaction.response_headers =
6326       "Etag: \"foopy\"\n"
6327       "Cache-Control: max-age=0\n"
6328       "Vary: Foo\n";
6329   RunTransactionTest(cache.http_cache(), transaction);
6330 
6331   // Validate the entry and change the vary field in the response.
6332   transaction.request_headers = "Foo: bar\r\n Name: none\r\n";
6333   transaction.status = "HTTP/1.1 304 Not Modified";
6334   transaction.response_headers =
6335       "Etag: \"foopy\"\n"
6336       "Cache-Control: max-age=3600\n"
6337       "Vary: Name\n";
6338   RunTransactionTest(cache.http_cache(), transaction);
6339 
6340   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6341   EXPECT_EQ(1, cache.disk_cache()->open_count());
6342   EXPECT_EQ(1, cache.disk_cache()->create_count());
6343 
6344   // Make sure that the ActiveEntry is gone.
6345   base::RunLoop().RunUntilIdle();
6346 
6347   // Generate a vary mismatch.
6348   transaction.request_headers = "Foo: bar\r\n Name: bar\r\n";
6349   RunTransactionTest(cache.http_cache(), transaction);
6350 
6351   EXPECT_EQ(3, cache.network_layer()->transaction_count());
6352   EXPECT_EQ(2, cache.disk_cache()->open_count());
6353   EXPECT_EQ(1, cache.disk_cache()->create_count());
6354 }
6355 
6356 // Tests that new request headers causing a vary mismatch are paired with the
6357 // new response when the server says the old response can be used.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMismatch_UpdateRequestHeader)6358 TEST_F(HttpCacheTest, GET_ValidateCache_VaryMismatch_UpdateRequestHeader) {
6359   MockHttpCache cache;
6360 
6361   // Write to the cache.
6362   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6363   transaction.request_headers = "Foo: bar\r\n";
6364   transaction.response_headers =
6365       "Etag: \"foopy\"\n"
6366       "Cache-Control: max-age=3600\n"
6367       "Vary: Foo\n";
6368   RunTransactionTest(cache.http_cache(), transaction);
6369 
6370   // Vary-mismatch validation receives 304.
6371   transaction.request_headers = "Foo: none\r\n";
6372   transaction.status = "HTTP/1.1 304 Not Modified";
6373   RunTransactionTest(cache.http_cache(), transaction);
6374 
6375   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6376   EXPECT_EQ(1, cache.disk_cache()->open_count());
6377   EXPECT_EQ(1, cache.disk_cache()->create_count());
6378 
6379   // Make sure that the ActiveEntry is gone.
6380   base::RunLoop().RunUntilIdle();
6381 
6382   // Generate a vary mismatch.
6383   transaction.request_headers = "Foo: bar\r\n";
6384   RunTransactionTest(cache.http_cache(), transaction);
6385 
6386   EXPECT_EQ(3, cache.network_layer()->transaction_count());
6387   EXPECT_EQ(2, cache.disk_cache()->open_count());
6388   EXPECT_EQ(1, cache.disk_cache()->create_count());
6389 }
6390 
6391 // Tests that a 304 without vary headers doesn't delete the previously stored
6392 // vary data after a vary match revalidation.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMatch_DontDeleteVary)6393 TEST_F(HttpCacheTest, GET_ValidateCache_VaryMatch_DontDeleteVary) {
6394   MockHttpCache cache;
6395 
6396   // Write to the cache.
6397   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6398   transaction.request_headers = "Foo: bar\r\n";
6399   transaction.response_headers =
6400       "Etag: \"foopy\"\n"
6401       "Cache-Control: max-age=0\n"
6402       "Vary: Foo\n";
6403   RunTransactionTest(cache.http_cache(), transaction);
6404 
6405   // Validate the entry and remove the vary field in the response.
6406   transaction.status = "HTTP/1.1 304 Not Modified";
6407   transaction.response_headers =
6408       "Etag: \"foopy\"\n"
6409       "Cache-Control: max-age=3600\n";
6410   RunTransactionTest(cache.http_cache(), transaction);
6411 
6412   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6413   EXPECT_EQ(1, cache.disk_cache()->open_count());
6414   EXPECT_EQ(1, cache.disk_cache()->create_count());
6415 
6416   // Make sure that the ActiveEntry is gone.
6417   base::RunLoop().RunUntilIdle();
6418 
6419   // Generate a vary mismatch.
6420   transaction.request_headers = "Foo: none\r\n";
6421   RunTransactionTest(cache.http_cache(), transaction);
6422 
6423   EXPECT_EQ(3, cache.network_layer()->transaction_count());
6424   EXPECT_EQ(2, cache.disk_cache()->open_count());
6425   EXPECT_EQ(1, cache.disk_cache()->create_count());
6426 }
6427 
6428 // Tests that a 304 without vary headers doesn't delete the previously stored
6429 // vary data after a vary mismatch.
TEST_F(HttpCacheTest,GET_ValidateCache_VaryMismatch_DontDeleteVary)6430 TEST_F(HttpCacheTest, GET_ValidateCache_VaryMismatch_DontDeleteVary) {
6431   MockHttpCache cache;
6432 
6433   // Write to the cache.
6434   ScopedMockTransaction transaction(kTypicalGET_Transaction);
6435   transaction.request_headers = "Foo: bar\r\n";
6436   transaction.response_headers =
6437       "Etag: \"foopy\"\n"
6438       "Cache-Control: max-age=3600\n"
6439       "Vary: Foo\n";
6440   RunTransactionTest(cache.http_cache(), transaction);
6441 
6442   // Vary-mismatch validation receives 304 and no vary header.
6443   transaction.request_headers = "Foo: none\r\n";
6444   transaction.status = "HTTP/1.1 304 Not Modified";
6445   transaction.response_headers =
6446       "Etag: \"foopy\"\n"
6447       "Cache-Control: max-age=3600\n";
6448   RunTransactionTest(cache.http_cache(), transaction);
6449 
6450   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6451   EXPECT_EQ(1, cache.disk_cache()->open_count());
6452   EXPECT_EQ(1, cache.disk_cache()->create_count());
6453 
6454   // Make sure that the ActiveEntry is gone.
6455   base::RunLoop().RunUntilIdle();
6456 
6457   // Generate a vary mismatch.
6458   transaction.request_headers = "Foo: bar\r\n";
6459   RunTransactionTest(cache.http_cache(), transaction);
6460 
6461   EXPECT_EQ(3, cache.network_layer()->transaction_count());
6462   EXPECT_EQ(2, cache.disk_cache()->open_count());
6463   EXPECT_EQ(1, cache.disk_cache()->create_count());
6464 }
6465 
ETagGet_UnconditionalRequest_Handler(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)6466 static void ETagGet_UnconditionalRequest_Handler(const HttpRequestInfo* request,
6467                                                  std::string* response_status,
6468                                                  std::string* response_headers,
6469                                                  std::string* response_data) {
6470   EXPECT_FALSE(
6471       request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
6472 }
6473 
TEST_F(HttpCacheTest,ETagGET_Http10)6474 TEST_F(HttpCacheTest, ETagGET_Http10) {
6475   MockHttpCache cache;
6476 
6477   ScopedMockTransaction transaction(kETagGET_Transaction);
6478   transaction.status = "HTTP/1.0 200 OK";
6479 
6480   // Write to the cache.
6481   RunTransactionTest(cache.http_cache(), transaction);
6482 
6483   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6484   EXPECT_EQ(0, cache.disk_cache()->open_count());
6485   EXPECT_EQ(1, cache.disk_cache()->create_count());
6486 
6487   // Get the same URL again, without generating a conditional request.
6488   transaction.load_flags = LOAD_VALIDATE_CACHE;
6489   transaction.handler =
6490       base::BindRepeating(&ETagGet_UnconditionalRequest_Handler);
6491   RunTransactionTest(cache.http_cache(), transaction);
6492 
6493   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6494   EXPECT_EQ(1, cache.disk_cache()->open_count());
6495   EXPECT_EQ(1, cache.disk_cache()->create_count());
6496 }
6497 
TEST_F(HttpCacheTest,ETagGET_Http10_Range)6498 TEST_F(HttpCacheTest, ETagGET_Http10_Range) {
6499   MockHttpCache cache;
6500 
6501   ScopedMockTransaction transaction(kETagGET_Transaction);
6502   transaction.status = "HTTP/1.0 200 OK";
6503 
6504   // Write to the cache.
6505   RunTransactionTest(cache.http_cache(), transaction);
6506 
6507   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6508   EXPECT_EQ(0, cache.disk_cache()->open_count());
6509   EXPECT_EQ(1, cache.disk_cache()->create_count());
6510 
6511   // Get the same URL again, but use a byte range request.
6512   transaction.load_flags = LOAD_VALIDATE_CACHE;
6513   transaction.handler =
6514       base::BindRepeating(&ETagGet_UnconditionalRequest_Handler);
6515   transaction.request_headers = "Range: bytes = 5-\r\n";
6516   RunTransactionTest(cache.http_cache(), transaction);
6517 
6518   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6519   EXPECT_EQ(1, cache.disk_cache()->open_count());
6520   EXPECT_EQ(2, cache.disk_cache()->create_count());
6521 }
6522 
ETagGet_ConditionalRequest_NoStore_Handler(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)6523 static void ETagGet_ConditionalRequest_NoStore_Handler(
6524     const HttpRequestInfo* request,
6525     std::string* response_status,
6526     std::string* response_headers,
6527     std::string* response_data) {
6528   EXPECT_TRUE(
6529       request->extra_headers.HasHeader(HttpRequestHeaders::kIfNoneMatch));
6530   response_status->assign("HTTP/1.1 304 Not Modified");
6531   response_headers->assign("Cache-Control: no-store\n");
6532   response_data->clear();
6533 }
6534 
TEST_F(HttpCacheTest,ETagGET_ConditionalRequest_304_NoStore)6535 TEST_F(HttpCacheTest, ETagGET_ConditionalRequest_304_NoStore) {
6536   MockHttpCache cache;
6537 
6538   ScopedMockTransaction transaction(kETagGET_Transaction);
6539 
6540   // Write to the cache.
6541   RunTransactionTest(cache.http_cache(), transaction);
6542 
6543   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6544   EXPECT_EQ(0, cache.disk_cache()->open_count());
6545   EXPECT_EQ(1, cache.disk_cache()->create_count());
6546 
6547   // Get the same URL again, but this time we expect it to result
6548   // in a conditional request.
6549   transaction.load_flags = LOAD_VALIDATE_CACHE;
6550   transaction.handler =
6551       base::BindRepeating(&ETagGet_ConditionalRequest_NoStore_Handler);
6552   RunTransactionTest(cache.http_cache(), transaction);
6553 
6554   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6555   EXPECT_EQ(1, cache.disk_cache()->open_count());
6556   EXPECT_EQ(1, cache.disk_cache()->create_count());
6557 
6558   // Reset transaction
6559   transaction.load_flags = kETagGET_Transaction.load_flags;
6560   transaction.handler = kETagGET_Transaction.handler;
6561 
6562   // Write to the cache again. This should create a new entry.
6563   RunTransactionTest(cache.http_cache(), transaction);
6564 
6565   EXPECT_EQ(3, cache.network_layer()->transaction_count());
6566   EXPECT_EQ(1, cache.disk_cache()->open_count());
6567   EXPECT_EQ(2, cache.disk_cache()->create_count());
6568 }
6569 
6570 // Helper that does 4 requests using HttpCache:
6571 //
6572 // (1) loads |kUrl| -- expects |net_response_1| to be returned.
6573 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned.
6574 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to
6575 //     be returned.
6576 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be
6577 //     returned.
6578 // The entry will be created once and will be opened for the 3 subsequent
6579 // requests.
ConditionalizedRequestUpdatesCacheHelper(const Response & net_response_1,const Response & net_response_2,const Response & cached_response_2,const char * extra_request_headers)6580 static void ConditionalizedRequestUpdatesCacheHelper(
6581     const Response& net_response_1,
6582     const Response& net_response_2,
6583     const Response& cached_response_2,
6584     const char* extra_request_headers) {
6585   MockHttpCache cache;
6586 
6587   // The URL we will be requesting.
6588   const char kUrl[] = "http://foobar.com/main.css";
6589 
6590   // Junk network response.
6591   static const Response kUnexpectedResponse = {"HTTP/1.1 500 Unexpected",
6592                                                "Server: unexpected_header",
6593                                                "unexpected body"};
6594 
6595   // We will control the network layer's responses for |kUrl| using
6596   // |mock_network_response|.
6597   ScopedMockTransaction mock_network_response(kUrl);
6598 
6599   // Request |kUrl| for the first time. It should hit the network and
6600   // receive |kNetResponse1|, which it saves into the HTTP cache.
6601 
6602   MockTransaction request = {nullptr};
6603   request.url = kUrl;
6604   request.method = "GET";
6605   request.request_headers = "";
6606 
6607   net_response_1.AssignTo(&mock_network_response);  // Network mock.
6608   net_response_1.AssignTo(&request);                // Expected result.
6609 
6610   std::string response_headers;
6611   RunTransactionTestWithResponse(cache.http_cache(), request,
6612                                  &response_headers);
6613 
6614   EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
6615   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6616   EXPECT_EQ(0, cache.disk_cache()->open_count());
6617   EXPECT_EQ(1, cache.disk_cache()->create_count());
6618 
6619   // Request |kUrl| a second time. Now |kNetResponse1| it is in the HTTP
6620   // cache, so we don't hit the network.
6621 
6622   request.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
6623 
6624   kUnexpectedResponse.AssignTo(&mock_network_response);  // Network mock.
6625   net_response_1.AssignTo(&request);                     // Expected result.
6626 
6627   RunTransactionTestWithResponse(cache.http_cache(), request,
6628                                  &response_headers);
6629 
6630   EXPECT_EQ(net_response_1.status_and_headers(), response_headers);
6631   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6632   EXPECT_EQ(1, cache.disk_cache()->open_count());
6633   EXPECT_EQ(1, cache.disk_cache()->create_count());
6634 
6635   // Request |kUrl| yet again, but this time give the request an
6636   // "If-Modified-Since" header. This will cause the request to re-hit the
6637   // network. However now the network response is going to be
6638   // different -- this simulates a change made to the CSS file.
6639 
6640   request.request_headers = extra_request_headers;
6641   request.load_flags = LOAD_NORMAL;
6642 
6643   net_response_2.AssignTo(&mock_network_response);  // Network mock.
6644   net_response_2.AssignTo(&request);                // Expected result.
6645 
6646   RunTransactionTestWithResponse(cache.http_cache(), request,
6647                                  &response_headers);
6648 
6649   EXPECT_EQ(net_response_2.status_and_headers(), response_headers);
6650   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6651   EXPECT_EQ(1, cache.disk_cache()->open_count());
6652   EXPECT_EQ(1, cache.disk_cache()->create_count());
6653 
6654   // Finally, request |kUrl| again. This request should be serviced from
6655   // the cache. Moreover, the value in the cache should be |kNetResponse2|
6656   // and NOT |kNetResponse1|. The previous step should have replaced the
6657   // value in the cache with the modified response.
6658 
6659   request.request_headers = "";
6660   request.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
6661 
6662   kUnexpectedResponse.AssignTo(&mock_network_response);  // Network mock.
6663   cached_response_2.AssignTo(&request);                  // Expected result.
6664 
6665   RunTransactionTestWithResponse(cache.http_cache(), request,
6666                                  &response_headers);
6667 
6668   EXPECT_EQ(cached_response_2.status_and_headers(), response_headers);
6669   EXPECT_EQ(2, cache.network_layer()->transaction_count());
6670   EXPECT_EQ(2, cache.disk_cache()->open_count());
6671   EXPECT_EQ(1, cache.disk_cache()->create_count());
6672 }
6673 
6674 // Check that when an "if-modified-since" header is attached
6675 // to the request, the result still updates the cached entry.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache1)6676 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache1) {
6677   // First network response for |kUrl|.
6678   static const Response kNetResponse1 = {
6679       "HTTP/1.1 200 OK",
6680       "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6681       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6682       "body1"};
6683 
6684   // Second network response for |kUrl|.
6685   static const Response kNetResponse2 = {
6686       "HTTP/1.1 200 OK",
6687       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6688       "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
6689       "body2"};
6690 
6691   const char extra_headers[] =
6692       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
6693 
6694   ConditionalizedRequestUpdatesCacheHelper(kNetResponse1, kNetResponse2,
6695                                            kNetResponse2, extra_headers);
6696 }
6697 
6698 // Check that when an "if-none-match" header is attached
6699 // to the request, the result updates the cached entry.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache2)6700 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache2) {
6701   // First network response for |kUrl|.
6702   static const Response kNetResponse1 = {
6703       "HTTP/1.1 200 OK",
6704       "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6705       "Etag: \"ETAG1\"\n"
6706       "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n",  // Should never expire.
6707       "body1"};
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   const char extra_headers[] = "If-None-Match: \"ETAG1\"\r\n";
6718 
6719   ConditionalizedRequestUpdatesCacheHelper(kNetResponse1, kNetResponse2,
6720                                            kNetResponse2, extra_headers);
6721 }
6722 
6723 // Check that when an "if-modified-since" header is attached
6724 // to a request, the 304 (not modified result) result updates the cached
6725 // headers, and the 304 response is returned rather than the cached response.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache3)6726 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache3) {
6727   // First network response for |kUrl|.
6728   static const Response kNetResponse1 = {
6729       "HTTP/1.1 200 OK",
6730       "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6731       "Server: server1\n"
6732       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6733       "body1"};
6734 
6735   // Second network response for |kUrl|.
6736   static const Response kNetResponse2 = {
6737       "HTTP/1.1 304 Not Modified",
6738       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6739       "Server: server2\n"
6740       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6741       ""};
6742 
6743   static const Response kCachedResponse2 = {
6744       "HTTP/1.1 200 OK",
6745       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6746       "Server: server2\n"
6747       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6748       "body1"};
6749 
6750   const char extra_headers[] =
6751       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
6752 
6753   ConditionalizedRequestUpdatesCacheHelper(kNetResponse1, kNetResponse2,
6754                                            kCachedResponse2, extra_headers);
6755 }
6756 
6757 // Test that when doing an externally conditionalized if-modified-since
6758 // and there is no corresponding cache entry, a new cache entry is NOT
6759 // created (304 response).
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache4)6760 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache4) {
6761   MockHttpCache cache;
6762 
6763   const char kUrl[] = "http://foobar.com/main.css";
6764 
6765   static const Response kNetResponse = {
6766       "HTTP/1.1 304 Not Modified",
6767       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6768       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6769       ""};
6770 
6771   const char kExtraRequestHeaders[] =
6772       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
6773 
6774   // We will control the network layer's responses for |kUrl| using
6775   // |mock_network_response|.
6776   ScopedMockTransaction mock_network_response(kUrl);
6777 
6778   MockTransaction request = {nullptr};
6779   request.url = kUrl;
6780   request.method = "GET";
6781   request.request_headers = kExtraRequestHeaders;
6782 
6783   kNetResponse.AssignTo(&mock_network_response);  // Network mock.
6784   kNetResponse.AssignTo(&request);                // Expected result.
6785 
6786   std::string response_headers;
6787   RunTransactionTestWithResponse(cache.http_cache(), request,
6788                                  &response_headers);
6789 
6790   EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
6791   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6792   EXPECT_EQ(0, cache.disk_cache()->open_count());
6793   EXPECT_EQ(0, cache.disk_cache()->create_count());
6794 }
6795 
6796 // Test that when doing an externally conditionalized if-modified-since
6797 // and there is no corresponding cache entry, a new cache entry is NOT
6798 // created (200 response).
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache5)6799 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache5) {
6800   MockHttpCache cache;
6801 
6802   const char kUrl[] = "http://foobar.com/main.css";
6803 
6804   static const Response kNetResponse = {
6805       "HTTP/1.1 200 OK",
6806       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6807       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6808       "foobar!!!"};
6809 
6810   const char kExtraRequestHeaders[] =
6811       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
6812 
6813   // We will control the network layer's responses for |kUrl| using
6814   // |mock_network_response|.
6815   ScopedMockTransaction mock_network_response(kUrl);
6816 
6817   MockTransaction request = {nullptr};
6818   request.url = kUrl;
6819   request.method = "GET";
6820   request.request_headers = kExtraRequestHeaders;
6821 
6822   kNetResponse.AssignTo(&mock_network_response);  // Network mock.
6823   kNetResponse.AssignTo(&request);                // Expected result.
6824 
6825   std::string response_headers;
6826   RunTransactionTestWithResponse(cache.http_cache(), request,
6827                                  &response_headers);
6828 
6829   EXPECT_EQ(kNetResponse.status_and_headers(), response_headers);
6830   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6831   EXPECT_EQ(0, cache.disk_cache()->open_count());
6832   EXPECT_EQ(0, cache.disk_cache()->create_count());
6833 }
6834 
6835 // Test that when doing an externally conditionalized if-modified-since
6836 // if the date does not match the cache entry's last-modified date,
6837 // then we do NOT use the response (304) to update the cache.
6838 // (the if-modified-since date is 2 days AFTER the cache's modification date).
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache6)6839 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache6) {
6840   static const Response kNetResponse1 = {
6841       "HTTP/1.1 200 OK",
6842       "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6843       "Server: server1\n"
6844       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6845       "body1"};
6846 
6847   // Second network response for |kUrl|.
6848   static const Response kNetResponse2 = {
6849       "HTTP/1.1 304 Not Modified",
6850       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6851       "Server: server2\n"
6852       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6853       ""};
6854 
6855   // This is two days in the future from the original response's last-modified
6856   // date!
6857   const char kExtraRequestHeaders[] =
6858       "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n";
6859 
6860   ConditionalizedRequestUpdatesCacheHelper(kNetResponse1, kNetResponse2,
6861                                            kNetResponse1, kExtraRequestHeaders);
6862 }
6863 
6864 // Test that when doing an externally conditionalized if-none-match
6865 // if the etag does not match the cache entry's etag, then we do not use the
6866 // response (304) to update the cache.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache7)6867 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache7) {
6868   static const Response kNetResponse1 = {
6869       "HTTP/1.1 200 OK",
6870       "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6871       "Etag: \"Foo1\"\n"
6872       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6873       "body1"};
6874 
6875   // Second network response for |kUrl|.
6876   static const Response kNetResponse2 = {
6877       "HTTP/1.1 304 Not Modified",
6878       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6879       "Etag: \"Foo2\"\n"
6880       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6881       ""};
6882 
6883   // Different etag from original response.
6884   const char kExtraRequestHeaders[] = "If-None-Match: \"Foo2\"\r\n";
6885 
6886   ConditionalizedRequestUpdatesCacheHelper(kNetResponse1, kNetResponse2,
6887                                            kNetResponse1, kExtraRequestHeaders);
6888 }
6889 
6890 // Test that doing an externally conditionalized request with both if-none-match
6891 // and if-modified-since updates the cache.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache8)6892 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache8) {
6893   static const Response kNetResponse1 = {
6894       "HTTP/1.1 200 OK",
6895       "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6896       "Etag: \"Foo1\"\n"
6897       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6898       "body1"};
6899 
6900   // Second network response for |kUrl|.
6901   static const Response kNetResponse2 = {
6902       "HTTP/1.1 200 OK",
6903       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6904       "Etag: \"Foo2\"\n"
6905       "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
6906       "body2"};
6907 
6908   const char kExtraRequestHeaders[] =
6909       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
6910       "If-None-Match: \"Foo1\"\r\n";
6911 
6912   ConditionalizedRequestUpdatesCacheHelper(kNetResponse1, kNetResponse2,
6913                                            kNetResponse2, kExtraRequestHeaders);
6914 }
6915 
6916 // Test that doing an externally conditionalized request with both if-none-match
6917 // and if-modified-since does not update the cache with only one match.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache9)6918 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache9) {
6919   static const Response kNetResponse1 = {
6920       "HTTP/1.1 200 OK",
6921       "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6922       "Etag: \"Foo1\"\n"
6923       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6924       "body1"};
6925 
6926   // Second network response for |kUrl|.
6927   static const Response kNetResponse2 = {
6928       "HTTP/1.1 200 OK",
6929       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6930       "Etag: \"Foo2\"\n"
6931       "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
6932       "body2"};
6933 
6934   // The etag doesn't match what we have stored.
6935   const char kExtraRequestHeaders[] =
6936       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n"
6937       "If-None-Match: \"Foo2\"\r\n";
6938 
6939   ConditionalizedRequestUpdatesCacheHelper(kNetResponse1, kNetResponse2,
6940                                            kNetResponse1, kExtraRequestHeaders);
6941 }
6942 
6943 // Test that doing an externally conditionalized request with both if-none-match
6944 // and if-modified-since does not update the cache with only one match.
TEST_F(HttpCacheTest,ConditionalizedRequestUpdatesCache10)6945 TEST_F(HttpCacheTest, ConditionalizedRequestUpdatesCache10) {
6946   static const Response kNetResponse1 = {
6947       "HTTP/1.1 200 OK",
6948       "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
6949       "Etag: \"Foo1\"\n"
6950       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
6951       "body1"};
6952 
6953   // Second network response for |kUrl|.
6954   static const Response kNetResponse2 = {
6955       "HTTP/1.1 200 OK",
6956       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
6957       "Etag: \"Foo2\"\n"
6958       "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n",
6959       "body2"};
6960 
6961   // The modification date doesn't match what we have stored.
6962   const char kExtraRequestHeaders[] =
6963       "If-Modified-Since: Fri, 08 Feb 2008 22:38:21 GMT\r\n"
6964       "If-None-Match: \"Foo1\"\r\n";
6965 
6966   ConditionalizedRequestUpdatesCacheHelper(kNetResponse1, kNetResponse2,
6967                                            kNetResponse1, kExtraRequestHeaders);
6968 }
6969 
TEST_F(HttpCacheTest,UrlContainingHash)6970 TEST_F(HttpCacheTest, UrlContainingHash) {
6971   MockHttpCache cache;
6972 
6973   // Do a typical GET request -- should write an entry into our cache.
6974   MockTransaction trans(kTypicalGET_Transaction);
6975   RunTransactionTest(cache.http_cache(), trans);
6976 
6977   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6978   EXPECT_EQ(0, cache.disk_cache()->open_count());
6979   EXPECT_EQ(1, cache.disk_cache()->create_count());
6980 
6981   // Request the same URL, but this time with a reference section (hash).
6982   // Since the cache key strips the hash sections, this should be a cache hit.
6983   std::string url_with_hash = std::string(trans.url) + "#multiple#hashes";
6984   trans.url = url_with_hash.c_str();
6985   trans.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
6986 
6987   RunTransactionTest(cache.http_cache(), trans);
6988 
6989   EXPECT_EQ(1, cache.network_layer()->transaction_count());
6990   EXPECT_EQ(1, cache.disk_cache()->open_count());
6991   EXPECT_EQ(1, cache.disk_cache()->create_count());
6992 }
6993 
6994 // Tests that we skip the cache for POST requests that do not have an upload
6995 // identifier.
TEST_F(HttpCacheTest,SimplePOST_SkipsCache)6996 TEST_F(HttpCacheTest, SimplePOST_SkipsCache) {
6997   MockHttpCache cache;
6998 
6999   RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
7000 
7001   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7002   EXPECT_EQ(0, cache.disk_cache()->open_count());
7003   EXPECT_EQ(0, cache.disk_cache()->create_count());
7004 }
7005 
7006 // Tests POST handling with a disabled cache (no DCHECK).
TEST_F(HttpCacheTest,SimplePOST_DisabledCache)7007 TEST_F(HttpCacheTest, SimplePOST_DisabledCache) {
7008   MockHttpCache cache;
7009   cache.http_cache()->set_mode(HttpCache::Mode::DISABLE);
7010 
7011   RunTransactionTest(cache.http_cache(), kSimplePOST_Transaction);
7012 
7013   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7014   EXPECT_EQ(0, cache.disk_cache()->open_count());
7015   EXPECT_EQ(0, cache.disk_cache()->create_count());
7016 }
7017 
TEST_F(HttpCacheTest,SimplePOST_LoadOnlyFromCache_Miss)7018 TEST_F(HttpCacheTest, SimplePOST_LoadOnlyFromCache_Miss) {
7019   MockHttpCache cache;
7020 
7021   MockTransaction transaction(kSimplePOST_Transaction);
7022   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7023 
7024   MockHttpRequest request(transaction);
7025   TestCompletionCallback callback;
7026 
7027   std::unique_ptr<HttpTransaction> trans;
7028   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
7029   ASSERT_TRUE(trans.get());
7030 
7031   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
7032   ASSERT_THAT(callback.GetResult(rv), IsError(ERR_CACHE_MISS));
7033 
7034   trans.reset();
7035 
7036   EXPECT_EQ(0, cache.network_layer()->transaction_count());
7037   EXPECT_EQ(0, cache.disk_cache()->open_count());
7038   EXPECT_EQ(0, cache.disk_cache()->create_count());
7039 }
7040 
TEST_F(HttpCacheTest,SimplePOST_LoadOnlyFromCache_Hit)7041 TEST_F(HttpCacheTest, SimplePOST_LoadOnlyFromCache_Hit) {
7042   MockHttpCache cache;
7043 
7044   // Test that we hit the cache for POST requests.
7045 
7046   MockTransaction transaction(kSimplePOST_Transaction);
7047 
7048   const int64_t kUploadId = 1;  // Just a dummy value.
7049 
7050   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7051   element_readers.push_back(
7052       std::make_unique<UploadBytesElementReader>("hello", 5));
7053   ElementsUploadDataStream upload_data_stream(std::move(element_readers),
7054                                               kUploadId);
7055   MockHttpRequest request(transaction);
7056   request.upload_data_stream = &upload_data_stream;
7057 
7058   // Populate the cache.
7059   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
7060                                 nullptr);
7061 
7062   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7063   EXPECT_EQ(0, cache.disk_cache()->open_count());
7064   EXPECT_EQ(1, cache.disk_cache()->create_count());
7065 
7066   // Load from cache.
7067   request.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7068   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
7069                                 nullptr);
7070 
7071   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7072   EXPECT_EQ(1, cache.disk_cache()->open_count());
7073   EXPECT_EQ(1, cache.disk_cache()->create_count());
7074 }
7075 
7076 // Test that we don't hit the cache for POST requests if there is a byte range.
TEST_F(HttpCacheTest,SimplePOST_WithRanges)7077 TEST_F(HttpCacheTest, SimplePOST_WithRanges) {
7078   MockHttpCache cache;
7079 
7080   MockTransaction transaction(kSimplePOST_Transaction);
7081   transaction.request_headers = "Range: bytes = 0-4\r\n";
7082 
7083   const int64_t kUploadId = 1;  // Just a dummy value.
7084 
7085   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7086   element_readers.push_back(
7087       std::make_unique<UploadBytesElementReader>("hello", 5));
7088   ElementsUploadDataStream upload_data_stream(std::move(element_readers),
7089                                               kUploadId);
7090 
7091   MockHttpRequest request(transaction);
7092   request.upload_data_stream = &upload_data_stream;
7093 
7094   // Attempt to populate the cache.
7095   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
7096                                 nullptr);
7097 
7098   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7099   EXPECT_EQ(0, cache.disk_cache()->open_count());
7100   EXPECT_EQ(0, cache.disk_cache()->create_count());
7101 }
7102 
7103 // Tests that a POST is cached separately from a GET.
TEST_F(HttpCacheTest,SimplePOST_SeparateCache)7104 TEST_F(HttpCacheTest, SimplePOST_SeparateCache) {
7105   MockHttpCache cache;
7106 
7107   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7108   element_readers.push_back(
7109       std::make_unique<UploadBytesElementReader>("hello", 5));
7110   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 1);
7111 
7112   MockTransaction transaction(kSimplePOST_Transaction);
7113   MockHttpRequest req1(transaction);
7114   req1.upload_data_stream = &upload_data_stream;
7115 
7116   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7117 
7118   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7119   EXPECT_EQ(0, cache.disk_cache()->open_count());
7120   EXPECT_EQ(1, cache.disk_cache()->create_count());
7121 
7122   transaction.method = "GET";
7123   MockHttpRequest req2(transaction);
7124 
7125   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7126 
7127   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7128   EXPECT_EQ(0, cache.disk_cache()->open_count());
7129   EXPECT_EQ(2, cache.disk_cache()->create_count());
7130 }
7131 
7132 // Tests that a successful POST invalidates a previously cached GET.
TEST_F(HttpCacheTest,SimplePOST_Invalidate_205)7133 TEST_F(HttpCacheTest, SimplePOST_Invalidate_205) {
7134   MockHttpCache cache;
7135 
7136   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7137   MockHttpRequest req1(transaction);
7138 
7139   // Attempt to populate the cache.
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   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7147   element_readers.push_back(
7148       std::make_unique<UploadBytesElementReader>("hello", 5));
7149   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 1);
7150 
7151   transaction.method = "POST";
7152   transaction.status = "HTTP/1.1 205 No Content";
7153   MockHttpRequest req2(transaction);
7154   req2.upload_data_stream = &upload_data_stream;
7155 
7156   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7157 
7158   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7159   EXPECT_EQ(0, cache.disk_cache()->open_count());
7160   EXPECT_EQ(2, cache.disk_cache()->create_count());
7161 
7162   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7163 
7164   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7165   EXPECT_EQ(0, cache.disk_cache()->open_count());
7166   EXPECT_EQ(3, cache.disk_cache()->create_count());
7167 }
7168 
7169 // Tests that a successful POST invalidates a previously cached GET,
7170 // with cache split by top-frame origin.
TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,SimplePOST_Invalidate_205_SplitCache)7171 TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,
7172        SimplePOST_Invalidate_205_SplitCache) {
7173   SchemefulSite site_a(GURL("http://a.com"));
7174   SchemefulSite site_b(GURL("http://b.com"));
7175 
7176   MockHttpCache cache;
7177 
7178   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7179   MockHttpRequest req1(transaction);
7180   req1.network_isolation_key = NetworkIsolationKey(site_a, site_a);
7181   req1.network_anonymization_key =
7182       net::NetworkAnonymizationKey::CreateSameSite(site_a);
7183 
7184   // Attempt to populate the cache.
7185   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7186 
7187   // Same for a different origin.
7188   MockHttpRequest req1b(transaction);
7189   req1b.network_isolation_key = NetworkIsolationKey(site_b, site_b);
7190   req1b.network_anonymization_key =
7191       net::NetworkAnonymizationKey::CreateSameSite(site_b);
7192   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1b,
7193                                 nullptr);
7194 
7195   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7196   EXPECT_EQ(0, cache.disk_cache()->open_count());
7197   EXPECT_EQ(2, cache.disk_cache()->create_count());
7198 
7199   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7200   element_readers.push_back(
7201       std::make_unique<UploadBytesElementReader>("hello", 5));
7202   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 1);
7203 
7204   transaction.method = "POST";
7205   transaction.status = "HTTP/1.1 205 No Content";
7206   MockHttpRequest req2(transaction);
7207   req2.upload_data_stream = &upload_data_stream;
7208   req2.network_isolation_key = NetworkIsolationKey(site_a, site_a);
7209   req2.network_anonymization_key =
7210       net::NetworkAnonymizationKey::CreateSameSite(site_a);
7211 
7212   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7213 
7214   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7215   EXPECT_EQ(0, cache.disk_cache()->open_count());
7216   EXPECT_EQ(3, cache.disk_cache()->create_count());
7217 
7218   // req1b should still be cached, since it has a different top-level frame
7219   // origin.
7220   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1b,
7221                                 nullptr);
7222   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7223   EXPECT_EQ(1, cache.disk_cache()->open_count());
7224   EXPECT_EQ(3, cache.disk_cache()->create_count());
7225 
7226   // req1 should not be cached after the POST.
7227   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7228   EXPECT_EQ(4, cache.network_layer()->transaction_count());
7229   EXPECT_EQ(1, cache.disk_cache()->open_count());
7230   EXPECT_EQ(4, cache.disk_cache()->create_count());
7231 }
7232 
7233 // Tests that a successful POST invalidates a previously cached GET, even when
7234 // there is no upload identifier.
TEST_F(HttpCacheTest,SimplePOST_NoUploadId_Invalidate_205)7235 TEST_F(HttpCacheTest, SimplePOST_NoUploadId_Invalidate_205) {
7236   MockHttpCache cache;
7237 
7238   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7239   MockHttpRequest req1(transaction);
7240 
7241   // Attempt to populate the cache.
7242   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7243 
7244   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7245   EXPECT_EQ(0, cache.disk_cache()->open_count());
7246   EXPECT_EQ(1, cache.disk_cache()->create_count());
7247 
7248   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7249   element_readers.push_back(
7250       std::make_unique<UploadBytesElementReader>("hello", 5));
7251   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7252 
7253   transaction.method = "POST";
7254   transaction.status = "HTTP/1.1 205 No Content";
7255   MockHttpRequest req2(transaction);
7256   req2.upload_data_stream = &upload_data_stream;
7257 
7258   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7259 
7260   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7261   EXPECT_EQ(0, cache.disk_cache()->open_count());
7262   EXPECT_EQ(1, cache.disk_cache()->create_count());
7263 
7264   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7265 
7266   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7267   EXPECT_EQ(0, cache.disk_cache()->open_count());
7268   EXPECT_EQ(2, cache.disk_cache()->create_count());
7269 }
7270 
7271 // Tests that processing a POST before creating the backend doesn't crash.
TEST_F(HttpCacheTest,SimplePOST_NoUploadId_NoBackend)7272 TEST_F(HttpCacheTest, SimplePOST_NoUploadId_NoBackend) {
7273   // This will initialize a cache object with NULL backend.
7274   auto factory = std::make_unique<MockBlockingBackendFactory>();
7275   factory->set_fail(true);
7276   factory->FinishCreation();
7277   MockHttpCache cache(std::move(factory));
7278 
7279   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7280   element_readers.push_back(
7281       std::make_unique<UploadBytesElementReader>("hello", 5));
7282   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7283 
7284   ScopedMockTransaction transaction(kSimplePOST_Transaction);
7285   MockHttpRequest req(transaction);
7286   req.upload_data_stream = &upload_data_stream;
7287 
7288   RunTransactionTestWithRequest(cache.http_cache(), transaction, req, nullptr);
7289 }
7290 
7291 // Tests that we don't invalidate entries as a result of a failed POST.
TEST_F(HttpCacheTest,SimplePOST_DontInvalidate_100)7292 TEST_F(HttpCacheTest, SimplePOST_DontInvalidate_100) {
7293   MockHttpCache cache;
7294 
7295   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7296   MockHttpRequest req1(transaction);
7297 
7298   // Attempt to populate the cache.
7299   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7300 
7301   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7302   EXPECT_EQ(0, cache.disk_cache()->open_count());
7303   EXPECT_EQ(1, cache.disk_cache()->create_count());
7304 
7305   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7306   element_readers.push_back(
7307       std::make_unique<UploadBytesElementReader>("hello", 5));
7308   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 1);
7309 
7310   transaction.method = "POST";
7311   transaction.status = "HTTP/1.1 100 Continue";
7312   MockHttpRequest req2(transaction);
7313   req2.upload_data_stream = &upload_data_stream;
7314 
7315   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7316 
7317   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7318   EXPECT_EQ(0, cache.disk_cache()->open_count());
7319   EXPECT_EQ(2, cache.disk_cache()->create_count());
7320 
7321   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7322 
7323   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7324   EXPECT_EQ(1, cache.disk_cache()->open_count());
7325   EXPECT_EQ(2, cache.disk_cache()->create_count());
7326 }
7327 
7328 // Tests that a HEAD request is not cached by itself.
TEST_F(HttpCacheTest,SimpleHEAD_LoadOnlyFromCache_Miss)7329 TEST_F(HttpCacheTest, SimpleHEAD_LoadOnlyFromCache_Miss) {
7330   MockHttpCache cache;
7331   ScopedMockTransaction transaction(kSimplePOST_Transaction);
7332   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7333   transaction.method = "HEAD";
7334 
7335   MockHttpRequest request(transaction);
7336   TestCompletionCallback callback;
7337 
7338   std::unique_ptr<HttpTransaction> trans;
7339   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
7340   ASSERT_TRUE(trans.get());
7341 
7342   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
7343   ASSERT_THAT(callback.GetResult(rv), IsError(ERR_CACHE_MISS));
7344 
7345   trans.reset();
7346 
7347   EXPECT_EQ(0, cache.network_layer()->transaction_count());
7348   EXPECT_EQ(0, cache.disk_cache()->open_count());
7349   EXPECT_EQ(0, cache.disk_cache()->create_count());
7350 }
7351 
7352 // Tests that a HEAD request is served from a cached GET.
TEST_F(HttpCacheTest,SimpleHEAD_LoadOnlyFromCache_Hit)7353 TEST_F(HttpCacheTest, SimpleHEAD_LoadOnlyFromCache_Hit) {
7354   MockHttpCache cache;
7355   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7356 
7357   // Populate the cache.
7358   RunTransactionTest(cache.http_cache(), transaction);
7359 
7360   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7361   EXPECT_EQ(0, cache.disk_cache()->open_count());
7362   EXPECT_EQ(1, cache.disk_cache()->create_count());
7363 
7364   // Load from cache.
7365   transaction.method = "HEAD";
7366   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7367   transaction.data = "";
7368   RunTransactionTest(cache.http_cache(), transaction);
7369 
7370   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7371   EXPECT_EQ(1, cache.disk_cache()->open_count());
7372   EXPECT_EQ(1, cache.disk_cache()->create_count());
7373 }
7374 
7375 // Tests that a read-only request served from the cache preserves CL.
TEST_F(HttpCacheTest,SimpleHEAD_ContentLengthOnHit_Read)7376 TEST_F(HttpCacheTest, SimpleHEAD_ContentLengthOnHit_Read) {
7377   MockHttpCache cache;
7378   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7379   transaction.response_headers = "Content-Length: 42\n";
7380 
7381   // Populate the cache.
7382   RunTransactionTest(cache.http_cache(), transaction);
7383 
7384   // Load from cache.
7385   transaction.method = "HEAD";
7386   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7387   transaction.data = "";
7388   std::string headers;
7389 
7390   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7391 
7392   EXPECT_EQ("HTTP/1.1 200 OK\nContent-Length: 42\n", headers);
7393 }
7394 
7395 // Tests that a read-write request served from the cache preserves CL.
TEST_F(HttpCacheTest,ETagHEAD_ContentLengthOnHit_ReadWrite)7396 TEST_F(HttpCacheTest, ETagHEAD_ContentLengthOnHit_ReadWrite) {
7397   MockHttpCache cache;
7398   ScopedMockTransaction transaction(kETagGET_Transaction);
7399   std::string server_headers(kETagGET_Transaction.response_headers);
7400   server_headers.append("Content-Length: 42\n");
7401   transaction.response_headers = server_headers.data();
7402 
7403   // Populate the cache.
7404   RunTransactionTest(cache.http_cache(), transaction);
7405 
7406   // Load from cache.
7407   transaction.method = "HEAD";
7408   transaction.data = "";
7409   std::string headers;
7410 
7411   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7412 
7413   EXPECT_NE(std::string::npos, headers.find("Content-Length: 42\n"));
7414 }
7415 
7416 // Tests that a HEAD request that includes byte ranges bypasses the cache.
TEST_F(HttpCacheTest,SimpleHEAD_WithRanges)7417 TEST_F(HttpCacheTest, SimpleHEAD_WithRanges) {
7418   MockHttpCache cache;
7419   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7420 
7421   // Populate the cache.
7422   RunTransactionTest(cache.http_cache(), transaction);
7423 
7424   // Load from cache.
7425   transaction.method = "HEAD";
7426   transaction.request_headers = "Range: bytes = 0-4\r\n";
7427   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7428   transaction.start_return_code = ERR_CACHE_MISS;
7429   RunTransactionTest(cache.http_cache(), transaction);
7430 
7431   EXPECT_EQ(0, cache.disk_cache()->open_count());
7432   EXPECT_EQ(1, cache.disk_cache()->create_count());
7433 }
7434 
7435 // Tests that a HEAD request can be served from a partially cached resource.
TEST_F(HttpCacheTest,SimpleHEAD_WithCachedRanges)7436 TEST_F(HttpCacheTest, SimpleHEAD_WithCachedRanges) {
7437   MockHttpCache cache;
7438   {
7439     ScopedMockTransaction scoped_mock_transaction(kRangeGET_TransactionOK);
7440     // Write to the cache (40-49).
7441     RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
7442   }
7443 
7444   ScopedMockTransaction transaction(kSimpleGET_Transaction,
7445                                     kRangeGET_TransactionOK.url);
7446   transaction.method = "HEAD";
7447   transaction.data = "";
7448   std::string headers;
7449 
7450   // Load from cache.
7451   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7452 
7453   EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
7454   EXPECT_NE(std::string::npos, headers.find("Content-Length: 80\n"));
7455   EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
7456   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7457   EXPECT_EQ(1, cache.disk_cache()->open_count());
7458   EXPECT_EQ(1, cache.disk_cache()->create_count());
7459 }
7460 
7461 // Tests that a HEAD request can be served from a truncated resource.
TEST_F(HttpCacheTest,SimpleHEAD_WithTruncatedEntry)7462 TEST_F(HttpCacheTest, SimpleHEAD_WithTruncatedEntry) {
7463   MockHttpCache cache;
7464   {
7465     ScopedMockTransaction scoped_mock_transaction(kRangeGET_TransactionOK);
7466     std::string raw_headers(
7467         "HTTP/1.1 200 OK\n"
7468         "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
7469         "ETag: \"foo\"\n"
7470         "Accept-Ranges: bytes\n"
7471         "Content-Length: 80\n");
7472     CreateTruncatedEntry(raw_headers, &cache);
7473   }
7474 
7475   ScopedMockTransaction transaction(kSimpleGET_Transaction,
7476                                     kRangeGET_TransactionOK.url);
7477   transaction.method = "HEAD";
7478   transaction.data = "";
7479   std::string headers;
7480 
7481   // Load from cache.
7482   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7483 
7484   EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
7485   EXPECT_NE(std::string::npos, headers.find("Content-Length: 80\n"));
7486   EXPECT_EQ(std::string::npos, headers.find("Content-Range"));
7487   EXPECT_EQ(0, cache.network_layer()->transaction_count());
7488   EXPECT_EQ(1, cache.disk_cache()->open_count());
7489   EXPECT_EQ(1, cache.disk_cache()->create_count());
7490 }
7491 
7492 // Tests that a HEAD request updates the cached response.
TEST_F(HttpCacheTest,TypicalHEAD_UpdatesResponse)7493 TEST_F(HttpCacheTest, TypicalHEAD_UpdatesResponse) {
7494   MockHttpCache cache;
7495   std::string headers;
7496   {
7497     ScopedMockTransaction transaction(kTypicalGET_Transaction);
7498 
7499     // Populate the cache.
7500     RunTransactionTest(cache.http_cache(), transaction);
7501 
7502     // Update the cache.
7503     transaction.method = "HEAD";
7504     transaction.response_headers = "Foo: bar\n";
7505     transaction.data = "";
7506     transaction.status = "HTTP/1.1 304 Not Modified\n";
7507     RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7508   }
7509 
7510   EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 200 OK\n"));
7511   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7512 
7513   ScopedMockTransaction transaction2(kTypicalGET_Transaction);
7514 
7515   // Make sure we are done with the previous transaction.
7516   base::RunLoop().RunUntilIdle();
7517 
7518   // Load from the cache.
7519   transaction2.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7520   RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
7521 
7522   EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
7523   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7524   EXPECT_EQ(2, cache.disk_cache()->open_count());
7525   EXPECT_EQ(1, cache.disk_cache()->create_count());
7526 }
7527 
7528 // Tests that an externally conditionalized HEAD request updates the cache.
TEST_F(HttpCacheTest,TypicalHEAD_ConditionalizedRequestUpdatesResponse)7529 TEST_F(HttpCacheTest, TypicalHEAD_ConditionalizedRequestUpdatesResponse) {
7530   MockHttpCache cache;
7531   std::string headers;
7532 
7533   {
7534     ScopedMockTransaction transaction(kTypicalGET_Transaction);
7535 
7536     // Populate the cache.
7537     RunTransactionTest(cache.http_cache(), transaction);
7538 
7539     // Update the cache.
7540     transaction.method = "HEAD";
7541     transaction.request_headers =
7542         "If-Modified-Since: Wed, 28 Nov 2007 00:40:09 GMT\r\n";
7543     transaction.response_headers = "Foo: bar\n";
7544     transaction.data = "";
7545     transaction.status = "HTTP/1.1 304 Not Modified\n";
7546     RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
7547 
7548     EXPECT_NE(std::string::npos, headers.find("HTTP/1.1 304 Not Modified\n"));
7549     EXPECT_EQ(2, cache.network_layer()->transaction_count());
7550 
7551     // Make sure we are done with the previous transaction.
7552     base::RunLoop().RunUntilIdle();
7553   }
7554   {
7555     ScopedMockTransaction transaction2(kTypicalGET_Transaction);
7556 
7557     // Load from the cache.
7558     transaction2.load_flags |=
7559         LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7560     RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
7561 
7562     EXPECT_NE(std::string::npos, headers.find("Foo: bar\n"));
7563     EXPECT_EQ(2, cache.network_layer()->transaction_count());
7564     EXPECT_EQ(2, cache.disk_cache()->open_count());
7565     EXPECT_EQ(1, cache.disk_cache()->create_count());
7566   }
7567 }
7568 
7569 // Tests that a HEAD request invalidates an old cached entry.
TEST_F(HttpCacheTest,SimpleHEAD_InvalidatesEntry)7570 TEST_F(HttpCacheTest, SimpleHEAD_InvalidatesEntry) {
7571   MockHttpCache cache;
7572   ScopedMockTransaction transaction(kTypicalGET_Transaction);
7573 
7574   // Populate the cache.
7575   RunTransactionTest(cache.http_cache(), transaction);
7576 
7577   // Update the cache.
7578   transaction.method = "HEAD";
7579   transaction.data = "";
7580   RunTransactionTest(cache.http_cache(), transaction);
7581   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7582 
7583   // Load from the cache.
7584   transaction.method = "GET";
7585   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7586   transaction.start_return_code = ERR_CACHE_MISS;
7587   RunTransactionTest(cache.http_cache(), transaction);
7588 }
7589 
7590 // Tests that we do not cache the response of a PUT.
TEST_F(HttpCacheTest,SimplePUT_Miss)7591 TEST_F(HttpCacheTest, SimplePUT_Miss) {
7592   MockHttpCache cache;
7593 
7594   MockTransaction transaction(kSimplePOST_Transaction);
7595   transaction.method = "PUT";
7596 
7597   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7598   element_readers.push_back(
7599       std::make_unique<UploadBytesElementReader>("hello", 5));
7600   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7601 
7602   MockHttpRequest request(transaction);
7603   request.upload_data_stream = &upload_data_stream;
7604 
7605   // Attempt to populate the cache.
7606   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
7607                                 nullptr);
7608 
7609   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7610   EXPECT_EQ(0, cache.disk_cache()->open_count());
7611   EXPECT_EQ(0, cache.disk_cache()->create_count());
7612 }
7613 
7614 // Tests that we invalidate entries as a result of a PUT.
TEST_F(HttpCacheTest,SimplePUT_Invalidate)7615 TEST_F(HttpCacheTest, SimplePUT_Invalidate) {
7616   MockHttpCache cache;
7617 
7618   MockTransaction transaction(kSimpleGET_Transaction);
7619   MockHttpRequest req1(transaction);
7620 
7621   // Attempt to populate the cache.
7622   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7623 
7624   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7625   EXPECT_EQ(0, cache.disk_cache()->open_count());
7626   EXPECT_EQ(1, cache.disk_cache()->create_count());
7627 
7628   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7629   element_readers.push_back(
7630       std::make_unique<UploadBytesElementReader>("hello", 5));
7631   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7632 
7633   transaction.method = "PUT";
7634   MockHttpRequest req2(transaction);
7635   req2.upload_data_stream = &upload_data_stream;
7636 
7637   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7638 
7639   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7640   EXPECT_EQ(1, cache.disk_cache()->open_count());
7641   EXPECT_EQ(1, cache.disk_cache()->create_count());
7642 
7643   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7644 
7645   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7646   EXPECT_EQ(1, cache.disk_cache()->open_count());
7647   EXPECT_EQ(2, cache.disk_cache()->create_count());
7648 }
7649 
7650 // Tests that we invalidate entries as a result of a PUT.
TEST_F(HttpCacheTest,SimplePUT_Invalidate_305)7651 TEST_F(HttpCacheTest, SimplePUT_Invalidate_305) {
7652   MockHttpCache cache;
7653 
7654   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7655   MockHttpRequest req1(transaction);
7656 
7657   // Attempt to populate the cache.
7658   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7659 
7660   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7661   EXPECT_EQ(0, cache.disk_cache()->open_count());
7662   EXPECT_EQ(1, cache.disk_cache()->create_count());
7663 
7664   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7665   element_readers.push_back(
7666       std::make_unique<UploadBytesElementReader>("hello", 5));
7667   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7668 
7669   transaction.method = "PUT";
7670   transaction.status = "HTTP/1.1 305 Use Proxy";
7671   MockHttpRequest req2(transaction);
7672   req2.upload_data_stream = &upload_data_stream;
7673 
7674   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7675 
7676   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7677   EXPECT_EQ(1, cache.disk_cache()->open_count());
7678   EXPECT_EQ(1, cache.disk_cache()->create_count());
7679 
7680   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7681 
7682   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7683   EXPECT_EQ(1, cache.disk_cache()->open_count());
7684   EXPECT_EQ(2, cache.disk_cache()->create_count());
7685 }
7686 
7687 // Tests that we don't invalidate entries as a result of a failed PUT.
TEST_F(HttpCacheTest,SimplePUT_DontInvalidate_404)7688 TEST_F(HttpCacheTest, SimplePUT_DontInvalidate_404) {
7689   MockHttpCache cache;
7690 
7691   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7692   MockHttpRequest req1(transaction);
7693 
7694   // Attempt to populate the cache.
7695   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7696 
7697   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7698   EXPECT_EQ(0, cache.disk_cache()->open_count());
7699   EXPECT_EQ(1, cache.disk_cache()->create_count());
7700 
7701   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7702   element_readers.push_back(
7703       std::make_unique<UploadBytesElementReader>("hello", 5));
7704   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7705 
7706   transaction.method = "PUT";
7707   transaction.status = "HTTP/1.1 404 Not Found";
7708   MockHttpRequest req2(transaction);
7709   req2.upload_data_stream = &upload_data_stream;
7710 
7711   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7712 
7713   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7714   EXPECT_EQ(1, cache.disk_cache()->open_count());
7715   EXPECT_EQ(1, cache.disk_cache()->create_count());
7716 
7717   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7718 
7719   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7720   EXPECT_EQ(2, cache.disk_cache()->open_count());
7721   EXPECT_EQ(1, cache.disk_cache()->create_count());
7722 }
7723 
7724 // Tests that we do not cache the response of a DELETE.
TEST_F(HttpCacheTest,SimpleDELETE_Miss)7725 TEST_F(HttpCacheTest, SimpleDELETE_Miss) {
7726   MockHttpCache cache;
7727 
7728   MockTransaction transaction(kSimplePOST_Transaction);
7729   transaction.method = "DELETE";
7730 
7731   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7732   element_readers.push_back(
7733       std::make_unique<UploadBytesElementReader>("hello", 5));
7734   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7735 
7736   MockHttpRequest request(transaction);
7737   request.upload_data_stream = &upload_data_stream;
7738 
7739   // Attempt to populate the cache.
7740   RunTransactionTestWithRequest(cache.http_cache(), transaction, request,
7741                                 nullptr);
7742 
7743   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7744   EXPECT_EQ(0, cache.disk_cache()->open_count());
7745   EXPECT_EQ(0, cache.disk_cache()->create_count());
7746 }
7747 
7748 // Tests that we invalidate entries as a result of a DELETE.
TEST_F(HttpCacheTest,SimpleDELETE_Invalidate)7749 TEST_F(HttpCacheTest, SimpleDELETE_Invalidate) {
7750   MockHttpCache cache;
7751 
7752   MockTransaction transaction(kSimpleGET_Transaction);
7753   MockHttpRequest req1(transaction);
7754 
7755   // Attempt to populate the cache.
7756   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7757 
7758   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7759   EXPECT_EQ(0, cache.disk_cache()->open_count());
7760   EXPECT_EQ(1, cache.disk_cache()->create_count());
7761 
7762   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7763   element_readers.push_back(
7764       std::make_unique<UploadBytesElementReader>("hello", 5));
7765   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7766 
7767   transaction.method = "DELETE";
7768   MockHttpRequest req2(transaction);
7769   req2.upload_data_stream = &upload_data_stream;
7770 
7771   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7772 
7773   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7774   EXPECT_EQ(1, cache.disk_cache()->open_count());
7775   EXPECT_EQ(1, cache.disk_cache()->create_count());
7776 
7777   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7778 
7779   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7780   EXPECT_EQ(1, cache.disk_cache()->open_count());
7781   EXPECT_EQ(2, cache.disk_cache()->create_count());
7782 }
7783 
7784 // Tests that we invalidate entries as a result of a DELETE.
TEST_F(HttpCacheTest,SimpleDELETE_Invalidate_301)7785 TEST_F(HttpCacheTest, SimpleDELETE_Invalidate_301) {
7786   MockHttpCache cache;
7787 
7788   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7789 
7790   // Attempt to populate the cache.
7791   RunTransactionTest(cache.http_cache(), transaction);
7792 
7793   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7794   EXPECT_EQ(0, cache.disk_cache()->open_count());
7795   EXPECT_EQ(1, cache.disk_cache()->create_count());
7796 
7797   transaction.method = "DELETE";
7798   transaction.status = "HTTP/1.1 301 Moved Permanently ";
7799 
7800   RunTransactionTest(cache.http_cache(), transaction);
7801 
7802   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7803   EXPECT_EQ(1, cache.disk_cache()->open_count());
7804   EXPECT_EQ(1, cache.disk_cache()->create_count());
7805 
7806   transaction.method = "GET";
7807   RunTransactionTest(cache.http_cache(), transaction);
7808 
7809   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7810   EXPECT_EQ(1, cache.disk_cache()->open_count());
7811   EXPECT_EQ(2, cache.disk_cache()->create_count());
7812 }
7813 
7814 // Tests that we don't invalidate entries as a result of a failed DELETE.
TEST_F(HttpCacheTest,SimpleDELETE_DontInvalidate_416)7815 TEST_F(HttpCacheTest, SimpleDELETE_DontInvalidate_416) {
7816   MockHttpCache cache;
7817 
7818   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7819 
7820   // Attempt to populate the cache.
7821   RunTransactionTest(cache.http_cache(), transaction);
7822 
7823   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7824   EXPECT_EQ(0, cache.disk_cache()->open_count());
7825   EXPECT_EQ(1, cache.disk_cache()->create_count());
7826 
7827   transaction.method = "DELETE";
7828   transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
7829 
7830   RunTransactionTest(cache.http_cache(), transaction);
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   transaction.method = "GET";
7837   transaction.status = "HTTP/1.1 200 OK";
7838   RunTransactionTest(cache.http_cache(), transaction);
7839 
7840   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7841   EXPECT_EQ(2, cache.disk_cache()->open_count());
7842   EXPECT_EQ(1, cache.disk_cache()->create_count());
7843 }
7844 
7845 // Tests that we invalidate entries as a result of a PATCH.
TEST_F(HttpCacheTest,SimplePATCH_Invalidate)7846 TEST_F(HttpCacheTest, SimplePATCH_Invalidate) {
7847   MockHttpCache cache;
7848 
7849   MockTransaction transaction(kSimpleGET_Transaction);
7850   MockHttpRequest req1(transaction);
7851 
7852   // Attempt to populate the cache.
7853   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7854 
7855   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7856   EXPECT_EQ(0, cache.disk_cache()->open_count());
7857   EXPECT_EQ(1, cache.disk_cache()->create_count());
7858 
7859   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
7860   element_readers.push_back(
7861       std::make_unique<UploadBytesElementReader>("hello", 5));
7862   ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
7863 
7864   transaction.method = "PATCH";
7865   MockHttpRequest req2(transaction);
7866   req2.upload_data_stream = &upload_data_stream;
7867 
7868   RunTransactionTestWithRequest(cache.http_cache(), transaction, req2, nullptr);
7869 
7870   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7871   EXPECT_EQ(1, cache.disk_cache()->open_count());
7872   EXPECT_EQ(1, cache.disk_cache()->create_count());
7873 
7874   RunTransactionTestWithRequest(cache.http_cache(), transaction, req1, nullptr);
7875 
7876   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7877   EXPECT_EQ(1, cache.disk_cache()->open_count());
7878   EXPECT_EQ(2, cache.disk_cache()->create_count());
7879 }
7880 
7881 // Tests that we invalidate entries as a result of a PATCH.
TEST_F(HttpCacheTest,SimplePATCH_Invalidate_301)7882 TEST_F(HttpCacheTest, SimplePATCH_Invalidate_301) {
7883   MockHttpCache cache;
7884 
7885   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7886 
7887   // Attempt to populate the cache.
7888   RunTransactionTest(cache.http_cache(), transaction);
7889 
7890   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7891   EXPECT_EQ(0, cache.disk_cache()->open_count());
7892   EXPECT_EQ(1, cache.disk_cache()->create_count());
7893 
7894   transaction.method = "PATCH";
7895   transaction.status = "HTTP/1.1 301 Moved Permanently ";
7896 
7897   RunTransactionTest(cache.http_cache(), transaction);
7898 
7899   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7900   EXPECT_EQ(1, cache.disk_cache()->open_count());
7901   EXPECT_EQ(1, cache.disk_cache()->create_count());
7902 
7903   transaction.method = "GET";
7904   RunTransactionTest(cache.http_cache(), transaction);
7905 
7906   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7907   EXPECT_EQ(1, cache.disk_cache()->open_count());
7908   EXPECT_EQ(2, cache.disk_cache()->create_count());
7909 }
7910 
7911 // Tests that we don't invalidate entries as a result of a failed PATCH.
TEST_F(HttpCacheTest,SimplePATCH_DontInvalidate_416)7912 TEST_F(HttpCacheTest, SimplePATCH_DontInvalidate_416) {
7913   MockHttpCache cache;
7914 
7915   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7916 
7917   // Attempt to populate the cache.
7918   RunTransactionTest(cache.http_cache(), transaction);
7919 
7920   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7921   EXPECT_EQ(0, cache.disk_cache()->open_count());
7922   EXPECT_EQ(1, cache.disk_cache()->create_count());
7923 
7924   transaction.method = "PATCH";
7925   transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
7926 
7927   RunTransactionTest(cache.http_cache(), transaction);
7928 
7929   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7930   EXPECT_EQ(1, cache.disk_cache()->open_count());
7931   EXPECT_EQ(1, cache.disk_cache()->create_count());
7932 
7933   transaction.method = "GET";
7934   transaction.status = "HTTP/1.1 200 OK";
7935   RunTransactionTest(cache.http_cache(), transaction);
7936 
7937   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7938   EXPECT_EQ(2, cache.disk_cache()->open_count());
7939   EXPECT_EQ(1, cache.disk_cache()->create_count());
7940 }
7941 
7942 // Tests that we don't invalidate entries after a failed network transaction.
TEST_F(HttpCacheTest,SimpleGET_DontInvalidateOnFailure)7943 TEST_F(HttpCacheTest, SimpleGET_DontInvalidateOnFailure) {
7944   MockHttpCache cache;
7945 
7946   // Populate the cache.
7947   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
7948   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7949 
7950   // Fail the network request.
7951   ScopedMockTransaction transaction(kSimpleGET_Transaction);
7952   transaction.start_return_code = ERR_FAILED;
7953   transaction.load_flags |= LOAD_VALIDATE_CACHE;
7954 
7955   RunTransactionTest(cache.http_cache(), transaction);
7956   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7957 
7958   transaction.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
7959   transaction.start_return_code = OK;
7960   RunTransactionTest(cache.http_cache(), transaction);
7961 
7962   // Make sure the transaction didn't reach the network.
7963   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7964 }
7965 
TEST_F(HttpCacheTest,RangeGET_SkipsCache)7966 TEST_F(HttpCacheTest, RangeGET_SkipsCache) {
7967   MockHttpCache cache;
7968 
7969   // Test that we skip the cache for range GET requests.  Eventually, we will
7970   // want to cache these, but we'll still have cases where skipping the cache
7971   // makes sense, so we want to make sure that it works properly.
7972 
7973   RunTransactionTest(cache.http_cache(), kRangeGET_Transaction);
7974 
7975   EXPECT_EQ(1, cache.network_layer()->transaction_count());
7976   EXPECT_EQ(0, cache.disk_cache()->open_count());
7977   EXPECT_EQ(0, cache.disk_cache()->create_count());
7978 
7979   MockTransaction transaction(kSimpleGET_Transaction);
7980   transaction.request_headers = "If-None-Match: foo\r\n";
7981   RunTransactionTest(cache.http_cache(), transaction);
7982 
7983   EXPECT_EQ(2, cache.network_layer()->transaction_count());
7984   EXPECT_EQ(0, cache.disk_cache()->open_count());
7985   EXPECT_EQ(0, cache.disk_cache()->create_count());
7986 
7987   transaction.request_headers =
7988       "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n";
7989   RunTransactionTest(cache.http_cache(), transaction);
7990 
7991   EXPECT_EQ(3, cache.network_layer()->transaction_count());
7992   EXPECT_EQ(0, cache.disk_cache()->open_count());
7993   EXPECT_EQ(0, cache.disk_cache()->create_count());
7994 }
7995 
7996 // Test that we skip the cache for range requests that include a validation
7997 // header.
TEST_F(HttpCacheTest,RangeGET_SkipsCache2)7998 TEST_F(HttpCacheTest, RangeGET_SkipsCache2) {
7999   MockHttpCache cache;
8000 
8001   MockTransaction transaction(kRangeGET_Transaction);
8002   transaction.request_headers =
8003       "If-None-Match: foo\r\n" EXTRA_HEADER "Range: bytes = 40-49\r\n";
8004   RunTransactionTest(cache.http_cache(), transaction);
8005 
8006   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8007   EXPECT_EQ(0, cache.disk_cache()->open_count());
8008   EXPECT_EQ(0, cache.disk_cache()->create_count());
8009 
8010   transaction.request_headers =
8011       "If-Modified-Since: Wed, 28 Nov 2007 00:45:20 GMT\r\n" EXTRA_HEADER
8012       "Range: bytes = 40-49\r\n";
8013   RunTransactionTest(cache.http_cache(), transaction);
8014 
8015   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8016   EXPECT_EQ(0, cache.disk_cache()->open_count());
8017   EXPECT_EQ(0, cache.disk_cache()->create_count());
8018 
8019   transaction.request_headers =
8020       "If-Range: bla\r\n" EXTRA_HEADER "Range: bytes = 40-49\r\n";
8021   RunTransactionTest(cache.http_cache(), transaction);
8022 
8023   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8024   EXPECT_EQ(0, cache.disk_cache()->open_count());
8025   EXPECT_EQ(0, cache.disk_cache()->create_count());
8026 }
8027 
TEST_F(HttpCacheTest,SimpleGET_DoesntLogHeaders)8028 TEST_F(HttpCacheTest, SimpleGET_DoesntLogHeaders) {
8029   MockHttpCache cache;
8030 
8031   RecordingNetLogObserver net_log_observer;
8032   RunTransactionTestWithLog(cache.http_cache(), kSimpleGET_Transaction,
8033                             NetLogWithSource::Make(NetLogSourceType::NONE));
8034 
8035   EXPECT_FALSE(LogContainsEventType(
8036       net_log_observer, NetLogEventType::HTTP_CACHE_CALLER_REQUEST_HEADERS));
8037 }
8038 
TEST_F(HttpCacheTest,RangeGET_LogsHeaders)8039 TEST_F(HttpCacheTest, RangeGET_LogsHeaders) {
8040   MockHttpCache cache;
8041 
8042   RecordingNetLogObserver net_log_observer;
8043   RunTransactionTestWithLog(cache.http_cache(), kRangeGET_Transaction,
8044                             NetLogWithSource::Make(NetLogSourceType::NONE));
8045 
8046   EXPECT_TRUE(LogContainsEventType(
8047       net_log_observer, NetLogEventType::HTTP_CACHE_CALLER_REQUEST_HEADERS));
8048 }
8049 
TEST_F(HttpCacheTest,ExternalValidation_LogsHeaders)8050 TEST_F(HttpCacheTest, ExternalValidation_LogsHeaders) {
8051   MockHttpCache cache;
8052 
8053   RecordingNetLogObserver net_log_observer;
8054   MockTransaction transaction(kSimpleGET_Transaction);
8055   transaction.request_headers = "If-None-Match: foo\r\n" EXTRA_HEADER;
8056   RunTransactionTestWithLog(cache.http_cache(), transaction,
8057                             NetLogWithSource::Make(NetLogSourceType::NONE));
8058 
8059   EXPECT_TRUE(LogContainsEventType(
8060       net_log_observer, NetLogEventType::HTTP_CACHE_CALLER_REQUEST_HEADERS));
8061 }
8062 
TEST_F(HttpCacheTest,SpecialHeaders_LogsHeaders)8063 TEST_F(HttpCacheTest, SpecialHeaders_LogsHeaders) {
8064   MockHttpCache cache;
8065 
8066   RecordingNetLogObserver net_log_observer;
8067   MockTransaction transaction(kSimpleGET_Transaction);
8068   transaction.request_headers = "cache-control: no-cache\r\n" EXTRA_HEADER;
8069   RunTransactionTestWithLog(cache.http_cache(), transaction,
8070                             NetLogWithSource::Make(NetLogSourceType::NONE));
8071 
8072   EXPECT_TRUE(LogContainsEventType(
8073       net_log_observer, NetLogEventType::HTTP_CACHE_CALLER_REQUEST_HEADERS));
8074 }
8075 
8076 // Tests that receiving 206 for a regular request is handled correctly.
TEST_F(HttpCacheTest,GET_Crazy206)8077 TEST_F(HttpCacheTest, GET_Crazy206) {
8078   MockHttpCache cache;
8079 
8080   // Write to the cache.
8081   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8082   transaction.request_headers = EXTRA_HEADER;
8083   transaction.handler = MockTransactionHandler();
8084   RunTransactionTest(cache.http_cache(), transaction);
8085 
8086   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8087   EXPECT_EQ(0, cache.disk_cache()->open_count());
8088   EXPECT_EQ(1, cache.disk_cache()->create_count());
8089 
8090   // This should read again from the net.
8091   RunTransactionTest(cache.http_cache(), transaction);
8092 
8093   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8094   EXPECT_EQ(0, cache.disk_cache()->open_count());
8095   EXPECT_EQ(2, cache.disk_cache()->create_count());
8096 }
8097 
8098 // Tests that receiving 416 for a regular request is handled correctly.
TEST_F(HttpCacheTest,GET_Crazy416)8099 TEST_F(HttpCacheTest, GET_Crazy416) {
8100   MockHttpCache cache;
8101 
8102   // Write to the cache.
8103   ScopedMockTransaction transaction(kSimpleGET_Transaction);
8104   transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
8105   RunTransactionTest(cache.http_cache(), transaction);
8106 
8107   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8108   EXPECT_EQ(0, cache.disk_cache()->open_count());
8109   EXPECT_EQ(1, cache.disk_cache()->create_count());
8110 }
8111 
8112 // Tests that we don't store partial responses that can't be validated.
TEST_F(HttpCacheTest,RangeGET_NoStrongValidators)8113 TEST_F(HttpCacheTest, RangeGET_NoStrongValidators) {
8114   MockHttpCache cache;
8115   std::string headers;
8116 
8117   // Attempt to write to the cache (40-49).
8118   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8119   transaction.response_headers =
8120       "Content-Length: 10\n"
8121       "Cache-Control: max-age=3600\n"
8122       "ETag: w/\"foo\"\n";
8123   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8124 
8125   Verify206Response(headers, 40, 49);
8126   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8127   EXPECT_EQ(0, cache.disk_cache()->open_count());
8128   EXPECT_EQ(1, cache.disk_cache()->create_count());
8129 
8130   // Now verify that there's no cached data.
8131   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8132                                  &headers);
8133 
8134   Verify206Response(headers, 40, 49);
8135   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8136   EXPECT_EQ(0, cache.disk_cache()->open_count());
8137   EXPECT_EQ(2, cache.disk_cache()->create_count());
8138 }
8139 
8140 // Tests failures to conditionalize byte range requests.
TEST_F(HttpCacheTest,RangeGET_NoConditionalization)8141 TEST_F(HttpCacheTest, RangeGET_NoConditionalization) {
8142   MockHttpCache cache;
8143   cache.FailConditionalizations();
8144   std::string headers;
8145 
8146   // Write to the cache (40-49).
8147   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8148   transaction.response_headers =
8149       "Content-Length: 10\n"
8150       "ETag: \"foo\"\n";
8151   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8152 
8153   Verify206Response(headers, 40, 49);
8154   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8155   EXPECT_EQ(0, cache.disk_cache()->open_count());
8156   EXPECT_EQ(1, cache.disk_cache()->create_count());
8157 
8158   // Now verify that the cached data is not used.
8159   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8160                                  &headers);
8161 
8162   Verify206Response(headers, 40, 49);
8163   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8164   EXPECT_EQ(1, cache.disk_cache()->open_count());
8165   EXPECT_EQ(2, cache.disk_cache()->create_count());
8166 }
8167 
8168 // Tests that restarting a partial request when the cached data cannot be
8169 // revalidated logs an event.
TEST_F(HttpCacheTest,RangeGET_NoValidation_LogsRestart)8170 TEST_F(HttpCacheTest, RangeGET_NoValidation_LogsRestart) {
8171   MockHttpCache cache;
8172   cache.FailConditionalizations();
8173 
8174   // Write to the cache (40-49).
8175   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8176   transaction.response_headers =
8177       "Content-Length: 10\n"
8178       "ETag: \"foo\"\n";
8179   RunTransactionTest(cache.http_cache(), transaction);
8180 
8181   // Now verify that the cached data is not used.
8182   RecordingNetLogObserver net_log_observer;
8183   RunTransactionTestWithLog(cache.http_cache(), kRangeGET_TransactionOK,
8184                             NetLogWithSource::Make(NetLogSourceType::NONE));
8185 
8186   EXPECT_TRUE(LogContainsEventType(
8187       net_log_observer, NetLogEventType::HTTP_CACHE_RESTART_PARTIAL_REQUEST));
8188 }
8189 
8190 // Tests that a failure to conditionalize a regular request (no range) with a
8191 // sparse entry results in a full response.
TEST_F(HttpCacheTest,GET_NoConditionalization)8192 TEST_F(HttpCacheTest, GET_NoConditionalization) {
8193   for (bool use_memory_entry_data : {false, true}) {
8194     MockHttpCache cache;
8195     cache.disk_cache()->set_support_in_memory_entry_data(use_memory_entry_data);
8196     cache.FailConditionalizations();
8197     std::string headers;
8198 
8199     // Write to the cache (40-49).
8200     ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8201     transaction.response_headers =
8202         "Content-Length: 10\n"
8203         "ETag: \"foo\"\n";
8204     RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8205 
8206     Verify206Response(headers, 40, 49);
8207     EXPECT_EQ(1, cache.network_layer()->transaction_count());
8208     EXPECT_EQ(0, cache.disk_cache()->open_count());
8209     EXPECT_EQ(1, cache.disk_cache()->create_count());
8210 
8211     // Now verify that the cached data is not used.
8212     // Don't ask for a range. The cache will attempt to use the cached data but
8213     // should discard it as it cannot be validated. A regular request should go
8214     // to the server and a new entry should be created.
8215     transaction.request_headers = EXTRA_HEADER;
8216     transaction.data = "Not a range";
8217     RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8218 
8219     EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
8220     EXPECT_EQ(2, cache.network_layer()->transaction_count());
8221     EXPECT_EQ(1, cache.disk_cache()->open_count());
8222     EXPECT_EQ(2, cache.disk_cache()->create_count());
8223 
8224     // The last response was saved.
8225     RunTransactionTest(cache.http_cache(), transaction);
8226     EXPECT_EQ(3, cache.network_layer()->transaction_count());
8227     if (use_memory_entry_data) {
8228       // The cache entry isn't really useful, since when
8229       // &RangeTransactionServer::RangeHandler gets a non-range request,
8230       // (the network transaction #2) it returns headers without ETag,
8231       // Last-Modified or caching headers, with a Date in 2007 (so no heuristic
8232       // freshness), so it's both expired and not conditionalizable --- so in
8233       // this branch we avoid opening it.
8234       EXPECT_EQ(1, cache.disk_cache()->open_count());
8235       EXPECT_EQ(3, cache.disk_cache()->create_count());
8236     } else {
8237       EXPECT_EQ(2, cache.disk_cache()->open_count());
8238       EXPECT_EQ(2, cache.disk_cache()->create_count());
8239     }
8240   }
8241 }
8242 
8243 // Verifies that conditionalization failures when asking for a range that would
8244 // require the cache to modify the range to ask, result in a network request
8245 // that matches the user's one.
TEST_F(HttpCacheTest,RangeGET_NoConditionalization2)8246 TEST_F(HttpCacheTest, RangeGET_NoConditionalization2) {
8247   MockHttpCache cache;
8248   cache.FailConditionalizations();
8249   std::string headers;
8250 
8251   // Write to the cache (40-49).
8252   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8253   transaction.response_headers =
8254       "Content-Length: 10\n"
8255       "ETag: \"foo\"\n";
8256   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8257 
8258   Verify206Response(headers, 40, 49);
8259   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8260   EXPECT_EQ(0, cache.disk_cache()->open_count());
8261   EXPECT_EQ(1, cache.disk_cache()->create_count());
8262 
8263   // Now verify that the cached data is not used.
8264   // Ask for a range that extends before and after the cached data so that the
8265   // cache would normally mix data from three sources. After deleting the entry,
8266   // the response will come from a single network request.
8267   transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
8268   transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
8269   transaction.response_headers = kRangeGET_TransactionOK.response_headers;
8270   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8271 
8272   Verify206Response(headers, 20, 59);
8273   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8274   EXPECT_EQ(1, cache.disk_cache()->open_count());
8275   EXPECT_EQ(2, cache.disk_cache()->create_count());
8276 
8277   // The last response was saved.
8278   RunTransactionTest(cache.http_cache(), transaction);
8279   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8280   EXPECT_EQ(2, cache.disk_cache()->open_count());
8281   EXPECT_EQ(2, cache.disk_cache()->create_count());
8282 }
8283 
8284 // Tests that we cache partial responses that lack content-length.
TEST_F(HttpCacheTest,RangeGET_NoContentLength)8285 TEST_F(HttpCacheTest, RangeGET_NoContentLength) {
8286   MockHttpCache cache;
8287   std::string headers;
8288 
8289   // Attempt to write to the cache (40-49).
8290   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8291   transaction.response_headers =
8292       "ETag: \"foo\"\n"
8293       "Accept-Ranges: bytes\n"
8294       "Content-Range: bytes 40-49/80\n";
8295   transaction.handler = MockTransactionHandler();
8296   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8297 
8298   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8299   EXPECT_EQ(0, cache.disk_cache()->open_count());
8300   EXPECT_EQ(1, cache.disk_cache()->create_count());
8301 
8302   // Now verify that there's no cached data.
8303   transaction.handler =
8304       base::BindRepeating(&RangeTransactionServer::RangeHandler);
8305   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8306                                  &headers);
8307 
8308   Verify206Response(headers, 40, 49);
8309   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8310   EXPECT_EQ(1, cache.disk_cache()->open_count());
8311   EXPECT_EQ(1, cache.disk_cache()->create_count());
8312 }
8313 
8314 // Tests that we can cache range requests and fetch random blocks from the
8315 // cache and the network.
TEST_F(HttpCacheTest,RangeGET_OK)8316 TEST_F(HttpCacheTest, RangeGET_OK) {
8317   MockHttpCache cache;
8318   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
8319   std::string headers;
8320 
8321   // Write to the cache (40-49).
8322   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8323                                  &headers);
8324 
8325   Verify206Response(headers, 40, 49);
8326   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8327   EXPECT_EQ(0, cache.disk_cache()->open_count());
8328   EXPECT_EQ(1, cache.disk_cache()->create_count());
8329 
8330   // Read from the cache (40-49).
8331   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8332                                  &headers);
8333 
8334   Verify206Response(headers, 40, 49);
8335   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8336   EXPECT_EQ(1, cache.disk_cache()->open_count());
8337   EXPECT_EQ(1, cache.disk_cache()->create_count());
8338 
8339   // Make sure we are done with the previous transaction.
8340   base::RunLoop().RunUntilIdle();
8341 
8342   // Write to the cache (30-39).
8343   MockTransaction transaction(kRangeGET_TransactionOK);
8344   transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
8345   transaction.data = "rg: 30-39 ";
8346   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8347 
8348   Verify206Response(headers, 30, 39);
8349   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8350   EXPECT_EQ(2, cache.disk_cache()->open_count());
8351   EXPECT_EQ(1, cache.disk_cache()->create_count());
8352 
8353   // Make sure we are done with the previous transaction.
8354   base::RunLoop().RunUntilIdle();
8355 
8356   // Write and read from the cache (20-59).
8357   transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
8358   transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
8359   LoadTimingInfo load_timing_info;
8360   RunTransactionTestWithResponseAndGetTiming(
8361       cache.http_cache(), transaction, &headers,
8362       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info);
8363 
8364   Verify206Response(headers, 20, 59);
8365   EXPECT_EQ(4, cache.network_layer()->transaction_count());
8366   EXPECT_EQ(3, cache.disk_cache()->open_count());
8367   EXPECT_EQ(1, cache.disk_cache()->create_count());
8368   TestLoadTimingNetworkRequest(load_timing_info);
8369 }
8370 
TEST_F(HttpCacheTest,RangeGET_CacheReadError)8371 TEST_F(HttpCacheTest, RangeGET_CacheReadError) {
8372   // Tests recovery on cache read error on range request.
8373   MockHttpCache cache;
8374   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8375   std::string headers;
8376 
8377   // Write to the cache (40-49).
8378   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8379                                  &headers);
8380 
8381   Verify206Response(headers, 40, 49);
8382   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8383   EXPECT_EQ(0, cache.disk_cache()->open_count());
8384   EXPECT_EQ(1, cache.disk_cache()->create_count());
8385 
8386   cache.disk_cache()->set_soft_failures_one_instance(MockDiskEntry::FAIL_ALL);
8387 
8388   // Try to read from the cache (40-49), which will fail quickly enough to
8389   // restart, due to the failure injected above.  This should still be a range
8390   // request. (https://crbug.com/891212)
8391   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
8392                                  &headers);
8393 
8394   Verify206Response(headers, 40, 49);
8395   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8396   EXPECT_EQ(1, cache.disk_cache()->open_count());
8397   EXPECT_EQ(2, cache.disk_cache()->create_count());
8398 }
8399 
8400 // Tests that range requests with no-store get correct content-length
8401 // (https://crbug.com/700197).
TEST_F(HttpCacheTest,RangeGET_NoStore)8402 TEST_F(HttpCacheTest, RangeGET_NoStore) {
8403   MockHttpCache cache;
8404 
8405   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8406   std::string response_headers = base::StrCat(
8407       {kRangeGET_TransactionOK.response_headers, "Cache-Control: no-store\n"});
8408   transaction.response_headers = response_headers.c_str();
8409 
8410   std::string headers;
8411   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8412 
8413   Verify206Response(headers, 40, 49);
8414   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8415   EXPECT_EQ(0, cache.disk_cache()->open_count());
8416   EXPECT_EQ(1, cache.disk_cache()->create_count());
8417 }
8418 
8419 // Tests a 304 setting no-store on existing 206 entry.
TEST_F(HttpCacheTest,RangeGET_NoStore304)8420 TEST_F(HttpCacheTest, RangeGET_NoStore304) {
8421   MockHttpCache cache;
8422 
8423   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8424   std::string response_headers = base::StrCat(
8425       {kRangeGET_TransactionOK.response_headers, "Cache-Control: max-age=0\n"});
8426   transaction.response_headers = response_headers.c_str();
8427 
8428   std::string headers;
8429   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8430 
8431   Verify206Response(headers, 40, 49);
8432   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8433   EXPECT_EQ(0, cache.disk_cache()->open_count());
8434   EXPECT_EQ(1, cache.disk_cache()->create_count());
8435 
8436   response_headers = base::StrCat(
8437       {kRangeGET_TransactionOK.response_headers, "Cache-Control: no-store\n"});
8438   transaction.response_headers = response_headers.c_str();
8439   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8440   Verify206Response(headers, 40, 49);
8441 
8442   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8443   EXPECT_EQ(1, cache.disk_cache()->open_count());
8444   EXPECT_EQ(1, cache.disk_cache()->create_count());
8445 
8446   // Fetch again, this one should be from newly created cache entry, due to
8447   // earlier no-store.
8448   transaction.response_headers = kRangeGET_TransactionOK.response_headers;
8449   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8450   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8451   EXPECT_EQ(1, cache.disk_cache()->open_count());
8452   EXPECT_EQ(2, cache.disk_cache()->create_count());
8453   Verify206Response(headers, 40, 49);
8454 }
8455 
8456 // Tests that we can cache range requests and fetch random blocks from the
8457 // cache and the network, with synchronous responses.
TEST_F(HttpCacheTest,RangeGET_SyncOK)8458 TEST_F(HttpCacheTest, RangeGET_SyncOK) {
8459   MockHttpCache cache;
8460 
8461   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8462   transaction.test_mode = TEST_MODE_SYNC_ALL;
8463 
8464   // Write to the cache (40-49).
8465   std::string headers;
8466   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8467 
8468   Verify206Response(headers, 40, 49);
8469   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8470   EXPECT_EQ(0, cache.disk_cache()->open_count());
8471   EXPECT_EQ(1, cache.disk_cache()->create_count());
8472 
8473   // Read from the cache (40-49).
8474   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8475 
8476   Verify206Response(headers, 40, 49);
8477   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8478   EXPECT_EQ(0, cache.disk_cache()->open_count());
8479   EXPECT_EQ(1, cache.disk_cache()->create_count());
8480 
8481   // Make sure we are done with the previous transaction.
8482   base::RunLoop().RunUntilIdle();
8483 
8484   // Write to the cache (30-39).
8485   transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
8486   transaction.data = "rg: 30-39 ";
8487   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8488 
8489   Verify206Response(headers, 30, 39);
8490   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8491   EXPECT_EQ(1, cache.disk_cache()->open_count());
8492   EXPECT_EQ(1, cache.disk_cache()->create_count());
8493 
8494   // Make sure we are done with the previous transaction.
8495   base::RunLoop().RunUntilIdle();
8496 
8497   // Write and read from the cache (20-59).
8498   transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
8499   transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
8500   LoadTimingInfo load_timing_info;
8501   RunTransactionTestWithResponseAndGetTiming(
8502       cache.http_cache(), transaction, &headers,
8503       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info);
8504 
8505   Verify206Response(headers, 20, 59);
8506   EXPECT_EQ(4, cache.network_layer()->transaction_count());
8507   EXPECT_EQ(2, cache.disk_cache()->open_count());
8508   EXPECT_EQ(1, cache.disk_cache()->create_count());
8509   TestLoadTimingNetworkRequest(load_timing_info);
8510 }
8511 
8512 // Tests that if the previous transaction is cancelled while busy (doing sparse
8513 // IO), a new transaction (that reuses that same ActiveEntry) waits until the
8514 // entry is ready again.
TEST_F(HttpCacheTest,Sparse_WaitForEntry)8515 TEST_F(HttpCacheTest, Sparse_WaitForEntry) {
8516   MockHttpCache cache;
8517 
8518   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8519 
8520   // Create a sparse entry.
8521   RunTransactionTest(cache.http_cache(), transaction);
8522 
8523   // Simulate a previous transaction being cancelled.
8524   disk_cache::Entry* entry;
8525   MockHttpRequest request(transaction);
8526   std::string cache_key =
8527       *cache.http_cache()->GenerateCacheKeyForRequest(&request);
8528   ASSERT_TRUE(cache.OpenBackendEntry(cache_key, &entry));
8529   entry->CancelSparseIO();
8530 
8531   // Test with a range request.
8532   RunTransactionTest(cache.http_cache(), transaction);
8533 
8534   // Now test with a regular request.
8535   entry->CancelSparseIO();
8536   transaction.request_headers = EXTRA_HEADER;
8537   transaction.data = kFullRangeData;
8538   RunTransactionTest(cache.http_cache(), transaction);
8539 
8540   entry->Close();
8541 }
8542 
8543 // Tests that we don't revalidate an entry unless we are required to do so.
TEST_F(HttpCacheTest,RangeGET_Revalidate1)8544 TEST_F(HttpCacheTest, RangeGET_Revalidate1) {
8545   MockHttpCache cache;
8546   std::string headers;
8547 
8548   // Write to the cache (40-49).
8549   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8550   transaction.response_headers =
8551       "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
8552       "Expires: Wed, 7 Sep 2033 21:46:42 GMT\n"  // Should never expire.
8553       "ETag: \"foo\"\n"
8554       "Accept-Ranges: bytes\n"
8555       "Content-Length: 10\n";
8556   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8557 
8558   Verify206Response(headers, 40, 49);
8559   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8560   EXPECT_EQ(0, cache.disk_cache()->open_count());
8561   EXPECT_EQ(1, cache.disk_cache()->create_count());
8562 
8563   // Read from the cache (40-49).
8564   NetLogWithSource net_log_with_source =
8565       NetLogWithSource::Make(NetLogSourceType::NONE);
8566   LoadTimingInfo load_timing_info;
8567   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
8568                                              &headers, net_log_with_source,
8569                                              &load_timing_info);
8570 
8571   Verify206Response(headers, 40, 49);
8572   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8573   EXPECT_EQ(1, cache.disk_cache()->open_count());
8574   EXPECT_EQ(1, cache.disk_cache()->create_count());
8575   TestLoadTimingCachedResponse(load_timing_info);
8576 
8577   // Read again forcing the revalidation.
8578   transaction.load_flags |= LOAD_VALIDATE_CACHE;
8579   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
8580                                              &headers, net_log_with_source,
8581                                              &load_timing_info);
8582 
8583   Verify206Response(headers, 40, 49);
8584   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8585   EXPECT_EQ(1, cache.disk_cache()->open_count());
8586   EXPECT_EQ(1, cache.disk_cache()->create_count());
8587   TestLoadTimingNetworkRequest(load_timing_info);
8588 }
8589 
8590 // Checks that we revalidate an entry when the headers say so.
TEST_F(HttpCacheTest,RangeGET_Revalidate2)8591 TEST_F(HttpCacheTest, RangeGET_Revalidate2) {
8592   MockHttpCache cache;
8593   std::string headers;
8594 
8595   // Write to the cache (40-49).
8596   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8597   transaction.response_headers =
8598       "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
8599       "Expires: Sat, 18 Apr 2009 01:10:43 GMT\n"  // Expired.
8600       "ETag: \"foo\"\n"
8601       "Accept-Ranges: bytes\n"
8602       "Content-Length: 10\n";
8603   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8604 
8605   Verify206Response(headers, 40, 49);
8606   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8607   EXPECT_EQ(0, cache.disk_cache()->open_count());
8608   EXPECT_EQ(1, cache.disk_cache()->create_count());
8609 
8610   // Read from the cache (40-49).
8611   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8612   Verify206Response(headers, 40, 49);
8613 
8614   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8615   EXPECT_EQ(1, cache.disk_cache()->open_count());
8616   EXPECT_EQ(1, cache.disk_cache()->create_count());
8617 }
8618 
8619 // Tests that we deal with 304s for range requests.
TEST_F(HttpCacheTest,RangeGET_304)8620 TEST_F(HttpCacheTest, RangeGET_304) {
8621   MockHttpCache cache;
8622   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
8623   std::string headers;
8624 
8625   // Write to the cache (40-49).
8626   RunTransactionTestWithResponse(cache.http_cache(), scoped_transaction,
8627                                  &headers);
8628 
8629   Verify206Response(headers, 40, 49);
8630   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8631   EXPECT_EQ(0, cache.disk_cache()->open_count());
8632   EXPECT_EQ(1, cache.disk_cache()->create_count());
8633 
8634   // Read from the cache (40-49).
8635   RangeTransactionServer handler;
8636   handler.set_not_modified(true);
8637   MockTransaction transaction(kRangeGET_TransactionOK);
8638   transaction.load_flags |= LOAD_VALIDATE_CACHE;
8639   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8640 
8641   Verify206Response(headers, 40, 49);
8642   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8643   EXPECT_EQ(1, cache.disk_cache()->open_count());
8644   EXPECT_EQ(1, cache.disk_cache()->create_count());
8645 }
8646 
8647 // Tests that we deal with 206s when revalidating range requests.
TEST_F(HttpCacheTest,RangeGET_ModifiedResult)8648 TEST_F(HttpCacheTest, RangeGET_ModifiedResult) {
8649   MockHttpCache cache;
8650   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
8651   std::string headers;
8652 
8653   // Write to the cache (40-49).
8654   RunTransactionTestWithResponse(cache.http_cache(), scoped_transaction,
8655                                  &headers);
8656 
8657   Verify206Response(headers, 40, 49);
8658   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8659   EXPECT_EQ(0, cache.disk_cache()->open_count());
8660   EXPECT_EQ(1, cache.disk_cache()->create_count());
8661 
8662   // Attempt to read from the cache (40-49).
8663   RangeTransactionServer handler;
8664   handler.set_modified(true);
8665   MockTransaction transaction(kRangeGET_TransactionOK);
8666   transaction.load_flags |= LOAD_VALIDATE_CACHE;
8667   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8668 
8669   Verify206Response(headers, 40, 49);
8670   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8671   EXPECT_EQ(1, cache.disk_cache()->open_count());
8672   EXPECT_EQ(1, cache.disk_cache()->create_count());
8673 
8674   // And the entry should be gone.
8675   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
8676   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8677   EXPECT_EQ(1, cache.disk_cache()->open_count());
8678   EXPECT_EQ(2, cache.disk_cache()->create_count());
8679 }
8680 
8681 // Tests that when a server returns 206 with a sub-range of the requested range,
8682 // and there is nothing stored in the cache, the returned response is passed to
8683 // the caller as is. In this context, a subrange means a response that starts
8684 // with the same byte that was requested, but that is not the whole range that
8685 // was requested.
TEST_F(HttpCacheTest,RangeGET_206ReturnsSubrangeRange_NoCachedContent)8686 TEST_F(HttpCacheTest, RangeGET_206ReturnsSubrangeRange_NoCachedContent) {
8687   MockHttpCache cache;
8688   std::string headers;
8689 
8690   // Request a large range (40-59). The server sends 40-49.
8691   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8692   transaction.request_headers = "Range: bytes = 40-59\r\n" EXTRA_HEADER;
8693   transaction.response_headers =
8694       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
8695       "ETag: \"foo\"\n"
8696       "Accept-Ranges: bytes\n"
8697       "Content-Length: 10\n"
8698       "Content-Range: bytes 40-49/80\n";
8699   transaction.handler = MockTransactionHandler();
8700   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8701 
8702   Verify206Response(headers, 40, 49);
8703   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8704   EXPECT_EQ(0, cache.disk_cache()->open_count());
8705   EXPECT_EQ(1, cache.disk_cache()->create_count());
8706 }
8707 
8708 // Tests that when a server returns 206 with a sub-range of the requested range,
8709 // and there was an entry stored in the cache, the cache gets out of the way.
TEST_F(HttpCacheTest,RangeGET_206ReturnsSubrangeRange_CachedContent)8710 TEST_F(HttpCacheTest, RangeGET_206ReturnsSubrangeRange_CachedContent) {
8711   MockHttpCache cache;
8712   std::string headers;
8713 
8714   // Write to the cache (70-79).
8715   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8716   transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
8717   transaction.data = "rg: 70-79 ";
8718   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8719   Verify206Response(headers, 70, 79);
8720 
8721   // Request a large range (40-79). The cache will ask the server for 40-59.
8722   // The server returns 40-49. The cache should consider the server confused and
8723   // abort caching, restarting the request without caching.
8724   transaction.request_headers = "Range: bytes = 40-79\r\n" EXTRA_HEADER;
8725   transaction.response_headers =
8726       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
8727       "ETag: \"foo\"\n"
8728       "Accept-Ranges: bytes\n"
8729       "Content-Length: 10\n"
8730       "Content-Range: bytes 40-49/80\n";
8731   transaction.handler = MockTransactionHandler();
8732   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8733 
8734   // Two new network requests were issued, one from the cache and another after
8735   // deleting the entry.
8736   Verify206Response(headers, 40, 49);
8737   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8738   EXPECT_EQ(1, cache.disk_cache()->open_count());
8739   EXPECT_EQ(1, cache.disk_cache()->create_count());
8740 
8741   // The entry was deleted.
8742   RunTransactionTest(cache.http_cache(), transaction);
8743   EXPECT_EQ(4, cache.network_layer()->transaction_count());
8744   EXPECT_EQ(1, cache.disk_cache()->open_count());
8745   EXPECT_EQ(2, cache.disk_cache()->create_count());
8746 }
8747 
8748 // Tests that when a server returns 206 with a sub-range of the requested range,
8749 // and there was an entry stored in the cache, the cache gets out of the way,
8750 // when the caller is not using ranges.
TEST_F(HttpCacheTest,GET_206ReturnsSubrangeRange_CachedContent)8751 TEST_F(HttpCacheTest, GET_206ReturnsSubrangeRange_CachedContent) {
8752   MockHttpCache cache;
8753   std::string headers;
8754 
8755   // Write to the cache (70-79).
8756   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8757   transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
8758   transaction.data = "rg: 70-79 ";
8759   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8760   Verify206Response(headers, 70, 79);
8761 
8762   // Don't ask for a range. The cache will ask the server for 0-69.
8763   // The server returns 40-49. The cache should consider the server confused and
8764   // abort caching, restarting the request.
8765   // The second network request should not be a byte range request so the server
8766   // should return 200 + "Not a range"
8767   transaction.request_headers = "X-Return-Default-Range:\r\n" EXTRA_HEADER;
8768   transaction.data = "Not a range";
8769   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8770 
8771   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
8772   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8773   EXPECT_EQ(1, cache.disk_cache()->open_count());
8774   EXPECT_EQ(1, cache.disk_cache()->create_count());
8775 
8776   // The entry was deleted.
8777   RunTransactionTest(cache.http_cache(), transaction);
8778   EXPECT_EQ(4, cache.network_layer()->transaction_count());
8779   EXPECT_EQ(1, cache.disk_cache()->open_count());
8780   EXPECT_EQ(2, cache.disk_cache()->create_count());
8781 }
8782 
8783 // Tests that when a server returns 206 with a random range and there is
8784 // nothing stored in the cache, the returned response is passed to the caller
8785 // as is. In this context, a WrongRange means that the returned range may or may
8786 // not have any relationship with the requested range (may or may not be
8787 // contained). The important part is that the first byte doesn't match the first
8788 // requested byte.
TEST_F(HttpCacheTest,RangeGET_206ReturnsWrongRange_NoCachedContent)8789 TEST_F(HttpCacheTest, RangeGET_206ReturnsWrongRange_NoCachedContent) {
8790   MockHttpCache cache;
8791   std::string headers;
8792 
8793   // Request a large range (30-59). The server sends (40-49).
8794   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8795   transaction.request_headers = "Range: bytes = 30-59\r\n" EXTRA_HEADER;
8796   transaction.response_headers =
8797       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
8798       "ETag: \"foo\"\n"
8799       "Accept-Ranges: bytes\n"
8800       "Content-Length: 10\n"
8801       "Content-Range: bytes 40-49/80\n";
8802   transaction.handler = MockTransactionHandler();
8803   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8804 
8805   Verify206Response(headers, 40, 49);
8806   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8807   EXPECT_EQ(0, cache.disk_cache()->open_count());
8808   EXPECT_EQ(1, cache.disk_cache()->create_count());
8809 
8810   // The entry was deleted.
8811   RunTransactionTest(cache.http_cache(), transaction);
8812   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8813   EXPECT_EQ(0, cache.disk_cache()->open_count());
8814   EXPECT_EQ(2, cache.disk_cache()->create_count());
8815 }
8816 
8817 // Tests that when a server returns 206 with a random range and there is
8818 // an entry stored in the cache, the cache gets out of the way.
TEST_F(HttpCacheTest,RangeGET_206ReturnsWrongRange_CachedContent)8819 TEST_F(HttpCacheTest, RangeGET_206ReturnsWrongRange_CachedContent) {
8820   MockHttpCache cache;
8821   std::string headers;
8822 
8823   // Write to the cache (70-79).
8824   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8825   transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
8826   transaction.data = "rg: 70-79 ";
8827   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8828   Verify206Response(headers, 70, 79);
8829 
8830   // Request a large range (30-79). The cache will ask the server for 30-69.
8831   // The server returns 40-49. The cache should consider the server confused and
8832   // abort caching, returning the weird range to the caller.
8833   transaction.request_headers = "Range: bytes = 30-79\r\n" EXTRA_HEADER;
8834   transaction.response_headers =
8835       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
8836       "ETag: \"foo\"\n"
8837       "Accept-Ranges: bytes\n"
8838       "Content-Length: 10\n"
8839       "Content-Range: bytes 40-49/80\n";
8840   transaction.handler = MockTransactionHandler();
8841   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8842 
8843   Verify206Response(headers, 40, 49);
8844   EXPECT_EQ(3, cache.network_layer()->transaction_count());
8845   EXPECT_EQ(1, cache.disk_cache()->open_count());
8846   EXPECT_EQ(1, cache.disk_cache()->create_count());
8847 
8848   // The entry was deleted.
8849   RunTransactionTest(cache.http_cache(), transaction);
8850   EXPECT_EQ(4, cache.network_layer()->transaction_count());
8851   EXPECT_EQ(1, cache.disk_cache()->open_count());
8852   EXPECT_EQ(2, cache.disk_cache()->create_count());
8853 }
8854 
8855 // Tests that when a caller asks for a range beyond EOF, with an empty cache,
8856 // the response matches the one provided by the server.
TEST_F(HttpCacheTest,RangeGET_206ReturnsSmallerFile_NoCachedContent)8857 TEST_F(HttpCacheTest, RangeGET_206ReturnsSmallerFile_NoCachedContent) {
8858   MockHttpCache cache;
8859   std::string headers;
8860 
8861   // Request a large range (70-99). The server sends 70-79.
8862   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8863   transaction.request_headers = "Range: bytes = 70-99\r\n" EXTRA_HEADER;
8864   transaction.data = "rg: 70-79 ";
8865   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8866 
8867   Verify206Response(headers, 70, 79);
8868   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8869   EXPECT_EQ(0, cache.disk_cache()->open_count());
8870   EXPECT_EQ(1, cache.disk_cache()->create_count());
8871 
8872   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
8873   EXPECT_EQ(1, cache.disk_cache()->open_count());
8874 }
8875 
8876 // Tests that when a caller asks for a range beyond EOF, with a cached entry,
8877 // the cache automatically fixes the request.
TEST_F(HttpCacheTest,RangeGET_206ReturnsSmallerFile_CachedContent)8878 TEST_F(HttpCacheTest, RangeGET_206ReturnsSmallerFile_CachedContent) {
8879   MockHttpCache cache;
8880   std::string headers;
8881 
8882   // Write to the cache (40-49).
8883   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8884   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8885 
8886   // Request a large range (70-99). The server sends 70-79.
8887   transaction.request_headers = "Range: bytes = 70-99\r\n" EXTRA_HEADER;
8888   transaction.data = "rg: 70-79 ";
8889   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8890 
8891   Verify206Response(headers, 70, 79);
8892   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8893   EXPECT_EQ(1, cache.disk_cache()->open_count());
8894   EXPECT_EQ(1, cache.disk_cache()->create_count());
8895 
8896   // The entry was not deleted (the range was automatically fixed).
8897   RunTransactionTest(cache.http_cache(), transaction);
8898   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8899   EXPECT_EQ(2, cache.disk_cache()->open_count());
8900   EXPECT_EQ(1, cache.disk_cache()->create_count());
8901 }
8902 
8903 // Tests that when a caller asks for a not-satisfiable range, the server's
8904 // response is forwarded to the caller.
TEST_F(HttpCacheTest,RangeGET_416_NoCachedContent)8905 TEST_F(HttpCacheTest, RangeGET_416_NoCachedContent) {
8906   MockHttpCache cache;
8907   std::string headers;
8908 
8909   // Request a range beyond EOF (80-99).
8910   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8911   transaction.request_headers = "Range: bytes = 80-99\r\n" EXTRA_HEADER;
8912   transaction.data = "";
8913   transaction.status = "HTTP/1.1 416 Requested Range Not Satisfiable";
8914   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8915 
8916   EXPECT_EQ(0U, headers.find(transaction.status));
8917   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8918   EXPECT_EQ(0, cache.disk_cache()->open_count());
8919   EXPECT_EQ(1, cache.disk_cache()->create_count());
8920 
8921   // The entry was deleted.
8922   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
8923   EXPECT_EQ(2, cache.disk_cache()->create_count());
8924 }
8925 
8926 // Tests that we cache 301s for range requests.
TEST_F(HttpCacheTest,RangeGET_301)8927 TEST_F(HttpCacheTest, RangeGET_301) {
8928   MockHttpCache cache;
8929   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8930   transaction.status = "HTTP/1.1 301 Moved Permanently";
8931   transaction.response_headers = "Location: http://www.bar.com/\n";
8932   transaction.data = "";
8933   transaction.handler = MockTransactionHandler();
8934 
8935   // Write to the cache.
8936   RunTransactionTest(cache.http_cache(), transaction);
8937   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8938   EXPECT_EQ(0, cache.disk_cache()->open_count());
8939   EXPECT_EQ(1, cache.disk_cache()->create_count());
8940 
8941   // Read from the cache.
8942   RunTransactionTest(cache.http_cache(), transaction);
8943   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8944   EXPECT_EQ(1, cache.disk_cache()->open_count());
8945   EXPECT_EQ(1, cache.disk_cache()->create_count());
8946 }
8947 
8948 // Tests that we can cache range requests when the start or end is unknown.
8949 // We start with one suffix request, followed by a request from a given point.
TEST_F(HttpCacheTest,UnknownRangeGET_1)8950 TEST_F(HttpCacheTest, UnknownRangeGET_1) {
8951   MockHttpCache cache;
8952   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
8953   std::string headers;
8954 
8955   // Write to the cache (70-79).
8956   MockTransaction transaction(kRangeGET_TransactionOK);
8957   transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
8958   transaction.data = "rg: 70-79 ";
8959   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8960 
8961   Verify206Response(headers, 70, 79);
8962   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8963   EXPECT_EQ(0, cache.disk_cache()->open_count());
8964   EXPECT_EQ(1, cache.disk_cache()->create_count());
8965 
8966   // Make sure we are done with the previous transaction.
8967   base::RunLoop().RunUntilIdle();
8968 
8969   // Write and read from the cache (60-79).
8970   transaction.request_headers = "Range: bytes = 60-\r\n" EXTRA_HEADER;
8971   transaction.data = "rg: 60-69 rg: 70-79 ";
8972   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8973 
8974   Verify206Response(headers, 60, 79);
8975   EXPECT_EQ(2, cache.network_layer()->transaction_count());
8976   EXPECT_EQ(1, cache.disk_cache()->open_count());
8977   EXPECT_EQ(1, cache.disk_cache()->create_count());
8978 }
8979 
8980 // Tests that we can cache range requests when the start or end is unknown.
8981 // We start with one request from a given point, followed by a suffix request.
8982 // We'll also verify that synchronous cache responses work as intended.
TEST_F(HttpCacheTest,UnknownRangeGET_2)8983 TEST_F(HttpCacheTest, UnknownRangeGET_2) {
8984   MockHttpCache cache;
8985   std::string headers;
8986 
8987   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
8988   transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
8989                           TEST_MODE_SYNC_CACHE_READ |
8990                           TEST_MODE_SYNC_CACHE_WRITE;
8991 
8992   // Write to the cache (70-79).
8993   transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
8994   transaction.data = "rg: 70-79 ";
8995   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
8996 
8997   Verify206Response(headers, 70, 79);
8998   EXPECT_EQ(1, cache.network_layer()->transaction_count());
8999   EXPECT_EQ(0, cache.disk_cache()->open_count());
9000   EXPECT_EQ(1, cache.disk_cache()->create_count());
9001 
9002   // Make sure we are done with the previous transaction.
9003   base::RunLoop().RunUntilIdle();
9004 
9005   // Write and read from the cache (60-79).
9006   transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
9007   transaction.data = "rg: 60-69 rg: 70-79 ";
9008   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9009 
9010   Verify206Response(headers, 60, 79);
9011   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9012   EXPECT_EQ(1, cache.disk_cache()->open_count());
9013   EXPECT_EQ(1, cache.disk_cache()->create_count());
9014 }
9015 
9016 // Similar to UnknownRangeGET_2, except that the resource size is empty.
9017 // Regression test for crbug.com/813061, and probably https://crbug.com/1375128
TEST_F(HttpCacheTest,UnknownRangeGET_3)9018 TEST_F(HttpCacheTest, UnknownRangeGET_3) {
9019   MockHttpCache cache;
9020   std::string headers;
9021 
9022   ScopedMockTransaction transaction(kSimpleGET_Transaction);
9023   transaction.response_headers =
9024       "Cache-Control: max-age=10000\n"
9025       "Content-Length: 0\n",
9026   transaction.data = "";
9027   transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
9028                           TEST_MODE_SYNC_CACHE_READ |
9029                           TEST_MODE_SYNC_CACHE_WRITE;
9030 
9031   // Write the empty resource to the cache.
9032   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9033 
9034   EXPECT_EQ(
9035       "HTTP/1.1 200 OK\nCache-Control: max-age=10000\nContent-Length: 0\n",
9036       headers);
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   // Make sure we are done with the previous transaction.
9042   base::RunLoop().RunUntilIdle();
9043 
9044   // Write and read from the cache. This used to trigger a DCHECK
9045   // (or loop infinitely with it off).
9046   transaction.request_headers = "Range: bytes = -20\r\n" EXTRA_HEADER;
9047   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9048 
9049   EXPECT_EQ(
9050       "HTTP/1.1 200 OK\nCache-Control: max-age=10000\nContent-Length: 0\n",
9051       headers);
9052   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9053   EXPECT_EQ(1, cache.disk_cache()->open_count());
9054   EXPECT_EQ(1, cache.disk_cache()->create_count());
9055 }
9056 
9057 // Testcase for https://crbug.com/1433305, validation of range request to a
9058 // cache 302, which is notably bodiless.
TEST_F(HttpCacheTest,UnknownRangeGET_302)9059 TEST_F(HttpCacheTest, UnknownRangeGET_302) {
9060   MockHttpCache cache;
9061   std::string headers;
9062 
9063   ScopedMockTransaction transaction(kSimpleGET_Transaction);
9064   transaction.status = "HTTP/1.1 302 Found";
9065   transaction.response_headers =
9066       "Cache-Control: max-age=0\n"
9067       "Content-Length: 0\n"
9068       "Location: https://example.org/\n",
9069 
9070   transaction.data = "";
9071   transaction.request_headers = "Range: bytes = 0-\r\n" EXTRA_HEADER;
9072   transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
9073                           TEST_MODE_SYNC_CACHE_READ |
9074                           TEST_MODE_SYNC_CACHE_WRITE;
9075 
9076   // Write the empty resource to the cache.
9077   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9078 
9079   EXPECT_EQ(
9080       "HTTP/1.1 302 Found\n"
9081       "Cache-Control: max-age=0\n"
9082       "Content-Length: 0\n"
9083       "Location: https://example.org/\n",
9084       headers);
9085   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9086   EXPECT_EQ(0, cache.disk_cache()->open_count());
9087   EXPECT_EQ(1, cache.disk_cache()->create_count());
9088 
9089   // Make sure we are done with the previous transaction.
9090   base::RunLoop().RunUntilIdle();
9091 
9092   // Try to read from the cache. This should send a network request to
9093   // validate it, and get a different redirect.
9094   transaction.response_headers =
9095       "Cache-Control: max-age=0\n"
9096       "Content-Length: 0\n"
9097       "Location: https://example.com/\n",
9098   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9099 
9100   EXPECT_EQ(
9101       "HTTP/1.1 302 Found\n"
9102       "Cache-Control: max-age=0\n"
9103       "Content-Length: 0\n"
9104       "Location: https://example.com/\n",
9105       headers);
9106   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9107   EXPECT_EQ(1, cache.disk_cache()->open_count());
9108   // A new entry is created since this one isn't conditionalizable.
9109   EXPECT_EQ(2, cache.disk_cache()->create_count());
9110 }
9111 
9112 // Testcase for https://crbug.com/1433305, validation of range request to a
9113 // cache 302, which is notably bodiless, where the 302 is replaced with an
9114 // actual body.
TEST_F(HttpCacheTest,UnknownRangeGET_302_Replaced)9115 TEST_F(HttpCacheTest, UnknownRangeGET_302_Replaced) {
9116   MockHttpCache cache;
9117   std::string headers;
9118 
9119   ScopedMockTransaction transaction(kSimpleGET_Transaction);
9120   transaction.status = "HTTP/1.1 302 Found";
9121   transaction.response_headers =
9122       "Cache-Control: max-age=0\n"
9123       "Content-Length: 0\n"
9124       "Location: https://example.org/\n",
9125 
9126   transaction.data = "";
9127   transaction.test_mode = TEST_MODE_SYNC_CACHE_START |
9128                           TEST_MODE_SYNC_CACHE_READ |
9129                           TEST_MODE_SYNC_CACHE_WRITE;
9130 
9131   // Write the empty resource to the cache.
9132   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9133 
9134   EXPECT_EQ(
9135       "HTTP/1.1 302 Found\n"
9136       "Cache-Control: max-age=0\n"
9137       "Content-Length: 0\n"
9138       "Location: https://example.org/\n",
9139       headers);
9140   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9141   EXPECT_EQ(0, cache.disk_cache()->open_count());
9142   EXPECT_EQ(1, cache.disk_cache()->create_count());
9143 
9144   // Make sure we are done with the previous transaction.
9145   base::RunLoop().RunUntilIdle();
9146 
9147   // Try to read from the cache. This should send a network request to
9148   // validate it, and get a different response.
9149   transaction.handler =
9150       base::BindRepeating(&RangeTransactionServer::RangeHandler);
9151   transaction.request_headers = "Range: bytes = -30\r\n" EXTRA_HEADER;
9152   // Tail 30 bytes out of 80
9153   transaction.data = "rg: 50-59 rg: 60-69 rg: 70-79 ";
9154   transaction.status = "HTTP/1.1 206 Partial Content";
9155   transaction.response_headers = "Content-Length: 10\n";
9156   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9157 
9158   EXPECT_EQ(
9159       "HTTP/1.1 206 Partial Content\n"
9160       "Content-Range: bytes 50-79/80\n"
9161       "Content-Length: 30\n",
9162       headers);
9163   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9164   EXPECT_EQ(1, cache.disk_cache()->open_count());
9165   // A new entry is created since this one isn't conditionalizable.
9166   EXPECT_EQ(2, cache.disk_cache()->create_count());
9167 }
9168 
9169 // Tests that receiving Not Modified when asking for an open range doesn't mess
9170 // up things.
TEST_F(HttpCacheTest,UnknownRangeGET_304)9171 TEST_F(HttpCacheTest, UnknownRangeGET_304) {
9172   MockHttpCache cache;
9173   std::string headers;
9174 
9175   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9176 
9177   RangeTransactionServer handler;
9178   handler.set_not_modified(true);
9179 
9180   // Ask for the end of the file, without knowing the length.
9181   transaction.request_headers = "Range: bytes = 70-\r\n" EXTRA_HEADER;
9182   transaction.data = "";
9183   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9184 
9185   // We just bypass the cache.
9186   EXPECT_EQ(0U, headers.find("HTTP/1.1 304 Not Modified\n"));
9187   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9188   EXPECT_EQ(0, cache.disk_cache()->open_count());
9189   EXPECT_EQ(1, cache.disk_cache()->create_count());
9190 
9191   RunTransactionTest(cache.http_cache(), transaction);
9192   EXPECT_EQ(2, cache.disk_cache()->create_count());
9193 }
9194 
9195 // Tests that we can handle non-range requests when we have cached a range.
TEST_F(HttpCacheTest,GET_Previous206)9196 TEST_F(HttpCacheTest, GET_Previous206) {
9197   MockHttpCache cache;
9198   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
9199   std::string headers;
9200   NetLogWithSource net_log_with_source =
9201       NetLogWithSource::Make(NetLogSourceType::NONE);
9202   LoadTimingInfo load_timing_info;
9203 
9204   // Write to the cache (40-49).
9205   RunTransactionTestWithResponseAndGetTiming(
9206       cache.http_cache(), kRangeGET_TransactionOK, &headers,
9207       net_log_with_source, &load_timing_info);
9208 
9209   Verify206Response(headers, 40, 49);
9210   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9211   EXPECT_EQ(0, cache.disk_cache()->open_count());
9212   EXPECT_EQ(1, cache.disk_cache()->create_count());
9213   TestLoadTimingNetworkRequest(load_timing_info);
9214 
9215   // Write and read from the cache (0-79), when not asked for a range.
9216   MockTransaction transaction(kRangeGET_TransactionOK);
9217   transaction.request_headers = EXTRA_HEADER;
9218   transaction.data = kFullRangeData;
9219   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
9220                                              &headers, net_log_with_source,
9221                                              &load_timing_info);
9222 
9223   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
9224   EXPECT_EQ(3, cache.network_layer()->transaction_count());
9225   EXPECT_EQ(1, cache.disk_cache()->open_count());
9226   EXPECT_EQ(1, cache.disk_cache()->create_count());
9227   TestLoadTimingNetworkRequest(load_timing_info);
9228 }
9229 
9230 // Tests that we can handle non-range requests when we have cached the first
9231 // part of the object and the server replies with 304 (Not Modified).
TEST_F(HttpCacheTest,GET_Previous206_NotModified)9232 TEST_F(HttpCacheTest, GET_Previous206_NotModified) {
9233   MockHttpCache cache;
9234 
9235   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9236   std::string headers;
9237   NetLogWithSource net_log_with_source =
9238       NetLogWithSource::Make(NetLogSourceType::NONE);
9239 
9240   LoadTimingInfo load_timing_info;
9241 
9242   // Write to the cache (0-9).
9243   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
9244   transaction.data = "rg: 00-09 ";
9245   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
9246                                              &headers, net_log_with_source,
9247                                              &load_timing_info);
9248   Verify206Response(headers, 0, 9);
9249   TestLoadTimingNetworkRequest(load_timing_info);
9250 
9251   // Write to the cache (70-79).
9252   transaction.request_headers = "Range: bytes = 70-79\r\n" EXTRA_HEADER;
9253   transaction.data = "rg: 70-79 ";
9254   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
9255                                              &headers, net_log_with_source,
9256                                              &load_timing_info);
9257   Verify206Response(headers, 70, 79);
9258 
9259   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9260   EXPECT_EQ(1, cache.disk_cache()->open_count());
9261   EXPECT_EQ(1, cache.disk_cache()->create_count());
9262   TestLoadTimingNetworkRequest(load_timing_info);
9263 
9264   // Read from the cache (0-9), write and read from cache (10 - 79).
9265   transaction.load_flags |= LOAD_VALIDATE_CACHE;
9266   transaction.request_headers = "Foo: bar\r\n" EXTRA_HEADER;
9267   transaction.data = kFullRangeData;
9268   RunTransactionTestWithResponseAndGetTiming(cache.http_cache(), transaction,
9269                                              &headers, net_log_with_source,
9270                                              &load_timing_info);
9271 
9272   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
9273   EXPECT_EQ(4, cache.network_layer()->transaction_count());
9274   EXPECT_EQ(2, cache.disk_cache()->open_count());
9275   EXPECT_EQ(1, cache.disk_cache()->create_count());
9276   TestLoadTimingNetworkRequest(load_timing_info);
9277 }
9278 
9279 // Tests that we can handle a regular request to a sparse entry, that results in
9280 // new content provided by the server (206).
TEST_F(HttpCacheTest,GET_Previous206_NewContent)9281 TEST_F(HttpCacheTest, GET_Previous206_NewContent) {
9282   MockHttpCache cache;
9283   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
9284   std::string headers;
9285 
9286   // Write to the cache (0-9).
9287   MockTransaction transaction(kRangeGET_TransactionOK);
9288   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
9289   transaction.data = "rg: 00-09 ";
9290   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9291 
9292   Verify206Response(headers, 0, 9);
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   // Now we'll issue a request without any range that should result first in a
9298   // 206 (when revalidating), and then in a weird standard answer: the test
9299   // server will not modify the response so we'll get the default range... a
9300   // real server will answer with 200.
9301   MockTransaction transaction2(kRangeGET_TransactionOK);
9302   transaction2.request_headers = EXTRA_HEADER;
9303   transaction2.load_flags |= LOAD_VALIDATE_CACHE;
9304   transaction2.data = "Not a range";
9305   RangeTransactionServer handler;
9306   handler.set_modified(true);
9307   LoadTimingInfo load_timing_info;
9308   RunTransactionTestWithResponseAndGetTiming(
9309       cache.http_cache(), transaction2, &headers,
9310       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info);
9311 
9312   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n"));
9313   EXPECT_EQ(3, cache.network_layer()->transaction_count());
9314   EXPECT_EQ(1, cache.disk_cache()->open_count());
9315   EXPECT_EQ(1, cache.disk_cache()->create_count());
9316   TestLoadTimingNetworkRequest(load_timing_info);
9317 
9318   // Verify that the previous request deleted the entry.
9319   RunTransactionTest(cache.http_cache(), transaction);
9320   EXPECT_EQ(2, cache.disk_cache()->create_count());
9321 }
9322 
9323 // Tests that we can handle cached 206 responses that are not sparse.
TEST_F(HttpCacheTest,GET_Previous206_NotSparse)9324 TEST_F(HttpCacheTest, GET_Previous206_NotSparse) {
9325   MockHttpCache cache;
9326 
9327   MockHttpRequest request(kSimpleGET_Transaction);
9328   // Create a disk cache entry that stores 206 headers while not being sparse.
9329   disk_cache::Entry* entry;
9330   ASSERT_TRUE(cache.CreateBackendEntry(request.CacheKey(), &entry, nullptr));
9331 
9332   std::string raw_headers(kRangeGET_TransactionOK.status);
9333   raw_headers.append("\n");
9334   raw_headers.append(kRangeGET_TransactionOK.response_headers);
9335 
9336   HttpResponseInfo response;
9337   response.headers = base::MakeRefCounted<HttpResponseHeaders>(
9338       HttpUtil::AssembleRawHeaders(raw_headers));
9339   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
9340 
9341   auto buf(base::MakeRefCounted<IOBufferWithSize>(500));
9342   int len = static_cast<int>(
9343       base::strlcpy(buf->data(), kRangeGET_TransactionOK.data, 500));
9344   TestCompletionCallback cb;
9345   int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
9346   EXPECT_EQ(len, cb.GetResult(rv));
9347   entry->Close();
9348 
9349   // Now see that we don't use the stored entry.
9350   std::string headers;
9351   LoadTimingInfo load_timing_info;
9352   RunTransactionTestWithResponseAndGetTiming(
9353       cache.http_cache(), kSimpleGET_Transaction, &headers,
9354       NetLogWithSource::Make(NetLogSourceType::NONE), &load_timing_info);
9355 
9356   // We are expecting a 200.
9357   std::string expected_headers(kSimpleGET_Transaction.status);
9358   expected_headers.append("\n");
9359   expected_headers.append(kSimpleGET_Transaction.response_headers);
9360   EXPECT_EQ(expected_headers, headers);
9361   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9362   EXPECT_EQ(1, cache.disk_cache()->open_count());
9363   EXPECT_EQ(2, cache.disk_cache()->create_count());
9364   TestLoadTimingNetworkRequest(load_timing_info);
9365 }
9366 
9367 // Tests that we can handle cached 206 responses that are not sparse. This time
9368 // we issue a range request and expect to receive a range.
TEST_F(HttpCacheTest,RangeGET_Previous206_NotSparse_2)9369 TEST_F(HttpCacheTest, RangeGET_Previous206_NotSparse_2) {
9370   MockHttpCache cache;
9371   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
9372 
9373   // Create a disk cache entry that stores 206 headers while not being sparse.
9374   MockHttpRequest request(kRangeGET_TransactionOK);
9375   disk_cache::Entry* entry;
9376   ASSERT_TRUE(cache.CreateBackendEntry(request.CacheKey(), &entry, nullptr));
9377 
9378   std::string raw_headers(kRangeGET_TransactionOK.status);
9379   raw_headers.append("\n");
9380   raw_headers.append(kRangeGET_TransactionOK.response_headers);
9381 
9382   HttpResponseInfo response;
9383   response.headers = base::MakeRefCounted<HttpResponseHeaders>(
9384       HttpUtil::AssembleRawHeaders(raw_headers));
9385   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
9386 
9387   auto buf = base::MakeRefCounted<IOBufferWithSize>(500);
9388   int len = static_cast<int>(
9389       base::strlcpy(buf->data(), kRangeGET_TransactionOK.data, 500));
9390   TestCompletionCallback cb;
9391   int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
9392   EXPECT_EQ(len, cb.GetResult(rv));
9393   entry->Close();
9394 
9395   // Now see that we don't use the stored entry.
9396   std::string headers;
9397   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
9398                                  &headers);
9399 
9400   // We are expecting a 206.
9401   Verify206Response(headers, 40, 49);
9402   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9403   EXPECT_EQ(1, cache.disk_cache()->open_count());
9404   EXPECT_EQ(2, cache.disk_cache()->create_count());
9405 }
9406 
9407 // Tests that we can handle cached 206 responses that can't be validated.
TEST_F(HttpCacheTest,GET_Previous206_NotValidation)9408 TEST_F(HttpCacheTest, GET_Previous206_NotValidation) {
9409   MockHttpCache cache;
9410 
9411   MockHttpRequest request(kSimpleGET_Transaction);
9412   // Create a disk cache entry that stores 206 headers.
9413   disk_cache::Entry* entry;
9414   ASSERT_TRUE(cache.CreateBackendEntry(request.CacheKey(), &entry, nullptr));
9415 
9416   // Make sure that the headers cannot be validated with the server.
9417   std::string raw_headers(kRangeGET_TransactionOK.status);
9418   raw_headers.append("\n");
9419   raw_headers.append("Content-Length: 80\n");
9420 
9421   HttpResponseInfo response;
9422   response.headers = base::MakeRefCounted<HttpResponseHeaders>(
9423       HttpUtil::AssembleRawHeaders(raw_headers));
9424   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
9425 
9426   auto buf = base::MakeRefCounted<IOBufferWithSize>(500);
9427   int len = static_cast<int>(
9428       base::strlcpy(buf->data(), kRangeGET_TransactionOK.data, 500));
9429   TestCompletionCallback cb;
9430   int rv = entry->WriteData(1, 0, buf.get(), len, cb.callback(), true);
9431   EXPECT_EQ(len, cb.GetResult(rv));
9432   entry->Close();
9433 
9434   // Now see that we don't use the stored entry.
9435   std::string headers;
9436   RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction,
9437                                  &headers);
9438 
9439   // We are expecting a 200.
9440   std::string expected_headers(kSimpleGET_Transaction.status);
9441   expected_headers.append("\n");
9442   expected_headers.append(kSimpleGET_Transaction.response_headers);
9443   EXPECT_EQ(expected_headers, headers);
9444   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9445   EXPECT_EQ(1, cache.disk_cache()->open_count());
9446   EXPECT_EQ(2, cache.disk_cache()->create_count());
9447 }
9448 
9449 // Tests that we can handle range requests with cached 200 responses.
TEST_F(HttpCacheTest,RangeGET_Previous200)9450 TEST_F(HttpCacheTest, RangeGET_Previous200) {
9451   MockHttpCache cache;
9452 
9453   {
9454     // Store the whole thing with status 200.
9455     ScopedMockTransaction transaction(kTypicalGET_Transaction,
9456                                       kRangeGET_TransactionOK.url);
9457     transaction.data = kFullRangeData;
9458     RunTransactionTest(cache.http_cache(), transaction);
9459     EXPECT_EQ(1, cache.network_layer()->transaction_count());
9460     EXPECT_EQ(0, cache.disk_cache()->open_count());
9461     EXPECT_EQ(1, cache.disk_cache()->create_count());
9462   }
9463 
9464   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
9465   // Now see that we use the stored entry.
9466   std::string headers;
9467   MockTransaction transaction2(kRangeGET_TransactionOK);
9468   RangeTransactionServer handler;
9469   handler.set_not_modified(true);
9470   RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
9471 
9472   // We are expecting a 206.
9473   Verify206Response(headers, 40, 49);
9474   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9475   EXPECT_EQ(1, cache.disk_cache()->open_count());
9476   EXPECT_EQ(1, cache.disk_cache()->create_count());
9477 
9478   // The last transaction has finished so make sure the entry is deactivated.
9479   base::RunLoop().RunUntilIdle();
9480 
9481   // Make a request for an invalid range.
9482   MockTransaction transaction3(kRangeGET_TransactionOK);
9483   transaction3.request_headers = "Range: bytes = 80-90\r\n" EXTRA_HEADER;
9484   transaction3.data = kFullRangeData;
9485   transaction3.load_flags = LOAD_SKIP_CACHE_VALIDATION;
9486   RunTransactionTestWithResponse(cache.http_cache(), transaction3, &headers);
9487   EXPECT_EQ(2, cache.disk_cache()->open_count());
9488   EXPECT_EQ(0U, headers.find("HTTP/1.1 200 "));
9489   EXPECT_EQ(std::string::npos, headers.find("Content-Range:"));
9490   EXPECT_EQ(std::string::npos, headers.find("Content-Length: 80"));
9491 
9492   // Make sure the entry is deactivated.
9493   base::RunLoop().RunUntilIdle();
9494 
9495   // Even though the request was invalid, we should have the entry.
9496   RunTransactionTest(cache.http_cache(), transaction2);
9497   EXPECT_EQ(3, cache.disk_cache()->open_count());
9498 
9499   // Make sure the entry is deactivated.
9500   base::RunLoop().RunUntilIdle();
9501 
9502   // Now we should receive a range from the server and drop the stored entry.
9503   handler.set_not_modified(false);
9504   transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
9505   RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
9506   Verify206Response(headers, 40, 49);
9507   EXPECT_EQ(4, cache.network_layer()->transaction_count());
9508   EXPECT_EQ(4, cache.disk_cache()->open_count());
9509   EXPECT_EQ(1, cache.disk_cache()->create_count());
9510 
9511   RunTransactionTest(cache.http_cache(), transaction2);
9512   EXPECT_EQ(2, cache.disk_cache()->create_count());
9513 }
9514 
9515 // Tests that we can handle a 200 response when dealing with sparse entries.
TEST_F(HttpCacheTest,RangeRequestResultsIn200)9516 TEST_F(HttpCacheTest, RangeRequestResultsIn200) {
9517   MockHttpCache cache;
9518   std::string headers;
9519 
9520   {
9521     ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9522     // Write to the cache (70-79).
9523     transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
9524     transaction.data = "rg: 70-79 ";
9525     RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9526 
9527     Verify206Response(headers, 70, 79);
9528     EXPECT_EQ(1, cache.network_layer()->transaction_count());
9529     EXPECT_EQ(0, cache.disk_cache()->open_count());
9530     EXPECT_EQ(1, cache.disk_cache()->create_count());
9531   }
9532   // Now we'll issue a request that results in a plain 200 response, but to
9533   // the to the same URL that we used to store sparse data, and making sure
9534   // that we ask for a range.
9535   ScopedMockTransaction transaction2(kSimpleGET_Transaction,
9536                                      kRangeGET_TransactionOK.url);
9537   transaction2.request_headers = kRangeGET_TransactionOK.request_headers;
9538 
9539   RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers);
9540 
9541   std::string expected_headers(kSimpleGET_Transaction.status);
9542   expected_headers.append("\n");
9543   expected_headers.append(kSimpleGET_Transaction.response_headers);
9544   EXPECT_EQ(expected_headers, headers);
9545   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9546   EXPECT_EQ(1, cache.disk_cache()->open_count());
9547   EXPECT_EQ(1, cache.disk_cache()->create_count());
9548 }
9549 
9550 // Tests that a range request that falls outside of the size that we know about
9551 // only deletes the entry if the resource has indeed changed.
TEST_F(HttpCacheTest,RangeGET_MoreThanCurrentSize)9552 TEST_F(HttpCacheTest, RangeGET_MoreThanCurrentSize) {
9553   MockHttpCache cache;
9554   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
9555   std::string headers;
9556 
9557   // Write to the cache (40-49).
9558   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
9559                                  &headers);
9560 
9561   Verify206Response(headers, 40, 49);
9562   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9563   EXPECT_EQ(0, cache.disk_cache()->open_count());
9564   EXPECT_EQ(1, cache.disk_cache()->create_count());
9565 
9566   // A weird request should not delete this entry. Ask for bytes 120-.
9567   MockTransaction transaction(kRangeGET_TransactionOK);
9568   transaction.request_headers = "Range: bytes = 120-\r\n" EXTRA_HEADER;
9569   transaction.data = "";
9570   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9571 
9572   EXPECT_EQ(0U, headers.find("HTTP/1.1 416 "));
9573   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9574   EXPECT_EQ(1, cache.disk_cache()->open_count());
9575   EXPECT_EQ(1, cache.disk_cache()->create_count());
9576 
9577   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9578   EXPECT_EQ(2, cache.disk_cache()->open_count());
9579   EXPECT_EQ(1, cache.disk_cache()->create_count());
9580 }
9581 
9582 // Tests that we don't delete a sparse entry when we cancel a request.
TEST_F(HttpCacheTest,RangeGET_Cancel)9583 TEST_F(HttpCacheTest, RangeGET_Cancel) {
9584   MockHttpCache cache;
9585   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
9586 
9587   MockHttpRequest request(kRangeGET_TransactionOK);
9588 
9589   auto c = std::make_unique<Context>();
9590   int rv = cache.CreateTransaction(&c->trans);
9591   ASSERT_THAT(rv, IsOk());
9592 
9593   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
9594   if (rv == ERR_IO_PENDING) {
9595     rv = c->callback.WaitForResult();
9596   }
9597 
9598   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9599   EXPECT_EQ(0, cache.disk_cache()->open_count());
9600   EXPECT_EQ(1, cache.disk_cache()->create_count());
9601 
9602   // Make sure that the entry has some data stored.
9603   scoped_refptr<IOBufferWithSize> buf =
9604       base::MakeRefCounted<IOBufferWithSize>(10);
9605   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
9606   if (rv == ERR_IO_PENDING) {
9607     rv = c->callback.WaitForResult();
9608   }
9609   EXPECT_EQ(buf->size(), rv);
9610 
9611   // Destroy the transaction.
9612   c.reset();
9613 
9614   // Verify that the entry has not been deleted.
9615   disk_cache::Entry* entry;
9616   ASSERT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &entry));
9617   entry->Close();
9618 }
9619 
9620 // Tests that we don't mark an entry as truncated if it is partial and not
9621 // already truncated.
TEST_F(HttpCacheTest,RangeGET_CancelWhileReading)9622 TEST_F(HttpCacheTest, RangeGET_CancelWhileReading) {
9623   MockHttpCache cache;
9624   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
9625 
9626   MockHttpRequest request(kRangeGET_TransactionOK);
9627 
9628   auto context = std::make_unique<Context>();
9629   int rv = cache.CreateTransaction(&context->trans);
9630   ASSERT_THAT(rv, IsOk());
9631 
9632   rv = context->trans->Start(&request, context->callback.callback(),
9633                              NetLogWithSource());
9634   if (rv == ERR_IO_PENDING) {
9635     rv = context->callback.WaitForResult();
9636   }
9637 
9638   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9639   EXPECT_EQ(0, cache.disk_cache()->open_count());
9640   EXPECT_EQ(1, cache.disk_cache()->create_count());
9641 
9642   // Start Read.
9643   scoped_refptr<IOBufferWithSize> buf =
9644       base::MakeRefCounted<IOBufferWithSize>(5);
9645   rv = context->trans->Read(buf.get(), buf->size(),
9646                             context->callback.callback());
9647   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9648 
9649   // Destroy the transaction.
9650   context.reset();
9651 
9652   // Complete Read.
9653   base::RunLoop().RunUntilIdle();
9654 
9655   // Verify that the entry has not been marked as truncated.
9656   VerifyTruncatedFlag(&cache, request.CacheKey(), false, 0);
9657 }
9658 
9659 // Tests that we don't delete a sparse entry when we start a new request after
9660 // cancelling the previous one.
TEST_F(HttpCacheTest,RangeGET_Cancel2)9661 TEST_F(HttpCacheTest, RangeGET_Cancel2) {
9662   MockHttpCache cache;
9663   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
9664 
9665   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9666   MockHttpRequest request(kRangeGET_TransactionOK);
9667   request.load_flags |= LOAD_VALIDATE_CACHE;
9668 
9669   auto c = std::make_unique<Context>();
9670   int rv = cache.CreateTransaction(&c->trans);
9671   ASSERT_THAT(rv, IsOk());
9672 
9673   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
9674   if (rv == ERR_IO_PENDING) {
9675     rv = c->callback.WaitForResult();
9676   }
9677 
9678   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9679   EXPECT_EQ(1, cache.disk_cache()->open_count());
9680   EXPECT_EQ(1, cache.disk_cache()->create_count());
9681 
9682   // Make sure that we revalidate the entry and read from the cache (a single
9683   // read will return while waiting for the network).
9684   scoped_refptr<IOBufferWithSize> buf =
9685       base::MakeRefCounted<IOBufferWithSize>(5);
9686   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
9687   EXPECT_EQ(5, c->callback.GetResult(rv));
9688   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
9689   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9690 
9691   // Destroy the transaction before completing the read.
9692   c.reset();
9693 
9694   // We have the read and the delete (OnProcessPendingQueue) waiting on the
9695   // message loop. This means that a new transaction will just reuse the same
9696   // active entry (no open or create).
9697 
9698   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9699 
9700   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9701   EXPECT_EQ(1, cache.disk_cache()->open_count());
9702   EXPECT_EQ(1, cache.disk_cache()->create_count());
9703 }
9704 
9705 // A slight variation of the previous test, this time we cancel two requests in
9706 // a row, making sure that the second is waiting for the entry to be ready.
TEST_F(HttpCacheTest,RangeGET_Cancel3)9707 TEST_F(HttpCacheTest, RangeGET_Cancel3) {
9708   MockHttpCache cache;
9709   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
9710 
9711   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9712   MockHttpRequest request(kRangeGET_TransactionOK);
9713   request.load_flags |= LOAD_VALIDATE_CACHE;
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   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9721   rv = c->callback.WaitForResult();
9722 
9723   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9724   EXPECT_EQ(1, cache.disk_cache()->open_count());
9725   EXPECT_EQ(1, cache.disk_cache()->create_count());
9726 
9727   // Make sure that we revalidate the entry and read from the cache (a single
9728   // read will return while waiting for the network).
9729   scoped_refptr<IOBufferWithSize> buf =
9730       base::MakeRefCounted<IOBufferWithSize>(5);
9731   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
9732   EXPECT_EQ(5, c->callback.GetResult(rv));
9733   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
9734   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9735 
9736   // Destroy the previous transaction before completing the read.
9737   c.reset();
9738 
9739   // We have the read and the delete (OnProcessPendingQueue) waiting on the
9740   // message loop. This means that a new transaction will just reuse the same
9741   // active entry (no open or create).
9742 
9743   c = std::make_unique<Context>();
9744   rv = cache.CreateTransaction(&c->trans);
9745   ASSERT_THAT(rv, IsOk());
9746 
9747   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
9748   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9749 
9750   MockDiskEntry::IgnoreCallbacks(true);
9751   base::RunLoop().RunUntilIdle();
9752   MockDiskEntry::IgnoreCallbacks(false);
9753 
9754   // The new transaction is waiting for the query range callback.
9755   c.reset();
9756 
9757   // And we should not crash when the callback is delivered.
9758   base::RunLoop().RunUntilIdle();
9759 
9760   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9761   EXPECT_EQ(1, cache.disk_cache()->open_count());
9762   EXPECT_EQ(1, cache.disk_cache()->create_count());
9763 }
9764 
9765 // Tests that an invalid range response results in no cached entry.
TEST_F(HttpCacheTest,RangeGET_InvalidResponse1)9766 TEST_F(HttpCacheTest, RangeGET_InvalidResponse1) {
9767   MockHttpCache cache;
9768   std::string headers;
9769 
9770   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9771   transaction.handler = MockTransactionHandler();
9772   transaction.response_headers =
9773       "Content-Range: bytes 40-49/45\n"
9774       "Content-Length: 10\n";
9775   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9776 
9777   std::string expected(transaction.status);
9778   expected.append("\n");
9779   expected.append(transaction.response_headers);
9780   EXPECT_EQ(expected, headers);
9781 
9782   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9783   EXPECT_EQ(0, cache.disk_cache()->open_count());
9784   EXPECT_EQ(1, cache.disk_cache()->create_count());
9785 
9786   // Verify that we don't have a cached entry.
9787   disk_cache::Entry* entry;
9788   MockHttpRequest request(transaction);
9789   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
9790 }
9791 
9792 // Tests that we reject a range that doesn't match the content-length.
TEST_F(HttpCacheTest,RangeGET_InvalidResponse2)9793 TEST_F(HttpCacheTest, RangeGET_InvalidResponse2) {
9794   MockHttpCache cache;
9795   std::string headers;
9796 
9797   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9798   transaction.handler = MockTransactionHandler();
9799   transaction.response_headers =
9800       "Content-Range: bytes 40-49/80\n"
9801       "Content-Length: 20\n";
9802   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9803 
9804   std::string expected(transaction.status);
9805   expected.append("\n");
9806   expected.append(transaction.response_headers);
9807   EXPECT_EQ(expected, headers);
9808 
9809   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9810   EXPECT_EQ(0, cache.disk_cache()->open_count());
9811   EXPECT_EQ(1, cache.disk_cache()->create_count());
9812 
9813   // Verify that we don't have a cached entry.
9814   disk_cache::Entry* entry;
9815   MockHttpRequest request(transaction);
9816   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
9817 }
9818 
9819 // Tests that if a server tells us conflicting information about a resource we
9820 // drop the entry.
TEST_F(HttpCacheTest,RangeGET_InvalidResponse3)9821 TEST_F(HttpCacheTest, RangeGET_InvalidResponse3) {
9822   MockHttpCache cache;
9823   std::string headers;
9824   {
9825     ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9826     transaction.handler = MockTransactionHandler();
9827     transaction.request_headers = "Range: bytes = 50-59\r\n" EXTRA_HEADER;
9828     std::string response_headers(transaction.response_headers);
9829     response_headers.append("Content-Range: bytes 50-59/160\n");
9830     transaction.response_headers = response_headers.c_str();
9831     RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9832 
9833     Verify206Response(headers, 50, 59);
9834     EXPECT_EQ(1, cache.network_layer()->transaction_count());
9835     EXPECT_EQ(0, cache.disk_cache()->open_count());
9836     EXPECT_EQ(1, cache.disk_cache()->create_count());
9837   }
9838   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9839 
9840   // This transaction will report a resource size of 80 bytes, and we think it's
9841   // 160 so we should ignore the response.
9842   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
9843                                  &headers);
9844 
9845   Verify206Response(headers, 40, 49);
9846   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9847   EXPECT_EQ(1, cache.disk_cache()->open_count());
9848   EXPECT_EQ(1, cache.disk_cache()->create_count());
9849 
9850   // Verify that the entry is gone.
9851   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9852   EXPECT_EQ(1, cache.disk_cache()->open_count());
9853   EXPECT_EQ(2, cache.disk_cache()->create_count());
9854 }
9855 
9856 // Tests that we handle large range values properly.
TEST_F(HttpCacheTest,RangeGET_LargeValues)9857 TEST_F(HttpCacheTest, RangeGET_LargeValues) {
9858   // We need a real sparse cache for this test.
9859   MockHttpCache cache(HttpCache::DefaultBackend::InMemory(1024 * 1024));
9860   std::string headers;
9861 
9862   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9863   transaction.handler = MockTransactionHandler();
9864   transaction.request_headers =
9865       "Range: bytes = 4294967288-4294967297\r\n" EXTRA_HEADER;
9866   transaction.response_headers =
9867       "ETag: \"foo\"\n"
9868       "Content-Range: bytes 4294967288-4294967297/4294967299\n"
9869       "Content-Length: 10\n";
9870   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9871 
9872   std::string expected(transaction.status);
9873   expected.append("\n");
9874   expected.append(transaction.response_headers);
9875   EXPECT_EQ(expected, headers);
9876 
9877   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9878 
9879   // Verify that we have a cached entry.
9880   disk_cache::Entry* en;
9881   MockHttpRequest request(transaction);
9882   ASSERT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &en));
9883   en->Close();
9884 }
9885 
9886 // Tests that we don't crash with a range request if the disk cache was not
9887 // initialized properly.
TEST_F(HttpCacheTest,RangeGET_NoDiskCache)9888 TEST_F(HttpCacheTest, RangeGET_NoDiskCache) {
9889   auto factory = std::make_unique<MockBlockingBackendFactory>();
9890   factory->set_fail(true);
9891   factory->FinishCreation();  // We'll complete synchronously.
9892   MockHttpCache cache(std::move(factory));
9893 
9894   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9895 
9896   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9897   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9898 }
9899 
9900 // Tests that we handle byte range requests that skip the cache.
TEST_F(HttpCacheTest,RangeHEAD)9901 TEST_F(HttpCacheTest, RangeHEAD) {
9902   MockHttpCache cache;
9903   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9904   transaction.request_headers = "Range: bytes = -10\r\n" EXTRA_HEADER;
9905   transaction.method = "HEAD";
9906   transaction.data = "rg: 70-79 ";
9907 
9908   std::string headers;
9909   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
9910 
9911   Verify206Response(headers, 70, 79);
9912   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9913   EXPECT_EQ(0, cache.disk_cache()->open_count());
9914   EXPECT_EQ(0, cache.disk_cache()->create_count());
9915 }
9916 
9917 // Tests that we don't crash when after reading from the cache we issue a
9918 // request for the next range and the server gives us a 200 synchronously.
TEST_F(HttpCacheTest,RangeGET_FastFlakyServer)9919 TEST_F(HttpCacheTest, RangeGET_FastFlakyServer) {
9920   MockHttpCache cache;
9921 
9922   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9923   transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER;
9924   transaction.test_mode = TEST_MODE_SYNC_NET_START;
9925   transaction.load_flags |= LOAD_VALIDATE_CACHE;
9926 
9927   // Write to the cache.
9928   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9929 
9930   // And now read from the cache and the network.
9931   RangeTransactionServer handler;
9932   handler.set_bad_200(true);
9933   transaction.data = "Not a range";
9934   RecordingNetLogObserver net_log_observer;
9935   RunTransactionTestWithLog(cache.http_cache(), transaction,
9936                             NetLogWithSource::Make(NetLogSourceType::NONE));
9937 
9938   EXPECT_EQ(3, cache.network_layer()->transaction_count());
9939   EXPECT_EQ(1, cache.disk_cache()->open_count());
9940   EXPECT_EQ(1, cache.disk_cache()->create_count());
9941   EXPECT_TRUE(LogContainsEventType(
9942       net_log_observer, NetLogEventType::HTTP_CACHE_RE_SEND_PARTIAL_REQUEST));
9943 }
9944 
9945 // Tests that when the server gives us less data than expected, we don't keep
9946 // asking for more data.
TEST_F(HttpCacheTest,RangeGET_FastFlakyServer2)9947 TEST_F(HttpCacheTest, RangeGET_FastFlakyServer2) {
9948   MockHttpCache cache;
9949 
9950   // First, check with an empty cache (WRITE mode).
9951   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9952   transaction.request_headers = "Range: bytes = 40-49\r\n" EXTRA_HEADER;
9953   transaction.data = "rg: 40-";  // Less than expected.
9954   transaction.handler = MockTransactionHandler();
9955   std::string headers(transaction.response_headers);
9956   headers.append("Content-Range: bytes 40-49/80\n");
9957   transaction.response_headers = headers.c_str();
9958 
9959   // Write to the cache.
9960   RunTransactionTest(cache.http_cache(), transaction);
9961 
9962   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9963   EXPECT_EQ(0, cache.disk_cache()->open_count());
9964   EXPECT_EQ(1, cache.disk_cache()->create_count());
9965 
9966   // Now verify that even in READ_WRITE mode, we forward the bad response to
9967   // the caller.
9968   transaction.request_headers = "Range: bytes = 60-69\r\n" EXTRA_HEADER;
9969   transaction.data = "rg: 60-";  // Less than expected.
9970   headers = kRangeGET_TransactionOK.response_headers;
9971   headers.append("Content-Range: bytes 60-69/80\n");
9972   transaction.response_headers = headers.c_str();
9973 
9974   RunTransactionTest(cache.http_cache(), transaction);
9975 
9976   EXPECT_EQ(2, cache.network_layer()->transaction_count());
9977   EXPECT_EQ(1, cache.disk_cache()->open_count());
9978   EXPECT_EQ(1, cache.disk_cache()->create_count());
9979 }
9980 
TEST_F(HttpCacheTest,RangeGET_OK_LoadOnlyFromCache)9981 TEST_F(HttpCacheTest, RangeGET_OK_LoadOnlyFromCache) {
9982   MockHttpCache cache;
9983   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
9984 
9985   // Write to the cache (40-49).
9986   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
9987   EXPECT_EQ(1, cache.network_layer()->transaction_count());
9988   EXPECT_EQ(0, cache.disk_cache()->open_count());
9989   EXPECT_EQ(1, cache.disk_cache()->create_count());
9990 
9991   // Force this transaction to read from the cache.
9992   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
9993 
9994   MockHttpRequest request(transaction);
9995   TestCompletionCallback callback;
9996 
9997   std::unique_ptr<HttpTransaction> trans;
9998   int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
9999   EXPECT_THAT(rv, IsOk());
10000   ASSERT_TRUE(trans.get());
10001 
10002   rv = trans->Start(&request, callback.callback(), NetLogWithSource());
10003   if (rv == ERR_IO_PENDING) {
10004     rv = callback.WaitForResult();
10005   }
10006   ASSERT_THAT(rv, IsError(ERR_CACHE_MISS));
10007 
10008   trans.reset();
10009 
10010   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10011   EXPECT_EQ(1, cache.disk_cache()->open_count());
10012   EXPECT_EQ(1, cache.disk_cache()->create_count());
10013 }
10014 
10015 // Tests the handling of the "truncation" flag.
TEST_F(HttpCacheTest,WriteResponseInfo_Truncated)10016 TEST_F(HttpCacheTest, WriteResponseInfo_Truncated) {
10017   MockHttpCache cache;
10018   disk_cache::Entry* entry;
10019   ASSERT_TRUE(cache.CreateBackendEntry(
10020       GenerateCacheKey("http://www.google.com"), &entry, nullptr));
10021 
10022   HttpResponseInfo response;
10023   response.headers = base::MakeRefCounted<HttpResponseHeaders>(
10024       HttpUtil::AssembleRawHeaders("HTTP/1.1 200 OK"));
10025 
10026   // Set the last argument for this to be an incomplete request.
10027   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true));
10028   bool truncated = false;
10029   EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
10030   EXPECT_TRUE(truncated);
10031 
10032   // And now test the opposite case.
10033   EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, false));
10034   truncated = true;
10035   EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated));
10036   EXPECT_FALSE(truncated);
10037   entry->Close();
10038 }
10039 
10040 // Tests basic pickling/unpickling of HttpResponseInfo.
TEST_F(HttpCacheTest,PersistHttpResponseInfo)10041 TEST_F(HttpCacheTest, PersistHttpResponseInfo) {
10042   const IPEndPoint expected_endpoint = IPEndPoint(IPAddress(1, 2, 3, 4), 80);
10043   // Set some fields (add more if needed.)
10044   HttpResponseInfo response1;
10045   response1.was_cached = false;
10046   response1.remote_endpoint = expected_endpoint;
10047   response1.headers =
10048       base::MakeRefCounted<HttpResponseHeaders>("HTTP/1.1 200 OK");
10049 
10050   // Pickle.
10051   base::Pickle pickle;
10052   response1.Persist(&pickle, false, false);
10053 
10054   // Unpickle.
10055   HttpResponseInfo response2;
10056   bool response_truncated;
10057   EXPECT_TRUE(response2.InitFromPickle(pickle, &response_truncated));
10058   EXPECT_FALSE(response_truncated);
10059 
10060   // Verify fields.
10061   EXPECT_TRUE(response2.was_cached);  // InitFromPickle sets this flag.
10062   EXPECT_EQ(expected_endpoint, response2.remote_endpoint);
10063   EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
10064 }
10065 
10066 // Tests that we delete an entry when the request is cancelled before starting
10067 // to read from the network.
TEST_F(HttpCacheTest,DoomOnDestruction)10068 TEST_F(HttpCacheTest, DoomOnDestruction) {
10069   MockHttpCache cache;
10070 
10071   MockHttpRequest request(kSimpleGET_Transaction);
10072 
10073   auto c = std::make_unique<Context>();
10074   int rv = cache.CreateTransaction(&c->trans);
10075   ASSERT_THAT(rv, IsOk());
10076 
10077   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10078   if (rv == ERR_IO_PENDING) {
10079     c->result = c->callback.WaitForResult();
10080   }
10081 
10082   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10083   EXPECT_EQ(0, cache.disk_cache()->open_count());
10084   EXPECT_EQ(1, cache.disk_cache()->create_count());
10085 
10086   // Destroy the transaction. We only have the headers so we should delete this
10087   // entry.
10088   c.reset();
10089 
10090   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
10091 
10092   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10093   EXPECT_EQ(0, cache.disk_cache()->open_count());
10094   EXPECT_EQ(2, cache.disk_cache()->create_count());
10095 }
10096 
10097 // Tests that we delete an entry when the request is cancelled if the response
10098 // does not have content-length and strong validators.
TEST_F(HttpCacheTest,DoomOnDestruction2)10099 TEST_F(HttpCacheTest, DoomOnDestruction2) {
10100   MockHttpCache cache;
10101 
10102   MockHttpRequest request(kSimpleGET_Transaction);
10103 
10104   auto c = std::make_unique<Context>();
10105   int rv = cache.CreateTransaction(&c->trans);
10106   ASSERT_THAT(rv, IsOk());
10107 
10108   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10109   if (rv == ERR_IO_PENDING) {
10110     rv = c->callback.WaitForResult();
10111   }
10112 
10113   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10114   EXPECT_EQ(0, cache.disk_cache()->open_count());
10115   EXPECT_EQ(1, cache.disk_cache()->create_count());
10116 
10117   // Make sure that the entry has some data stored.
10118   scoped_refptr<IOBufferWithSize> buf =
10119       base::MakeRefCounted<IOBufferWithSize>(10);
10120   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10121   if (rv == ERR_IO_PENDING) {
10122     rv = c->callback.WaitForResult();
10123   }
10124   EXPECT_EQ(buf->size(), rv);
10125 
10126   // Destroy the transaction.
10127   c.reset();
10128 
10129   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
10130 
10131   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10132   EXPECT_EQ(0, cache.disk_cache()->open_count());
10133   EXPECT_EQ(2, cache.disk_cache()->create_count());
10134 }
10135 
10136 // Tests that we delete an entry when the request is cancelled if the response
10137 // has an "Accept-Ranges: none" header.
TEST_F(HttpCacheTest,DoomOnDestruction3)10138 TEST_F(HttpCacheTest, DoomOnDestruction3) {
10139   MockHttpCache cache;
10140 
10141   ScopedMockTransaction transaction(kSimpleGET_Transaction);
10142   transaction.response_headers =
10143       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
10144       "Content-Length: 22\n"
10145       "Accept-Ranges: none\n"
10146       "Etag: \"foopy\"\n";
10147   MockHttpRequest request(transaction);
10148 
10149   auto c = std::make_unique<Context>();
10150   int rv = cache.CreateTransaction(&c->trans);
10151   ASSERT_THAT(rv, IsOk());
10152 
10153   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10154   if (rv == ERR_IO_PENDING) {
10155     rv = c->callback.WaitForResult();
10156   }
10157 
10158   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10159   EXPECT_EQ(0, cache.disk_cache()->open_count());
10160   EXPECT_EQ(1, cache.disk_cache()->create_count());
10161 
10162   // Make sure that the entry has some data stored.
10163   scoped_refptr<IOBufferWithSize> buf =
10164       base::MakeRefCounted<IOBufferWithSize>(10);
10165   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10166   if (rv == ERR_IO_PENDING) {
10167     rv = c->callback.WaitForResult();
10168   }
10169   EXPECT_EQ(buf->size(), rv);
10170 
10171   // Destroy the transaction.
10172   c.reset();
10173 
10174   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
10175 
10176   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10177   EXPECT_EQ(0, cache.disk_cache()->open_count());
10178   EXPECT_EQ(2, cache.disk_cache()->create_count());
10179 }
10180 
10181 // Tests that we mark an entry as incomplete when the request is cancelled.
TEST_F(HttpCacheTest,SetTruncatedFlag)10182 TEST_F(HttpCacheTest, SetTruncatedFlag) {
10183   MockHttpCache cache;
10184 
10185   ScopedMockTransaction transaction(kSimpleGET_Transaction);
10186   transaction.response_headers =
10187       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
10188       "Content-Length: 22\n"
10189       "Etag: \"foopy\"\n";
10190   MockHttpRequest request(transaction);
10191 
10192   auto c = std::make_unique<Context>();
10193 
10194   int rv = cache.CreateTransaction(&c->trans);
10195   ASSERT_THAT(rv, IsOk());
10196 
10197   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10198   if (rv == ERR_IO_PENDING) {
10199     rv = c->callback.WaitForResult();
10200   }
10201 
10202   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10203   EXPECT_EQ(0, cache.disk_cache()->open_count());
10204   EXPECT_EQ(1, cache.disk_cache()->create_count());
10205 
10206   // Make sure that the entry has some data stored.
10207   scoped_refptr<IOBufferWithSize> buf =
10208       base::MakeRefCounted<IOBufferWithSize>(10);
10209   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10210   if (rv == ERR_IO_PENDING) {
10211     rv = c->callback.WaitForResult();
10212   }
10213   EXPECT_EQ(buf->size(), rv);
10214 
10215   // We want to cancel the request when the transaction is busy.
10216   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10217   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10218   EXPECT_FALSE(c->callback.have_result());
10219 
10220   // Destroy the transaction.
10221   c->trans.reset();
10222 
10223   // Make sure that we don't invoke the callback. We may have an issue if the
10224   // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
10225   // could end up with the transaction being deleted twice if we send any
10226   // notification from the transaction destructor (see http://crbug.com/31723).
10227   EXPECT_FALSE(c->callback.have_result());
10228 
10229   base::RunLoop().RunUntilIdle();
10230   VerifyTruncatedFlag(&cache, request.CacheKey(), true, 0);
10231 }
10232 
10233 // Tests that we do not mark an entry as truncated when the request is
10234 // cancelled.
TEST_F(HttpCacheTest,DontSetTruncatedFlagForGarbledResponseCode)10235 TEST_F(HttpCacheTest, DontSetTruncatedFlagForGarbledResponseCode) {
10236   MockHttpCache cache;
10237 
10238   ScopedMockTransaction transaction(kSimpleGET_Transaction);
10239   transaction.response_headers =
10240       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
10241       "Content-Length: 22\n"
10242       "Etag: \"foopy\"\n";
10243   transaction.status = "HTTP/1.1 2";
10244   MockHttpRequest request(transaction);
10245 
10246   auto c = std::make_unique<Context>();
10247 
10248   int rv = cache.CreateTransaction(&c->trans);
10249   ASSERT_THAT(rv, IsOk());
10250 
10251   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10252   if (rv == ERR_IO_PENDING) {
10253     rv = c->callback.WaitForResult();
10254   }
10255 
10256   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10257   EXPECT_EQ(0, cache.disk_cache()->open_count());
10258   EXPECT_EQ(1, cache.disk_cache()->create_count());
10259 
10260   // Make sure that the entry has some data stored.
10261   scoped_refptr<IOBufferWithSize> buf =
10262       base::MakeRefCounted<IOBufferWithSize>(10);
10263   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10264   if (rv == ERR_IO_PENDING) {
10265     rv = c->callback.WaitForResult();
10266   }
10267   EXPECT_EQ(buf->size(), rv);
10268 
10269   // We want to cancel the request when the transaction is busy.
10270   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10271   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10272   EXPECT_FALSE(c->callback.have_result());
10273 
10274   MockHttpCache::SetTestMode(TEST_MODE_SYNC_ALL);
10275 
10276   // Destroy the transaction.
10277   c->trans.reset();
10278   MockHttpCache::SetTestMode(0);
10279 
10280   // Make sure that we don't invoke the callback. We may have an issue if the
10281   // UrlRequestJob is killed directly (without cancelling the UrlRequest) so we
10282   // could end up with the transaction being deleted twice if we send any
10283   // notification from the transaction destructor (see http://crbug.com/31723).
10284   EXPECT_FALSE(c->callback.have_result());
10285 
10286   // Verify that the entry is deleted as well, since the response status is
10287   // garbled. Note that the entry will be deleted after the pending Read is
10288   // complete.
10289   base::RunLoop().RunUntilIdle();
10290   disk_cache::Entry* entry;
10291   ASSERT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
10292 }
10293 
10294 // Tests that we don't mark an entry as truncated when we read everything.
TEST_F(HttpCacheTest,DontSetTruncatedFlag)10295 TEST_F(HttpCacheTest, DontSetTruncatedFlag) {
10296   MockHttpCache cache;
10297 
10298   ScopedMockTransaction transaction(kSimpleGET_Transaction);
10299   transaction.response_headers =
10300       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
10301       "Content-Length: 22\n"
10302       "Etag: \"foopy\"\n";
10303   MockHttpRequest request(transaction);
10304 
10305   auto c = std::make_unique<Context>();
10306   int rv = cache.CreateTransaction(&c->trans);
10307   ASSERT_THAT(rv, IsOk());
10308 
10309   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10310   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10311 
10312   // Read everything.
10313   scoped_refptr<IOBufferWithSize> buf =
10314       base::MakeRefCounted<IOBufferWithSize>(22);
10315   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10316   EXPECT_EQ(buf->size(), c->callback.GetResult(rv));
10317 
10318   // Destroy the transaction.
10319   c->trans.reset();
10320 
10321   // Verify that the entry is not marked as truncated.
10322   VerifyTruncatedFlag(&cache, request.CacheKey(), false, 0);
10323 }
10324 
10325 // Tests that sparse entries don't set the truncate flag.
TEST_F(HttpCacheTest,RangeGET_DontTruncate)10326 TEST_F(HttpCacheTest, RangeGET_DontTruncate) {
10327   MockHttpCache cache;
10328 
10329   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10330   transaction.request_headers = "Range: bytes = 0-19\r\n" EXTRA_HEADER;
10331 
10332   auto request = std::make_unique<MockHttpRequest>(transaction);
10333   std::unique_ptr<HttpTransaction> trans;
10334 
10335   int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
10336   EXPECT_THAT(rv, IsOk());
10337 
10338   TestCompletionCallback cb;
10339   rv = trans->Start(request.get(), cb.callback(), NetLogWithSource());
10340   EXPECT_EQ(0, cb.GetResult(rv));
10341 
10342   auto buf = base::MakeRefCounted<IOBufferWithSize>(10);
10343   rv = trans->Read(buf.get(), 10, cb.callback());
10344   EXPECT_EQ(10, cb.GetResult(rv));
10345 
10346   // Should not trigger any DCHECK.
10347   trans.reset();
10348   VerifyTruncatedFlag(&cache, request->CacheKey(), false, 0);
10349 }
10350 
10351 // Tests that sparse entries don't set the truncate flag (when the byte range
10352 //  starts after 0).
TEST_F(HttpCacheTest,RangeGET_DontTruncate2)10353 TEST_F(HttpCacheTest, RangeGET_DontTruncate2) {
10354   MockHttpCache cache;
10355 
10356   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10357   transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER;
10358 
10359   auto request = std::make_unique<MockHttpRequest>(transaction);
10360   std::unique_ptr<HttpTransaction> trans;
10361 
10362   int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
10363   EXPECT_THAT(rv, IsOk());
10364 
10365   TestCompletionCallback cb;
10366   rv = trans->Start(request.get(), cb.callback(), NetLogWithSource());
10367   EXPECT_EQ(0, cb.GetResult(rv));
10368 
10369   auto buf = base::MakeRefCounted<IOBufferWithSize>(10);
10370   rv = trans->Read(buf.get(), 10, cb.callback());
10371   EXPECT_EQ(10, cb.GetResult(rv));
10372 
10373   // Should not trigger any DCHECK.
10374   trans.reset();
10375   VerifyTruncatedFlag(&cache, request->CacheKey(), false, 0);
10376 }
10377 
10378 // Tests that we can continue with a request that was interrupted.
TEST_F(HttpCacheTest,GET_IncompleteResource)10379 TEST_F(HttpCacheTest, GET_IncompleteResource) {
10380   MockHttpCache cache;
10381   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10382 
10383   std::string raw_headers(
10384       "HTTP/1.1 200 OK\n"
10385       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10386       "ETag: \"foo\"\n"
10387       "Accept-Ranges: bytes\n"
10388       "Content-Length: 80\n");
10389   CreateTruncatedEntry(raw_headers, &cache);
10390 
10391   // Now make a regular request.
10392   std::string headers;
10393   transaction.request_headers = EXTRA_HEADER;
10394   transaction.data = kFullRangeData;
10395   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
10396 
10397   // We update the headers with the ones received while revalidating.
10398   std::string expected_headers(
10399       "HTTP/1.1 200 OK\n"
10400       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10401       "Accept-Ranges: bytes\n"
10402       "ETag: \"foo\"\n"
10403       "Content-Length: 80\n");
10404 
10405   EXPECT_EQ(expected_headers, headers);
10406   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10407   EXPECT_EQ(1, cache.disk_cache()->open_count());
10408   EXPECT_EQ(1, cache.disk_cache()->create_count());
10409 
10410   // Verify that the disk entry was updated.
10411   MockHttpRequest request(transaction);
10412   VerifyTruncatedFlag(&cache, request.CacheKey(), false, 80);
10413 }
10414 
10415 // Tests the handling of no-store when revalidating a truncated entry.
TEST_F(HttpCacheTest,GET_IncompleteResource_NoStore)10416 TEST_F(HttpCacheTest, GET_IncompleteResource_NoStore) {
10417   MockHttpCache cache;
10418   {
10419     ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
10420 
10421     std::string raw_headers(
10422         "HTTP/1.1 200 OK\n"
10423         "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10424         "ETag: \"foo\"\n"
10425         "Accept-Ranges: bytes\n"
10426         "Content-Length: 80\n");
10427     CreateTruncatedEntry(raw_headers, &cache);
10428   }
10429 
10430   // Now make a regular request.
10431   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10432   transaction.request_headers = EXTRA_HEADER;
10433   std::string response_headers(transaction.response_headers);
10434   response_headers += ("Cache-Control: no-store\n");
10435   transaction.response_headers = response_headers.c_str();
10436   transaction.data = kFullRangeData;
10437 
10438   std::string headers;
10439   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
10440 
10441   // We update the headers with the ones received while revalidating.
10442   std::string expected_headers(
10443       "HTTP/1.1 200 OK\n"
10444       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10445       "Accept-Ranges: bytes\n"
10446       "Cache-Control: no-store\n"
10447       "ETag: \"foo\"\n"
10448       "Content-Length: 80\n");
10449 
10450   EXPECT_EQ(expected_headers, headers);
10451   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10452   EXPECT_EQ(1, cache.disk_cache()->open_count());
10453   EXPECT_EQ(1, cache.disk_cache()->create_count());
10454 
10455   // Verify that the disk entry was deleted.
10456   disk_cache::Entry* entry;
10457   MockHttpRequest request(transaction);
10458   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
10459 }
10460 
10461 // Tests cancelling a request after the server sent no-store.
TEST_F(HttpCacheTest,GET_IncompleteResource_Cancel)10462 TEST_F(HttpCacheTest, GET_IncompleteResource_Cancel) {
10463   MockHttpCache cache;
10464   {
10465     ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
10466     std::string raw_headers(
10467         "HTTP/1.1 200 OK\n"
10468         "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10469         "ETag: \"foo\"\n"
10470         "Accept-Ranges: bytes\n"
10471         "Content-Length: 80\n");
10472     CreateTruncatedEntry(raw_headers, &cache);
10473   }
10474 
10475   // Now make a regular request.
10476   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10477   transaction.request_headers = EXTRA_HEADER;
10478   std::string response_headers(transaction.response_headers);
10479   response_headers += ("Cache-Control: no-store\n");
10480   transaction.response_headers = response_headers.c_str();
10481   transaction.data = kFullRangeData;
10482 
10483   MockHttpRequest request(transaction);
10484   auto c = std::make_unique<Context>();
10485 
10486   int rv = cache.CreateTransaction(&c->trans);
10487   ASSERT_THAT(rv, IsOk());
10488 
10489   // Queue another request to this transaction. We have to start this request
10490   // before the first one gets the response from the server and dooms the entry,
10491   // otherwise it will just create a new entry without being queued to the first
10492   // request.
10493   auto pending = std::make_unique<Context>();
10494   ASSERT_THAT(cache.CreateTransaction(&pending->trans), IsOk());
10495 
10496   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10497   EXPECT_EQ(ERR_IO_PENDING,
10498             pending->trans->Start(&request, pending->callback.callback(),
10499                                   NetLogWithSource()));
10500   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10501 
10502   // Make sure that the entry has some data stored.
10503   scoped_refptr<IOBufferWithSize> buf =
10504       base::MakeRefCounted<IOBufferWithSize>(5);
10505   rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback());
10506   EXPECT_EQ(5, c->callback.GetResult(rv));
10507 
10508   // Since |pending| is currently validating the already written headers
10509   // it will be restarted as well.
10510   c.reset();
10511   pending.reset();
10512 
10513   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10514   EXPECT_EQ(1, cache.disk_cache()->open_count());
10515   EXPECT_EQ(1, cache.disk_cache()->create_count());
10516 
10517   base::RunLoop().RunUntilIdle();
10518 }
10519 
10520 // Tests that we delete truncated entries if the server changes its mind midway.
TEST_F(HttpCacheTest,GET_IncompleteResource2)10521 TEST_F(HttpCacheTest, GET_IncompleteResource2) {
10522   MockHttpCache cache;
10523   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
10524   // Content-length will be intentionally bad.
10525   std::string raw_headers(
10526       "HTTP/1.1 200 OK\n"
10527       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10528       "ETag: \"foo\"\n"
10529       "Accept-Ranges: bytes\n"
10530       "Content-Length: 50\n");
10531   CreateTruncatedEntry(raw_headers, &cache);
10532 
10533   // Now make a regular request. We expect the code to fail the validation and
10534   // retry the request without using byte ranges.
10535   std::string headers;
10536   MockTransaction transaction(kRangeGET_TransactionOK);
10537   transaction.request_headers = EXTRA_HEADER;
10538   transaction.data = "Not a range";
10539   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
10540 
10541   // The server will return 200 instead of a byte range.
10542   std::string expected_headers(
10543       "HTTP/1.1 200 OK\n"
10544       "Date: Wed, 28 Nov 2007 09:40:09 GMT\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 deleted.
10552   disk_cache::Entry* entry;
10553   MockHttpRequest request(transaction);
10554   ASSERT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
10555 }
10556 
10557 // Tests that we always validate a truncated request.
TEST_F(HttpCacheTest,GET_IncompleteResource3)10558 TEST_F(HttpCacheTest, GET_IncompleteResource3) {
10559   MockHttpCache cache;
10560   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
10561 
10562   // This should not require validation for 10 hours.
10563   std::string raw_headers(
10564       "HTTP/1.1 200 OK\n"
10565       "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
10566       "ETag: \"foo\"\n"
10567       "Cache-Control: max-age= 36000\n"
10568       "Accept-Ranges: bytes\n"
10569       "Content-Length: 80\n");
10570   CreateTruncatedEntry(raw_headers, &cache);
10571 
10572   // Now make a regular request.
10573   std::string headers;
10574   MockTransaction transaction(kRangeGET_TransactionOK);
10575   transaction.request_headers = EXTRA_HEADER;
10576   transaction.data = kFullRangeData;
10577 
10578   auto c = std::make_unique<Context>();
10579   int rv = cache.CreateTransaction(&c->trans);
10580   ASSERT_THAT(rv, IsOk());
10581 
10582   MockHttpRequest request(transaction);
10583   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10584   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10585 
10586   // We should have checked with the server before finishing Start().
10587   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10588   EXPECT_EQ(1, cache.disk_cache()->open_count());
10589   EXPECT_EQ(1, cache.disk_cache()->create_count());
10590 }
10591 
10592 // Tests that we handle 401s for truncated resources.
TEST_F(HttpCacheTest,GET_IncompleteResourceWithAuth)10593 TEST_F(HttpCacheTest, GET_IncompleteResourceWithAuth) {
10594   MockHttpCache cache;
10595   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
10596 
10597   std::string raw_headers(
10598       "HTTP/1.1 200 OK\n"
10599       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
10600       "ETag: \"foo\"\n"
10601       "Accept-Ranges: bytes\n"
10602       "Content-Length: 80\n");
10603   CreateTruncatedEntry(raw_headers, &cache);
10604 
10605   // Now make a regular request.
10606   MockTransaction transaction(kRangeGET_TransactionOK);
10607   transaction.request_headers = "X-Require-Mock-Auth: dummy\r\n" EXTRA_HEADER;
10608   transaction.data = kFullRangeData;
10609   RangeTransactionServer handler;
10610 
10611   auto c = std::make_unique<Context>();
10612   int rv = cache.CreateTransaction(&c->trans);
10613   ASSERT_THAT(rv, IsOk());
10614 
10615   MockHttpRequest request(transaction);
10616   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10617   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10618 
10619   const HttpResponseInfo* response = c->trans->GetResponseInfo();
10620   ASSERT_TRUE(response);
10621   ASSERT_EQ(401, response->headers->response_code());
10622   rv = c->trans->RestartWithAuth(AuthCredentials(), c->callback.callback());
10623   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10624   response = c->trans->GetResponseInfo();
10625   ASSERT_TRUE(response);
10626   ASSERT_EQ(200, response->headers->response_code());
10627 
10628   ReadAndVerifyTransaction(c->trans.get(), transaction);
10629   c.reset();  // The destructor could delete the entry.
10630   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10631 
10632   // Verify that the entry was deleted.
10633   disk_cache::Entry* entry;
10634   ASSERT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &entry));
10635   entry->Close();
10636 }
10637 
10638 // Test that the transaction won't retry failed partial requests
10639 // after it starts reading data.  http://crbug.com/474835
TEST_F(HttpCacheTest,TransactionRetryLimit)10640 TEST_F(HttpCacheTest, TransactionRetryLimit) {
10641   MockHttpCache cache;
10642 
10643   // Cache 0-9, so that we have data to read before failing.
10644   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10645   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
10646   transaction.data = "rg: 00-09 ";
10647 
10648   // Write to the cache.
10649   RunTransactionTest(cache.http_cache(), transaction);
10650   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10651 
10652   // And now read from the cache and the network.  10-19 will get a
10653   // 401, but will have already returned 0-9.
10654   // We do not set X-Require-Mock-Auth because that causes the mock
10655   // network transaction to become IsReadyToRestartForAuth().
10656   transaction.request_headers =
10657       "Range: bytes = 0-79\r\n"
10658       "X-Require-Mock-Auth-Alt: dummy\r\n" EXTRA_HEADER;
10659 
10660   auto c = std::make_unique<Context>();
10661   int rv = cache.CreateTransaction(&c->trans);
10662   ASSERT_THAT(rv, IsOk());
10663 
10664   MockHttpRequest request(transaction);
10665 
10666   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10667   if (rv == ERR_IO_PENDING) {
10668     rv = c->callback.WaitForResult();
10669   }
10670   std::string content;
10671   rv = ReadTransaction(c->trans.get(), &content);
10672   EXPECT_THAT(rv, IsError(ERR_CACHE_AUTH_FAILURE_AFTER_READ));
10673 }
10674 
10675 // Tests that we cache a 200 response to the validation request.
TEST_F(HttpCacheTest,GET_IncompleteResource4)10676 TEST_F(HttpCacheTest, GET_IncompleteResource4) {
10677   MockHttpCache cache;
10678   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10679 
10680   std::string raw_headers(
10681       "HTTP/1.1 200 OK\n"
10682       "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
10683       "ETag: \"foo\"\n"
10684       "Accept-Ranges: bytes\n"
10685       "Content-Length: 80\n");
10686   CreateTruncatedEntry(raw_headers, &cache);
10687 
10688   // Now make a regular request.
10689   std::string headers;
10690   transaction.request_headers = EXTRA_HEADER;
10691   transaction.data = "Not a range";
10692   RangeTransactionServer handler;
10693   handler.set_bad_200(true);
10694   RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers);
10695 
10696   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10697   EXPECT_EQ(1, cache.disk_cache()->open_count());
10698   EXPECT_EQ(1, cache.disk_cache()->create_count());
10699 
10700   // Verify that the disk entry was updated.
10701   MockHttpRequest request(transaction);
10702   VerifyTruncatedFlag(&cache, request.CacheKey(), false, 11);
10703 }
10704 
10705 // Tests that when we cancel a request that was interrupted, we mark it again
10706 // as truncated.
TEST_F(HttpCacheTest,GET_CancelIncompleteResource)10707 TEST_F(HttpCacheTest, GET_CancelIncompleteResource) {
10708   MockHttpCache cache;
10709   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
10710 
10711   std::string raw_headers(
10712       "HTTP/1.1 200 OK\n"
10713       "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n"
10714       "ETag: \"foo\"\n"
10715       "Accept-Ranges: bytes\n"
10716       "Content-Length: 80\n");
10717   CreateTruncatedEntry(raw_headers, &cache);
10718 
10719   // Now make a regular request.
10720   transaction.request_headers = EXTRA_HEADER;
10721 
10722   MockHttpRequest request(transaction);
10723   auto c = std::make_unique<Context>();
10724   int rv = cache.CreateTransaction(&c->trans);
10725   ASSERT_THAT(rv, IsOk());
10726 
10727   rv = c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
10728   EXPECT_THAT(c->callback.GetResult(rv), IsOk());
10729 
10730   // Read 20 bytes from the cache, and 10 from the net.
10731   auto buf = base::MakeRefCounted<IOBufferWithSize>(100);
10732   rv = c->trans->Read(buf.get(), 20, c->callback.callback());
10733   EXPECT_EQ(20, c->callback.GetResult(rv));
10734   rv = c->trans->Read(buf.get(), 10, c->callback.callback());
10735   EXPECT_EQ(10, c->callback.GetResult(rv));
10736 
10737   // At this point, we are already reading so canceling the request should leave
10738   // a truncated one.
10739   c.reset();
10740 
10741   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10742   EXPECT_EQ(1, cache.disk_cache()->open_count());
10743   EXPECT_EQ(1, cache.disk_cache()->create_count());
10744 
10745   // Verify that the disk entry was updated: now we have 30 bytes.
10746   VerifyTruncatedFlag(&cache, request.CacheKey(), true, 30);
10747 }
10748 
10749 // Tests that we can handle range requests when we have a truncated entry.
TEST_F(HttpCacheTest,RangeGET_IncompleteResource)10750 TEST_F(HttpCacheTest, RangeGET_IncompleteResource) {
10751   MockHttpCache cache;
10752   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
10753 
10754   // Content-length will be intentionally bogus.
10755   std::string raw_headers(
10756       "HTTP/1.1 200 OK\n"
10757       "Last-Modified: something\n"
10758       "ETag: \"foo\"\n"
10759       "Accept-Ranges: bytes\n"
10760       "Content-Length: 10\n");
10761   CreateTruncatedEntry(raw_headers, &cache);
10762 
10763   // Now make a range request.
10764   std::string headers;
10765   RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK,
10766                                  &headers);
10767 
10768   Verify206Response(headers, 40, 49);
10769   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10770   EXPECT_EQ(1, cache.disk_cache()->open_count());
10771   EXPECT_EQ(2, cache.disk_cache()->create_count());
10772 }
10773 
TEST_F(HttpCacheTest,SyncRead)10774 TEST_F(HttpCacheTest, SyncRead) {
10775   MockHttpCache cache;
10776 
10777   // This test ensures that a read that completes synchronously does not cause
10778   // any problems.
10779 
10780   ScopedMockTransaction transaction(kSimpleGET_Transaction);
10781   transaction.test_mode |=
10782       (TEST_MODE_SYNC_CACHE_START | TEST_MODE_SYNC_CACHE_READ |
10783        TEST_MODE_SYNC_CACHE_WRITE);
10784 
10785   MockHttpRequest r1(transaction), r2(transaction), r3(transaction);
10786 
10787   TestTransactionConsumer c1(DEFAULT_PRIORITY, cache.http_cache()),
10788       c2(DEFAULT_PRIORITY, cache.http_cache()),
10789       c3(DEFAULT_PRIORITY, cache.http_cache());
10790 
10791   c1.Start(&r1, NetLogWithSource());
10792 
10793   r2.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
10794   c2.Start(&r2, NetLogWithSource());
10795 
10796   r3.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
10797   c3.Start(&r3, NetLogWithSource());
10798 
10799   EXPECT_TRUE(c1.is_done());
10800   EXPECT_TRUE(c2.is_done());
10801   EXPECT_TRUE(c3.is_done());
10802 
10803   EXPECT_THAT(c1.error(), IsOk());
10804   EXPECT_THAT(c2.error(), IsOk());
10805   EXPECT_THAT(c3.error(), IsOk());
10806 }
10807 
TEST_F(HttpCacheTest,ValidationResultsIn200)10808 TEST_F(HttpCacheTest, ValidationResultsIn200) {
10809   MockHttpCache cache;
10810 
10811   // This test ensures that a conditional request, which results in a 200
10812   // instead of a 304, properly truncates the existing response data.
10813 
10814   // write to the cache
10815   RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
10816 
10817   // force this transaction to validate the cache
10818   MockTransaction transaction(kETagGET_Transaction);
10819   transaction.load_flags |= LOAD_VALIDATE_CACHE;
10820   RunTransactionTest(cache.http_cache(), transaction);
10821 
10822   // read from the cache
10823   RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
10824 }
10825 
TEST_F(HttpCacheTest,CachedRedirect)10826 TEST_F(HttpCacheTest, CachedRedirect) {
10827   MockHttpCache cache;
10828 
10829   ScopedMockTransaction kTestTransaction(kSimpleGET_Transaction);
10830   kTestTransaction.status = "HTTP/1.1 301 Moved Permanently";
10831   kTestTransaction.response_headers = "Location: http://www.bar.com/\n";
10832 
10833   MockHttpRequest request(kTestTransaction);
10834   TestCompletionCallback callback;
10835 
10836   // Write to the cache.
10837   {
10838     std::unique_ptr<HttpTransaction> trans;
10839     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
10840 
10841     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
10842     if (rv == ERR_IO_PENDING) {
10843       rv = callback.WaitForResult();
10844     }
10845     ASSERT_THAT(rv, IsOk());
10846 
10847     const HttpResponseInfo* info = trans->GetResponseInfo();
10848     ASSERT_TRUE(info);
10849 
10850     EXPECT_EQ(info->headers->response_code(), 301);
10851 
10852     std::string location;
10853     info->headers->EnumerateHeader(nullptr, "Location", &location);
10854     EXPECT_EQ(location, "http://www.bar.com/");
10855 
10856     // Mark the transaction as completed so it is cached.
10857     trans->DoneReading();
10858 
10859     // Destroy transaction when going out of scope. We have not actually
10860     // read the response body -- want to test that it is still getting cached.
10861   }
10862   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10863   EXPECT_EQ(0, cache.disk_cache()->open_count());
10864   EXPECT_EQ(1, cache.disk_cache()->create_count());
10865 
10866   // Active entries in the cache are not retired synchronously. Make
10867   // sure the next run hits the MockHttpCache and open_count is
10868   // correct.
10869   base::RunLoop().RunUntilIdle();
10870 
10871   // Read from the cache.
10872   {
10873     std::unique_ptr<HttpTransaction> trans;
10874     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
10875 
10876     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
10877     if (rv == ERR_IO_PENDING) {
10878       rv = callback.WaitForResult();
10879     }
10880     ASSERT_THAT(rv, IsOk());
10881 
10882     const HttpResponseInfo* info = trans->GetResponseInfo();
10883     ASSERT_TRUE(info);
10884 
10885     EXPECT_EQ(info->headers->response_code(), 301);
10886 
10887     std::string location;
10888     info->headers->EnumerateHeader(nullptr, "Location", &location);
10889     EXPECT_EQ(location, "http://www.bar.com/");
10890 
10891     // Mark the transaction as completed so it is cached.
10892     trans->DoneReading();
10893 
10894     // Destroy transaction when going out of scope. We have not actually
10895     // read the response body -- want to test that it is still getting cached.
10896   }
10897   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10898   EXPECT_EQ(1, cache.disk_cache()->open_count());
10899   EXPECT_EQ(1, cache.disk_cache()->create_count());
10900 }
10901 
10902 // Verify that no-cache resources are stored in cache, but are not fetched from
10903 // cache during normal loads.
TEST_F(HttpCacheTest,CacheControlNoCacheNormalLoad)10904 TEST_F(HttpCacheTest, CacheControlNoCacheNormalLoad) {
10905   for (bool use_memory_entry_data : {false, true}) {
10906     MockHttpCache cache;
10907     cache.disk_cache()->set_support_in_memory_entry_data(use_memory_entry_data);
10908 
10909     ScopedMockTransaction transaction(kSimpleGET_Transaction);
10910     transaction.response_headers = "cache-control: no-cache\n";
10911 
10912     // Initial load.
10913     RunTransactionTest(cache.http_cache(), transaction);
10914 
10915     EXPECT_EQ(1, cache.network_layer()->transaction_count());
10916     EXPECT_EQ(0, cache.disk_cache()->open_count());
10917     EXPECT_EQ(1, cache.disk_cache()->create_count());
10918 
10919     // Try loading again; it should result in a network fetch.
10920     RunTransactionTest(cache.http_cache(), transaction);
10921 
10922     EXPECT_EQ(2, cache.network_layer()->transaction_count());
10923     if (use_memory_entry_data) {
10924       EXPECT_EQ(0, cache.disk_cache()->open_count());
10925       EXPECT_EQ(2, cache.disk_cache()->create_count());
10926     } else {
10927       EXPECT_EQ(1, cache.disk_cache()->open_count());
10928       EXPECT_EQ(1, cache.disk_cache()->create_count());
10929     }
10930 
10931     disk_cache::Entry* entry;
10932     MockHttpRequest request(transaction);
10933     EXPECT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &entry));
10934     entry->Close();
10935   }
10936 }
10937 
10938 // Verify that no-cache resources are stored in cache and fetched from cache
10939 // when the LOAD_SKIP_CACHE_VALIDATION flag is set.
TEST_F(HttpCacheTest,CacheControlNoCacheHistoryLoad)10940 TEST_F(HttpCacheTest, CacheControlNoCacheHistoryLoad) {
10941   MockHttpCache cache;
10942 
10943   ScopedMockTransaction transaction(kSimpleGET_Transaction);
10944   transaction.response_headers = "cache-control: no-cache\n";
10945 
10946   // Initial load.
10947   RunTransactionTest(cache.http_cache(), transaction);
10948 
10949   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10950   EXPECT_EQ(0, cache.disk_cache()->open_count());
10951   EXPECT_EQ(1, cache.disk_cache()->create_count());
10952 
10953   // Try loading again with LOAD_SKIP_CACHE_VALIDATION.
10954   transaction.load_flags = LOAD_SKIP_CACHE_VALIDATION;
10955   RunTransactionTest(cache.http_cache(), transaction);
10956 
10957   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10958   EXPECT_EQ(1, cache.disk_cache()->open_count());
10959   EXPECT_EQ(1, cache.disk_cache()->create_count());
10960 
10961   disk_cache::Entry* entry;
10962   MockHttpRequest request(transaction);
10963   EXPECT_TRUE(cache.OpenBackendEntry(request.CacheKey(), &entry));
10964   entry->Close();
10965 }
10966 
TEST_F(HttpCacheTest,CacheControlNoStore)10967 TEST_F(HttpCacheTest, CacheControlNoStore) {
10968   MockHttpCache cache;
10969 
10970   ScopedMockTransaction transaction(kSimpleGET_Transaction);
10971   transaction.response_headers = "cache-control: no-store\n";
10972 
10973   // initial load
10974   RunTransactionTest(cache.http_cache(), transaction);
10975 
10976   EXPECT_EQ(1, cache.network_layer()->transaction_count());
10977   EXPECT_EQ(0, cache.disk_cache()->open_count());
10978   EXPECT_EQ(1, cache.disk_cache()->create_count());
10979 
10980   // try loading again; it should result in a network fetch
10981   RunTransactionTest(cache.http_cache(), transaction);
10982 
10983   EXPECT_EQ(2, cache.network_layer()->transaction_count());
10984   EXPECT_EQ(0, cache.disk_cache()->open_count());
10985   EXPECT_EQ(2, cache.disk_cache()->create_count());
10986 
10987   disk_cache::Entry* entry;
10988   MockHttpRequest request(transaction);
10989   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
10990 }
10991 
TEST_F(HttpCacheTest,CacheControlNoStore2)10992 TEST_F(HttpCacheTest, CacheControlNoStore2) {
10993   // this test is similar to the above test, except that the initial response
10994   // is cachable, but when it is validated, no-store is received causing the
10995   // cached document to be deleted.
10996   MockHttpCache cache;
10997 
10998   ScopedMockTransaction transaction(kETagGET_Transaction);
10999 
11000   // initial load
11001   RunTransactionTest(cache.http_cache(), transaction);
11002 
11003   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11004   EXPECT_EQ(0, cache.disk_cache()->open_count());
11005   EXPECT_EQ(1, cache.disk_cache()->create_count());
11006 
11007   // try loading again; it should result in a network fetch
11008   transaction.load_flags = LOAD_VALIDATE_CACHE;
11009   transaction.response_headers = "cache-control: no-store\n";
11010   RunTransactionTest(cache.http_cache(), transaction);
11011 
11012   EXPECT_EQ(2, cache.network_layer()->transaction_count());
11013   EXPECT_EQ(1, cache.disk_cache()->open_count());
11014   EXPECT_EQ(1, cache.disk_cache()->create_count());
11015 
11016   disk_cache::Entry* entry;
11017   MockHttpRequest request(transaction);
11018   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
11019 }
11020 
TEST_F(HttpCacheTest,CacheControlNoStore3)11021 TEST_F(HttpCacheTest, CacheControlNoStore3) {
11022   // this test is similar to the above test, except that the response is a 304
11023   // instead of a 200.  this should never happen in practice, but it seems like
11024   // a good thing to verify that we still destroy the cache entry.
11025   MockHttpCache cache;
11026 
11027   ScopedMockTransaction transaction(kETagGET_Transaction);
11028 
11029   // initial load
11030   RunTransactionTest(cache.http_cache(), transaction);
11031 
11032   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11033   EXPECT_EQ(0, cache.disk_cache()->open_count());
11034   EXPECT_EQ(1, cache.disk_cache()->create_count());
11035 
11036   // try loading again; it should result in a network fetch
11037   transaction.load_flags = LOAD_VALIDATE_CACHE;
11038   transaction.response_headers = "cache-control: no-store\n";
11039   transaction.status = "HTTP/1.1 304 Not Modified";
11040   RunTransactionTest(cache.http_cache(), transaction);
11041 
11042   EXPECT_EQ(2, cache.network_layer()->transaction_count());
11043   EXPECT_EQ(1, cache.disk_cache()->open_count());
11044   EXPECT_EQ(1, cache.disk_cache()->create_count());
11045 
11046   disk_cache::Entry* entry;
11047   MockHttpRequest request(transaction);
11048   EXPECT_FALSE(cache.OpenBackendEntry(request.CacheKey(), &entry));
11049 }
11050 
11051 // Ensure that we don't cache requests served over bad HTTPS.
TEST_F(HttpCacheTest,SimpleGET_SSLError)11052 TEST_F(HttpCacheTest, SimpleGET_SSLError) {
11053   MockHttpCache cache;
11054 
11055   MockTransaction transaction = kSimpleGET_Transaction;
11056   transaction.cert_status = CERT_STATUS_REVOKED;
11057   ScopedMockTransaction scoped_transaction(transaction);
11058 
11059   // write to the cache
11060   RunTransactionTest(cache.http_cache(), transaction);
11061 
11062   // Test that it was not cached.
11063   transaction.load_flags |= LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
11064 
11065   MockHttpRequest request(transaction);
11066   TestCompletionCallback callback;
11067 
11068   std::unique_ptr<HttpTransaction> trans;
11069   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11070 
11071   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11072   if (rv == ERR_IO_PENDING) {
11073     rv = callback.WaitForResult();
11074   }
11075   ASSERT_THAT(rv, IsError(ERR_CACHE_MISS));
11076 }
11077 
11078 // Ensure that we don't crash by if left-behind transactions.
TEST_F(HttpCacheTest,OutlivedTransactions)11079 TEST_F(HttpCacheTest, OutlivedTransactions) {
11080   auto cache = std::make_unique<MockHttpCache>();
11081 
11082   std::unique_ptr<HttpTransaction> trans;
11083   EXPECT_THAT(cache->CreateTransaction(&trans), IsOk());
11084 
11085   cache.reset();
11086   trans.reset();
11087 }
11088 
11089 // Test that the disabled mode works.
TEST_F(HttpCacheTest,CacheDisabledMode)11090 TEST_F(HttpCacheTest, CacheDisabledMode) {
11091   MockHttpCache cache;
11092 
11093   // write to the cache
11094   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
11095 
11096   // go into disabled mode
11097   cache.http_cache()->set_mode(HttpCache::DISABLE);
11098 
11099   // force this transaction to write to the cache again
11100   MockTransaction transaction(kSimpleGET_Transaction);
11101 
11102   RunTransactionTest(cache.http_cache(), transaction);
11103 
11104   EXPECT_EQ(2, cache.network_layer()->transaction_count());
11105   EXPECT_EQ(0, cache.disk_cache()->open_count());
11106   EXPECT_EQ(1, cache.disk_cache()->create_count());
11107 }
11108 
11109 // Other tests check that the response headers of the cached response
11110 // get updated on 304. Here we specifically check that the
11111 // HttpResponseHeaders::request_time and HttpResponseHeaders::response_time
11112 // fields also gets updated.
11113 // http://crbug.com/20594.
TEST_F(HttpCacheTest,UpdatesRequestResponseTimeOn304)11114 TEST_F(HttpCacheTest, UpdatesRequestResponseTimeOn304) {
11115   MockHttpCache cache;
11116 
11117   const char kUrl[] = "http://foobar";
11118   const char kData[] = "body";
11119 
11120   ScopedMockTransaction mock_network_response(kUrl);
11121 
11122   // Request |kUrl|, causing |kNetResponse1| to be written to the cache.
11123 
11124   MockTransaction request = {nullptr};
11125   request.url = kUrl;
11126   request.method = "GET";
11127   request.request_headers = "\r\n";
11128   request.data = kData;
11129 
11130   static const Response kNetResponse1 = {
11131       "HTTP/1.1 200 OK",
11132       "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
11133       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
11134       kData};
11135 
11136   kNetResponse1.AssignTo(&mock_network_response);
11137 
11138   RunTransactionTest(cache.http_cache(), request);
11139 
11140   // Request |kUrl| again, this time validating the cache and getting
11141   // a 304 back.
11142 
11143   request.load_flags = LOAD_VALIDATE_CACHE;
11144 
11145   static const Response kNetResponse2 = {
11146       "HTTP/1.1 304 Not Modified", "Date: Wed, 22 Jul 2009 03:15:26 GMT\n", ""};
11147 
11148   kNetResponse2.AssignTo(&mock_network_response);
11149 
11150   base::Time request_time = base::Time() + base::Hours(1234);
11151   base::Time response_time = base::Time() + base::Hours(1235);
11152 
11153   mock_network_response.request_time = request_time;
11154   mock_network_response.response_time = response_time;
11155 
11156   HttpResponseInfo response;
11157   RunTransactionTestWithResponseInfo(cache.http_cache(), request, &response);
11158 
11159   // The request and response times should have been updated.
11160   EXPECT_EQ(request_time.ToInternalValue(),
11161             response.request_time.ToInternalValue());
11162   EXPECT_EQ(response_time.ToInternalValue(),
11163             response.response_time.ToInternalValue());
11164 
11165   EXPECT_EQ(
11166       "HTTP/1.1 200 OK\n"
11167       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
11168       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
11169       ToSimpleString(response.headers));
11170 }
11171 
TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,SplitCacheWithNetworkIsolationKey)11172 TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,
11173        SplitCacheWithNetworkIsolationKey) {
11174   MockHttpCache cache;
11175   HttpResponseInfo response;
11176 
11177   SchemefulSite site_a(GURL("http://a.com"));
11178   SchemefulSite site_b(GURL("http://b.com"));
11179   SchemefulSite site_data(GURL("data:text/html,<body>Hello World</body>"));
11180 
11181   MockHttpRequest trans_info = MockHttpRequest(kSimpleGET_Transaction);
11182   // Request with a.com as the top frame and subframe origins. This should
11183   // result in a cache miss.
11184   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11185   trans_info.network_anonymization_key =
11186       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11187   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11188                                 trans_info, &response);
11189   EXPECT_FALSE(response.was_cached);
11190 
11191   // The second request should result in a cache hit.
11192   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11193                                 trans_info, &response);
11194   EXPECT_TRUE(response.was_cached);
11195 
11196   // Now request with b.com as the subframe origin. It should result in a cache
11197   // miss.
11198   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_b);
11199   trans_info.network_anonymization_key =
11200       net::NetworkAnonymizationKey::CreateCrossSite(site_a);
11201   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11202                                 trans_info, &response);
11203   EXPECT_FALSE(response.was_cached);
11204 
11205   // The second request should result in a cache hit.
11206   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11207                                 trans_info, &response);
11208   EXPECT_TRUE(response.was_cached);
11209 
11210   // Another request with a.com as the top frame and subframe origin should
11211   // still result in a cache hit.
11212   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11213   trans_info.network_anonymization_key =
11214       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11215   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11216                                 trans_info, &response);
11217   EXPECT_TRUE(response.was_cached);
11218 
11219   // Now make a request with an opaque subframe site. It shouldn't cause
11220   // anything to be added to the cache when the NIK makes use of the frame site.
11221   // Note that we will use `site_b` as the top-level site so that this resource
11222   // won't be in the cache at first regardless of the NIK partitioning scheme.
11223   trans_info.network_isolation_key = NetworkIsolationKey(site_b, site_data);
11224   trans_info.network_anonymization_key =
11225       net::NetworkAnonymizationKey::CreateCrossSite(site_b);
11226   switch (GetParam()) {
11227     case SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled:
11228       EXPECT_EQ(std::nullopt,
11229                 trans_info.network_isolation_key.ToCacheKeyString());
11230       break;
11231     case SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled:
11232       EXPECT_EQ("http://b.com _1",
11233                 trans_info.network_isolation_key.ToCacheKeyString().value());
11234       break;
11235     case SplitCacheTestCase::kSplitCacheNikFrameSiteSharedOpaqueEnabled:
11236       EXPECT_EQ("http://b.com _opaque",
11237                 trans_info.network_isolation_key.ToCacheKeyString().value());
11238       break;
11239     case SplitCacheTestCase::kSplitCacheDisabled:
11240       NOTREACHED_NORETURN();
11241   }
11242 
11243   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11244                                 trans_info, &response);
11245   EXPECT_FALSE(response.was_cached);
11246 
11247   // On the second request, expect a cache miss if the NIK uses the frame site.
11248   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11249                                 trans_info, &response);
11250   switch (GetParam()) {
11251     case SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled:
11252       EXPECT_FALSE(response.was_cached);
11253       break;
11254     case SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled:
11255     case SplitCacheTestCase::kSplitCacheNikFrameSiteSharedOpaqueEnabled:
11256       EXPECT_TRUE(response.was_cached);
11257       break;
11258     case SplitCacheTestCase::kSplitCacheDisabled:
11259       NOTREACHED_NORETURN();
11260   }
11261 
11262   // Verify that a post transaction with a data stream uses a separate key.
11263   const int64_t kUploadId = 1;  // Just a dummy value.
11264 
11265   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
11266   element_readers.push_back(
11267       std::make_unique<UploadBytesElementReader>("hello", 5));
11268   ElementsUploadDataStream upload_data_stream(std::move(element_readers),
11269                                               kUploadId);
11270 
11271   MockHttpRequest post_info = MockHttpRequest(kSimplePOST_Transaction);
11272   post_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11273   post_info.network_anonymization_key =
11274       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11275   post_info.upload_data_stream = &upload_data_stream;
11276 
11277   RunTransactionTestWithRequest(cache.http_cache(), kSimplePOST_Transaction,
11278                                 post_info, &response);
11279   EXPECT_FALSE(response.was_cached);
11280 }
11281 
TEST_F(HttpCacheTest,HttpCacheProfileThirdPartyCSS)11282 TEST_F(HttpCacheTest, HttpCacheProfileThirdPartyCSS) {
11283   base::HistogramTester histograms;
11284   MockHttpCache cache;
11285   HttpResponseInfo response;
11286 
11287   url::Origin origin_a = url::Origin::Create(GURL(kSimpleGET_Transaction.url));
11288   url::Origin origin_b = url::Origin::Create(GURL("http://b.com"));
11289   SchemefulSite site_a(origin_a);
11290   SchemefulSite site_b(origin_b);
11291 
11292   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11293   transaction.response_headers = "Content-Type: text/css\n";
11294 
11295   MockHttpRequest trans_info = MockHttpRequest(transaction);
11296 
11297   // Requesting with the same top-frame site should not count as third-party
11298   // but should still be recorded as CSS
11299   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11300   trans_info.network_anonymization_key =
11301       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11302   trans_info.possibly_top_frame_origin = origin_a;
11303 
11304   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11305                                 &response);
11306 
11307   histograms.ExpectTotalCount("HttpCache.Pattern", 1);
11308   histograms.ExpectTotalCount("HttpCache.Pattern.CSS", 1);
11309   histograms.ExpectTotalCount("HttpCache.Pattern.CSSThirdParty", 0);
11310 
11311   // Requesting with a different top-frame site should count as third-party
11312   // and recorded as CSS
11313   trans_info.network_isolation_key = NetworkIsolationKey(site_b, site_b);
11314   trans_info.network_anonymization_key =
11315       net::NetworkAnonymizationKey::CreateSameSite(site_b);
11316   trans_info.possibly_top_frame_origin = origin_b;
11317 
11318   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11319                                 &response);
11320   histograms.ExpectTotalCount("HttpCache.Pattern", 2);
11321   histograms.ExpectTotalCount("HttpCache.Pattern.CSS", 2);
11322   histograms.ExpectTotalCount("HttpCache.Pattern.CSSThirdParty", 1);
11323 }
11324 
TEST_F(HttpCacheTest,HttpCacheProfileThirdPartyJavaScript)11325 TEST_F(HttpCacheTest, HttpCacheProfileThirdPartyJavaScript) {
11326   base::HistogramTester histograms;
11327   MockHttpCache cache;
11328   HttpResponseInfo response;
11329 
11330   url::Origin origin_a = url::Origin::Create(GURL(kSimpleGET_Transaction.url));
11331   url::Origin origin_b = url::Origin::Create(GURL("http://b.com"));
11332   SchemefulSite site_a(origin_a);
11333   SchemefulSite site_b(origin_b);
11334 
11335   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11336   transaction.response_headers = "Content-Type: application/javascript\n";
11337 
11338   MockHttpRequest trans_info = MockHttpRequest(transaction);
11339 
11340   // Requesting with the same top-frame site should not count as third-party
11341   // but should still be recorded as JavaScript
11342   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11343   trans_info.network_anonymization_key =
11344       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11345   trans_info.possibly_top_frame_origin = origin_a;
11346 
11347   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11348                                 &response);
11349 
11350   histograms.ExpectTotalCount("HttpCache.Pattern", 1);
11351   histograms.ExpectTotalCount("HttpCache.Pattern.JavaScript", 1);
11352   histograms.ExpectTotalCount("HttpCache.Pattern.JavaScriptThirdParty", 0);
11353 
11354   // Requesting with a different top-frame site should count as third-party
11355   // and recorded as JavaScript
11356   trans_info.network_isolation_key = NetworkIsolationKey(site_b, site_b);
11357   trans_info.network_anonymization_key =
11358       net::NetworkAnonymizationKey::CreateSameSite(site_b);
11359   trans_info.possibly_top_frame_origin = origin_b;
11360 
11361   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11362                                 &response);
11363   histograms.ExpectTotalCount("HttpCache.Pattern", 2);
11364   histograms.ExpectTotalCount("HttpCache.Pattern.JavaScript", 2);
11365   histograms.ExpectTotalCount("HttpCache.Pattern.JavaScriptThirdParty", 1);
11366 }
11367 
TEST_F(HttpCacheTest,HttpCacheProfileThirdPartyFont)11368 TEST_F(HttpCacheTest, HttpCacheProfileThirdPartyFont) {
11369   base::HistogramTester histograms;
11370   MockHttpCache cache;
11371   HttpResponseInfo response;
11372 
11373   url::Origin origin_a = url::Origin::Create(GURL(kSimpleGET_Transaction.url));
11374   url::Origin origin_b = url::Origin::Create(GURL("http://b.com"));
11375   SchemefulSite site_a(origin_a);
11376   SchemefulSite site_b(origin_b);
11377 
11378   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11379   transaction.response_headers = "Content-Type: font/otf\n";
11380 
11381   MockHttpRequest trans_info = MockHttpRequest(transaction);
11382 
11383   // Requesting with the same top-frame site should not count as third-party
11384   // but should still be recorded as a font
11385   trans_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11386   trans_info.network_anonymization_key =
11387       net::NetworkAnonymizationKey::CreateSameSite(site_a);
11388   trans_info.possibly_top_frame_origin = origin_a;
11389 
11390   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11391                                 &response);
11392 
11393   histograms.ExpectTotalCount("HttpCache.Pattern", 1);
11394   histograms.ExpectTotalCount("HttpCache.Pattern.Font", 1);
11395   histograms.ExpectTotalCount("HttpCache.Pattern.FontThirdParty", 0);
11396 
11397   // Requesting with a different top-frame site should count as third-party
11398   // and recorded as a font
11399   trans_info.network_isolation_key = NetworkIsolationKey(site_b, site_b);
11400   trans_info.network_anonymization_key =
11401       net::NetworkAnonymizationKey::CreateSameSite(site_b);
11402   trans_info.possibly_top_frame_origin = origin_b;
11403 
11404   RunTransactionTestWithRequest(cache.http_cache(), transaction, trans_info,
11405                                 &response);
11406   histograms.ExpectTotalCount("HttpCache.Pattern", 2);
11407   histograms.ExpectTotalCount("HttpCache.Pattern.Font", 2);
11408   histograms.ExpectTotalCount("HttpCache.Pattern.FontThirdParty", 1);
11409 }
11410 
TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,SplitCache)11411 TEST_P(HttpCacheTest_SplitCacheFeatureEnabled, SplitCache) {
11412   MockHttpCache cache;
11413   HttpResponseInfo response;
11414 
11415   SchemefulSite site_a(GURL("http://a.com"));
11416   SchemefulSite site_b(GURL("http://b.com"));
11417   SchemefulSite site_data(GURL("data:text/html,<body>Hello World</body>"));
11418 
11419   // A request without a top frame origin shouldn't result in anything being
11420   // added to the cache.
11421   MockHttpRequest trans_info = MockHttpRequest(kSimpleGET_Transaction);
11422   trans_info.network_isolation_key = net::NetworkIsolationKey();
11423   trans_info.network_anonymization_key = net::NetworkAnonymizationKey();
11424   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11425                                 trans_info, &response);
11426   EXPECT_FALSE(response.was_cached);
11427 
11428   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11429                                 trans_info, &response);
11430   EXPECT_FALSE(response.was_cached);
11431 
11432   // Now request with a.com as the top frame origin. This should initially
11433   // result in a cache miss since the cached resource has a different top frame
11434   // origin.
11435   net::NetworkIsolationKey key_a(site_a, site_a);
11436   auto nak_a = net::NetworkAnonymizationKey::CreateSameSite(site_a);
11437   trans_info.network_isolation_key = key_a;
11438   trans_info.network_anonymization_key = nak_a;
11439   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11440                                 trans_info, &response);
11441   EXPECT_FALSE(response.was_cached);
11442 
11443   // The second request should result in a cache hit.
11444   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11445                                 trans_info, &response);
11446   EXPECT_TRUE(response.was_cached);
11447 
11448   // If the same resource with the same NIK is for a subframe document resource,
11449   // it should not be a cache hit.
11450   MockHttpRequest subframe_document_trans_info = trans_info;
11451   subframe_document_trans_info.is_subframe_document_resource = true;
11452   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11453                                 subframe_document_trans_info, &response);
11454   EXPECT_FALSE(response.was_cached);
11455 
11456   // Same request again should be a cache hit.
11457   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11458                                 subframe_document_trans_info, &response);
11459   EXPECT_TRUE(response.was_cached);
11460 
11461   // Now request with b.com as the top frame origin. It should be a cache miss.
11462   trans_info.network_isolation_key = NetworkIsolationKey(site_b, site_b);
11463   trans_info.network_anonymization_key =
11464       NetworkAnonymizationKey::CreateSameSite(site_b);
11465   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11466                                 trans_info, &response);
11467   EXPECT_FALSE(response.was_cached);
11468 
11469   // The second request should be a cache hit.
11470   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11471                                 trans_info, &response);
11472   EXPECT_TRUE(response.was_cached);
11473 
11474   // Another request for a.com should still result in a cache hit.
11475   trans_info.network_isolation_key = key_a;
11476   trans_info.network_anonymization_key = nak_a;
11477   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11478                                 trans_info, &response);
11479   EXPECT_TRUE(response.was_cached);
11480 
11481   // Now make a request with an opaque top frame origin. It shouldn't result in
11482   // a cache hit.
11483   trans_info.network_isolation_key = NetworkIsolationKey(site_data, site_data);
11484   trans_info.network_anonymization_key =
11485       NetworkAnonymizationKey::CreateSameSite(site_data);
11486   EXPECT_EQ(std::nullopt, trans_info.network_isolation_key.ToCacheKeyString());
11487   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11488                                 trans_info, &response);
11489   EXPECT_FALSE(response.was_cached);
11490 
11491   // On the second request, it still shouldn't result in a cache hit.
11492   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11493                                 trans_info, &response);
11494   EXPECT_FALSE(response.was_cached);
11495 
11496   // Verify that a post transaction with a data stream uses a separate key.
11497   const int64_t kUploadId = 1;  // Just a dummy value.
11498 
11499   std::vector<std::unique_ptr<UploadElementReader>> element_readers;
11500   element_readers.push_back(
11501       std::make_unique<UploadBytesElementReader>("hello", 5));
11502   ElementsUploadDataStream upload_data_stream(std::move(element_readers),
11503                                               kUploadId);
11504 
11505   MockHttpRequest post_info = MockHttpRequest(kSimplePOST_Transaction);
11506   post_info.network_isolation_key = NetworkIsolationKey(site_a, site_a);
11507   post_info.network_anonymization_key =
11508       NetworkAnonymizationKey::CreateSameSite(site_a);
11509   post_info.upload_data_stream = &upload_data_stream;
11510 
11511   RunTransactionTestWithRequest(cache.http_cache(), kSimplePOST_Transaction,
11512                                 post_info, &response);
11513   EXPECT_FALSE(response.was_cached);
11514 }
11515 
TEST_F(HttpCacheTest,SplitCacheEnabledByDefault)11516 TEST_F(HttpCacheTest, SplitCacheEnabledByDefault) {
11517   HttpCache::ClearGlobalsForTesting();
11518   HttpCache::SplitCacheFeatureEnableByDefault();
11519   EXPECT_TRUE(HttpCache::IsSplitCacheEnabled());
11520 
11521   MockHttpCache cache;
11522   HttpResponseInfo response;
11523 
11524   SchemefulSite site_a(GURL("http://a.com"));
11525   SchemefulSite site_b(GURL("http://b.com"));
11526   MockHttpRequest trans_info = MockHttpRequest(kSimpleGET_Transaction);
11527   net::NetworkIsolationKey key_a(site_a, site_a);
11528   auto nak_a = net::NetworkAnonymizationKey::CreateSameSite(site_a);
11529   trans_info.network_isolation_key = key_a;
11530   trans_info.network_anonymization_key = nak_a;
11531   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11532                                 trans_info, &response);
11533   EXPECT_FALSE(response.was_cached);
11534 
11535   // Subsequent requests with the same NIK and different NIK will be a cache hit
11536   // and miss respectively.
11537   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11538                                 trans_info, &response);
11539   EXPECT_TRUE(response.was_cached);
11540 
11541   net::NetworkIsolationKey key_b(site_b, site_b);
11542   auto nak_b = net::NetworkAnonymizationKey::CreateSameSite(site_b);
11543   trans_info.network_isolation_key = key_b;
11544   trans_info.network_anonymization_key = nak_b;
11545   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11546                                 trans_info, &response);
11547   EXPECT_FALSE(response.was_cached);
11548 }
11549 
TEST_F(HttpCacheTest,SplitCacheEnabledByDefaultButOverridden)11550 TEST_F(HttpCacheTest, SplitCacheEnabledByDefaultButOverridden) {
11551   HttpCache::ClearGlobalsForTesting();
11552   base::test::ScopedFeatureList feature_list;
11553   feature_list.InitAndDisableFeature(
11554       net::features::kSplitCacheByNetworkIsolationKey);
11555 
11556   // Enabling it here should have no effect as it is already overridden.
11557   HttpCache::SplitCacheFeatureEnableByDefault();
11558   EXPECT_FALSE(HttpCache::IsSplitCacheEnabled());
11559 }
11560 
TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,SplitCacheUsesRegistrableDomain)11561 TEST_P(HttpCacheTest_SplitCacheFeatureEnabled,
11562        SplitCacheUsesRegistrableDomain) {
11563   MockHttpCache cache;
11564   HttpResponseInfo response;
11565   MockHttpRequest trans_info = MockHttpRequest(kSimpleGET_Transaction);
11566 
11567   SchemefulSite site_a(GURL("http://a.foo.com"));
11568   SchemefulSite site_b(GURL("http://b.foo.com"));
11569 
11570   net::NetworkIsolationKey key_a(site_a, site_a);
11571   auto nak_a = net::NetworkAnonymizationKey::CreateSameSite(site_a);
11572   trans_info.network_isolation_key = key_a;
11573   trans_info.network_anonymization_key = nak_a;
11574   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11575                                 trans_info, &response);
11576   EXPECT_FALSE(response.was_cached);
11577 
11578   // The second request with a different origin but the same registrable domain
11579   // should be a cache hit.
11580   net::NetworkIsolationKey key_b(site_b, site_b);
11581   auto nak_b = net::NetworkAnonymizationKey::CreateSameSite(site_b);
11582   trans_info.network_isolation_key = key_b;
11583   trans_info.network_anonymization_key = nak_b;
11584   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11585                                 trans_info, &response);
11586   EXPECT_TRUE(response.was_cached);
11587 
11588   // Request with a different registrable domain. It should be a cache miss.
11589   SchemefulSite new_site_a(GURL("http://a.bar.com"));
11590   net::NetworkIsolationKey new_key_a(new_site_a, new_site_a);
11591   auto new_nak_a = net::NetworkAnonymizationKey::CreateSameSite(new_site_a);
11592   trans_info.network_isolation_key = new_key_a;
11593   trans_info.network_anonymization_key = new_nak_a;
11594   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11595                                 trans_info, &response);
11596   EXPECT_FALSE(response.was_cached);
11597 }
11598 
TEST_F(HttpCacheTest,NonSplitCache)11599 TEST_F(HttpCacheTest, NonSplitCache) {
11600   base::test::ScopedFeatureList feature_list;
11601   feature_list.InitAndDisableFeature(
11602       net::features::kSplitCacheByNetworkIsolationKey);
11603 
11604   MockHttpCache cache;
11605   HttpResponseInfo response;
11606 
11607   // A request without a top frame is added to the cache normally.
11608   MockHttpRequest trans_info = MockHttpRequest(kSimpleGET_Transaction);
11609   trans_info.network_isolation_key = NetworkIsolationKey();
11610   trans_info.network_anonymization_key = NetworkAnonymizationKey();
11611   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11612                                 trans_info, &response);
11613   EXPECT_FALSE(response.was_cached);
11614 
11615   // The second request should result in a cache hit.
11616   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11617                                 trans_info, &response);
11618   EXPECT_TRUE(response.was_cached);
11619 
11620   // Now request with a.com as the top frame origin. The same cached object
11621   // should be used.
11622   const SchemefulSite kSiteA(GURL("http://a.com/"));
11623   trans_info.network_isolation_key = NetworkIsolationKey(kSiteA, kSiteA);
11624   trans_info.network_anonymization_key =
11625       NetworkAnonymizationKey::CreateSameSite(kSiteA);
11626   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
11627                                 trans_info, &response);
11628   EXPECT_TRUE(response.was_cached);
11629 }
11630 
TEST_F(HttpCacheTest,SkipVaryCheck)11631 TEST_F(HttpCacheTest, SkipVaryCheck) {
11632   MockHttpCache cache;
11633 
11634   // Write a simple vary transaction to the cache.
11635   HttpResponseInfo response;
11636   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11637   transaction.request_headers = "accept-encoding: gzip\r\n";
11638   transaction.response_headers =
11639       "Vary: accept-encoding\n"
11640       "Cache-Control: max-age=10000\n";
11641   RunTransactionTest(cache.http_cache(), transaction);
11642 
11643   // Change the request headers so that the request doesn't match due to vary.
11644   // The request should fail.
11645   transaction.load_flags = LOAD_ONLY_FROM_CACHE;
11646   transaction.request_headers = "accept-encoding: foo\r\n";
11647   transaction.start_return_code = ERR_CACHE_MISS;
11648   RunTransactionTest(cache.http_cache(), transaction);
11649 
11650   // Change the load flags to ignore vary checks, the request should now hit.
11651   transaction.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_VARY_CHECK;
11652   transaction.start_return_code = OK;
11653   RunTransactionTest(cache.http_cache(), transaction);
11654 }
11655 
TEST_F(HttpCacheTest,SkipVaryCheckStar)11656 TEST_F(HttpCacheTest, SkipVaryCheckStar) {
11657   MockHttpCache cache;
11658 
11659   // Write a simple vary:* transaction to the cache.
11660   HttpResponseInfo response;
11661   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11662   transaction.request_headers = "accept-encoding: gzip\r\n";
11663   transaction.response_headers =
11664       "Vary: *\n"
11665       "Cache-Control: max-age=10000\n";
11666   RunTransactionTest(cache.http_cache(), transaction);
11667 
11668   // The request shouldn't match even with the same request headers due to the
11669   // Vary: *. The request should fail.
11670   transaction.load_flags = LOAD_ONLY_FROM_CACHE;
11671   transaction.start_return_code = ERR_CACHE_MISS;
11672   RunTransactionTest(cache.http_cache(), transaction);
11673 
11674   // Change the load flags to ignore vary checks, the request should now hit.
11675   transaction.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_VARY_CHECK;
11676   transaction.start_return_code = OK;
11677   RunTransactionTest(cache.http_cache(), transaction);
11678 }
11679 
11680 // Tests that we only return valid entries with LOAD_ONLY_FROM_CACHE
11681 // transactions unless LOAD_SKIP_CACHE_VALIDATION is set.
TEST_F(HttpCacheTest,ValidLoadOnlyFromCache)11682 TEST_F(HttpCacheTest, ValidLoadOnlyFromCache) {
11683   MockHttpCache cache;
11684   base::SimpleTestClock clock;
11685   cache.http_cache()->SetClockForTesting(&clock);
11686   cache.network_layer()->SetClock(&clock);
11687 
11688   // Write a resource that will expire in 100 seconds.
11689   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11690   transaction.response_headers = "Cache-Control: max-age=100\n";
11691   RunTransactionTest(cache.http_cache(), transaction);
11692 
11693   // Move forward in time such that the cached response is no longer valid.
11694   clock.Advance(base::Seconds(101));
11695 
11696   // Skipping cache validation should still return a response.
11697   transaction.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION;
11698   RunTransactionTest(cache.http_cache(), transaction);
11699 
11700   // If the cache entry is checked for validitiy, it should fail.
11701   transaction.load_flags = LOAD_ONLY_FROM_CACHE;
11702   transaction.start_return_code = ERR_CACHE_MISS;
11703   RunTransactionTest(cache.http_cache(), transaction);
11704 }
11705 
TEST_F(HttpCacheTest,InvalidLoadFlagCombination)11706 TEST_F(HttpCacheTest, InvalidLoadFlagCombination) {
11707   MockHttpCache cache;
11708 
11709   // Put the resource in the cache.
11710   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
11711 
11712   // Now try to fetch it again, but with a flag combination disallowing both
11713   // cache and network access.
11714   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11715   // DevTools relies on this combination of flags for "disable cache" mode
11716   // when a resource is only supposed to be loaded from cache.
11717   transaction.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_BYPASS_CACHE;
11718   transaction.start_return_code = ERR_CACHE_MISS;
11719   RunTransactionTest(cache.http_cache(), transaction);
11720 }
11721 
11722 // Tests that we don't mark entries as truncated when a filter detects the end
11723 // of the stream.
TEST_F(HttpCacheTest,FilterCompletion)11724 TEST_F(HttpCacheTest, FilterCompletion) {
11725   MockHttpCache cache;
11726   TestCompletionCallback callback;
11727 
11728   {
11729     MockHttpRequest request(kSimpleGET_Transaction);
11730     std::unique_ptr<HttpTransaction> trans;
11731     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11732 
11733     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11734     EXPECT_THAT(callback.GetResult(rv), IsOk());
11735 
11736     auto buf = base::MakeRefCounted<IOBufferWithSize>(256);
11737     rv = trans->Read(buf.get(), 256, callback.callback());
11738     EXPECT_GT(callback.GetResult(rv), 0);
11739 
11740     // Now make sure that the entry is preserved.
11741     trans->DoneReading();
11742   }
11743 
11744   // Make sure that the ActiveEntry is gone.
11745   base::RunLoop().RunUntilIdle();
11746 
11747   // Read from the cache.
11748   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
11749 
11750   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11751   EXPECT_EQ(1, cache.disk_cache()->open_count());
11752   EXPECT_EQ(1, cache.disk_cache()->create_count());
11753 }
11754 
11755 // Tests that we don't mark entries as truncated and release the cache
11756 // entry when DoneReading() is called before any Read() calls, such as
11757 // for a redirect.
TEST_F(HttpCacheTest,DoneReading)11758 TEST_F(HttpCacheTest, DoneReading) {
11759   MockHttpCache cache;
11760   TestCompletionCallback callback;
11761 
11762   ScopedMockTransaction transaction(kSimpleGET_Transaction);
11763   transaction.data = "";
11764   MockHttpRequest request(transaction);
11765 
11766   std::unique_ptr<HttpTransaction> trans;
11767   ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11768 
11769   int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11770   EXPECT_THAT(callback.GetResult(rv), IsOk());
11771 
11772   trans->DoneReading();
11773   // Leave the transaction around.
11774 
11775   // Make sure that the ActiveEntry is gone.
11776   base::RunLoop().RunUntilIdle();
11777 
11778   // Read from the cache. This should not deadlock.
11779   RunTransactionTest(cache.http_cache(), transaction);
11780 
11781   EXPECT_EQ(1, cache.network_layer()->transaction_count());
11782   EXPECT_EQ(1, cache.disk_cache()->open_count());
11783   EXPECT_EQ(1, cache.disk_cache()->create_count());
11784 }
11785 
11786 // Tests that we stop caching when told.
TEST_F(HttpCacheTest,StopCachingDeletesEntry)11787 TEST_F(HttpCacheTest, StopCachingDeletesEntry) {
11788   MockHttpCache cache;
11789   TestCompletionCallback callback;
11790   MockHttpRequest request(kSimpleGET_Transaction);
11791 
11792   {
11793     std::unique_ptr<HttpTransaction> trans;
11794     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11795 
11796     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11797     EXPECT_THAT(callback.GetResult(rv), IsOk());
11798 
11799     auto buf = base::MakeRefCounted<IOBufferWithSize>(256);
11800     rv = trans->Read(buf.get(), 10, callback.callback());
11801     EXPECT_EQ(10, callback.GetResult(rv));
11802 
11803     trans->StopCaching();
11804 
11805     // We should be able to keep reading.
11806     rv = trans->Read(buf.get(), 256, callback.callback());
11807     EXPECT_GT(callback.GetResult(rv), 0);
11808     rv = trans->Read(buf.get(), 256, callback.callback());
11809     EXPECT_EQ(0, callback.GetResult(rv));
11810   }
11811 
11812   // Make sure that the ActiveEntry is gone.
11813   base::RunLoop().RunUntilIdle();
11814 
11815   // Verify that the entry is gone.
11816   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
11817 
11818   EXPECT_EQ(2, cache.network_layer()->transaction_count());
11819   EXPECT_EQ(0, cache.disk_cache()->open_count());
11820   EXPECT_EQ(2, cache.disk_cache()->create_count());
11821 }
11822 
11823 // Tests that we stop caching when told, even if DoneReading is called
11824 // after StopCaching.
TEST_F(HttpCacheTest,StopCachingThenDoneReadingDeletesEntry)11825 TEST_F(HttpCacheTest, StopCachingThenDoneReadingDeletesEntry) {
11826   MockHttpCache cache;
11827   TestCompletionCallback callback;
11828   MockHttpRequest request(kSimpleGET_Transaction);
11829 
11830   {
11831     std::unique_ptr<HttpTransaction> trans;
11832     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11833 
11834     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11835     EXPECT_THAT(callback.GetResult(rv), IsOk());
11836 
11837     auto buf = base::MakeRefCounted<IOBufferWithSize>(256);
11838     rv = trans->Read(buf.get(), 10, callback.callback());
11839     EXPECT_EQ(10, callback.GetResult(rv));
11840 
11841     trans->StopCaching();
11842 
11843     // We should be able to keep reading.
11844     rv = trans->Read(buf.get(), 256, callback.callback());
11845     EXPECT_GT(callback.GetResult(rv), 0);
11846     rv = trans->Read(buf.get(), 256, callback.callback());
11847     EXPECT_EQ(0, callback.GetResult(rv));
11848 
11849     // We should be able to call DoneReading.
11850     trans->DoneReading();
11851   }
11852 
11853   // Make sure that the ActiveEntry is gone.
11854   base::RunLoop().RunUntilIdle();
11855 
11856   // Verify that the entry is gone.
11857   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
11858 
11859   EXPECT_EQ(2, cache.network_layer()->transaction_count());
11860   EXPECT_EQ(0, cache.disk_cache()->open_count());
11861   EXPECT_EQ(2, cache.disk_cache()->create_count());
11862 }
11863 
11864 // Tests that we stop caching when told, when using auth.
TEST_F(HttpCacheTest,StopCachingWithAuthDeletesEntry)11865 TEST_F(HttpCacheTest, StopCachingWithAuthDeletesEntry) {
11866   MockHttpCache cache;
11867   TestCompletionCallback callback;
11868   ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
11869   mock_transaction.status = "HTTP/1.1 401 Unauthorized";
11870   MockHttpRequest request(mock_transaction);
11871 
11872   {
11873     std::unique_ptr<HttpTransaction> trans;
11874     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11875 
11876     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11877     EXPECT_THAT(callback.GetResult(rv), IsOk());
11878 
11879     trans->StopCaching();
11880   }
11881 
11882   // Make sure that the ActiveEntry is gone.
11883   base::RunLoop().RunUntilIdle();
11884 
11885   // Verify that the entry is gone.
11886   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
11887 
11888   EXPECT_EQ(2, cache.network_layer()->transaction_count());
11889   EXPECT_EQ(0, cache.disk_cache()->open_count());
11890   EXPECT_EQ(2, cache.disk_cache()->create_count());
11891 }
11892 
11893 // Tests that when we are told to stop caching we don't throw away valid data.
TEST_F(HttpCacheTest,StopCachingSavesEntry)11894 TEST_F(HttpCacheTest, StopCachingSavesEntry) {
11895   MockHttpCache cache;
11896   TestCompletionCallback callback;
11897   MockHttpRequest request(kSimpleGET_Transaction);
11898 
11899   {
11900     std::unique_ptr<HttpTransaction> trans;
11901     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11902 
11903     // Force a response that can be resumed.
11904     ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
11905     mock_transaction.response_headers =
11906         "Cache-Control: max-age=10000\n"
11907         "Content-Length: 42\n"
11908         "Etag: \"foo\"\n";
11909 
11910     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11911     EXPECT_THAT(callback.GetResult(rv), IsOk());
11912 
11913     auto buf = base::MakeRefCounted<IOBufferWithSize>(256);
11914     rv = trans->Read(buf.get(), 10, callback.callback());
11915     EXPECT_EQ(callback.GetResult(rv), 10);
11916 
11917     trans->StopCaching();
11918 
11919     // We should be able to keep reading.
11920     rv = trans->Read(buf.get(), 256, callback.callback());
11921     EXPECT_GT(callback.GetResult(rv), 0);
11922     rv = trans->Read(buf.get(), 256, callback.callback());
11923     EXPECT_EQ(callback.GetResult(rv), 0);
11924   }
11925 
11926   // Verify that the entry is marked as incomplete.
11927   // VerifyTruncatedFlag(&cache, kSimpleGET_Transaction.url, true, 0);
11928   // Verify that the entry is doomed.
11929   cache.disk_cache()->IsDiskEntryDoomed(request.CacheKey());
11930 }
11931 
11932 // Tests that we handle truncated enries when StopCaching is called.
TEST_F(HttpCacheTest,StopCachingTruncatedEntry)11933 TEST_F(HttpCacheTest, StopCachingTruncatedEntry) {
11934   MockHttpCache cache;
11935   TestCompletionCallback callback;
11936   MockHttpRequest request(kRangeGET_TransactionOK);
11937   request.extra_headers.Clear();
11938   request.extra_headers.AddHeaderFromString(EXTRA_HEADER_LINE);
11939   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
11940 
11941   std::string raw_headers(
11942       "HTTP/1.1 200 OK\n"
11943       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
11944       "ETag: \"foo\"\n"
11945       "Accept-Ranges: bytes\n"
11946       "Content-Length: 80\n");
11947   CreateTruncatedEntry(raw_headers, &cache);
11948 
11949   {
11950     // Now make a regular request.
11951     std::unique_ptr<HttpTransaction> trans;
11952     ASSERT_THAT(cache.CreateTransaction(&trans), IsOk());
11953 
11954     int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
11955     EXPECT_THAT(callback.GetResult(rv), IsOk());
11956 
11957     auto buf = base::MakeRefCounted<IOBufferWithSize>(256);
11958     rv = trans->Read(buf.get(), 10, callback.callback());
11959     EXPECT_EQ(callback.GetResult(rv), 10);
11960 
11961     // This is actually going to do nothing.
11962     trans->StopCaching();
11963 
11964     // We should be able to keep reading.
11965     rv = trans->Read(buf.get(), 256, callback.callback());
11966     EXPECT_GT(callback.GetResult(rv), 0);
11967     rv = trans->Read(buf.get(), 256, callback.callback());
11968     EXPECT_GT(callback.GetResult(rv), 0);
11969     rv = trans->Read(buf.get(), 256, callback.callback());
11970     EXPECT_EQ(callback.GetResult(rv), 0);
11971   }
11972 
11973   // Verify that the disk entry was updated.
11974   VerifyTruncatedFlag(&cache, request.CacheKey(), false, 80);
11975 }
11976 
11977 namespace {
11978 
11979 enum class TransactionPhase {
11980   BEFORE_FIRST_READ,
11981   AFTER_FIRST_READ,
11982   AFTER_NETWORK_READ
11983 };
11984 
11985 using CacheInitializer = void (*)(MockHttpCache*);
11986 using HugeCacheTestConfiguration =
11987     std::pair<TransactionPhase, CacheInitializer>;
11988 
11989 class HttpCacheHugeResourceTest
11990     : public ::testing::TestWithParam<HugeCacheTestConfiguration>,
11991       public WithTaskEnvironment {
11992  public:
11993   static std::list<HugeCacheTestConfiguration> GetTestModes();
11994   static std::list<HugeCacheTestConfiguration> kTestModes;
11995 
11996   // CacheInitializer callbacks. These are used to initialize the cache
11997   // depending on the test run configuration.
11998 
11999   // Initializes a cache containing a truncated entry containing the first 20
12000   // bytes of the reponse body.
12001   static void SetupTruncatedCacheEntry(MockHttpCache* cache);
12002 
12003   // Initializes a cache containing a sparse entry. The first 10 bytes are
12004   // present in the cache.
12005   static void SetupPrefixSparseCacheEntry(MockHttpCache* cache);
12006 
12007   // Initializes a cache containing a sparse entry. The 10 bytes at offset
12008   // 99990 are present in the cache.
12009   static void SetupInfixSparseCacheEntry(MockHttpCache* cache);
12010 
12011  protected:
12012   static void LargeResourceTransactionHandler(
12013       const net::HttpRequestInfo* request,
12014       std::string* response_status,
12015       std::string* response_headers,
12016       std::string* response_data);
12017   static int LargeBufferReader(int64_t content_length,
12018                                int64_t offset,
12019                                net::IOBuffer* buf,
12020                                int buf_len);
12021 
12022   static void SetFlagOnBeforeNetworkStart(bool* started, bool* /* defer */);
12023 
12024   // Size of resource to be tested.
12025   static const int64_t kTotalSize = 5000LL * 1000 * 1000;
12026 };
12027 
12028 const int64_t HttpCacheHugeResourceTest::kTotalSize;
12029 
12030 // static
LargeResourceTransactionHandler(const net::HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)12031 void HttpCacheHugeResourceTest::LargeResourceTransactionHandler(
12032     const net::HttpRequestInfo* request,
12033     std::string* response_status,
12034     std::string* response_headers,
12035     std::string* response_data) {
12036   std::string if_range;
12037   if (!request->extra_headers.GetHeader(net::HttpRequestHeaders::kIfRange,
12038                                         &if_range)) {
12039     // If there were no range headers in the request, we are going to just
12040     // return the entire response body.
12041     *response_status = "HTTP/1.1 200 Success";
12042     *response_headers = base::StringPrintf("Content-Length: %" PRId64
12043                                            "\n"
12044                                            "ETag: \"foo\"\n"
12045                                            "Accept-Ranges: bytes\n",
12046                                            kTotalSize);
12047     return;
12048   }
12049 
12050   // From this point on, we should be processing a valid byte-range request.
12051   EXPECT_EQ("\"foo\"", if_range);
12052 
12053   std::string range_header;
12054   EXPECT_TRUE(request->extra_headers.GetHeader(net::HttpRequestHeaders::kRange,
12055                                                &range_header));
12056   std::vector<net::HttpByteRange> ranges;
12057 
12058   EXPECT_TRUE(net::HttpUtil::ParseRangeHeader(range_header, &ranges));
12059   ASSERT_EQ(1u, ranges.size());
12060 
12061   net::HttpByteRange range = ranges[0];
12062   EXPECT_TRUE(range.HasFirstBytePosition());
12063   int64_t last_byte_position =
12064       range.HasLastBytePosition() ? range.last_byte_position() : kTotalSize - 1;
12065 
12066   *response_status = "HTTP/1.1 206 Partial";
12067   *response_headers = base::StringPrintf(
12068       "Content-Range: bytes %" PRId64 "-%" PRId64 "/%" PRId64
12069       "\n"
12070       "Content-Length: %" PRId64 "\n",
12071       range.first_byte_position(), last_byte_position, kTotalSize,
12072       last_byte_position - range.first_byte_position() + 1);
12073 }
12074 
12075 // static
LargeBufferReader(int64_t content_length,int64_t offset,net::IOBuffer * buf,int buf_len)12076 int HttpCacheHugeResourceTest::LargeBufferReader(int64_t content_length,
12077                                                  int64_t offset,
12078                                                  net::IOBuffer* buf,
12079                                                  int buf_len) {
12080   // This test involves reading multiple gigabytes of data. To make it run in a
12081   // reasonable amount of time, we are going to skip filling the buffer with
12082   // data. Instead the test relies on verifying that the count of bytes expected
12083   // at the end is correct.
12084   EXPECT_LT(0, content_length);
12085   EXPECT_LE(offset, content_length);
12086   int num = std::min(static_cast<int64_t>(buf_len), content_length - offset);
12087   return num;
12088 }
12089 
12090 // static
SetFlagOnBeforeNetworkStart(bool * started,bool *)12091 void HttpCacheHugeResourceTest::SetFlagOnBeforeNetworkStart(bool* started,
12092                                                             bool* /* defer */) {
12093   *started = true;
12094 }
12095 
12096 // static
SetupTruncatedCacheEntry(MockHttpCache * cache)12097 void HttpCacheHugeResourceTest::SetupTruncatedCacheEntry(MockHttpCache* cache) {
12098   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
12099   std::string cached_headers = base::StringPrintf(
12100       "HTTP/1.1 200 OK\n"
12101       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12102       "ETag: \"foo\"\n"
12103       "Accept-Ranges: bytes\n"
12104       "Content-Length: %" PRId64 "\n",
12105       kTotalSize);
12106   CreateTruncatedEntry(cached_headers, cache);
12107 }
12108 
12109 // static
SetupPrefixSparseCacheEntry(MockHttpCache * cache)12110 void HttpCacheHugeResourceTest::SetupPrefixSparseCacheEntry(
12111     MockHttpCache* cache) {
12112   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
12113   transaction.handler = MockTransactionHandler();
12114   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
12115   transaction.response_headers =
12116       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12117       "ETag: \"foo\"\n"
12118       "Accept-Ranges: bytes\n"
12119       "Content-Range: bytes 0-9/5000000000\n"
12120       "Content-Length: 10\n";
12121   std::string headers;
12122   RunTransactionTestWithResponse(cache->http_cache(), transaction, &headers);
12123 }
12124 
12125 // static
SetupInfixSparseCacheEntry(MockHttpCache * cache)12126 void HttpCacheHugeResourceTest::SetupInfixSparseCacheEntry(
12127     MockHttpCache* cache) {
12128   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
12129   transaction.handler = MockTransactionHandler();
12130   transaction.request_headers = "Range: bytes = 99990-99999\r\n" EXTRA_HEADER;
12131   transaction.response_headers =
12132       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12133       "ETag: \"foo\"\n"
12134       "Accept-Ranges: bytes\n"
12135       "Content-Range: bytes 99990-99999/5000000000\n"
12136       "Content-Length: 10\n";
12137   std::string headers;
12138   RunTransactionTestWithResponse(cache->http_cache(), transaction, &headers);
12139 }
12140 
12141 // static
12142 std::list<HugeCacheTestConfiguration>
GetTestModes()12143 HttpCacheHugeResourceTest::GetTestModes() {
12144   std::list<HugeCacheTestConfiguration> test_modes;
12145   const TransactionPhase kTransactionPhases[] = {
12146       TransactionPhase::BEFORE_FIRST_READ, TransactionPhase::AFTER_FIRST_READ,
12147       TransactionPhase::AFTER_NETWORK_READ};
12148   const CacheInitializer kInitializers[] = {&SetupTruncatedCacheEntry,
12149                                             &SetupPrefixSparseCacheEntry,
12150                                             &SetupInfixSparseCacheEntry};
12151 
12152   for (const auto phase : kTransactionPhases) {
12153     for (const auto initializer : kInitializers) {
12154       test_modes.emplace_back(phase, initializer);
12155     }
12156   }
12157 
12158   return test_modes;
12159 }
12160 
12161 // static
12162 std::list<HugeCacheTestConfiguration> HttpCacheHugeResourceTest::kTestModes =
12163     HttpCacheHugeResourceTest::GetTestModes();
12164 
12165 INSTANTIATE_TEST_SUITE_P(
12166     _,
12167     HttpCacheHugeResourceTest,
12168     ::testing::ValuesIn(HttpCacheHugeResourceTest::kTestModes));
12169 
12170 }  // namespace
12171 
12172 // Test what happens when StopCaching() is called while reading a huge resource
12173 // fetched via GET. Various combinations of cache state and when StopCaching()
12174 // is called is controlled by the parameter passed into the test via the
12175 // INSTANTIATE_TEST_SUITE_P invocation above.
TEST_P(HttpCacheHugeResourceTest,StopCachingFollowedByReadForHugeTruncatedResource)12176 TEST_P(HttpCacheHugeResourceTest,
12177        StopCachingFollowedByReadForHugeTruncatedResource) {
12178   // This test is going to be repeated for all combinations of TransactionPhase
12179   // and CacheInitializers returned by GetTestModes().
12180   const TransactionPhase stop_caching_phase = GetParam().first;
12181   const CacheInitializer cache_initializer = GetParam().second;
12182 
12183   MockHttpCache cache;
12184   (*cache_initializer)(&cache);
12185 
12186   MockTransaction transaction(kSimpleGET_Transaction);
12187   transaction.url = kRangeGET_TransactionOK.url;
12188   transaction.handler = base::BindRepeating(&LargeResourceTransactionHandler);
12189   transaction.read_handler = base::BindRepeating(&LargeBufferReader);
12190   ScopedMockTransaction scoped_transaction(transaction);
12191 
12192   MockHttpRequest request(transaction);
12193   net::TestCompletionCallback callback;
12194   std::unique_ptr<net::HttpTransaction> http_transaction;
12195   int rv = cache.http_cache()->CreateTransaction(net::DEFAULT_PRIORITY,
12196                                                  &http_transaction);
12197   ASSERT_EQ(net::OK, rv);
12198   ASSERT_TRUE(http_transaction.get());
12199 
12200   bool network_transaction_started = false;
12201   if (stop_caching_phase == TransactionPhase::AFTER_NETWORK_READ) {
12202     http_transaction->SetBeforeNetworkStartCallback(base::BindOnce(
12203         &SetFlagOnBeforeNetworkStart, &network_transaction_started));
12204   }
12205 
12206   rv = http_transaction->Start(&request, callback.callback(),
12207                                NetLogWithSource());
12208   rv = callback.GetResult(rv);
12209   ASSERT_EQ(net::OK, rv);
12210 
12211   if (stop_caching_phase == TransactionPhase::BEFORE_FIRST_READ) {
12212     http_transaction->StopCaching();
12213   }
12214 
12215   int64_t total_bytes_received = 0;
12216 
12217   EXPECT_EQ(kTotalSize,
12218             http_transaction->GetResponseInfo()->headers->GetContentLength());
12219   do {
12220     // This test simulates reading gigabytes of data. Buffer size is set to 10MB
12221     // to reduce the number of reads and speed up the test.
12222     const int kBufferSize = 1024 * 1024 * 10;
12223     scoped_refptr<net::IOBuffer> buf =
12224         base::MakeRefCounted<net::IOBufferWithSize>(kBufferSize);
12225     rv = http_transaction->Read(buf.get(), kBufferSize, callback.callback());
12226     rv = callback.GetResult(rv);
12227 
12228     if (stop_caching_phase == TransactionPhase::AFTER_FIRST_READ &&
12229         total_bytes_received == 0) {
12230       http_transaction->StopCaching();
12231     }
12232 
12233     if (rv > 0) {
12234       total_bytes_received += rv;
12235     }
12236 
12237     if (network_transaction_started &&
12238         stop_caching_phase == TransactionPhase::AFTER_NETWORK_READ) {
12239       http_transaction->StopCaching();
12240       network_transaction_started = false;
12241     }
12242   } while (rv > 0);
12243 
12244   // The only verification we are going to do is that the received resource has
12245   // the correct size. This is sufficient to verify that the state machine
12246   // didn't terminate abruptly due to the StopCaching() call.
12247   EXPECT_EQ(kTotalSize, total_bytes_received);
12248 }
12249 
12250 // Tests that we detect truncated resources from the net when there is
12251 // a Content-Length header.
TEST_F(HttpCacheTest,TruncatedByContentLength)12252 TEST_F(HttpCacheTest, TruncatedByContentLength) {
12253   MockHttpCache cache;
12254   TestCompletionCallback callback;
12255 
12256   {
12257     ScopedMockTransaction transaction(kSimpleGET_Transaction);
12258     transaction.response_headers =
12259         "Cache-Control: max-age=10000\n"
12260         "Content-Length: 100\n";
12261     RunTransactionTest(cache.http_cache(), transaction);
12262   }
12263 
12264   // Read from the cache.
12265   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
12266 
12267   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12268   EXPECT_EQ(0, cache.disk_cache()->open_count());
12269   EXPECT_EQ(2, cache.disk_cache()->create_count());
12270 }
12271 
12272 // Tests that we actually flag entries as truncated when we detect an error
12273 // from the net.
TEST_F(HttpCacheTest,TruncatedByContentLength2)12274 TEST_F(HttpCacheTest, TruncatedByContentLength2) {
12275   MockHttpCache cache;
12276   TestCompletionCallback callback;
12277 
12278   {
12279     ScopedMockTransaction transaction(kSimpleGET_Transaction);
12280     transaction.response_headers =
12281         "Cache-Control: max-age=10000\n"
12282         "Content-Length: 100\n"
12283         "Etag: \"foo\"\n";
12284     RunTransactionTest(cache.http_cache(), transaction);
12285   }
12286 
12287   // Verify that the entry is marked as incomplete.
12288   MockHttpRequest request(kSimpleGET_Transaction);
12289   VerifyTruncatedFlag(&cache, request.CacheKey(), true, 0);
12290 }
12291 
12292 // Make sure that calling SetPriority on a cache transaction passes on
12293 // its priority updates to its underlying network transaction.
TEST_F(HttpCacheTest,SetPriority)12294 TEST_F(HttpCacheTest, SetPriority) {
12295   MockHttpCache cache;
12296 
12297   HttpRequestInfo info;
12298   std::unique_ptr<HttpTransaction> trans;
12299   ASSERT_THAT(cache.http_cache()->CreateTransaction(IDLE, &trans), IsOk());
12300 
12301   // Shouldn't crash, but doesn't do anything either.
12302   trans->SetPriority(LOW);
12303 
12304   EXPECT_FALSE(cache.network_layer()->last_transaction());
12305   EXPECT_EQ(DEFAULT_PRIORITY,
12306             cache.network_layer()->last_create_transaction_priority());
12307 
12308   info.url = GURL(kSimpleGET_Transaction.url);
12309   TestCompletionCallback callback;
12310   EXPECT_EQ(ERR_IO_PENDING,
12311             trans->Start(&info, callback.callback(), NetLogWithSource()));
12312 
12313   EXPECT_TRUE(cache.network_layer()->last_transaction());
12314   if (cache.network_layer()->last_transaction()) {
12315     EXPECT_EQ(LOW, cache.network_layer()->last_create_transaction_priority());
12316     EXPECT_EQ(LOW, cache.network_layer()->last_transaction()->priority());
12317   }
12318 
12319   trans->SetPriority(HIGHEST);
12320 
12321   if (cache.network_layer()->last_transaction()) {
12322     EXPECT_EQ(LOW, cache.network_layer()->last_create_transaction_priority());
12323     EXPECT_EQ(HIGHEST, cache.network_layer()->last_transaction()->priority());
12324   }
12325 
12326   EXPECT_THAT(callback.WaitForResult(), IsOk());
12327 }
12328 
12329 // Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache
12330 // transaction passes on its argument to the underlying network transaction.
TEST_F(HttpCacheTest,SetWebSocketHandshakeStreamCreateHelper)12331 TEST_F(HttpCacheTest, SetWebSocketHandshakeStreamCreateHelper) {
12332   MockHttpCache cache;
12333   HttpRequestInfo info;
12334 
12335   FakeWebSocketHandshakeStreamCreateHelper create_helper;
12336   std::unique_ptr<HttpTransaction> trans;
12337   ASSERT_THAT(cache.http_cache()->CreateTransaction(IDLE, &trans), IsOk());
12338 
12339   EXPECT_FALSE(cache.network_layer()->last_transaction());
12340 
12341   info.url = GURL(kSimpleGET_Transaction.url);
12342   TestCompletionCallback callback;
12343   EXPECT_EQ(ERR_IO_PENDING,
12344             trans->Start(&info, callback.callback(), NetLogWithSource()));
12345 
12346   ASSERT_TRUE(cache.network_layer()->last_transaction());
12347   EXPECT_FALSE(cache.network_layer()
12348                    ->last_transaction()
12349                    ->websocket_handshake_stream_create_helper());
12350   trans->SetWebSocketHandshakeStreamCreateHelper(&create_helper);
12351   EXPECT_EQ(&create_helper, cache.network_layer()
12352                                 ->last_transaction()
12353                                 ->websocket_handshake_stream_create_helper());
12354   EXPECT_THAT(callback.WaitForResult(), IsOk());
12355 }
12356 
12357 // Make sure that a cache transaction passes on its priority to
12358 // newly-created network transactions.
TEST_F(HttpCacheTest,SetPriorityNewTransaction)12359 TEST_F(HttpCacheTest, SetPriorityNewTransaction) {
12360   MockHttpCache cache;
12361   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
12362 
12363   std::string raw_headers(
12364       "HTTP/1.1 200 OK\n"
12365       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12366       "ETag: \"foo\"\n"
12367       "Accept-Ranges: bytes\n"
12368       "Content-Length: 80\n");
12369   CreateTruncatedEntry(raw_headers, &cache);
12370 
12371   // Now make a regular request.
12372   std::string headers;
12373   MockTransaction transaction(kRangeGET_TransactionOK);
12374   transaction.request_headers = EXTRA_HEADER;
12375   transaction.data = kFullRangeData;
12376 
12377   std::unique_ptr<HttpTransaction> trans;
12378   ASSERT_THAT(cache.http_cache()->CreateTransaction(MEDIUM, &trans), IsOk());
12379   EXPECT_EQ(DEFAULT_PRIORITY,
12380             cache.network_layer()->last_create_transaction_priority());
12381 
12382   MockHttpRequest info(transaction);
12383   TestCompletionCallback callback;
12384   EXPECT_EQ(ERR_IO_PENDING,
12385             trans->Start(&info, callback.callback(), NetLogWithSource()));
12386   EXPECT_THAT(callback.WaitForResult(), IsOk());
12387 
12388   EXPECT_EQ(MEDIUM, cache.network_layer()->last_create_transaction_priority());
12389 
12390   trans->SetPriority(HIGHEST);
12391   // Should trigger a new network transaction and pick up the new
12392   // priority.
12393   ReadAndVerifyTransaction(trans.get(), transaction);
12394 
12395   EXPECT_EQ(HIGHEST, cache.network_layer()->last_create_transaction_priority());
12396 }
12397 
12398 namespace {
12399 
RunTransactionAndGetNetworkBytes(MockHttpCache * cache,const MockTransaction & trans_info,int64_t * sent_bytes,int64_t * received_bytes)12400 void RunTransactionAndGetNetworkBytes(MockHttpCache* cache,
12401                                       const MockTransaction& trans_info,
12402                                       int64_t* sent_bytes,
12403                                       int64_t* received_bytes) {
12404   RunTransactionTestBase(
12405       cache->http_cache(), trans_info, MockHttpRequest(trans_info), nullptr,
12406       NetLogWithSource(), nullptr, sent_bytes, received_bytes, nullptr);
12407 }
12408 
12409 }  // namespace
12410 
TEST_F(HttpCacheTest,NetworkBytesCacheMissAndThenHit)12411 TEST_F(HttpCacheTest, NetworkBytesCacheMissAndThenHit) {
12412   MockHttpCache cache;
12413 
12414   MockTransaction transaction(kSimpleGET_Transaction);
12415   int64_t sent, received;
12416   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12417   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12418   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12419 
12420   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12421   EXPECT_EQ(0, sent);
12422   EXPECT_EQ(0, received);
12423 }
12424 
TEST_F(HttpCacheTest,NetworkBytesConditionalRequest304)12425 TEST_F(HttpCacheTest, NetworkBytesConditionalRequest304) {
12426   MockHttpCache cache;
12427 
12428   ScopedMockTransaction transaction(kETagGET_Transaction);
12429   int64_t sent, received;
12430   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12431   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12432   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12433 
12434   transaction.load_flags = LOAD_VALIDATE_CACHE;
12435   transaction.handler = kETagGetConditionalRequestHandler;
12436   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12437   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12438   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12439 }
12440 
TEST_F(HttpCacheTest,NetworkBytesConditionalRequest200)12441 TEST_F(HttpCacheTest, NetworkBytesConditionalRequest200) {
12442   MockHttpCache cache;
12443 
12444   ScopedMockTransaction transaction(kTypicalGET_Transaction);
12445   transaction.request_headers = "Foo: bar\r\n";
12446   transaction.response_headers =
12447       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
12448       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
12449       "Etag: \"foopy\"\n"
12450       "Cache-Control: max-age=0\n"
12451       "Vary: Foo\n";
12452   int64_t sent, received;
12453   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12454   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12455   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12456 
12457   RevalidationServer server;
12458   transaction.handler = server.GetHandlerCallback();
12459 
12460   transaction.request_headers = "Foo: none\r\n";
12461   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12462   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12463   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12464 }
12465 
TEST_F(HttpCacheTest,NetworkBytesRange)12466 TEST_F(HttpCacheTest, NetworkBytesRange) {
12467   MockHttpCache cache;
12468   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
12469 
12470   // Read bytes 40-49 from the network.
12471   int64_t sent, received;
12472   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12473   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12474   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12475 
12476   // Read bytes 40-49 from the cache.
12477   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12478   EXPECT_EQ(0, sent);
12479   EXPECT_EQ(0, received);
12480   base::RunLoop().RunUntilIdle();
12481 
12482   // Read bytes 30-39 from the network.
12483   transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
12484   transaction.data = "rg: 30-39 ";
12485   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12486   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes, sent);
12487   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes, received);
12488   base::RunLoop().RunUntilIdle();
12489 
12490   // Read bytes 20-29 and 50-59 from the network, bytes 30-49 from the cache.
12491   transaction.request_headers = "Range: bytes = 20-59\r\n" EXTRA_HEADER;
12492   transaction.data = "rg: 20-29 rg: 30-39 rg: 40-49 rg: 50-59 ";
12493   RunTransactionAndGetNetworkBytes(&cache, transaction, &sent, &received);
12494   EXPECT_EQ(MockNetworkTransaction::kTotalSentBytes * 2, sent);
12495   EXPECT_EQ(MockNetworkTransaction::kTotalReceivedBytes * 2, received);
12496 }
12497 
12498 class HttpCachePrefetchValidationTest : public TestWithTaskEnvironment {
12499  protected:
12500   static const int kNumSecondsPerMinute = 60;
12501   static const int kMaxAgeSecs = 100;
12502   static const int kRequireValidationSecs = kMaxAgeSecs + 1;
12503 
HttpCachePrefetchValidationTest()12504   HttpCachePrefetchValidationTest() : transaction_(kSimpleGET_Transaction) {
12505     DCHECK_LT(kMaxAgeSecs, prefetch_reuse_mins() * kNumSecondsPerMinute);
12506 
12507     cache_.http_cache()->SetClockForTesting(&clock_);
12508     cache_.network_layer()->SetClock(&clock_);
12509 
12510     transaction_.response_headers = "Cache-Control: max-age=100\n";
12511   }
12512 
TransactionRequiredNetwork(int load_flags)12513   bool TransactionRequiredNetwork(int load_flags) {
12514     int pre_transaction_count = transaction_count();
12515     transaction_.load_flags = load_flags;
12516     RunTransactionTest(cache_.http_cache(), transaction_);
12517     return pre_transaction_count != transaction_count();
12518   }
12519 
AdvanceTime(int seconds)12520   void AdvanceTime(int seconds) { clock_.Advance(base::Seconds(seconds)); }
12521 
prefetch_reuse_mins()12522   int prefetch_reuse_mins() { return HttpCache::kPrefetchReuseMins; }
12523 
12524   // How many times this test has sent requests to the (fake) origin
12525   // server. Every test case needs to make at least one request to initialise
12526   // the cache.
transaction_count()12527   int transaction_count() {
12528     return cache_.network_layer()->transaction_count();
12529   }
12530 
12531   MockHttpCache cache_;
12532   ScopedMockTransaction transaction_;
12533   std::string response_headers_;
12534   base::SimpleTestClock clock_;
12535 };
12536 
TEST_F(HttpCachePrefetchValidationTest,SkipValidationShortlyAfterPrefetch)12537 TEST_F(HttpCachePrefetchValidationTest, SkipValidationShortlyAfterPrefetch) {
12538   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12539   AdvanceTime(kRequireValidationSecs);
12540   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12541 }
12542 
TEST_F(HttpCachePrefetchValidationTest,ValidateLongAfterPrefetch)12543 TEST_F(HttpCachePrefetchValidationTest, ValidateLongAfterPrefetch) {
12544   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12545   AdvanceTime(prefetch_reuse_mins() * kNumSecondsPerMinute);
12546   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12547 }
12548 
TEST_F(HttpCachePrefetchValidationTest,SkipValidationOnceOnly)12549 TEST_F(HttpCachePrefetchValidationTest, SkipValidationOnceOnly) {
12550   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12551   AdvanceTime(kRequireValidationSecs);
12552   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12553   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12554 }
12555 
TEST_F(HttpCachePrefetchValidationTest,SkipValidationOnceReadOnly)12556 TEST_F(HttpCachePrefetchValidationTest, SkipValidationOnceReadOnly) {
12557   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12558   AdvanceTime(kRequireValidationSecs);
12559   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_ONLY_FROM_CACHE |
12560                                           LOAD_SKIP_CACHE_VALIDATION));
12561   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12562 }
12563 
TEST_F(HttpCachePrefetchValidationTest,BypassCacheOverwritesPrefetch)12564 TEST_F(HttpCachePrefetchValidationTest, BypassCacheOverwritesPrefetch) {
12565   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12566   AdvanceTime(kRequireValidationSecs);
12567   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_BYPASS_CACHE));
12568   AdvanceTime(kRequireValidationSecs);
12569   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12570 }
12571 
TEST_F(HttpCachePrefetchValidationTest,SkipValidationOnExistingEntryThatNeedsValidation)12572 TEST_F(HttpCachePrefetchValidationTest,
12573        SkipValidationOnExistingEntryThatNeedsValidation) {
12574   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12575   AdvanceTime(kRequireValidationSecs);
12576   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12577   AdvanceTime(kRequireValidationSecs);
12578   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12579   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12580 }
12581 
TEST_F(HttpCachePrefetchValidationTest,SkipValidationOnExistingEntryThatDoesNotNeedValidation)12582 TEST_F(HttpCachePrefetchValidationTest,
12583        SkipValidationOnExistingEntryThatDoesNotNeedValidation) {
12584   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12585   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH));
12586   AdvanceTime(kRequireValidationSecs);
12587   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12588   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_NORMAL));
12589 }
12590 
TEST_F(HttpCachePrefetchValidationTest,PrefetchMultipleTimes)12591 TEST_F(HttpCachePrefetchValidationTest, PrefetchMultipleTimes) {
12592   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12593   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_PREFETCH));
12594   AdvanceTime(kRequireValidationSecs);
12595   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12596 }
12597 
TEST_F(HttpCachePrefetchValidationTest,ValidateOnDelayedSecondPrefetch)12598 TEST_F(HttpCachePrefetchValidationTest, ValidateOnDelayedSecondPrefetch) {
12599   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12600   AdvanceTime(kRequireValidationSecs);
12601   EXPECT_TRUE(TransactionRequiredNetwork(LOAD_PREFETCH));
12602   AdvanceTime(kRequireValidationSecs);
12603   EXPECT_FALSE(TransactionRequiredNetwork(LOAD_NORMAL));
12604 }
12605 
TEST_F(HttpCacheTest,StaleContentNotUsedWhenLoadFlagNotSet)12606 TEST_F(HttpCacheTest, StaleContentNotUsedWhenLoadFlagNotSet) {
12607   MockHttpCache cache;
12608 
12609   ScopedMockTransaction stale_while_revalidate_transaction(
12610       kSimpleGET_Transaction);
12611 
12612   stale_while_revalidate_transaction.response_headers =
12613       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12614       "Age: 10801\n"
12615       "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
12616 
12617   // Write to the cache.
12618   RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
12619 
12620   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12621 
12622   // Send the request again and check that it is sent to the network again.
12623   HttpResponseInfo response_info;
12624   RunTransactionTestWithResponseInfo(
12625       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12626 
12627   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12628   EXPECT_FALSE(response_info.async_revalidation_requested);
12629 }
12630 
TEST_F(HttpCacheTest,StaleContentUsedWhenLoadFlagSetAndUsableThenTimesout)12631 TEST_F(HttpCacheTest, StaleContentUsedWhenLoadFlagSetAndUsableThenTimesout) {
12632   MockHttpCache cache;
12633   base::SimpleTestClock clock;
12634   cache.http_cache()->SetClockForTesting(&clock);
12635   cache.network_layer()->SetClock(&clock);
12636   clock.Advance(base::Seconds(10));
12637 
12638   ScopedMockTransaction stale_while_revalidate_transaction(
12639       kSimpleGET_Transaction);
12640   stale_while_revalidate_transaction.load_flags |=
12641       LOAD_SUPPORT_ASYNC_REVALIDATION;
12642   stale_while_revalidate_transaction.response_headers =
12643       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12644       "Age: 10801\n"
12645       "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
12646 
12647   // Write to the cache.
12648   RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
12649 
12650   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12651 
12652   // Send the request again and check that it is not sent to the network again.
12653   HttpResponseInfo response_info;
12654   RunTransactionTestWithResponseInfo(
12655       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12656 
12657   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12658   EXPECT_TRUE(response_info.async_revalidation_requested);
12659   EXPECT_FALSE(response_info.stale_revalidate_timeout.is_null());
12660 
12661   // Move forward in time such that the stale response is no longer valid.
12662   clock.SetNow(response_info.stale_revalidate_timeout);
12663   clock.Advance(base::Seconds(1));
12664 
12665   RunTransactionTestWithResponseInfo(
12666       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12667 
12668   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12669   EXPECT_FALSE(response_info.async_revalidation_requested);
12670 }
12671 
TEST_F(HttpCacheTest,StaleContentUsedWhenLoadFlagSetAndUsable)12672 TEST_F(HttpCacheTest, StaleContentUsedWhenLoadFlagSetAndUsable) {
12673   MockHttpCache cache;
12674   base::SimpleTestClock clock;
12675   cache.http_cache()->SetClockForTesting(&clock);
12676   cache.network_layer()->SetClock(&clock);
12677   clock.Advance(base::Seconds(10));
12678 
12679   ScopedMockTransaction stale_while_revalidate_transaction(
12680       kSimpleGET_Transaction);
12681   stale_while_revalidate_transaction.load_flags |=
12682       LOAD_SUPPORT_ASYNC_REVALIDATION;
12683   stale_while_revalidate_transaction.response_headers =
12684       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12685       "Age: 10801\n"
12686       "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
12687 
12688   // Write to the cache.
12689   RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
12690 
12691   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12692 
12693   // Send the request again and check that it is not sent to the network again.
12694   HttpResponseInfo response_info;
12695   RunTransactionTestWithResponseInfo(
12696       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12697 
12698   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12699   EXPECT_TRUE(response_info.async_revalidation_requested);
12700   EXPECT_FALSE(response_info.stale_revalidate_timeout.is_null());
12701   base::Time revalidation_timeout = response_info.stale_revalidate_timeout;
12702   clock.Advance(base::Seconds(1));
12703   EXPECT_TRUE(clock.Now() < revalidation_timeout);
12704 
12705   // Fetch the resource again inside the revalidation timeout window.
12706   RunTransactionTestWithResponseInfo(
12707       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12708 
12709   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12710   EXPECT_TRUE(response_info.async_revalidation_requested);
12711   EXPECT_FALSE(response_info.stale_revalidate_timeout.is_null());
12712   // Expect that the original revalidation timeout hasn't changed.
12713   EXPECT_TRUE(revalidation_timeout == response_info.stale_revalidate_timeout);
12714 
12715   // mask of async revalidation flag.
12716   stale_while_revalidate_transaction.load_flags &=
12717       ~LOAD_SUPPORT_ASYNC_REVALIDATION;
12718   stale_while_revalidate_transaction.status = "HTTP/1.1 304 Not Modified";
12719   // Write 304 to the cache.
12720   RunTransactionTestWithResponseInfo(
12721       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12722 
12723   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12724   EXPECT_FALSE(response_info.async_revalidation_requested);
12725   EXPECT_TRUE(response_info.stale_revalidate_timeout.is_null());
12726 }
12727 
TEST_F(HttpCacheTest,StaleContentNotUsedWhenUnusable)12728 TEST_F(HttpCacheTest, StaleContentNotUsedWhenUnusable) {
12729   MockHttpCache cache;
12730 
12731   ScopedMockTransaction stale_while_revalidate_transaction(
12732       kSimpleGET_Transaction);
12733   stale_while_revalidate_transaction.load_flags |=
12734       LOAD_SUPPORT_ASYNC_REVALIDATION;
12735   stale_while_revalidate_transaction.response_headers =
12736       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12737       "Age: 10801\n"
12738       "Cache-Control: max-age=0,stale-while-revalidate=1800\n";
12739 
12740   // Write to the cache.
12741   RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
12742 
12743   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12744 
12745   // Send the request again and check that it is sent to the network again.
12746   HttpResponseInfo response_info;
12747   RunTransactionTestWithResponseInfo(
12748       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12749 
12750   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12751   EXPECT_FALSE(response_info.async_revalidation_requested);
12752 }
12753 
TEST_F(HttpCacheTest,StaleContentWriteError)12754 TEST_F(HttpCacheTest, StaleContentWriteError) {
12755   MockHttpCache cache;
12756   base::SimpleTestClock clock;
12757   cache.http_cache()->SetClockForTesting(&clock);
12758   cache.network_layer()->SetClock(&clock);
12759   clock.Advance(base::Seconds(10));
12760 
12761   ScopedMockTransaction stale_while_revalidate_transaction(
12762       kSimpleGET_Transaction);
12763   stale_while_revalidate_transaction.load_flags |=
12764       LOAD_SUPPORT_ASYNC_REVALIDATION;
12765   stale_while_revalidate_transaction.response_headers =
12766       "Last-Modified: Sat, 18 Apr 2007 01:10:43 GMT\n"
12767       "Age: 10801\n"
12768       "Cache-Control: max-age=0,stale-while-revalidate=86400\n";
12769 
12770   // Write to the cache.
12771   RunTransactionTest(cache.http_cache(), stale_while_revalidate_transaction);
12772 
12773   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12774 
12775   // Send the request again but inject a write fault. Should still work
12776   // (and not dereference any null pointers).
12777   cache.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_WRITE);
12778   HttpResponseInfo response_info;
12779   RunTransactionTestWithResponseInfo(
12780       cache.http_cache(), stale_while_revalidate_transaction, &response_info);
12781 
12782   EXPECT_EQ(2, cache.network_layer()->transaction_count());
12783 }
12784 
12785 // Tests that we allow multiple simultaneous, non-overlapping transactions to
12786 // take place on a sparse entry.
TEST_F(HttpCacheTest,RangeGET_MultipleRequests)12787 TEST_F(HttpCacheTest, RangeGET_MultipleRequests) {
12788   MockHttpCache cache;
12789 
12790   // Create a transaction for bytes 0-9.
12791   MockHttpRequest request(kRangeGET_TransactionOK);
12792   ScopedMockTransaction transaction(kRangeGET_TransactionOK);
12793   transaction.request_headers = "Range: bytes = 0-9\r\n" EXTRA_HEADER;
12794   transaction.data = "rg: 00-09 ";
12795 
12796   TestCompletionCallback callback;
12797   std::unique_ptr<HttpTransaction> trans;
12798   int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
12799   EXPECT_THAT(rv, IsOk());
12800   ASSERT_TRUE(trans.get());
12801 
12802   // Start our transaction.
12803   trans->Start(&request, callback.callback(), NetLogWithSource());
12804 
12805   // A second transaction on a different part of the file (the default
12806   // kRangeGET_TransactionOK requests 40-49) should not be blocked by
12807   // the already pending transaction.
12808   RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK);
12809 
12810   // Let the first transaction complete.
12811   callback.WaitForResult();
12812 }
12813 
12814 // Verify that a range request can be satisfied from a completely cached
12815 // resource with the LOAD_ONLY_FROM_CACHE flag set. Currently it's not
12816 // implemented so it returns ERR_CACHE_MISS. See also
12817 // HttpCacheTest.RangeGET_OK_LoadOnlyFromCache.
12818 // TODO(ricea): Update this test if it is implemented in future.
TEST_F(HttpCacheTest,RangeGET_Previous200_LoadOnlyFromCache)12819 TEST_F(HttpCacheTest, RangeGET_Previous200_LoadOnlyFromCache) {
12820   MockHttpCache cache;
12821 
12822   // Store the whole thing with status 200.
12823   {
12824     MockTransaction transaction(kETagGET_Transaction);
12825     transaction.url = kRangeGET_TransactionOK.url;
12826     transaction.data = kFullRangeData;
12827     ScopedMockTransaction scoped_transaction(transaction);
12828     RunTransactionTest(cache.http_cache(), transaction);
12829     EXPECT_EQ(1, cache.network_layer()->transaction_count());
12830     EXPECT_EQ(0, cache.disk_cache()->open_count());
12831     EXPECT_EQ(1, cache.disk_cache()->create_count());
12832   }
12833 
12834   ScopedMockTransaction scoped_transaction(kRangeGET_TransactionOK);
12835 
12836   // Now see that we use the stored entry.
12837   MockTransaction transaction2(kRangeGET_TransactionOK);
12838   transaction2.load_flags |= LOAD_ONLY_FROM_CACHE;
12839   MockHttpRequest request(transaction2);
12840   TestCompletionCallback callback;
12841 
12842   std::unique_ptr<HttpTransaction> trans;
12843   int rv = cache.http_cache()->CreateTransaction(DEFAULT_PRIORITY, &trans);
12844   EXPECT_THAT(rv, IsOk());
12845   ASSERT_TRUE(trans);
12846 
12847   rv = trans->Start(&request, callback.callback(), NetLogWithSource());
12848   if (rv == ERR_IO_PENDING) {
12849     rv = callback.WaitForResult();
12850   }
12851   EXPECT_THAT(rv, IsError(ERR_CACHE_MISS));
12852 
12853   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12854   EXPECT_EQ(1, cache.disk_cache()->open_count());
12855   EXPECT_EQ(1, cache.disk_cache()->create_count());
12856 }
12857 
12858 // Makes sure that a request stops using the cache when the response headers
12859 // with "Cache-Control: no-store" arrives. That means that another request for
12860 // the same URL can be processed before the response body of the original
12861 // request arrives.
TEST_F(HttpCacheTest,NoStoreResponseShouldNotBlockFollowingRequests)12862 TEST_F(HttpCacheTest, NoStoreResponseShouldNotBlockFollowingRequests) {
12863   MockHttpCache cache;
12864   ScopedMockTransaction mock_transaction(kSimpleGET_Transaction);
12865   mock_transaction.response_headers = "Cache-Control: no-store\n";
12866   MockHttpRequest request(mock_transaction);
12867 
12868   auto first = std::make_unique<Context>();
12869   first->result = cache.CreateTransaction(&first->trans);
12870   ASSERT_THAT(first->result, IsOk());
12871   EXPECT_EQ(LOAD_STATE_IDLE, first->trans->GetLoadState());
12872   first->result = first->trans->Start(&request, first->callback.callback(),
12873                                       NetLogWithSource());
12874   EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, first->trans->GetLoadState());
12875 
12876   base::RunLoop().RunUntilIdle();
12877   EXPECT_EQ(LOAD_STATE_IDLE, first->trans->GetLoadState());
12878   ASSERT_TRUE(first->trans->GetResponseInfo());
12879   EXPECT_TRUE(first->trans->GetResponseInfo()->headers->HasHeaderValue(
12880       "Cache-Control", "no-store"));
12881   // Here we have read the response header but not read the response body yet.
12882 
12883   // Let us create the second (read) transaction.
12884   auto second = std::make_unique<Context>();
12885   second->result = cache.CreateTransaction(&second->trans);
12886   ASSERT_THAT(second->result, IsOk());
12887   EXPECT_EQ(LOAD_STATE_IDLE, second->trans->GetLoadState());
12888   second->result = second->trans->Start(&request, second->callback.callback(),
12889                                         NetLogWithSource());
12890 
12891   // Here the second transaction proceeds without reading the first body.
12892   EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, second->trans->GetLoadState());
12893   base::RunLoop().RunUntilIdle();
12894   EXPECT_EQ(LOAD_STATE_IDLE, second->trans->GetLoadState());
12895   ASSERT_TRUE(second->trans->GetResponseInfo());
12896   EXPECT_TRUE(second->trans->GetResponseInfo()->headers->HasHeaderValue(
12897       "Cache-Control", "no-store"));
12898   ReadAndVerifyTransaction(second->trans.get(), kSimpleGET_Transaction);
12899 }
12900 
12901 // Tests that serving a response entirely from cache replays the previous
12902 // SSLInfo.
TEST_F(HttpCacheTest,CachePreservesSSLInfo)12903 TEST_F(HttpCacheTest, CachePreservesSSLInfo) {
12904   static const uint16_t kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xc02f;
12905   int status = 0;
12906   SSLConnectionStatusSetCipherSuite(kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
12907                                     &status);
12908   SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2, &status);
12909 
12910   scoped_refptr<X509Certificate> cert =
12911       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
12912 
12913   MockHttpCache cache;
12914 
12915   ScopedMockTransaction transaction(kSimpleGET_Transaction);
12916   transaction.cert = cert;
12917   transaction.ssl_connection_status = status;
12918 
12919   // Fetch the resource.
12920   HttpResponseInfo response_info;
12921   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
12922                                      &response_info);
12923 
12924   // The request should have hit the network and a cache entry created.
12925   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12926   EXPECT_EQ(0, cache.disk_cache()->open_count());
12927   EXPECT_EQ(1, cache.disk_cache()->create_count());
12928 
12929   // The expected SSL state was reported.
12930   EXPECT_EQ(transaction.ssl_connection_status,
12931             response_info.ssl_info.connection_status);
12932   EXPECT_TRUE(cert->EqualsIncludingChain(response_info.ssl_info.cert.get()));
12933 
12934   // Fetch the resource again.
12935   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
12936                                      &response_info);
12937 
12938   // The request should have been reused without hitting the network.
12939   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12940   EXPECT_EQ(1, cache.disk_cache()->open_count());
12941   EXPECT_EQ(1, cache.disk_cache()->create_count());
12942 
12943   // The SSL state was preserved.
12944   EXPECT_EQ(status, response_info.ssl_info.connection_status);
12945   EXPECT_TRUE(cert->EqualsIncludingChain(response_info.ssl_info.cert.get()));
12946 }
12947 
12948 // Tests that SSLInfo gets updated when revalidating a cached response.
TEST_F(HttpCacheTest,RevalidationUpdatesSSLInfo)12949 TEST_F(HttpCacheTest, RevalidationUpdatesSSLInfo) {
12950   static const uint16_t kTLS_RSA_WITH_RC4_128_MD5 = 0x0004;
12951   static const uint16_t kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xc02f;
12952 
12953   int status1 = 0;
12954   SSLConnectionStatusSetCipherSuite(kTLS_RSA_WITH_RC4_128_MD5, &status1);
12955   SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1, &status1);
12956   int status2 = 0;
12957   SSLConnectionStatusSetCipherSuite(kTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
12958                                     &status2);
12959   SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2, &status2);
12960 
12961   scoped_refptr<X509Certificate> cert1 =
12962       ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
12963   scoped_refptr<X509Certificate> cert2 =
12964       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
12965 
12966   MockHttpCache cache;
12967 
12968   ScopedMockTransaction transaction(kTypicalGET_Transaction);
12969   transaction.cert = cert1;
12970   transaction.ssl_connection_status = status1;
12971 
12972   // Fetch the resource.
12973   HttpResponseInfo response_info;
12974   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
12975                                      &response_info);
12976 
12977   // The request should have hit the network and a cache entry created.
12978   EXPECT_EQ(1, cache.network_layer()->transaction_count());
12979   EXPECT_EQ(0, cache.disk_cache()->open_count());
12980   EXPECT_EQ(1, cache.disk_cache()->create_count());
12981   EXPECT_FALSE(response_info.was_cached);
12982 
12983   // The expected SSL state was reported.
12984   EXPECT_EQ(status1, response_info.ssl_info.connection_status);
12985   EXPECT_TRUE(cert1->EqualsIncludingChain(response_info.ssl_info.cert.get()));
12986 
12987   // The server deploys a more modern configuration but reports 304 on the
12988   // revalidation attempt.
12989   transaction.status = "HTTP/1.1 304 Not Modified";
12990   transaction.cert = cert2;
12991   transaction.ssl_connection_status = status2;
12992 
12993   // Fetch the resource again, forcing a revalidation.
12994   transaction.request_headers = "Cache-Control: max-age=0\r\n";
12995   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
12996                                      &response_info);
12997 
12998   // The request should have been successfully revalidated.
12999   EXPECT_EQ(2, cache.network_layer()->transaction_count());
13000   EXPECT_EQ(1, cache.disk_cache()->open_count());
13001   EXPECT_EQ(1, cache.disk_cache()->create_count());
13002   EXPECT_TRUE(response_info.was_cached);
13003 
13004   // The new SSL state is reported.
13005   EXPECT_EQ(status2, response_info.ssl_info.connection_status);
13006   EXPECT_TRUE(cert2->EqualsIncludingChain(response_info.ssl_info.cert.get()));
13007 }
13008 
TEST_F(HttpCacheTest,CacheEntryStatusOther)13009 TEST_F(HttpCacheTest, CacheEntryStatusOther) {
13010   MockHttpCache cache;
13011 
13012   HttpResponseInfo response_info;
13013   RunTransactionTestWithResponseInfo(cache.http_cache(), kRangeGET_Transaction,
13014                                      &response_info);
13015 
13016   EXPECT_FALSE(response_info.was_cached);
13017   EXPECT_TRUE(response_info.network_accessed);
13018   EXPECT_EQ(CacheEntryStatus::ENTRY_OTHER, response_info.cache_entry_status);
13019 }
13020 
TEST_F(HttpCacheTest,CacheEntryStatusNotInCache)13021 TEST_F(HttpCacheTest, CacheEntryStatusNotInCache) {
13022   MockHttpCache cache;
13023 
13024   HttpResponseInfo response_info;
13025   RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
13026                                      &response_info);
13027 
13028   EXPECT_FALSE(response_info.was_cached);
13029   EXPECT_TRUE(response_info.network_accessed);
13030   EXPECT_EQ(CacheEntryStatus::ENTRY_NOT_IN_CACHE,
13031             response_info.cache_entry_status);
13032 }
13033 
TEST_F(HttpCacheTest,CacheEntryStatusUsed)13034 TEST_F(HttpCacheTest, CacheEntryStatusUsed) {
13035   MockHttpCache cache;
13036   RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction);
13037 
13038   HttpResponseInfo response_info;
13039   RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction,
13040                                      &response_info);
13041 
13042   EXPECT_TRUE(response_info.was_cached);
13043   EXPECT_FALSE(response_info.network_accessed);
13044   EXPECT_EQ(CacheEntryStatus::ENTRY_USED, response_info.cache_entry_status);
13045 }
13046 
TEST_F(HttpCacheTest,CacheEntryStatusValidated)13047 TEST_F(HttpCacheTest, CacheEntryStatusValidated) {
13048   MockHttpCache cache;
13049   RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
13050 
13051   ScopedMockTransaction still_valid(kETagGET_Transaction);
13052   still_valid.load_flags = LOAD_VALIDATE_CACHE;  // Force a validation.
13053   still_valid.handler = kETagGetConditionalRequestHandler;
13054 
13055   HttpResponseInfo response_info;
13056   RunTransactionTestWithResponseInfo(cache.http_cache(), still_valid,
13057                                      &response_info);
13058 
13059   EXPECT_TRUE(response_info.was_cached);
13060   EXPECT_TRUE(response_info.network_accessed);
13061   EXPECT_EQ(CacheEntryStatus::ENTRY_VALIDATED,
13062             response_info.cache_entry_status);
13063 }
13064 
TEST_F(HttpCacheTest,CacheEntryStatusUpdated)13065 TEST_F(HttpCacheTest, CacheEntryStatusUpdated) {
13066   MockHttpCache cache;
13067   RunTransactionTest(cache.http_cache(), kETagGET_Transaction);
13068 
13069   ScopedMockTransaction update(kETagGET_Transaction);
13070   update.load_flags = LOAD_VALIDATE_CACHE;  // Force a validation.
13071 
13072   HttpResponseInfo response_info;
13073   RunTransactionTestWithResponseInfo(cache.http_cache(), update,
13074                                      &response_info);
13075 
13076   EXPECT_FALSE(response_info.was_cached);
13077   EXPECT_TRUE(response_info.network_accessed);
13078   EXPECT_EQ(CacheEntryStatus::ENTRY_UPDATED, response_info.cache_entry_status);
13079 }
13080 
TEST_F(HttpCacheTest,CacheEntryStatusCantConditionalize)13081 TEST_F(HttpCacheTest, CacheEntryStatusCantConditionalize) {
13082   MockHttpCache cache;
13083   cache.FailConditionalizations();
13084   RunTransactionTest(cache.http_cache(), kTypicalGET_Transaction);
13085 
13086   HttpResponseInfo response_info;
13087   RunTransactionTestWithResponseInfo(cache.http_cache(),
13088                                      kTypicalGET_Transaction, &response_info);
13089 
13090   EXPECT_FALSE(response_info.was_cached);
13091   EXPECT_TRUE(response_info.network_accessed);
13092   EXPECT_EQ(CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE,
13093             response_info.cache_entry_status);
13094 }
13095 
TEST_F(HttpSplitCacheKeyTest,GetResourceURLFromHttpCacheKey)13096 TEST_F(HttpSplitCacheKeyTest, GetResourceURLFromHttpCacheKey) {
13097   base::test::ScopedFeatureList feature_list;
13098   feature_list.InitAndEnableFeature(
13099       net::features::kSplitCacheByNetworkIsolationKey);
13100   MockHttpCache cache;
13101   std::string urls[] = {"http://www.a.com/", "https://b.com/example.html",
13102                         "http://example.com/Some Path/Some Leaf?some query"};
13103 
13104   for (const std::string& url : urls) {
13105     std::string key = ComputeCacheKey(url);
13106     EXPECT_EQ(GURL(url).spec(), HttpCache::GetResourceURLFromHttpCacheKey(key));
13107   }
13108 }
13109 
TEST_F(HttpCacheTest,GetResourceURLFromHttpCacheKey)13110 TEST_F(HttpCacheTest, GetResourceURLFromHttpCacheKey) {
13111   const struct {
13112     std::string input;
13113     std::string output;
13114   } kTestCase[] = {
13115       // Valid input:
13116       {"0/0/https://a.com/", "https://a.com/"},
13117       {"0/0/https://a.com/path", "https://a.com/path"},
13118       {"0/0/https://a.com/?query", "https://a.com/?query"},
13119       {"0/0/https://a.com/#fragment", "https://a.com/#fragment"},
13120       {"0/0/_dk_s_ https://a.com/", "https://a.com/"},
13121       {"0/0/_dk_https://a.com https://b.com https://c.com/", "https://c.com/"},
13122       {"0/0/_dk_shttps://a.com https://b.com https://c.com/", "https://c.com/"},
13123 
13124       // Invalid input, producing garbage, without crashing.
13125       {"", ""},
13126       {"0/a.com", "0/a.com"},
13127       {"https://a.com/", "a.com/"},
13128       {"0/https://a.com/", "/a.com/"},
13129   };
13130 
13131   for (const auto& test : kTestCase) {
13132     EXPECT_EQ(test.output,
13133               HttpCache::GetResourceURLFromHttpCacheKey(test.input));
13134   }
13135 }
13136 
13137 class TestCompletionCallbackForHttpCache : public TestCompletionCallbackBase {
13138  public:
13139   TestCompletionCallbackForHttpCache() = default;
13140   ~TestCompletionCallbackForHttpCache() override = default;
13141 
callback()13142   CompletionRepeatingCallback callback() {
13143     return base::BindRepeating(&TestCompletionCallbackForHttpCache::SetResult,
13144                                base::Unretained(this));
13145   }
13146 
results()13147   const std::vector<int>& results() { return results_; }
13148 
13149  private:
13150   std::vector<int> results_;
13151 
13152  protected:
SetResult(int result)13153   void SetResult(int result) override {
13154     results_.push_back(result);
13155     DidSetResult();
13156   }
13157 };
13158 
TEST_F(HttpCacheIOCallbackTest,FailedDoomFollowedByOpen)13159 TEST_F(HttpCacheIOCallbackTest, FailedDoomFollowedByOpen) {
13160   MockHttpCache cache;
13161   TestCompletionCallbackForHttpCache cb;
13162   std::unique_ptr<Transaction> transaction =
13163       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13164 
13165   transaction->SetIOCallBackForTest(cb.callback());
13166   transaction->SetCacheIOCallBackForTest(cb.callback());
13167 
13168   // Create the backend here as our direct calls to DoomEntry and OpenEntry
13169   // below require that it exists.
13170   cache.backend();
13171 
13172   // Need a mock transaction in order to use some of MockHttpCache's
13173   // functions.
13174   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13175 
13176   scoped_refptr<ActiveEntry> entry1 = nullptr;
13177 
13178   cache.disk_cache()->set_force_fail_callback_later(true);
13179 
13180   // Queue up our operations.
13181   int rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get());
13182   ASSERT_EQ(rv, ERR_IO_PENDING);
13183   cache.disk_cache()->set_force_fail_callback_later(false);
13184   rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry1,
13185                  transaction.get());
13186   ASSERT_EQ(rv, ERR_IO_PENDING);
13187 
13188   // Wait for all the results to arrive.
13189   cb.GetResult(rv);
13190   ASSERT_EQ(cb.results().size(), 2u);
13191 
13192   // Verify that DoomEntry failed correctly.
13193   ASSERT_EQ(cb.results()[0], ERR_CACHE_DOOM_FAILURE);
13194   // Verify that OpenEntry fails with the same code.
13195   ASSERT_EQ(cb.results()[1], ERR_CACHE_DOOM_FAILURE);
13196   ASSERT_EQ(entry1, nullptr);
13197 }
13198 
TEST_F(HttpCacheIOCallbackTest,FailedDoomFollowedByCreate)13199 TEST_F(HttpCacheIOCallbackTest, FailedDoomFollowedByCreate) {
13200   MockHttpCache cache;
13201   TestCompletionCallbackForHttpCache cb;
13202   std::unique_ptr<Transaction> transaction =
13203       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13204 
13205   transaction->SetIOCallBackForTest(cb.callback());
13206   transaction->SetCacheIOCallBackForTest(cb.callback());
13207 
13208   // Create the backend here as our direct calls to DoomEntry and CreateEntry
13209   // below require that it exists.
13210   cache.backend();
13211 
13212   // Need a mock transaction in order to use some of MockHttpCache's
13213   // functions.
13214   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13215 
13216   scoped_refptr<ActiveEntry> entry1 = nullptr;
13217 
13218   cache.disk_cache()->set_force_fail_callback_later(true);
13219 
13220   // Queue up our operations.
13221   int rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get());
13222   ASSERT_EQ(rv, ERR_IO_PENDING);
13223   cache.disk_cache()->set_force_fail_callback_later(false);
13224   rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13225                    transaction.get());
13226   ASSERT_EQ(rv, ERR_IO_PENDING);
13227 
13228   // Wait for all the results to arrive.
13229   cb.GetResult(rv);
13230   ASSERT_EQ(cb.results().size(), 2u);
13231 
13232   // Verify that DoomEntry failed correctly.
13233   ASSERT_EQ(cb.results()[0], ERR_CACHE_DOOM_FAILURE);
13234   // Verify that CreateEntry requests a restart (CACHE_RACE).
13235   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13236   ASSERT_EQ(entry1, nullptr);
13237 }
13238 
TEST_F(HttpCacheIOCallbackTest,FailedDoomFollowedByDoom)13239 TEST_F(HttpCacheIOCallbackTest, FailedDoomFollowedByDoom) {
13240   MockHttpCache cache;
13241   TestCompletionCallbackForHttpCache cb;
13242   std::unique_ptr<Transaction> transaction =
13243       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13244 
13245   transaction->SetIOCallBackForTest(cb.callback());
13246   transaction->SetCacheIOCallBackForTest(cb.callback());
13247 
13248   // Create the backend here as our direct calls to DoomEntry below require that
13249   // it exists.
13250   cache.backend();
13251 
13252   // Need a mock transaction in order to use some of MockHttpCache's
13253   // functions.
13254   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13255 
13256   cache.disk_cache()->set_force_fail_callback_later(true);
13257 
13258   // Queue up our operations.
13259   int rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get());
13260   ASSERT_EQ(rv, ERR_IO_PENDING);
13261   cache.disk_cache()->set_force_fail_callback_later(false);
13262   rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get());
13263   ASSERT_EQ(rv, ERR_IO_PENDING);
13264 
13265   // Wait for all the results to arrive.
13266   cb.GetResult(rv);
13267   ASSERT_EQ(cb.results().size(), 2u);
13268 
13269   // Verify that DoomEntry failed correctly.
13270   ASSERT_EQ(cb.results()[0], ERR_CACHE_DOOM_FAILURE);
13271   // Verify that the second DoomEntry requests a restart (CACHE_RACE).
13272   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13273 }
13274 
TEST_F(HttpCacheIOCallbackTest,FailedOpenFollowedByCreate)13275 TEST_F(HttpCacheIOCallbackTest, FailedOpenFollowedByCreate) {
13276   MockHttpCache cache;
13277   TestCompletionCallbackForHttpCache cb;
13278   std::unique_ptr<Transaction> transaction =
13279       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13280 
13281   transaction->SetIOCallBackForTest(cb.callback());
13282   transaction->SetCacheIOCallBackForTest(cb.callback());
13283 
13284   // Create the backend here as our direct calls to OpenEntry and CreateEntry
13285   // below require that it exists.
13286   cache.backend();
13287 
13288   // Need a mock transaction in order to use some of MockHttpCache's
13289   // functions.
13290   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13291 
13292   scoped_refptr<ActiveEntry> entry1 = nullptr;
13293   scoped_refptr<ActiveEntry> entry2 = nullptr;
13294 
13295   cache.disk_cache()->set_force_fail_callback_later(true);
13296 
13297   // Queue up our operations.
13298   int rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry1,
13299                      transaction.get());
13300   ASSERT_EQ(rv, ERR_IO_PENDING);
13301   cache.disk_cache()->set_force_fail_callback_later(false);
13302   rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13303                    transaction.get());
13304   ASSERT_EQ(rv, ERR_IO_PENDING);
13305 
13306   // Wait for all the results to arrive.
13307   cb.GetResult(rv);
13308   ASSERT_EQ(cb.results().size(), 2u);
13309 
13310   // Verify that OpenEntry failed correctly.
13311   ASSERT_EQ(cb.results()[0], ERR_CACHE_OPEN_FAILURE);
13312   ASSERT_EQ(entry1, nullptr);
13313   // Verify that the CreateEntry requests a restart (CACHE_RACE).
13314   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13315   ASSERT_EQ(entry2, nullptr);
13316 }
13317 
TEST_F(HttpCacheIOCallbackTest,FailedCreateFollowedByOpen)13318 TEST_F(HttpCacheIOCallbackTest, FailedCreateFollowedByOpen) {
13319   MockHttpCache cache;
13320   TestCompletionCallbackForHttpCache cb;
13321   std::unique_ptr<Transaction> transaction =
13322       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13323 
13324   transaction->SetIOCallBackForTest(cb.callback());
13325   transaction->SetCacheIOCallBackForTest(cb.callback());
13326 
13327   // Create the backend here as our direct calls to CreateEntry and OpenEntry
13328   // below require that it exists.
13329   cache.backend();
13330 
13331   // Need a mock transaction in order to use some of MockHttpCache's
13332   // functions.
13333   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13334 
13335   scoped_refptr<ActiveEntry> entry1 = nullptr;
13336   scoped_refptr<ActiveEntry> entry2 = nullptr;
13337 
13338   cache.disk_cache()->set_force_fail_callback_later(true);
13339 
13340   // Queue up our operations.
13341   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13342                        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, &entry2,
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 CreateEntry failed correctly.
13354   ASSERT_EQ(cb.results()[0], ERR_CACHE_CREATE_FAILURE);
13355   ASSERT_EQ(entry1, nullptr);
13356   // Verify that the OpenEntry requests a restart (CACHE_RACE).
13357   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13358   ASSERT_EQ(entry2, nullptr);
13359 }
13360 
TEST_F(HttpCacheIOCallbackTest,FailedCreateFollowedByCreate)13361 TEST_F(HttpCacheIOCallbackTest, FailedCreateFollowedByCreate) {
13362   MockHttpCache cache;
13363   TestCompletionCallbackForHttpCache cb;
13364   std::unique_ptr<Transaction> transaction =
13365       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13366 
13367   transaction->SetIOCallBackForTest(cb.callback());
13368   transaction->SetCacheIOCallBackForTest(cb.callback());
13369 
13370   // Create the backend here as our direct calls to CreateEntry below require
13371   // that it exists.
13372   cache.backend();
13373 
13374   // Need a mock transaction in order to use some of MockHttpCache's
13375   // functions.
13376   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13377 
13378   scoped_refptr<ActiveEntry> entry1 = nullptr;
13379   scoped_refptr<ActiveEntry> entry2 = nullptr;
13380 
13381   cache.disk_cache()->set_force_fail_callback_later(true);
13382 
13383   // Queue up our operations.
13384   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13385                        transaction.get());
13386   ASSERT_EQ(rv, ERR_IO_PENDING);
13387   cache.disk_cache()->set_force_fail_callback_later(false);
13388   rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13389                    transaction.get());
13390   ASSERT_EQ(rv, ERR_IO_PENDING);
13391 
13392   // Wait for all the results to arrive.
13393   cb.GetResult(rv);
13394   ASSERT_EQ(cb.results().size(), 2u);
13395 
13396   // Verify the CreateEntry(s) failed.
13397   ASSERT_EQ(cb.results()[0], ERR_CACHE_CREATE_FAILURE);
13398   ASSERT_EQ(entry1, nullptr);
13399   ASSERT_EQ(cb.results()[1], ERR_CACHE_CREATE_FAILURE);
13400   ASSERT_EQ(entry2, nullptr);
13401 }
13402 
TEST_F(HttpCacheIOCallbackTest,CreateFollowedByCreate)13403 TEST_F(HttpCacheIOCallbackTest, CreateFollowedByCreate) {
13404   MockHttpCache cache;
13405   TestCompletionCallbackForHttpCache cb;
13406   std::unique_ptr<Transaction> transaction =
13407       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13408 
13409   transaction->SetIOCallBackForTest(cb.callback());
13410   transaction->SetCacheIOCallBackForTest(cb.callback());
13411 
13412   // Create the backend here as our direct calls to CreateEntry below require
13413   // that it exists.
13414   cache.backend();
13415 
13416   // Need a mock transaction in order to use some of MockHttpCache's
13417   // functions.
13418   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13419 
13420   scoped_refptr<ActiveEntry> entry1 = nullptr;
13421   scoped_refptr<ActiveEntry> entry2 = nullptr;
13422 
13423   // Queue up our operations.
13424   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13425                        transaction.get());
13426   ASSERT_EQ(rv, ERR_IO_PENDING);
13427   rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13428                    transaction.get());
13429   ASSERT_EQ(rv, ERR_IO_PENDING);
13430 
13431   // Wait for all the results to arrive.
13432   cb.GetResult(rv);
13433   ASSERT_EQ(cb.results().size(), 2u);
13434 
13435   // Verify that the first CreateEntry succeeded.
13436   ASSERT_EQ(cb.results()[0], OK);
13437   ASSERT_NE(entry1, nullptr);
13438   // Verify that the second CreateEntry failed.
13439   ASSERT_EQ(cb.results()[1], ERR_CACHE_CREATE_FAILURE);
13440   ASSERT_EQ(entry2, nullptr);
13441 }
13442 
TEST_F(HttpCacheIOCallbackTest,OperationFollowedByDoom)13443 TEST_F(HttpCacheIOCallbackTest, OperationFollowedByDoom) {
13444   MockHttpCache cache;
13445   TestCompletionCallbackForHttpCache cb;
13446   std::unique_ptr<Transaction> transaction =
13447       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13448 
13449   transaction->SetIOCallBackForTest(cb.callback());
13450   transaction->SetCacheIOCallBackForTest(cb.callback());
13451 
13452   // Create the backend here as our direct calls to CreateEntry and DoomEntry
13453   // below require that it exists.
13454   cache.backend();
13455 
13456   // Need a mock transaction in order to use some of MockHttpCache's
13457   // functions.
13458   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13459 
13460   scoped_refptr<ActiveEntry> entry1 = nullptr;
13461 
13462   // Queue up our operations.
13463   // For this test all we need is some operation followed by a doom, a create
13464   // fulfills that requirement.
13465   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13466                        transaction.get());
13467   ASSERT_EQ(rv, ERR_IO_PENDING);
13468   rv = DoomEntry(cache.http_cache(), m_transaction.url, transaction.get());
13469   ASSERT_EQ(rv, ERR_IO_PENDING);
13470 
13471   // Wait for all the results to arrive.
13472   cb.GetResult(rv);
13473   ASSERT_EQ(cb.results().size(), 2u);
13474 
13475   // Verify that the CreateEntry succeeded.
13476   ASSERT_EQ(cb.results()[0], OK);
13477   // Verify that the DoomEntry requests a restart (CACHE_RACE).
13478   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13479 }
13480 
TEST_F(HttpCacheIOCallbackTest,CreateFollowedByOpenOrCreate)13481 TEST_F(HttpCacheIOCallbackTest, CreateFollowedByOpenOrCreate) {
13482   MockHttpCache cache;
13483   TestCompletionCallbackForHttpCache cb;
13484   std::unique_ptr<Transaction> transaction =
13485       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13486 
13487   transaction->SetIOCallBackForTest(cb.callback());
13488   transaction->SetCacheIOCallBackForTest(cb.callback());
13489 
13490   // Create the backend here as our direct calls to CreateEntry and
13491   // OpenOrCreateEntry below require that it exists.
13492   cache.backend();
13493 
13494   // Need a mock transaction in order to use some of MockHttpCache's
13495   // functions.
13496   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13497 
13498   scoped_refptr<ActiveEntry> entry1 = nullptr;
13499   scoped_refptr<ActiveEntry> entry2 = nullptr;
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   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13506                          transaction.get());
13507   ASSERT_EQ(rv, ERR_IO_PENDING);
13508 
13509   // Wait for all the results to arrive.
13510   cb.GetResult(rv);
13511   ASSERT_EQ(cb.results().size(), 2u);
13512 
13513   // Verify that the CreateEntry succeeded.
13514   ASSERT_EQ(cb.results()[0], OK);
13515   ASSERT_NE(entry1, nullptr);
13516   // Verify that OpenOrCreateEntry succeeded.
13517   ASSERT_EQ(cb.results()[1], OK);
13518   ASSERT_NE(entry2, nullptr);
13519   ASSERT_EQ(entry1->GetEntry(), entry2->GetEntry());
13520 }
13521 
TEST_F(HttpCacheIOCallbackTest,FailedCreateFollowedByOpenOrCreate)13522 TEST_F(HttpCacheIOCallbackTest, FailedCreateFollowedByOpenOrCreate) {
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 and
13532   // OpenOrCreateEntry below require 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   scoped_refptr<ActiveEntry> entry1 = nullptr;
13540   scoped_refptr<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 = OpenOrCreateEntry(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 that CreateEntry failed correctly.
13558   ASSERT_EQ(cb.results()[0], ERR_CACHE_CREATE_FAILURE);
13559   ASSERT_EQ(entry1, nullptr);
13560   // Verify that the OpenOrCreateEntry requests a restart (CACHE_RACE).
13561   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13562   ASSERT_EQ(entry2, nullptr);
13563 }
13564 
TEST_F(HttpCacheIOCallbackTest,OpenFollowedByOpenOrCreate)13565 TEST_F(HttpCacheIOCallbackTest, OpenFollowedByOpenOrCreate) {
13566   MockHttpCache cache;
13567   TestCompletionCallbackForHttpCache cb;
13568   std::unique_ptr<Transaction> transaction =
13569       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13570 
13571   transaction->SetIOCallBackForTest(cb.callback());
13572   transaction->SetCacheIOCallBackForTest(cb.callback());
13573 
13574   // Create the backend here as our direct calls to OpenEntry and
13575   // OpenOrCreateEntry below require that it exists.
13576   cache.backend();
13577 
13578   // Need a mock transaction in order to use some of MockHttpCache's
13579   // functions.
13580   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13581 
13582   scoped_refptr<ActiveEntry> entry0 = nullptr;
13583   scoped_refptr<ActiveEntry> entry1 = nullptr;
13584   scoped_refptr<ActiveEntry> entry2 = nullptr;
13585 
13586   // First need to create and entry so we can open it.
13587   int rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry0,
13588                        transaction.get());
13589   ASSERT_EQ(rv, ERR_IO_PENDING);
13590   cb.GetResult(rv);
13591   ASSERT_EQ(cb.results().size(), static_cast<size_t>(1));
13592   ASSERT_EQ(cb.results()[0], OK);
13593   ASSERT_NE(entry0, nullptr);
13594   // Manually Deactivate() `entry0` because OpenEntry() fails if there is an
13595   // existing active entry.
13596   entry0.reset();
13597 
13598   // Queue up our operations.
13599   rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry1,
13600                  transaction.get());
13601   ASSERT_EQ(rv, ERR_IO_PENDING);
13602   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13603                          transaction.get());
13604   ASSERT_EQ(rv, ERR_IO_PENDING);
13605 
13606   // Wait for all the results to arrive.
13607   cb.GetResult(rv);
13608   ASSERT_EQ(cb.results().size(), 3u);
13609 
13610   // Verify that the OpenEntry succeeded.
13611   ASSERT_EQ(cb.results()[1], OK);
13612   ASSERT_NE(entry1, nullptr);
13613   // Verify that OpenOrCreateEntry succeeded.
13614   ASSERT_EQ(cb.results()[2], OK);
13615   ASSERT_NE(entry2, nullptr);
13616   ASSERT_EQ(entry1->GetEntry(), entry2->GetEntry());
13617 }
13618 
TEST_F(HttpCacheIOCallbackTest,FailedOpenFollowedByOpenOrCreate)13619 TEST_F(HttpCacheIOCallbackTest, FailedOpenFollowedByOpenOrCreate) {
13620   MockHttpCache cache;
13621   TestCompletionCallbackForHttpCache cb;
13622   std::unique_ptr<Transaction> transaction =
13623       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13624 
13625   transaction->SetIOCallBackForTest(cb.callback());
13626   transaction->SetCacheIOCallBackForTest(cb.callback());
13627 
13628   // Create the backend here as our direct calls to OpenEntry and
13629   // OpenOrCreateEntry below require that it exists.
13630   cache.backend();
13631 
13632   // Need a mock transaction in order to use some of MockHttpCache's
13633   // functions.
13634   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13635 
13636   scoped_refptr<ActiveEntry> entry1 = nullptr;
13637   scoped_refptr<ActiveEntry> entry2 = nullptr;
13638 
13639   cache.disk_cache()->set_force_fail_callback_later(true);
13640 
13641   // Queue up our operations.
13642   int rv = OpenEntry(cache.http_cache(), m_transaction.url, &entry1,
13643                      transaction.get());
13644   ASSERT_EQ(rv, ERR_IO_PENDING);
13645   cache.disk_cache()->set_force_fail_callback_later(false);
13646   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13647                          transaction.get());
13648   ASSERT_EQ(rv, ERR_IO_PENDING);
13649 
13650   // Wait for all the results to arrive.
13651   cb.GetResult(rv);
13652   ASSERT_EQ(cb.results().size(), 2u);
13653 
13654   // Verify that OpenEntry failed correctly.
13655   ASSERT_EQ(cb.results()[0], ERR_CACHE_OPEN_FAILURE);
13656   ASSERT_EQ(entry1, nullptr);
13657   // Verify that the OpenOrCreateEntry requests a restart (CACHE_RACE).
13658   ASSERT_EQ(cb.results()[1], ERR_CACHE_RACE);
13659   ASSERT_EQ(entry2, nullptr);
13660 }
13661 
TEST_F(HttpCacheIOCallbackTest,OpenOrCreateFollowedByCreate)13662 TEST_F(HttpCacheIOCallbackTest, OpenOrCreateFollowedByCreate) {
13663   MockHttpCache cache;
13664   TestCompletionCallbackForHttpCache cb;
13665   std::unique_ptr<Transaction> transaction =
13666       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13667 
13668   transaction->SetIOCallBackForTest(cb.callback());
13669   transaction->SetCacheIOCallBackForTest(cb.callback());
13670 
13671   // Create the backend here as our direct calls to OpenOrCreateEntry and
13672   // CreateEntry below require that it exists.
13673   cache.backend();
13674 
13675   // Need a mock transaction in order to use some of MockHttpCache's
13676   // functions.
13677   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13678 
13679   scoped_refptr<ActiveEntry> entry1 = nullptr;
13680   scoped_refptr<ActiveEntry> entry2 = nullptr;
13681 
13682   // Queue up our operations.
13683   int rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13684                              transaction.get());
13685   ASSERT_EQ(rv, ERR_IO_PENDING);
13686   rv = CreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13687                    transaction.get());
13688   ASSERT_EQ(rv, ERR_IO_PENDING);
13689 
13690   // Wait for all the results to arrive.
13691   cb.GetResult(rv);
13692   ASSERT_EQ(cb.results().size(), 2u);
13693 
13694   // Verify that the OpenOrCreateEntry succeeded.
13695   ASSERT_EQ(cb.results()[0], OK);
13696   ASSERT_NE(entry1, nullptr);
13697   // Verify that CreateEntry failed.
13698   ASSERT_EQ(cb.results()[1], ERR_CACHE_CREATE_FAILURE);
13699   ASSERT_EQ(entry2, nullptr);
13700 }
13701 
TEST_F(HttpCacheIOCallbackTest,OpenOrCreateFollowedByOpenOrCreate)13702 TEST_F(HttpCacheIOCallbackTest, OpenOrCreateFollowedByOpenOrCreate) {
13703   MockHttpCache cache;
13704   TestCompletionCallbackForHttpCache cb;
13705   std::unique_ptr<Transaction> transaction =
13706       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13707 
13708   transaction->SetIOCallBackForTest(cb.callback());
13709   transaction->SetCacheIOCallBackForTest(cb.callback());
13710 
13711   // Create the backend here as our direct calls to OpenOrCreateEntry below
13712   // require that it exists.
13713   cache.backend();
13714 
13715   // Need a mock transaction in order to use some of MockHttpCache's
13716   // functions.
13717   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13718 
13719   scoped_refptr<ActiveEntry> entry1 = nullptr;
13720   scoped_refptr<ActiveEntry> entry2 = nullptr;
13721 
13722   // Queue up our operations.
13723   int rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13724                              transaction.get());
13725   ASSERT_EQ(rv, ERR_IO_PENDING);
13726   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13727                          transaction.get());
13728   ASSERT_EQ(rv, ERR_IO_PENDING);
13729 
13730   // Wait for all the results to arrive.
13731   cb.GetResult(rv);
13732   ASSERT_EQ(cb.results().size(), 2u);
13733 
13734   // Verify that the OpenOrCreateEntry succeeded.
13735   ASSERT_EQ(cb.results()[0], OK);
13736   ASSERT_NE(entry1, nullptr);
13737   // Verify that the other succeeded.
13738   ASSERT_EQ(cb.results()[1], OK);
13739   ASSERT_NE(entry2, nullptr);
13740 }
13741 
TEST_F(HttpCacheIOCallbackTest,FailedOpenOrCreateFollowedByOpenOrCreate)13742 TEST_F(HttpCacheIOCallbackTest, FailedOpenOrCreateFollowedByOpenOrCreate) {
13743   MockHttpCache cache;
13744   TestCompletionCallbackForHttpCache cb;
13745   std::unique_ptr<Transaction> transaction =
13746       std::make_unique<Transaction>(DEFAULT_PRIORITY, cache.http_cache());
13747 
13748   transaction->SetIOCallBackForTest(cb.callback());
13749   transaction->SetCacheIOCallBackForTest(cb.callback());
13750 
13751   // Create the backend here as our direct calls to OpenOrCreateEntry below
13752   // require that it exists.
13753   cache.backend();
13754 
13755   // Need a mock transaction in order to use some of MockHttpCache's
13756   // functions.
13757   ScopedMockTransaction m_transaction(kSimpleGET_Transaction);
13758 
13759   scoped_refptr<ActiveEntry> entry1 = nullptr;
13760   scoped_refptr<ActiveEntry> entry2 = nullptr;
13761 
13762   cache.disk_cache()->set_force_fail_callback_later(true);
13763 
13764   // Queue up our operations.
13765   int rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry1,
13766                              transaction.get());
13767   ASSERT_EQ(rv, ERR_IO_PENDING);
13768   cache.disk_cache()->set_force_fail_callback_later(false);
13769   rv = OpenOrCreateEntry(cache.http_cache(), m_transaction.url, &entry2,
13770                          transaction.get());
13771   ASSERT_EQ(rv, ERR_IO_PENDING);
13772 
13773   // Wait for all the results to arrive.
13774   cb.GetResult(rv);
13775   ASSERT_EQ(cb.results().size(), 2u);
13776 
13777   // Verify that the OpenOrCreateEntry failed.
13778   ASSERT_EQ(cb.results()[0], ERR_CACHE_OPEN_OR_CREATE_FAILURE);
13779   ASSERT_EQ(entry1, nullptr);
13780   // Verify that the other failed.
13781   ASSERT_EQ(cb.results()[1], ERR_CACHE_OPEN_OR_CREATE_FAILURE);
13782   ASSERT_EQ(entry2, nullptr);
13783 }
13784 
TEST_F(HttpCacheTest,DnsAliasesNoRevalidation)13785 TEST_F(HttpCacheTest, DnsAliasesNoRevalidation) {
13786   MockHttpCache cache;
13787   HttpResponseInfo response;
13788   ScopedMockTransaction transaction(kSimpleGET_Transaction);
13789   transaction.dns_aliases = {"alias1", "alias2"};
13790 
13791   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13792                                      &response);
13793   EXPECT_FALSE(response.was_cached);
13794   EXPECT_THAT(response.dns_aliases, testing::ElementsAre("alias1", "alias2"));
13795 
13796   // The second request result in a cache hit and the response used without
13797   // revalidation. Set the transaction alias list to empty to verify that the
13798   // cached aliases are being used.
13799   transaction.dns_aliases = {};
13800   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13801                                      &response);
13802   EXPECT_TRUE(response.was_cached);
13803   EXPECT_THAT(response.dns_aliases, testing::ElementsAre("alias1", "alias2"));
13804 }
13805 
TEST_F(HttpCacheTest,NoDnsAliasesNoRevalidation)13806 TEST_F(HttpCacheTest, NoDnsAliasesNoRevalidation) {
13807   MockHttpCache cache;
13808   HttpResponseInfo response;
13809   ScopedMockTransaction transaction(kSimpleGET_Transaction);
13810   transaction.dns_aliases = {};
13811 
13812   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13813                                      &response);
13814   EXPECT_FALSE(response.was_cached);
13815   EXPECT_TRUE(response.dns_aliases.empty());
13816 
13817   // The second request should result in a cache hit and the response used
13818   // without revalidation. Set the transaction alias list to nonempty to verify
13819   // that the cached aliases are being used.
13820   transaction.dns_aliases = {"alias"};
13821   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13822                                      &response);
13823   EXPECT_TRUE(response.was_cached);
13824   EXPECT_TRUE(response.dns_aliases.empty());
13825 }
13826 
TEST_F(HttpCacheTest,DnsAliasesRevalidation)13827 TEST_F(HttpCacheTest, DnsAliasesRevalidation) {
13828   MockHttpCache cache;
13829   HttpResponseInfo response;
13830   ScopedMockTransaction transaction(kTypicalGET_Transaction);
13831   transaction.response_headers =
13832       "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"
13833       "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
13834       "Cache-Control: max-age=0\n";
13835   transaction.dns_aliases = {"alias1", "alias2"};
13836 
13837   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13838                                      &response);
13839   EXPECT_FALSE(response.was_cached);
13840   EXPECT_THAT(response.dns_aliases, testing::ElementsAre("alias1", "alias2"));
13841 
13842   // On the second request, the cache should be revalidated. Change the aliases
13843   // to be sure that the new aliases are being used, and have the response be
13844   // cached for next time.
13845   transaction.response_headers = "Cache-Control: max-age=10000\n";
13846   transaction.dns_aliases = {"alias3", "alias4"};
13847   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13848                                      &response);
13849   EXPECT_FALSE(response.was_cached);
13850   EXPECT_THAT(response.dns_aliases, testing::ElementsAre("alias3", "alias4"));
13851 
13852   transaction.dns_aliases = {"alias5", "alias6"};
13853   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13854                                      &response);
13855   EXPECT_TRUE(response.was_cached);
13856   EXPECT_THAT(response.dns_aliases, testing::ElementsAre("alias3", "alias4"));
13857 }
13858 
TEST_F(HttpCacheTest,FirstPartySetsBypassCache_ShouldBypass_NoId)13859 TEST_F(HttpCacheTest, FirstPartySetsBypassCache_ShouldBypass_NoId) {
13860   MockHttpCache cache;
13861   HttpResponseInfo response;
13862   ScopedMockTransaction transaction(kSimpleGET_Transaction);
13863 
13864   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13865                                      &response);
13866   EXPECT_FALSE(response.was_cached);
13867 
13868   transaction.fps_cache_filter = {5};
13869   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13870                                      &response);
13871   EXPECT_FALSE(response.was_cached);
13872 }
13873 
TEST_F(HttpCacheTest,FirstPartySetsBypassCache_ShouldBypass_IdTooSmall)13874 TEST_F(HttpCacheTest, FirstPartySetsBypassCache_ShouldBypass_IdTooSmall) {
13875   MockHttpCache cache;
13876   HttpResponseInfo response;
13877   ScopedMockTransaction transaction(kSimpleGET_Transaction);
13878   const int64_t kBrowserRunId = 4;
13879   transaction.browser_run_id = {kBrowserRunId};
13880   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13881                                      &response);
13882   EXPECT_FALSE(response.was_cached);
13883   EXPECT_TRUE(response.browser_run_id.has_value());
13884   EXPECT_EQ(kBrowserRunId, response.browser_run_id.value());
13885 
13886   transaction.fps_cache_filter = {5};
13887   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13888                                      &response);
13889   EXPECT_FALSE(response.was_cached);
13890 }
13891 
TEST_F(HttpCacheTest,FirstPartySetsBypassCache_ShouldNotBypass)13892 TEST_F(HttpCacheTest, FirstPartySetsBypassCache_ShouldNotBypass) {
13893   MockHttpCache cache;
13894   HttpResponseInfo response;
13895   ScopedMockTransaction transaction(kSimpleGET_Transaction);
13896   const int64_t kBrowserRunId = 5;
13897   transaction.browser_run_id = {kBrowserRunId};
13898   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13899                                      &response);
13900   EXPECT_FALSE(response.was_cached);
13901   EXPECT_TRUE(response.browser_run_id.has_value());
13902   EXPECT_EQ(kBrowserRunId, response.browser_run_id.value());
13903 
13904   transaction.fps_cache_filter = {5};
13905   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13906                                      &response);
13907   EXPECT_TRUE(response.was_cached);
13908 }
13909 
TEST_F(HttpCacheTest,FirstPartySetsBypassCache_ShouldNotBypass_NoFilter)13910 TEST_F(HttpCacheTest, FirstPartySetsBypassCache_ShouldNotBypass_NoFilter) {
13911   MockHttpCache cache;
13912   HttpResponseInfo response;
13913   ScopedMockTransaction transaction(kSimpleGET_Transaction);
13914 
13915   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13916                                      &response);
13917   EXPECT_FALSE(response.was_cached);
13918 
13919   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13920                                      &response);
13921   EXPECT_TRUE(response.was_cached);
13922 }
13923 
TEST_F(HttpCacheTest,SecurityHeadersAreCopiedToConditionalizedResponse)13924 TEST_F(HttpCacheTest, SecurityHeadersAreCopiedToConditionalizedResponse) {
13925   MockHttpCache cache;
13926   HttpResponseInfo response;
13927   ScopedMockTransaction transaction(kSimpleGET_Transaction);
13928 
13929   static const Response kNetResponse1 = {
13930       "HTTP/1.1 200 OK",
13931       "Date: Fri, 12 Jun 2009 21:46:42 GMT\n"
13932       "Server: server1\n"
13933       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n"
13934       "Cross-Origin-Resource-Policy: cross-origin\n",
13935       "body1"};
13936 
13937   static const Response kNetResponse2 = {
13938       "HTTP/1.1 304 Not Modified",
13939       "Date: Wed, 22 Jul 2009 03:15:26 GMT\n"
13940       "Server: server2\n"
13941       "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n",
13942       ""};
13943 
13944   kNetResponse1.AssignTo(&transaction);
13945   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13946                                      &response);
13947 
13948   // On the second request, the cache is revalidated.
13949   const char kExtraRequestHeaders[] =
13950       "If-Modified-Since: Wed, 06 Feb 2008 22:38:21 GMT\r\n";
13951   transaction.request_headers = kExtraRequestHeaders;
13952   kNetResponse2.AssignTo(&transaction);
13953   RunTransactionTestWithResponseInfo(cache.http_cache(), transaction,
13954                                      &response);
13955 
13956   // Verify that the CORP header was carried over to the response.
13957   std::string response_corp_header;
13958   response.headers->GetNormalizedHeader("Cross-Origin-Resource-Policy",
13959                                         &response_corp_header);
13960 
13961   EXPECT_EQ(304, response.headers->response_code());
13962   EXPECT_EQ("cross-origin", response_corp_header);
13963 }
13964 
13965 }  // namespace net
13966