xref: /aosp_15_r20/external/cronet/net/reporting/reporting_uploader_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2017 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/reporting/reporting_uploader.h"
6 
7 #include <memory>
8 #include <string>
9 #include <utility>
10 
11 #include "base/functional/bind.h"
12 #include "base/functional/callback.h"
13 #include "base/run_loop.h"
14 #include "base/test/scoped_feature_list.h"
15 #include "net/base/features.h"
16 #include "net/base/network_anonymization_key.h"
17 #include "net/base/schemeful_site.h"
18 #include "net/cookies/cookie_access_result.h"
19 #include "net/cookies/cookie_store.h"
20 #include "net/cookies/cookie_store_test_callbacks.h"
21 #include "net/http/http_status_code.h"
22 #include "net/socket/socket_test_util.h"
23 #include "net/test/embedded_test_server/embedded_test_server.h"
24 #include "net/test/embedded_test_server/http_request.h"
25 #include "net/test/embedded_test_server/http_response.h"
26 #include "net/test/test_with_task_environment.h"
27 #include "net/url_request/url_request_context.h"
28 #include "net/url_request/url_request_context_builder.h"
29 #include "net/url_request/url_request_test_util.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31 #include "url/gurl.h"
32 #include "url/origin.h"
33 
34 namespace net {
35 namespace {
36 
37 class ReportingUploaderTest : public TestWithTaskEnvironment {
38  protected:
ReportingUploaderTest()39   ReportingUploaderTest()
40       : server_(test_server::EmbeddedTestServer::TYPE_HTTPS),
41         context_(CreateTestURLRequestContextBuilder()->Build()),
42         uploader_(ReportingUploader::Create(context_.get())) {}
43 
44   test_server::EmbeddedTestServer server_;
45   std::unique_ptr<URLRequestContext> context_;
46   std::unique_ptr<ReportingUploader> uploader_;
47 
48   const url::Origin kOrigin = url::Origin::Create(GURL("https://origin/"));
49 };
50 
51 const char kUploadBody[] = "{}";
52 
CheckUpload(const test_server::HttpRequest & request)53 void CheckUpload(const test_server::HttpRequest& request) {
54   if (request.method_string != "POST") {
55     return;
56   }
57   auto it = request.headers.find("Content-Type");
58   EXPECT_TRUE(it != request.headers.end());
59   EXPECT_EQ("application/reports+json", it->second);
60   EXPECT_TRUE(request.has_content);
61   EXPECT_EQ(kUploadBody, request.content);
62 }
63 
AllowPreflight(const test_server::HttpRequest & request)64 std::unique_ptr<test_server::HttpResponse> AllowPreflight(
65     const test_server::HttpRequest& request) {
66   if (request.method_string != "OPTIONS") {
67     return nullptr;
68   }
69   auto it = request.headers.find("Origin");
70   EXPECT_TRUE(it != request.headers.end());
71   auto response = std::make_unique<test_server::BasicHttpResponse>();
72   response->AddCustomHeader("Access-Control-Allow-Origin", it->second);
73   response->AddCustomHeader("Access-Control-Allow-Methods", "POST");
74   response->AddCustomHeader("Access-Control-Allow-Headers", "Content-Type");
75   response->set_code(HTTP_OK);
76   response->set_content("");
77   response->set_content_type("text/plain");
78   return std::move(response);
79 }
80 
ReturnResponse(HttpStatusCode code,const test_server::HttpRequest & request)81 std::unique_ptr<test_server::HttpResponse> ReturnResponse(
82     HttpStatusCode code,
83     const test_server::HttpRequest& request) {
84   auto response = std::make_unique<test_server::BasicHttpResponse>();
85   response->set_code(code);
86   response->set_content("");
87   response->set_content_type("text/plain");
88   return std::move(response);
89 }
90 
ReturnInvalidResponse(const test_server::HttpRequest & request)91 std::unique_ptr<test_server::HttpResponse> ReturnInvalidResponse(
92     const test_server::HttpRequest& request) {
93   return std::make_unique<test_server::RawHttpResponse>(
94       "", "Not a valid HTTP response.");
95 }
96 
97 class TestUploadCallback {
98  public:
99   TestUploadCallback() = default;
100 
callback()101   ReportingUploader::UploadCallback callback() {
102     return base::BindOnce(&TestUploadCallback::OnUploadComplete,
103                           base::Unretained(this));
104   }
105 
WaitForCall()106   void WaitForCall() {
107     if (called_)
108       return;
109 
110     base::RunLoop run_loop;
111 
112     waiting_ = true;
113     closure_ = run_loop.QuitClosure();
114     run_loop.Run();
115   }
116 
outcome() const117   ReportingUploader::Outcome outcome() const { return outcome_; }
118 
119  private:
OnUploadComplete(ReportingUploader::Outcome outcome)120   void OnUploadComplete(ReportingUploader::Outcome outcome) {
121     EXPECT_FALSE(called_);
122 
123     called_ = true;
124     outcome_ = outcome;
125 
126     if (waiting_) {
127       waiting_ = false;
128       std::move(closure_).Run();
129     }
130   }
131 
132   bool called_ = false;
133   ReportingUploader::Outcome outcome_;
134 
135   bool waiting_ = false;
136   base::OnceClosure closure_;
137 };
138 
TEST_F(ReportingUploaderTest,Upload)139 TEST_F(ReportingUploaderTest, Upload) {
140   server_.RegisterRequestMonitor(base::BindRepeating(&CheckUpload));
141   server_.RegisterRequestHandler(base::BindRepeating(&AllowPreflight));
142   server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
143   ASSERT_TRUE(server_.Start());
144 
145   TestUploadCallback callback;
146   uploader_->StartUpload(kOrigin, server_.GetURL("/"),
147                          IsolationInfo::CreateTransient(), kUploadBody, 0,
148                          false, callback.callback());
149   callback.WaitForCall();
150 }
151 
TEST_F(ReportingUploaderTest,Success)152 TEST_F(ReportingUploaderTest, Success) {
153   server_.RegisterRequestHandler(base::BindRepeating(&AllowPreflight));
154   server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
155   ASSERT_TRUE(server_.Start());
156 
157   TestUploadCallback callback;
158   uploader_->StartUpload(kOrigin, server_.GetURL("/"),
159                          IsolationInfo::CreateTransient(), kUploadBody, 0,
160                          false, callback.callback());
161   callback.WaitForCall();
162 
163   EXPECT_EQ(ReportingUploader::Outcome::SUCCESS, callback.outcome());
164 }
165 
TEST_F(ReportingUploaderTest,NetworkError1)166 TEST_F(ReportingUploaderTest, NetworkError1) {
167   ASSERT_TRUE(server_.Start());
168   GURL url = server_.GetURL("/");
169   ASSERT_TRUE(server_.ShutdownAndWaitUntilComplete());
170 
171   TestUploadCallback callback;
172   uploader_->StartUpload(kOrigin, url, IsolationInfo::CreateTransient(),
173                          kUploadBody, 0, false, callback.callback());
174   callback.WaitForCall();
175 
176   EXPECT_EQ(ReportingUploader::Outcome::FAILURE, callback.outcome());
177 }
178 
TEST_F(ReportingUploaderTest,NetworkError2)179 TEST_F(ReportingUploaderTest, NetworkError2) {
180   server_.RegisterRequestHandler(base::BindRepeating(&AllowPreflight));
181   server_.RegisterRequestHandler(base::BindRepeating(&ReturnInvalidResponse));
182   ASSERT_TRUE(server_.Start());
183 
184   TestUploadCallback callback;
185   uploader_->StartUpload(kOrigin, server_.GetURL("/"),
186                          IsolationInfo::CreateTransient(), kUploadBody, 0,
187                          false, callback.callback());
188   callback.WaitForCall();
189 
190   EXPECT_EQ(ReportingUploader::Outcome::FAILURE, callback.outcome());
191 }
192 
TEST_F(ReportingUploaderTest,ServerError)193 TEST_F(ReportingUploaderTest, ServerError) {
194   server_.RegisterRequestHandler(base::BindRepeating(&AllowPreflight));
195   server_.RegisterRequestHandler(
196       base::BindRepeating(&ReturnResponse, HTTP_INTERNAL_SERVER_ERROR));
197   ASSERT_TRUE(server_.Start());
198 
199   TestUploadCallback callback;
200   uploader_->StartUpload(kOrigin, server_.GetURL("/"),
201                          IsolationInfo::CreateTransient(), kUploadBody, 0,
202                          false, callback.callback());
203   callback.WaitForCall();
204 
205   EXPECT_EQ(ReportingUploader::Outcome::FAILURE, callback.outcome());
206 }
207 
VerifyPreflight(bool * preflight_received_out,const test_server::HttpRequest & request)208 std::unique_ptr<test_server::HttpResponse> VerifyPreflight(
209     bool* preflight_received_out,
210     const test_server::HttpRequest& request) {
211   if (request.method_string != "OPTIONS") {
212     return nullptr;
213   }
214   *preflight_received_out = true;
215   return AllowPreflight(request);
216 }
217 
TEST_F(ReportingUploaderTest,VerifyPreflight)218 TEST_F(ReportingUploaderTest, VerifyPreflight) {
219   bool preflight_received = false;
220   server_.RegisterRequestHandler(
221       base::BindRepeating(&VerifyPreflight, &preflight_received));
222   server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
223   ASSERT_TRUE(server_.Start());
224 
225   TestUploadCallback callback;
226   uploader_->StartUpload(kOrigin, server_.GetURL("/"),
227                          IsolationInfo::CreateTransient(), kUploadBody, 0,
228                          false, callback.callback());
229   callback.WaitForCall();
230 
231   EXPECT_TRUE(preflight_received);
232   EXPECT_EQ(ReportingUploader::Outcome::SUCCESS, callback.outcome());
233 }
234 
TEST_F(ReportingUploaderTest,SkipPreflightForSameOrigin)235 TEST_F(ReportingUploaderTest, SkipPreflightForSameOrigin) {
236   bool preflight_received = false;
237   server_.RegisterRequestHandler(
238       base::BindRepeating(&VerifyPreflight, &preflight_received));
239   server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
240   ASSERT_TRUE(server_.Start());
241 
242   TestUploadCallback callback;
243   auto server_origin = url::Origin::Create(server_.base_url());
244   uploader_->StartUpload(server_origin, server_.GetURL("/"),
245                          IsolationInfo::CreateTransient(), kUploadBody, 0,
246                          false, callback.callback());
247   callback.WaitForCall();
248 
249   EXPECT_FALSE(preflight_received);
250   EXPECT_EQ(ReportingUploader::Outcome::SUCCESS, callback.outcome());
251 }
252 
ReturnPreflightError(const test_server::HttpRequest & request)253 std::unique_ptr<test_server::HttpResponse> ReturnPreflightError(
254     const test_server::HttpRequest& request) {
255   if (request.method_string != "OPTIONS") {
256     return nullptr;
257   }
258   auto response = std::make_unique<test_server::BasicHttpResponse>();
259   response->set_code(HTTP_FORBIDDEN);
260   response->set_content("");
261   response->set_content_type("text/plain");
262   return std::move(response);
263 }
264 
TEST_F(ReportingUploaderTest,FailedCorsPreflight)265 TEST_F(ReportingUploaderTest, FailedCorsPreflight) {
266   server_.RegisterRequestHandler(base::BindRepeating(&ReturnPreflightError));
267   server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
268   ASSERT_TRUE(server_.Start());
269 
270   TestUploadCallback callback;
271   uploader_->StartUpload(kOrigin, server_.GetURL("/"),
272                          IsolationInfo::CreateTransient(), kUploadBody, 0,
273                          false, callback.callback());
274   callback.WaitForCall();
275 
276   EXPECT_EQ(ReportingUploader::Outcome::FAILURE, callback.outcome());
277 }
278 
ReturnPreflightWithoutOrigin(const test_server::HttpRequest & request)279 std::unique_ptr<test_server::HttpResponse> ReturnPreflightWithoutOrigin(
280     const test_server::HttpRequest& request) {
281   if (request.method_string != "OPTIONS") {
282     return nullptr;
283   }
284   auto it = request.headers.find("Origin");
285   EXPECT_TRUE(it != request.headers.end());
286   auto response = std::make_unique<test_server::BasicHttpResponse>();
287   response->AddCustomHeader("Access-Control-Allow-Methods", "POST");
288   response->AddCustomHeader("Access-Control-Allow-Headers", "Content-Type");
289   response->set_code(HTTP_OK);
290   response->set_content("");
291   response->set_content_type("text/plain");
292   return std::move(response);
293 }
294 
TEST_F(ReportingUploaderTest,CorsPreflightWithoutOrigin)295 TEST_F(ReportingUploaderTest, CorsPreflightWithoutOrigin) {
296   server_.RegisterRequestHandler(
297       base::BindRepeating(&ReturnPreflightWithoutOrigin));
298   server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
299   ASSERT_TRUE(server_.Start());
300 
301   TestUploadCallback callback;
302   uploader_->StartUpload(kOrigin, server_.GetURL("/"),
303                          IsolationInfo::CreateTransient(), kUploadBody, 0,
304                          false, callback.callback());
305   callback.WaitForCall();
306 
307   EXPECT_EQ(ReportingUploader::Outcome::FAILURE, callback.outcome());
308 }
309 
ReturnPreflightWithoutMethods(const test_server::HttpRequest & request)310 std::unique_ptr<test_server::HttpResponse> ReturnPreflightWithoutMethods(
311     const test_server::HttpRequest& request) {
312   if (request.method_string != "OPTIONS") {
313     return nullptr;
314   }
315   auto it = request.headers.find("Origin");
316   EXPECT_TRUE(it != request.headers.end());
317   auto response = std::make_unique<test_server::BasicHttpResponse>();
318   response->AddCustomHeader("Access-Control-Allow-Origin", it->second);
319   response->AddCustomHeader("Access-Control-Allow-Headers", "Content-Type");
320   response->set_code(HTTP_OK);
321   response->set_content("");
322   response->set_content_type("text/plain");
323   return std::move(response);
324 }
325 
TEST_F(ReportingUploaderTest,CorsPreflightWithoutMethods)326 TEST_F(ReportingUploaderTest, CorsPreflightWithoutMethods) {
327   server_.RegisterRequestHandler(
328       base::BindRepeating(&ReturnPreflightWithoutMethods));
329   server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
330   ASSERT_TRUE(server_.Start());
331 
332   TestUploadCallback callback;
333   uploader_->StartUpload(kOrigin, server_.GetURL("/"),
334                          IsolationInfo::CreateTransient(), kUploadBody, 0,
335                          false, callback.callback());
336   callback.WaitForCall();
337 
338   EXPECT_EQ(ReportingUploader::Outcome::SUCCESS, callback.outcome());
339 }
340 
ReturnPreflightWithWildcardMethods(const test_server::HttpRequest & request)341 std::unique_ptr<test_server::HttpResponse> ReturnPreflightWithWildcardMethods(
342     const test_server::HttpRequest& request) {
343   if (request.method_string != "OPTIONS") {
344     return nullptr;
345   }
346   auto it = request.headers.find("Origin");
347   EXPECT_TRUE(it != request.headers.end());
348   auto response = std::make_unique<test_server::BasicHttpResponse>();
349   response->AddCustomHeader("Access-Control-Allow-Origin", it->second);
350   response->AddCustomHeader("Access-Control-Allow-Headers", "Content-Type");
351   response->AddCustomHeader("Access-Control-Allow-Methods", "*");
352   response->set_code(HTTP_OK);
353   response->set_content("");
354   response->set_content_type("text/plain");
355   return std::move(response);
356 }
357 
TEST_F(ReportingUploaderTest,CorsPreflightWildcardMethods)358 TEST_F(ReportingUploaderTest, CorsPreflightWildcardMethods) {
359   server_.RegisterRequestHandler(
360       base::BindRepeating(&ReturnPreflightWithWildcardMethods));
361   server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
362   ASSERT_TRUE(server_.Start());
363 
364   TestUploadCallback callback;
365   uploader_->StartUpload(kOrigin, server_.GetURL("/"),
366                          IsolationInfo::CreateTransient(), kUploadBody, 0,
367                          false, callback.callback());
368   callback.WaitForCall();
369 
370   EXPECT_EQ(ReportingUploader::Outcome::SUCCESS, callback.outcome());
371 }
372 
ReturnPreflightWithoutHeaders(const test_server::HttpRequest & request)373 std::unique_ptr<test_server::HttpResponse> ReturnPreflightWithoutHeaders(
374     const test_server::HttpRequest& request) {
375   if (request.method_string != "OPTIONS") {
376     return nullptr;
377   }
378   auto it = request.headers.find("Origin");
379   EXPECT_TRUE(it != request.headers.end());
380   auto response = std::make_unique<test_server::BasicHttpResponse>();
381   response->AddCustomHeader("Access-Control-Allow-Origin", it->second);
382   response->AddCustomHeader("Access-Control-Allow-Methods", "POST");
383   response->set_code(HTTP_OK);
384   response->set_content("");
385   response->set_content_type("text/plain");
386   return std::move(response);
387 }
388 
TEST_F(ReportingUploaderTest,CorsPreflightWithoutHeaders)389 TEST_F(ReportingUploaderTest, CorsPreflightWithoutHeaders) {
390   server_.RegisterRequestHandler(
391       base::BindRepeating(&ReturnPreflightWithoutHeaders));
392   server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
393   ASSERT_TRUE(server_.Start());
394 
395   TestUploadCallback callback;
396   uploader_->StartUpload(kOrigin, server_.GetURL("/"),
397                          IsolationInfo::CreateTransient(), kUploadBody, 0,
398                          false, callback.callback());
399   callback.WaitForCall();
400 
401   EXPECT_EQ(ReportingUploader::Outcome::FAILURE, callback.outcome());
402 }
403 
ReturnPreflightWithWildcardHeaders(const test_server::HttpRequest & request)404 std::unique_ptr<test_server::HttpResponse> ReturnPreflightWithWildcardHeaders(
405     const test_server::HttpRequest& request) {
406   if (request.method_string != "OPTIONS") {
407     return nullptr;
408   }
409   auto it = request.headers.find("Origin");
410   EXPECT_TRUE(it != request.headers.end());
411   auto response = std::make_unique<test_server::BasicHttpResponse>();
412   response->AddCustomHeader("Access-Control-Allow-Origin", it->second);
413   response->AddCustomHeader("Access-Control-Allow-Headers", "*");
414   response->AddCustomHeader("Access-Control-Allow-Methods", "POST");
415   response->set_code(HTTP_OK);
416   response->set_content("");
417   response->set_content_type("text/plain");
418   return std::move(response);
419 }
420 
TEST_F(ReportingUploaderTest,CorsPreflightWildcardHeaders)421 TEST_F(ReportingUploaderTest, CorsPreflightWildcardHeaders) {
422   server_.RegisterRequestHandler(
423       base::BindRepeating(&ReturnPreflightWithWildcardHeaders));
424   server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
425   ASSERT_TRUE(server_.Start());
426 
427   TestUploadCallback callback;
428   uploader_->StartUpload(kOrigin, server_.GetURL("/"),
429                          IsolationInfo::CreateTransient(), kUploadBody, 0,
430                          false, callback.callback());
431   callback.WaitForCall();
432 
433   EXPECT_EQ(ReportingUploader::Outcome::SUCCESS, callback.outcome());
434 }
435 
TEST_F(ReportingUploaderTest,RemoveEndpoint)436 TEST_F(ReportingUploaderTest, RemoveEndpoint) {
437   server_.RegisterRequestHandler(base::BindRepeating(&AllowPreflight));
438   server_.RegisterRequestHandler(
439       base::BindRepeating(&ReturnResponse, HTTP_GONE));
440   ASSERT_TRUE(server_.Start());
441 
442   TestUploadCallback callback;
443   uploader_->StartUpload(kOrigin, server_.GetURL("/"),
444                          IsolationInfo::CreateTransient(), kUploadBody, 0,
445                          false, callback.callback());
446   callback.WaitForCall();
447 
448   EXPECT_EQ(ReportingUploader::Outcome::REMOVE_ENDPOINT, callback.outcome());
449 }
450 
451 const char kRedirectPath[] = "/redirect";
452 
ReturnRedirect(const std::string & location,const test_server::HttpRequest & request)453 std::unique_ptr<test_server::HttpResponse> ReturnRedirect(
454     const std::string& location,
455     const test_server::HttpRequest& request) {
456   if (request.relative_url != "/")
457     return nullptr;
458 
459   auto response = std::make_unique<test_server::BasicHttpResponse>();
460   response->set_code(HTTP_FOUND);
461   response->AddCustomHeader("Location", location);
462   response->set_content(
463       "Thank you, Mario! But our Princess is in another castle.");
464   response->set_content_type("text/plain");
465   return std::move(response);
466 }
467 
CheckRedirect(bool * redirect_followed_out,const test_server::HttpRequest & request)468 std::unique_ptr<test_server::HttpResponse> CheckRedirect(
469     bool* redirect_followed_out,
470     const test_server::HttpRequest& request) {
471   if (request.relative_url != kRedirectPath)
472     return nullptr;
473 
474   *redirect_followed_out = true;
475   return ReturnResponse(HTTP_OK, request);
476 }
477 
TEST_F(ReportingUploaderTest,FollowHttpsRedirect)478 TEST_F(ReportingUploaderTest, FollowHttpsRedirect) {
479   bool followed = false;
480   server_.RegisterRequestHandler(base::BindRepeating(&AllowPreflight));
481   server_.RegisterRequestHandler(
482       base::BindRepeating(&ReturnRedirect, kRedirectPath));
483   server_.RegisterRequestHandler(
484       base::BindRepeating(&CheckRedirect, &followed));
485   ASSERT_TRUE(server_.Start());
486 
487   TestUploadCallback callback;
488   uploader_->StartUpload(kOrigin, server_.GetURL("/"),
489                          IsolationInfo::CreateTransient(), kUploadBody, 0,
490                          false, callback.callback());
491   callback.WaitForCall();
492 
493   EXPECT_TRUE(followed);
494   EXPECT_EQ(ReportingUploader::Outcome::SUCCESS, callback.outcome());
495 }
496 
TEST_F(ReportingUploaderTest,DontFollowHttpRedirect)497 TEST_F(ReportingUploaderTest, DontFollowHttpRedirect) {
498   bool followed = false;
499 
500   test_server::EmbeddedTestServer http_server_;
501   http_server_.RegisterRequestHandler(
502       base::BindRepeating(&CheckRedirect, &followed));
503   ASSERT_TRUE(http_server_.Start());
504 
505   const GURL target = http_server_.GetURL(kRedirectPath);
506   server_.RegisterRequestHandler(base::BindRepeating(&AllowPreflight));
507   server_.RegisterRequestHandler(
508       base::BindRepeating(&ReturnRedirect, target.spec()));
509   ASSERT_TRUE(server_.Start());
510 
511   TestUploadCallback callback;
512   uploader_->StartUpload(kOrigin, server_.GetURL("/"),
513                          IsolationInfo::CreateTransient(), kUploadBody, 0,
514                          false, callback.callback());
515   callback.WaitForCall();
516 
517   EXPECT_FALSE(followed);
518   EXPECT_EQ(ReportingUploader::Outcome::FAILURE, callback.outcome());
519 }
520 
CheckNoCookie(const test_server::HttpRequest & request)521 void CheckNoCookie(const test_server::HttpRequest& request) {
522   auto it = request.headers.find("Cookie");
523   EXPECT_TRUE(it == request.headers.end());
524 }
525 
TEST_F(ReportingUploaderTest,DontSendCookies)526 TEST_F(ReportingUploaderTest, DontSendCookies) {
527   server_.RegisterRequestMonitor(base::BindRepeating(&CheckNoCookie));
528   server_.RegisterRequestHandler(base::BindRepeating(&AllowPreflight));
529   server_.RegisterRequestHandler(base::BindRepeating(&ReturnResponse, HTTP_OK));
530   ASSERT_TRUE(server_.Start());
531 
532   ResultSavingCookieCallback<CookieAccessResult> cookie_callback;
533   GURL url = server_.GetURL("/");
534   auto cookie =
535       CanonicalCookie::CreateForTesting(url, "foo=bar", base::Time::Now());
536   context_->cookie_store()->SetCanonicalCookieAsync(
537       std::move(cookie), url, CookieOptions::MakeAllInclusive(),
538       cookie_callback.MakeCallback());
539   cookie_callback.WaitUntilDone();
540   ASSERT_TRUE(cookie_callback.result().status.IsInclude());
541 
542   TestUploadCallback upload_callback;
543   uploader_->StartUpload(kOrigin, server_.GetURL("/"),
544                          IsolationInfo::CreateTransient(), kUploadBody, 0,
545                          false, upload_callback.callback());
546   upload_callback.WaitForCall();
547 }
548 
SendCookie(const test_server::HttpRequest & request)549 std::unique_ptr<test_server::HttpResponse> SendCookie(
550     const test_server::HttpRequest& request) {
551   auto response = std::make_unique<test_server::BasicHttpResponse>();
552   response->set_code(HTTP_OK);
553   response->AddCustomHeader("Set-Cookie", "foo=bar");
554   response->set_content("");
555   response->set_content_type("text/plain");
556   return std::move(response);
557 }
558 
TEST_F(ReportingUploaderTest,DontSaveCookies)559 TEST_F(ReportingUploaderTest, DontSaveCookies) {
560   server_.RegisterRequestHandler(base::BindRepeating(&AllowPreflight));
561   server_.RegisterRequestHandler(base::BindRepeating(&SendCookie));
562   ASSERT_TRUE(server_.Start());
563 
564   TestUploadCallback upload_callback;
565   uploader_->StartUpload(kOrigin, server_.GetURL("/"),
566                          IsolationInfo::CreateTransient(), kUploadBody, 0,
567                          false, upload_callback.callback());
568   upload_callback.WaitForCall();
569 
570   GetCookieListCallback cookie_callback;
571   context_->cookie_store()->GetCookieListWithOptionsAsync(
572       server_.GetURL("/"), CookieOptions::MakeAllInclusive(),
573       CookiePartitionKeyCollection(),
574       base::BindOnce(&GetCookieListCallback::Run,
575                      base::Unretained(&cookie_callback)));
576   cookie_callback.WaitUntilDone();
577 
578   EXPECT_TRUE(cookie_callback.cookies().empty());
579 }
580 
ReturnCacheableResponse(int * request_count_out,const test_server::HttpRequest & request)581 std::unique_ptr<test_server::HttpResponse> ReturnCacheableResponse(
582     int* request_count_out,
583     const test_server::HttpRequest& request) {
584   ++*request_count_out;
585   auto response = std::make_unique<test_server::BasicHttpResponse>();
586   response->set_code(HTTP_OK);
587   response->AddCustomHeader("Cache-Control", "max-age=86400");
588   response->set_content("");
589   response->set_content_type("text/plain");
590   return std::move(response);
591 }
592 
593 // TODO(juliatuttle): This passes even if the uploader doesn't set
594 // LOAD_DISABLE_CACHE. Maybe that's okay -- Chromium might not cache POST
595 // responses ever -- but this test should either not exist or be sure that it is
596 // testing actual functionality, not a default.
TEST_F(ReportingUploaderTest,DontCacheResponse)597 TEST_F(ReportingUploaderTest, DontCacheResponse) {
598   int request_count = 0;
599   server_.RegisterRequestHandler(base::BindRepeating(&AllowPreflight));
600   server_.RegisterRequestHandler(
601       base::BindRepeating(&ReturnCacheableResponse, &request_count));
602   ASSERT_TRUE(server_.Start());
603 
604   {
605     TestUploadCallback callback;
606     uploader_->StartUpload(kOrigin, server_.GetURL("/"),
607                            IsolationInfo::CreateTransient(), kUploadBody, 0,
608                            false, callback.callback());
609     callback.WaitForCall();
610   }
611   EXPECT_EQ(1, request_count);
612 
613   {
614     TestUploadCallback callback;
615     uploader_->StartUpload(kOrigin, server_.GetURL("/"),
616                            IsolationInfo::CreateTransient(), kUploadBody, 0,
617                            false, callback.callback());
618     callback.WaitForCall();
619   }
620   EXPECT_EQ(2, request_count);
621 }
622 
623 // Create two requests with the same NetworkAnonymizationKey, and one request
624 // with a different one, and make sure only the requests with the same
625 // NetworkAnonymizationKey share a socket.
TEST_F(ReportingUploaderTest,RespectsNetworkAnonymizationKey)626 TEST_F(ReportingUploaderTest, RespectsNetworkAnonymizationKey) {
627   // While network state partitioning is not needed for reporting code to
628   // respect NetworkAnonymizationKey, this test works by ensuring that
629   // Reporting's NetworkAnonymizationKey makes it to the socket pool layer and
630   // is respected there, so this test needs to enable
631   // network state partitioning.
632   base::test::ScopedFeatureList feature_list;
633   feature_list.InitAndEnableFeature(
634       features::kPartitionConnectionsByNetworkIsolationKey);
635 
636   const SchemefulSite kSite1 = SchemefulSite(kOrigin);
637   const SchemefulSite kSite2(GURL("https://origin2/"));
638   ASSERT_NE(kSite1, kSite2);
639   const url::Origin kSiteOrigin1 = url::Origin::Create(kSite1.GetURL());
640   const url::Origin kSiteOrigin2 = url::Origin::Create(kSite2.GetURL());
641   const IsolationInfo kIsolationInfo1 =
642       IsolationInfo::Create(net::IsolationInfo::RequestType::kOther,
643                             kSiteOrigin1, kSiteOrigin1, net::SiteForCookies());
644   const IsolationInfo kIsolationInfo2 =
645       IsolationInfo::Create(net::IsolationInfo::RequestType::kOther,
646                             kSiteOrigin2, kSiteOrigin2, net::SiteForCookies());
647 
648   MockClientSocketFactory socket_factory;
649   auto context_builder = CreateTestURLRequestContextBuilder();
650   context_builder->set_client_socket_factory_for_testing(&socket_factory);
651   auto context = context_builder->Build();
652 
653   // First socket handles first and third requests.
654   MockWrite writes1[] = {
655       MockWrite(SYNCHRONOUS, 0,
656                 "POST /1 HTTP/1.1\r\n"
657                 "Host: origin\r\n"
658                 "Connection: keep-alive\r\n"
659                 "Content-Length: 2\r\n"
660                 "Content-Type: application/reports+json\r\n"
661                 "User-Agent: \r\n"
662                 "Accept-Encoding: gzip, deflate\r\n"
663                 "Accept-Language: en-us,fr\r\n\r\n"),
664       MockWrite(SYNCHRONOUS, 1, kUploadBody),
665       MockWrite(SYNCHRONOUS, 3,
666                 "POST /3 HTTP/1.1\r\n"
667                 "Host: origin\r\n"
668                 "Connection: keep-alive\r\n"
669                 "Content-Length: 2\r\n"
670                 "Content-Type: application/reports+json\r\n"
671                 "User-Agent: \r\n"
672                 "Accept-Encoding: gzip, deflate\r\n"
673                 "Accept-Language: en-us,fr\r\n\r\n"),
674       MockWrite(SYNCHRONOUS, 4, kUploadBody),
675   };
676   MockRead reads1[] = {
677       MockRead(SYNCHRONOUS, 2,
678                "HTTP/1.1 200 OK\r\n"
679                "Connection: Keep-Alive\r\n"
680                "Content-Length: 0\r\n\r\n"),
681       MockRead(SYNCHRONOUS, 5,
682                "HTTP/1.1 200 OK\r\n"
683                "Connection: Keep-Alive\r\n"
684                "Content-Length: 0\r\n\r\n"),
685   };
686   SequencedSocketData data1(reads1, writes1);
687   socket_factory.AddSocketDataProvider(&data1);
688   SSLSocketDataProvider ssl_data1(ASYNC, OK);
689   socket_factory.AddSSLSocketDataProvider(&ssl_data1);
690 
691   // Second socket handles second request.
692   MockWrite writes2[] = {
693       MockWrite(SYNCHRONOUS, 0,
694                 "POST /2 HTTP/1.1\r\n"
695                 "Host: origin\r\n"
696                 "Connection: keep-alive\r\n"
697                 "Content-Length: 2\r\n"
698                 "Content-Type: application/reports+json\r\n"
699                 "User-Agent: \r\n"
700                 "Accept-Encoding: gzip, deflate\r\n"
701                 "Accept-Language: en-us,fr\r\n\r\n"),
702       MockWrite(SYNCHRONOUS, 1, kUploadBody),
703   };
704   MockRead reads2[] = {
705       MockRead(SYNCHRONOUS, 2,
706                "HTTP/1.1 200 OK\r\n"
707                "Connection: Keep-Alive\r\n"
708                "Content-Length: 0\r\n\r\n"),
709   };
710   SequencedSocketData data2(reads2, writes2);
711   socket_factory.AddSocketDataProvider(&data2);
712   SSLSocketDataProvider ssl_data2(ASYNC, OK);
713   socket_factory.AddSSLSocketDataProvider(&ssl_data2);
714 
715   TestUploadCallback callback1;
716   std::unique_ptr<ReportingUploader> uploader1 =
717       ReportingUploader::Create(context.get());
718   uploader1->StartUpload(kOrigin, GURL("https://origin/1"), kIsolationInfo1,
719                          kUploadBody, 0, false, callback1.callback());
720   callback1.WaitForCall();
721   EXPECT_EQ(ReportingUploader::Outcome::SUCCESS, callback1.outcome());
722 
723   // Start two more requests in parallel. The first started uses a different
724   // NetworkAnonymizationKey, so should create a new socket, while the second
725   // one gets the other socket. Start in parallel to make sure that a new socket
726   // isn't created just because the first is returned to the socket pool
727   // asynchronously.
728   TestUploadCallback callback2;
729   std::unique_ptr<ReportingUploader> uploader2 =
730       ReportingUploader::Create(context.get());
731   uploader2->StartUpload(kOrigin, GURL("https://origin/2"), kIsolationInfo2,
732                          kUploadBody, 0, false, callback2.callback());
733   TestUploadCallback callback3;
734   std::unique_ptr<ReportingUploader> uploader3 =
735       ReportingUploader::Create(context.get());
736   uploader3->StartUpload(kOrigin, GURL("https://origin/3"), kIsolationInfo1,
737                          kUploadBody, 0, false, callback3.callback());
738 
739   callback2.WaitForCall();
740   EXPECT_EQ(ReportingUploader::Outcome::SUCCESS, callback2.outcome());
741 
742   callback3.WaitForCall();
743   EXPECT_EQ(ReportingUploader::Outcome::SUCCESS, callback3.outcome());
744 }
745 
746 }  // namespace
747 }  // namespace net
748