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