• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/url_request/url_request_job.h"
6 
7 #include <memory>
8 
9 #include "base/functional/bind.h"
10 #include "base/run_loop.h"
11 #include "base/test/bind.h"
12 #include "base/test/scoped_feature_list.h"
13 #include "net/base/features.h"
14 #include "net/base/request_priority.h"
15 #include "net/http/http_transaction_test_util.h"
16 #include "net/test/cert_test_util.h"
17 #include "net/test/gtest_util.h"
18 #include "net/test/test_data_directory.h"
19 #include "net/test/test_with_task_environment.h"
20 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
21 #include "net/url_request/referrer_policy.h"
22 #include "net/url_request/url_request.h"
23 #include "net/url_request/url_request_context.h"
24 #include "net/url_request/url_request_context_builder.h"
25 #include "net/url_request/url_request_test_util.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "third_party/abseil-cpp/absl/types/optional.h"
29 #include "url/url_util.h"
30 
31 using net::test::IsError;
32 using net::test::IsOk;
33 
34 namespace net {
35 
36 namespace {
37 
38 // Data encoded in kBrotliHelloData.
39 const char kHelloData[] = "hello, world!\n";
40 // kHelloData encoded with brotli.
41 const char kBrotliHelloData[] =
42     "\033\015\0\0\244\024\102\152\020\111\152\072\235\126\034";
43 
44 // This is a header that signals the end of the data.
45 const char kGzipData[] = "\x1f\x08b\x08\0\0\0\0\0\0\3\3\0\0\0\0\0\0\0\0";
46 const char kGzipDataWithName[] =
47     "\x1f\x08b\x08\x08\0\0\0\0\0\0name\0\3\0\0\0\0\0\0\0\0";
48 // kHelloData encoded with gzip.
49 const char kGzipHelloData[] =
50     "\x1f\x8b\x08\x08\x46\x7d\x4e\x56\x00\x03\x67\x7a\x69\x70\x2e\x74\x78\x74"
51     "\x00\xcb\x48\xcd\xc9\xc9\xe7\x02\x00\x20\x30\x3a\x36\x06\x00\x00\x00";
52 
GZipServer(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)53 void GZipServer(const HttpRequestInfo* request,
54                 std::string* response_status,
55                 std::string* response_headers,
56                 std::string* response_data) {
57   response_data->assign(kGzipData, sizeof(kGzipData));
58 }
59 
GZipHelloServer(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)60 void GZipHelloServer(const HttpRequestInfo* request,
61                      std::string* response_status,
62                      std::string* response_headers,
63                      std::string* response_data) {
64   response_data->assign(kGzipHelloData, sizeof(kGzipHelloData) - 1);
65 }
66 
BigGZipServer(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)67 void BigGZipServer(const HttpRequestInfo* request,
68                    std::string* response_status,
69                    std::string* response_headers,
70                    std::string* response_data) {
71   response_data->assign(kGzipDataWithName, sizeof(kGzipDataWithName));
72   response_data->insert(10, 64 * 1024, 'a');
73 }
74 
BrotliHelloServer(const HttpRequestInfo * request,std::string * response_status,std::string * response_headers,std::string * response_data)75 void BrotliHelloServer(const HttpRequestInfo* request,
76                        std::string* response_status,
77                        std::string* response_headers,
78                        std::string* response_data) {
79   response_data->assign(kBrotliHelloData, sizeof(kBrotliHelloData) - 1);
80 }
81 
MakeMockReferrerPolicyTransaction(const char * original_url,const char * referer_header,const char * response_headers,MockTransaction * transaction)82 void MakeMockReferrerPolicyTransaction(const char* original_url,
83                                        const char* referer_header,
84                                        const char* response_headers,
85                                        MockTransaction* transaction) {
86   transaction->url = original_url;
87   transaction->method = "GET";
88   transaction->request_time = base::Time();
89   transaction->request_headers = referer_header;
90   transaction->load_flags = LOAD_NORMAL;
91   transaction->status = "HTTP/1.1 302 Found";
92   transaction->response_headers = response_headers;
93   transaction->response_time = base::Time();
94   transaction->data = "hello";
95   transaction->dns_aliases = {};
96   transaction->test_mode = TEST_MODE_NORMAL;
97   transaction->handler = MockTransactionHandler();
98   transaction->read_handler = MockTransactionReadHandler();
99   if (GURL(original_url).SchemeIsCryptographic()) {
100     transaction->cert =
101         net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
102   } else {
103     transaction->cert = nullptr;
104   }
105   transaction->cert_status = 0;
106   transaction->ssl_connection_status = 0;
107   transaction->start_return_code = OK;
108 }
109 
110 const MockTransaction kNoFilterTransaction = {
111     "http://www.google.com/gzyp",
112     "GET",
113     base::Time(),
114     "",
115     LOAD_NORMAL,
116     DefaultTransportInfo(),
117     "HTTP/1.1 200 OK",
118     "Cache-Control: max-age=10000\n"
119     "Content-Length: 30\n",  // Intentionally wrong.
120     base::Time(),
121     "hello",
122     {},
123     absl::nullopt,
124     absl::nullopt,
125     TEST_MODE_NORMAL,
126     MockTransactionHandler(),
127     MockTransactionReadHandler(),
128     nullptr,
129     0,
130     OK,
131     OK,
132 };
133 
134 const MockTransaction kNoFilterTransactionWithInvalidLength = {
135     "http://www.google.com/gzyp",
136     "GET",
137     base::Time(),
138     "",
139     LOAD_NORMAL,
140     DefaultTransportInfo(),
141     "HTTP/1.1 200 OK",
142     "Cache-Control: max-age=10000\n"
143     "Content-Length: +30\n",  // Invalid
144     base::Time(),
145     "hello",
146     {},
147     absl::nullopt,
148     absl::nullopt,
149     TEST_MODE_NORMAL,
150     MockTransactionHandler(),
151     MockTransactionReadHandler(),
152     nullptr,
153     0,
154     OK,
155     OK,
156 };
157 
158 const MockTransaction kGZipTransaction = {
159     "http://www.google.com/gzyp",
160     "GET",
161     base::Time(),
162     "",
163     LOAD_NORMAL,
164     DefaultTransportInfo(),
165     "HTTP/1.1 200 OK",
166     "Cache-Control: max-age=10000\n"
167     "Content-Encoding: gzip\n"
168     "Content-Length: 30\n",  // Intentionally wrong.
169     base::Time(),
170     "",
171     {},
172     absl::nullopt,
173     absl::nullopt,
174     TEST_MODE_NORMAL,
175     base::BindRepeating(&GZipServer),
176     MockTransactionReadHandler(),
177     nullptr,
178     0,
179     0,
180     OK,
181     OK,
182 };
183 
184 const MockTransaction kGzipSlowTransaction = {
185     "http://www.google.com/gzyp",
186     "GET",
187     base::Time(),
188     "",
189     LOAD_NORMAL,
190     DefaultTransportInfo(),
191     "HTTP/1.1 200 OK",
192     "Cache-Control: max-age=10000\n"
193     "Content-Encoding: gzip\n",
194     base::Time(),
195     "",
196     {},
197     absl::nullopt,
198     absl::nullopt,
199     TEST_MODE_SLOW_READ,
200     base::BindRepeating(&GZipHelloServer),
201     MockTransactionReadHandler(),
202     nullptr,
203     0,
204     0,
205     OK,
206     OK,
207 };
208 
209 const MockTransaction kRedirectTransaction = {
210     "http://www.google.com/redirect",
211     "GET",
212     base::Time(),
213     "",
214     LOAD_NORMAL,
215     DefaultTransportInfo(),
216     "HTTP/1.1 302 Found",
217     "Cache-Control: max-age=10000\n"
218     "Location: http://www.google.com/destination\n"
219     "Content-Length: 5\n",
220     base::Time(),
221     "hello",
222     {},
223     absl::nullopt,
224     absl::nullopt,
225     TEST_MODE_NORMAL,
226     MockTransactionHandler(),
227     MockTransactionReadHandler(),
228     nullptr,
229     0,
230     0,
231     OK,
232     OK,
233 };
234 
235 const MockTransaction kEmptyBodyGzipTransaction = {
236     "http://www.google.com/empty_body",
237     "GET",
238     base::Time(),
239     "",
240     LOAD_NORMAL,
241     DefaultTransportInfo(),
242     "HTTP/1.1 200 OK",
243     "Content-Encoding: gzip\n",
244     base::Time(),
245     "",
246     {},
247     absl::nullopt,
248     absl::nullopt,
249     TEST_MODE_NORMAL,
250     MockTransactionHandler(),
251     MockTransactionReadHandler(),
252     nullptr,
253     0,
254     0,
255     OK,
256     OK,
257 };
258 
259 const MockTransaction kInvalidContentGZipTransaction = {
260     "http://www.google.com/gzyp",
261     "GET",
262     base::Time(),
263     "",
264     LOAD_NORMAL,
265     DefaultTransportInfo(),
266     "HTTP/1.1 200 OK",
267     "Content-Encoding: gzip\n"
268     "Content-Length: 21\n",
269     base::Time(),
270     "not a valid gzip body",
271     {},
272     absl::nullopt,
273     absl::nullopt,
274     TEST_MODE_NORMAL,
275     MockTransactionHandler(),
276     MockTransactionReadHandler(),
277     nullptr,
278     0,
279     0,
280     OK,
281     OK,
282 };
283 
284 const MockTransaction kBrotliSlowTransaction = {
285     "http://www.google.com/brotli",
286     "GET",
287     base::Time(),
288     "",
289     LOAD_NORMAL,
290     DefaultTransportInfo(),
291     "HTTP/1.1 200 OK",
292     "Cache-Control: max-age=10000\n"
293     "Content-Encoding: br\n"
294     "Content-Length: 230\n",  // Intentionally wrong.
295     base::Time(),
296     "",
297     {},
298     absl::nullopt,
299     absl::nullopt,
300     TEST_MODE_SLOW_READ,
301     base::BindRepeating(&BrotliHelloServer),
302     MockTransactionReadHandler(),
303     nullptr,
304     0,
305     0,
306     OK,
307     OK,
308 };
309 
310 }  // namespace
311 
312 using URLRequestJobTest = TestWithTaskEnvironment;
313 
TEST_F(URLRequestJobTest,TransactionNoFilter)314 TEST_F(URLRequestJobTest, TransactionNoFilter) {
315   auto context_builder = CreateTestURLRequestContextBuilder();
316   auto* network_layer = context_builder->SetHttpTransactionFactoryForTesting(
317       std::make_unique<MockNetworkLayer>());
318   context_builder->DisableHttpCache();
319   auto context = context_builder->Build();
320 
321   TestDelegate d;
322   std::unique_ptr<URLRequest> req(
323       context->CreateRequest(GURL(kNoFilterTransaction.url), DEFAULT_PRIORITY,
324                              &d, TRAFFIC_ANNOTATION_FOR_TESTS));
325   AddMockTransaction(&kNoFilterTransaction);
326 
327   req->set_method("GET");
328   req->Start();
329 
330   d.RunUntilComplete();
331 
332   EXPECT_FALSE(d.request_failed());
333   EXPECT_EQ(200, req->GetResponseCode());
334   EXPECT_EQ("hello", d.data_received());
335   EXPECT_TRUE(network_layer->done_reading_called());
336   // When there's no filter and a Content-Length, expected content size should
337   // be available.
338   EXPECT_EQ(30, req->GetExpectedContentSize());
339 
340   RemoveMockTransaction(&kNoFilterTransaction);
341 }
342 
TEST_F(URLRequestJobTest,TransactionNoFilterWithInvalidLength)343 TEST_F(URLRequestJobTest, TransactionNoFilterWithInvalidLength) {
344   auto context_builder = CreateTestURLRequestContextBuilder();
345   auto* network_layer = context_builder->SetHttpTransactionFactoryForTesting(
346       std::make_unique<MockNetworkLayer>());
347   context_builder->DisableHttpCache();
348   auto context = context_builder->Build();
349 
350   TestDelegate d;
351   std::unique_ptr<URLRequest> req(context->CreateRequest(
352       GURL(kNoFilterTransactionWithInvalidLength.url), DEFAULT_PRIORITY, &d,
353       TRAFFIC_ANNOTATION_FOR_TESTS));
354   AddMockTransaction(&kNoFilterTransactionWithInvalidLength);
355 
356   req->set_method("GET");
357   req->Start();
358 
359   d.RunUntilComplete();
360 
361   EXPECT_FALSE(d.request_failed());
362   EXPECT_EQ(200, req->GetResponseCode());
363   EXPECT_EQ("hello", d.data_received());
364   EXPECT_TRUE(network_layer->done_reading_called());
365   // Invalid Content-Lengths that start with a + should not be reported.
366   EXPECT_EQ(-1, req->GetExpectedContentSize());
367 
368   RemoveMockTransaction(&kNoFilterTransactionWithInvalidLength);
369 }
370 
TEST_F(URLRequestJobTest,TransactionNotifiedWhenDone)371 TEST_F(URLRequestJobTest, TransactionNotifiedWhenDone) {
372   auto context_builder = CreateTestURLRequestContextBuilder();
373   auto* network_layer = context_builder->SetHttpTransactionFactoryForTesting(
374       std::make_unique<MockNetworkLayer>());
375   context_builder->DisableHttpCache();
376   auto context = context_builder->Build();
377 
378   TestDelegate d;
379   std::unique_ptr<URLRequest> req(
380       context->CreateRequest(GURL(kGZipTransaction.url), DEFAULT_PRIORITY, &d,
381                              TRAFFIC_ANNOTATION_FOR_TESTS));
382   AddMockTransaction(&kGZipTransaction);
383 
384   req->set_method("GET");
385   req->Start();
386 
387   d.RunUntilComplete();
388 
389   EXPECT_TRUE(d.response_completed());
390   EXPECT_EQ(OK, d.request_status());
391   EXPECT_EQ(200, req->GetResponseCode());
392   EXPECT_EQ("", d.data_received());
393   EXPECT_TRUE(network_layer->done_reading_called());
394   // When there's a filter and a Content-Length, expected content size should
395   // not be available.
396   EXPECT_EQ(-1, req->GetExpectedContentSize());
397 
398   RemoveMockTransaction(&kGZipTransaction);
399 }
400 
TEST_F(URLRequestJobTest,SyncTransactionNotifiedWhenDone)401 TEST_F(URLRequestJobTest, SyncTransactionNotifiedWhenDone) {
402   auto context_builder = CreateTestURLRequestContextBuilder();
403   auto* network_layer = context_builder->SetHttpTransactionFactoryForTesting(
404       std::make_unique<MockNetworkLayer>());
405   context_builder->DisableHttpCache();
406   auto context = context_builder->Build();
407 
408   TestDelegate d;
409   std::unique_ptr<URLRequest> req(
410       context->CreateRequest(GURL(kGZipTransaction.url), DEFAULT_PRIORITY, &d,
411                              TRAFFIC_ANNOTATION_FOR_TESTS));
412   MockTransaction transaction(kGZipTransaction);
413   transaction.test_mode = TEST_MODE_SYNC_ALL;
414   AddMockTransaction(&transaction);
415 
416   req->set_method("GET");
417   req->Start();
418 
419   d.RunUntilComplete();
420 
421   EXPECT_TRUE(d.response_completed());
422   EXPECT_EQ(OK, d.request_status());
423   EXPECT_EQ(200, req->GetResponseCode());
424   EXPECT_EQ("", d.data_received());
425   EXPECT_TRUE(network_layer->done_reading_called());
426   // When there's a filter and a Content-Length, expected content size should
427   // not be available.
428   EXPECT_EQ(-1, req->GetExpectedContentSize());
429 
430   RemoveMockTransaction(&transaction);
431 }
432 
433 // Tests processing a large gzip header one byte at a time.
TEST_F(URLRequestJobTest,SyncSlowTransaction)434 TEST_F(URLRequestJobTest, SyncSlowTransaction) {
435   auto context_builder = CreateTestURLRequestContextBuilder();
436   auto* network_layer = context_builder->SetHttpTransactionFactoryForTesting(
437       std::make_unique<MockNetworkLayer>());
438   context_builder->DisableHttpCache();
439   auto context = context_builder->Build();
440 
441   TestDelegate d;
442   std::unique_ptr<URLRequest> req(
443       context->CreateRequest(GURL(kGZipTransaction.url), DEFAULT_PRIORITY, &d,
444                              TRAFFIC_ANNOTATION_FOR_TESTS));
445   MockTransaction transaction(kGZipTransaction);
446   transaction.test_mode = TEST_MODE_SYNC_ALL | TEST_MODE_SLOW_READ;
447   transaction.handler = base::BindRepeating(&BigGZipServer);
448   AddMockTransaction(&transaction);
449 
450   req->set_method("GET");
451   req->Start();
452 
453   d.RunUntilComplete();
454 
455   EXPECT_TRUE(d.response_completed());
456   EXPECT_EQ(OK, d.request_status());
457   EXPECT_EQ(200, req->GetResponseCode());
458   EXPECT_EQ("", d.data_received());
459   EXPECT_TRUE(network_layer->done_reading_called());
460   EXPECT_EQ(-1, req->GetExpectedContentSize());
461 
462   RemoveMockTransaction(&transaction);
463 }
464 
TEST_F(URLRequestJobTest,RedirectTransactionNotifiedWhenDone)465 TEST_F(URLRequestJobTest, RedirectTransactionNotifiedWhenDone) {
466   auto context_builder = CreateTestURLRequestContextBuilder();
467   auto* network_layer = context_builder->SetHttpTransactionFactoryForTesting(
468       std::make_unique<MockNetworkLayer>());
469   context_builder->DisableHttpCache();
470   auto context = context_builder->Build();
471 
472   TestDelegate d;
473   std::unique_ptr<URLRequest> req(
474       context->CreateRequest(GURL(kRedirectTransaction.url), DEFAULT_PRIORITY,
475                              &d, TRAFFIC_ANNOTATION_FOR_TESTS));
476   AddMockTransaction(&kRedirectTransaction);
477 
478   req->set_method("GET");
479   req->Start();
480 
481   d.RunUntilComplete();
482 
483   EXPECT_TRUE(network_layer->done_reading_called());
484 
485   RemoveMockTransaction(&kRedirectTransaction);
486 }
487 
TEST_F(URLRequestJobTest,RedirectTransactionWithReferrerPolicyHeader)488 TEST_F(URLRequestJobTest, RedirectTransactionWithReferrerPolicyHeader) {
489   struct TestCase {
490     const char* original_url;
491     const char* original_referrer;
492     const char* response_headers;
493     ReferrerPolicy original_referrer_policy;
494     ReferrerPolicy expected_final_referrer_policy;
495     const char* expected_final_referrer;
496   };
497 
498   // Note: There are more thorough test cases in RedirectInfoTest.
499   const TestCase kTests[] = {
500       // If a redirect serves 'Referrer-Policy: no-referrer', then the referrer
501       // should be cleared.
502       {"http://foo.test/one" /* original url */,
503        "http://foo.test/one" /* original referrer */,
504        "Location: http://foo.test/test\n"
505        "Referrer-Policy: no-referrer\n",
506        // original policy
507        ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
508        ReferrerPolicy::NO_REFERRER /* expected final policy */,
509        "" /* expected final referrer */},
510 
511       // A redirect response without Referrer-Policy header should not affect
512       // the policy and the referrer.
513       {"http://foo.test/one" /* original url */,
514        "http://foo.test/one" /* original referrer */,
515        "Location: http://foo.test/test\n",
516        // original policy
517        ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
518        // expected final policy
519        ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
520        "http://foo.test/one" /* expected final referrer */},
521   };
522 
523   for (const auto& test : kTests) {
524     MockTransaction transaction;
525     std::string request_headers =
526         "Referer: " + std::string(test.original_referrer) + "\n";
527     MakeMockReferrerPolicyTransaction(test.original_url,
528                                       request_headers.c_str(),
529                                       test.response_headers, &transaction);
530 
531     auto context_builder = CreateTestURLRequestContextBuilder();
532     auto* network_layer = context_builder->SetHttpTransactionFactoryForTesting(
533         std::make_unique<MockNetworkLayer>());
534     context_builder->DisableHttpCache();
535     auto context = context_builder->Build();
536 
537     TestDelegate d;
538     std::unique_ptr<URLRequest> req(
539         context->CreateRequest(GURL(transaction.url), DEFAULT_PRIORITY, &d,
540                                TRAFFIC_ANNOTATION_FOR_TESTS));
541     AddMockTransaction(&transaction);
542 
543     req->set_referrer_policy(test.original_referrer_policy);
544     req->SetReferrer(test.original_referrer);
545 
546     req->set_method("GET");
547     req->Start();
548 
549     d.RunUntilComplete();
550 
551     EXPECT_TRUE(network_layer->done_reading_called());
552 
553     RemoveMockTransaction(&transaction);
554 
555     // Test that the referrer policy and referrer were set correctly
556     // according to the header received during the redirect.
557     EXPECT_EQ(test.expected_final_referrer_policy, req->referrer_policy());
558     EXPECT_EQ(test.expected_final_referrer, req->referrer());
559   }
560 }
561 
TEST_F(URLRequestJobTest,TransactionNotCachedWhenNetworkDelegateRedirects)562 TEST_F(URLRequestJobTest, TransactionNotCachedWhenNetworkDelegateRedirects) {
563   auto context_builder = CreateTestURLRequestContextBuilder();
564   auto* network_layer = context_builder->SetHttpTransactionFactoryForTesting(
565       std::make_unique<MockNetworkLayer>());
566   auto network_delegate = std::make_unique<TestNetworkDelegate>();
567   network_delegate->set_redirect_on_headers_received_url(GURL("http://foo"));
568   context_builder->DisableHttpCache();
569   context_builder->set_network_delegate(std::move(network_delegate));
570   auto context = context_builder->Build();
571 
572   TestDelegate d;
573   std::unique_ptr<URLRequest> req(
574       context->CreateRequest(GURL(kGZipTransaction.url), DEFAULT_PRIORITY, &d,
575                              TRAFFIC_ANNOTATION_FOR_TESTS));
576   AddMockTransaction(&kGZipTransaction);
577 
578   req->set_method("GET");
579   req->Start();
580 
581   d.RunUntilComplete();
582 
583   EXPECT_TRUE(network_layer->stop_caching_called());
584 
585   RemoveMockTransaction(&kGZipTransaction);
586 }
587 
588 // Makes sure that ReadRawDataComplete correctly updates request status before
589 // calling ReadFilteredData.
590 // Regression test for crbug.com/553300.
TEST_F(URLRequestJobTest,EmptyBodySkipFilter)591 TEST_F(URLRequestJobTest, EmptyBodySkipFilter) {
592   auto context_builder = CreateTestURLRequestContextBuilder();
593   auto* network_layer = context_builder->SetHttpTransactionFactoryForTesting(
594       std::make_unique<MockNetworkLayer>());
595   context_builder->DisableHttpCache();
596   auto context = context_builder->Build();
597 
598   TestDelegate d;
599   std::unique_ptr<URLRequest> req(context->CreateRequest(
600       GURL(kEmptyBodyGzipTransaction.url), DEFAULT_PRIORITY, &d,
601       TRAFFIC_ANNOTATION_FOR_TESTS));
602   AddMockTransaction(&kEmptyBodyGzipTransaction);
603 
604   req->set_method("GET");
605   req->Start();
606 
607   d.RunUntilComplete();
608 
609   EXPECT_FALSE(d.request_failed());
610   EXPECT_EQ(200, req->GetResponseCode());
611   EXPECT_TRUE(d.data_received().empty());
612   EXPECT_TRUE(network_layer->done_reading_called());
613 
614   RemoveMockTransaction(&kEmptyBodyGzipTransaction);
615 }
616 
617 // Regression test for crbug.com/575213.
TEST_F(URLRequestJobTest,InvalidContentGZipTransaction)618 TEST_F(URLRequestJobTest, InvalidContentGZipTransaction) {
619   auto context_builder = CreateTestURLRequestContextBuilder();
620   auto* network_layer = context_builder->SetHttpTransactionFactoryForTesting(
621       std::make_unique<MockNetworkLayer>());
622   context_builder->DisableHttpCache();
623   auto context = context_builder->Build();
624 
625   TestDelegate d;
626   std::unique_ptr<URLRequest> req(context->CreateRequest(
627       GURL(kInvalidContentGZipTransaction.url), DEFAULT_PRIORITY, &d,
628       TRAFFIC_ANNOTATION_FOR_TESTS));
629   AddMockTransaction(&kInvalidContentGZipTransaction);
630 
631   req->set_method("GET");
632   req->Start();
633 
634   d.RunUntilComplete();
635 
636   // Request failed indicates the request failed before headers were received,
637   // so should be false.
638   EXPECT_FALSE(d.request_failed());
639   EXPECT_EQ(200, req->GetResponseCode());
640   EXPECT_EQ(ERR_CONTENT_DECODING_FAILED, d.request_status());
641   EXPECT_TRUE(d.data_received().empty());
642   EXPECT_FALSE(network_layer->done_reading_called());
643 
644   RemoveMockTransaction(&kInvalidContentGZipTransaction);
645 }
646 
647 // Regression test for crbug.com/553300.
TEST_F(URLRequestJobTest,SlowFilterRead)648 TEST_F(URLRequestJobTest, SlowFilterRead) {
649   auto context_builder = CreateTestURLRequestContextBuilder();
650   auto* network_layer = context_builder->SetHttpTransactionFactoryForTesting(
651       std::make_unique<MockNetworkLayer>());
652   context_builder->DisableHttpCache();
653   auto context = context_builder->Build();
654 
655   TestDelegate d;
656   std::unique_ptr<URLRequest> req(
657       context->CreateRequest(GURL(kGzipSlowTransaction.url), DEFAULT_PRIORITY,
658                              &d, TRAFFIC_ANNOTATION_FOR_TESTS));
659   AddMockTransaction(&kGzipSlowTransaction);
660 
661   req->set_method("GET");
662   req->Start();
663 
664   d.RunUntilComplete();
665 
666   EXPECT_FALSE(d.request_failed());
667   EXPECT_EQ(200, req->GetResponseCode());
668   EXPECT_EQ("hello\n", d.data_received());
669   EXPECT_TRUE(network_layer->done_reading_called());
670 
671   RemoveMockTransaction(&kGzipSlowTransaction);
672 }
673 
TEST_F(URLRequestJobTest,SlowBrotliRead)674 TEST_F(URLRequestJobTest, SlowBrotliRead) {
675   auto context_builder = CreateTestURLRequestContextBuilder();
676   auto* network_layer = context_builder->SetHttpTransactionFactoryForTesting(
677       std::make_unique<MockNetworkLayer>());
678   context_builder->DisableHttpCache();
679   auto context = context_builder->Build();
680 
681   TestDelegate d;
682   std::unique_ptr<URLRequest> req(
683       context->CreateRequest(GURL(kBrotliSlowTransaction.url), DEFAULT_PRIORITY,
684                              &d, TRAFFIC_ANNOTATION_FOR_TESTS));
685   AddMockTransaction(&kBrotliSlowTransaction);
686 
687   req->set_method("GET");
688   req->Start();
689 
690   base::RunLoop().RunUntilIdle();
691 
692   EXPECT_FALSE(d.request_failed());
693   EXPECT_EQ(200, req->GetResponseCode());
694   EXPECT_EQ(kHelloData, d.data_received());
695   EXPECT_TRUE(network_layer->done_reading_called());
696   // When there's a filter and a Content-Length, expected content size should
697   // not be available.
698   EXPECT_EQ(-1, req->GetExpectedContentSize());
699 
700   RemoveMockTransaction(&kBrotliSlowTransaction);
701 }
702 
TEST(URLRequestJobComputeReferrer,SetsSameOriginForMetricsOnSameOrigin)703 TEST(URLRequestJobComputeReferrer, SetsSameOriginForMetricsOnSameOrigin) {
704   bool same_origin = false;
705   URLRequestJob::ComputeReferrerForPolicy(
706       ReferrerPolicy(),
707       /*original_referrer=*/GURL("http://google.com"),
708       /*destination=*/GURL("http://google.com"), &same_origin);
709   EXPECT_TRUE(same_origin);
710 }
711 
TEST(URLRequestJobComputeReferrer,SetsSameOriginForMetricsOnCrossOrigin)712 TEST(URLRequestJobComputeReferrer, SetsSameOriginForMetricsOnCrossOrigin) {
713   bool same_origin = true;
714   URLRequestJob::ComputeReferrerForPolicy(
715       ReferrerPolicy(),
716       /*original_referrer=*/GURL("http://google.com"),
717       /*destination=*/GURL("http://boggle.com"), &same_origin);
718   EXPECT_FALSE(same_origin);
719 }
720 
TEST(URLRequestJobComputeReferrer,AcceptsNullptrInput)721 TEST(URLRequestJobComputeReferrer, AcceptsNullptrInput) {
722   // Shouldn't segfault.
723   URLRequestJob::ComputeReferrerForPolicy(ReferrerPolicy(), GURL(), GURL(),
724                                           nullptr);
725 }
726 
TEST(URLRequestJobComputeReferrer,FilesystemDestination)727 TEST(URLRequestJobComputeReferrer, FilesystemDestination) {
728   EXPECT_EQ(URLRequestJob::ComputeReferrerForPolicy(
729                 ReferrerPolicy::NEVER_CLEAR, GURL("https://referrer.example"),
730                 GURL("filesystem:https://destination.example"), nullptr),
731             GURL("https://referrer.example"));
732 }
733 
TEST(URLRequestJobComputeReferrer,TruncatesLongReferrer)734 TEST(URLRequestJobComputeReferrer, TruncatesLongReferrer) {
735   std::string original_spec = "https://referrer.example/";
736   original_spec.resize(4097, 'a');
737   const GURL kOriginalReferrer(original_spec);
738 
739   EXPECT_EQ(URLRequestJob::ComputeReferrerForPolicy(ReferrerPolicy::NEVER_CLEAR,
740                                                     kOriginalReferrer,
741                                                     GURL("https://google.com")),
742             GURL("https://referrer.example/"));
743 }
744 
TEST(URLRequestJobComputeReferrer,DoesntTruncateShortReferrer)745 TEST(URLRequestJobComputeReferrer, DoesntTruncateShortReferrer) {
746   std::string original_spec = "https://referrer.example/";
747   original_spec.resize(4096, 'a');
748   const GURL kOriginalReferrer(original_spec);
749 
750   EXPECT_EQ(URLRequestJob::ComputeReferrerForPolicy(ReferrerPolicy::NEVER_CLEAR,
751                                                     kOriginalReferrer,
752                                                     GURL("https://google.com")),
753             kOriginalReferrer);
754 }
755 
TEST(URLRequestJobComputeReferrer,DoesntTruncateEvenShorterReferrer)756 TEST(URLRequestJobComputeReferrer, DoesntTruncateEvenShorterReferrer) {
757   std::string original_spec = "https://referrer.example/";
758   original_spec.resize(4095, 'a');
759   const GURL kOriginalReferrer(original_spec);
760 
761   EXPECT_EQ(URLRequestJob::ComputeReferrerForPolicy(ReferrerPolicy::NEVER_CLEAR,
762                                                     kOriginalReferrer,
763                                                     GURL("https://google.com")),
764             kOriginalReferrer);
765 }
766 
TEST(URLRequestJobComputeReferrer,DoesntTruncateReferrerWithLongRef)767 TEST(URLRequestJobComputeReferrer, DoesntTruncateReferrerWithLongRef) {
768   // Because the "is the length greater than 4096?" check comes *after*
769   // stripping the ref in the Referrer Policy spec, a URL that is short except
770   // for having a very long ref should not be stripped to an origin by the "if
771   // the length is too long, strip to the origin" check.
772   EXPECT_EQ(URLRequestJob::ComputeReferrerForPolicy(
773                 ReferrerPolicy::NEVER_CLEAR,
774                 GURL(std::string("https://referrer.example/path#") +
775                      std::string(5000, 'a')),
776                 GURL("https://google.com")),
777             GURL("https://referrer.example/path"));
778 }
779 
TEST(URLRequestJobComputeReferrer,InvalidSchemeReferrer)780 TEST(URLRequestJobComputeReferrer, InvalidSchemeReferrer) {
781   const GURL kOriginalReferrer("about:blank");
782   ASSERT_FALSE(url::IsReferrerScheme(
783       kOriginalReferrer.spec().data(),
784       kOriginalReferrer.parsed_for_possibly_invalid_spec().scheme));
785 
786   EXPECT_EQ(URLRequestJob::ComputeReferrerForPolicy(ReferrerPolicy::NEVER_CLEAR,
787                                                     kOriginalReferrer,
788                                                     GURL("https://google.com")),
789             GURL());
790 
791   EXPECT_EQ(URLRequestJob::ComputeReferrerForPolicy(ReferrerPolicy::ORIGIN,
792                                                     kOriginalReferrer,
793                                                     GURL("https://google.com")),
794             GURL());
795 }
796 
TEST(URLRequestJobComputeReferrer,CapReferrerOnCrossOrigin)797 TEST(URLRequestJobComputeReferrer, CapReferrerOnCrossOrigin) {
798   base::test::ScopedFeatureList feature_list;
799   feature_list.InitAndEnableFeature(
800       features::kCapReferrerToOriginOnCrossOrigin);
801 
802   const GURL kOriginalReferrer("https://boggle.com/path");
803 
804   EXPECT_EQ(URLRequestJob::ComputeReferrerForPolicy(ReferrerPolicy::NEVER_CLEAR,
805                                                     kOriginalReferrer,
806                                                     GURL("https://google.com")),
807             GURL("https://boggle.com/"));
808 }
809 
TEST(URLRequestJobComputeReferrer,CapReferrerOnCrossOriginRespectsStricterPolicy)810 TEST(URLRequestJobComputeReferrer,
811      CapReferrerOnCrossOriginRespectsStricterPolicy) {
812   base::test::ScopedFeatureList feature_list;
813   feature_list.InitAndEnableFeature(
814       features::kCapReferrerToOriginOnCrossOrigin);
815 
816   const GURL kOriginalReferrer("https://boggle.com/path");
817 
818   EXPECT_EQ(URLRequestJob::ComputeReferrerForPolicy(ReferrerPolicy::NO_REFERRER,
819                                                     kOriginalReferrer,
820                                                     GURL("https://google.com")),
821             GURL());
822 }
823 
TEST(URLRequestJobComputeReferrer,CapReferrerOnCrossOriginDoesntCapOnSameOrigin)824 TEST(URLRequestJobComputeReferrer,
825      CapReferrerOnCrossOriginDoesntCapOnSameOrigin) {
826   base::test::ScopedFeatureList feature_list;
827   feature_list.InitAndEnableFeature(
828       features::kCapReferrerToOriginOnCrossOrigin);
829 
830   const GURL kOriginalReferrer("https://boggle.com/path");
831 
832   EXPECT_EQ(URLRequestJob::ComputeReferrerForPolicy(ReferrerPolicy::NEVER_CLEAR,
833                                                     kOriginalReferrer,
834                                                     GURL("https://boggle.com")),
835             kOriginalReferrer);
836 }
837 
838 }  // namespace net
839