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/test/embedded_test_server/embedded_test_server.h"
6
7 #include <tuple>
8 #include <utility>
9
10 #include "base/functional/bind.h"
11 #include "base/functional/callback_helpers.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/message_loop/message_pump_type.h"
14 #include "base/path_service.h"
15 #include "base/run_loop.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/synchronization/lock.h"
18 #include "base/task/single_thread_task_executor.h"
19 #include "base/task/single_thread_task_runner.h"
20 #include "base/test/bind.h"
21 #include "base/threading/thread.h"
22 #include "build/build_config.h"
23 #include "net/base/elements_upload_data_stream.h"
24 #include "net/base/test_completion_callback.h"
25 #include "net/base/upload_bytes_element_reader.h"
26 #include "net/http/http_response_headers.h"
27 #include "net/log/net_log_source.h"
28 #include "net/socket/client_socket_factory.h"
29 #include "net/socket/stream_socket.h"
30 #include "net/test/embedded_test_server/embedded_test_server_connection_listener.h"
31 #include "net/test/embedded_test_server/http_request.h"
32 #include "net/test/embedded_test_server/http_response.h"
33 #include "net/test/embedded_test_server/request_handler_util.h"
34 #include "net/test/gtest_util.h"
35 #include "net/test/test_with_task_environment.h"
36 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
37 #include "net/url_request/url_request.h"
38 #include "net/url_request/url_request_context.h"
39 #include "net/url_request/url_request_context_builder.h"
40 #include "net/url_request/url_request_test_util.h"
41 #include "testing/gmock/include/gmock/gmock.h"
42 #include "testing/gtest/include/gtest/gtest.h"
43
44 using net::test::IsOk;
45
46 namespace net::test_server {
47
48 // Gets notified by the EmbeddedTestServer on incoming connections being
49 // accepted, read from, or closed.
50 class TestConnectionListener
51 : public net::test_server::EmbeddedTestServerConnectionListener {
52 public:
TestConnectionListener()53 TestConnectionListener()
54 : task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()) {}
55
56 TestConnectionListener(const TestConnectionListener&) = delete;
57 TestConnectionListener& operator=(const TestConnectionListener&) = delete;
58
59 ~TestConnectionListener() override = default;
60
61 // Get called from the EmbeddedTestServer thread to be notified that
62 // a connection was accepted.
AcceptedSocket(std::unique_ptr<StreamSocket> connection)63 std::unique_ptr<StreamSocket> AcceptedSocket(
64 std::unique_ptr<StreamSocket> connection) override {
65 base::AutoLock lock(lock_);
66 ++socket_accepted_count_;
67 accept_loop_.Quit();
68 return connection;
69 }
70
71 // Get called from the EmbeddedTestServer thread to be notified that
72 // a connection was read from.
ReadFromSocket(const net::StreamSocket & connection,int rv)73 void ReadFromSocket(const net::StreamSocket& connection, int rv) override {
74 base::AutoLock lock(lock_);
75 did_read_from_socket_ = true;
76 }
77
OnResponseCompletedSuccessfully(std::unique_ptr<StreamSocket> socket)78 void OnResponseCompletedSuccessfully(
79 std::unique_ptr<StreamSocket> socket) override {
80 base::AutoLock lock(lock_);
81 did_get_socket_on_complete_ = socket && socket->IsConnected();
82 complete_loop_.Quit();
83 }
84
WaitUntilFirstConnectionAccepted()85 void WaitUntilFirstConnectionAccepted() { accept_loop_.Run(); }
86
WaitUntilGotSocketFromResponseCompleted()87 void WaitUntilGotSocketFromResponseCompleted() { complete_loop_.Run(); }
88
SocketAcceptedCount() const89 size_t SocketAcceptedCount() const {
90 base::AutoLock lock(lock_);
91 return socket_accepted_count_;
92 }
93
DidReadFromSocket() const94 bool DidReadFromSocket() const {
95 base::AutoLock lock(lock_);
96 return did_read_from_socket_;
97 }
98
DidGetSocketOnComplete() const99 bool DidGetSocketOnComplete() const {
100 base::AutoLock lock(lock_);
101 return did_get_socket_on_complete_;
102 }
103
104 private:
105 size_t socket_accepted_count_ = 0;
106 bool did_read_from_socket_ = false;
107 bool did_get_socket_on_complete_ = false;
108
109 base::RunLoop accept_loop_;
110 base::RunLoop complete_loop_;
111 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
112
113 mutable base::Lock lock_;
114 };
115
116 struct EmbeddedTestServerConfig {
117 EmbeddedTestServer::Type type;
118 HttpConnection::Protocol protocol;
119 };
120
EmbeddedTestServerConfigs()121 std::vector<EmbeddedTestServerConfig> EmbeddedTestServerConfigs() {
122 return {
123 {EmbeddedTestServer::TYPE_HTTP, HttpConnection::Protocol::kHttp1},
124 {EmbeddedTestServer::TYPE_HTTPS, HttpConnection::Protocol::kHttp1},
125 {EmbeddedTestServer::TYPE_HTTPS, HttpConnection::Protocol::kHttp2},
126 };
127 }
128
129 class EmbeddedTestServerTest
130 : public testing::TestWithParam<EmbeddedTestServerConfig>,
131 public WithTaskEnvironment {
132 public:
EmbeddedTestServerTest()133 EmbeddedTestServerTest()
134 : context_(CreateTestURLRequestContextBuilder()->Build()) {}
135
SetUp()136 void SetUp() override {
137 server_ = std::make_unique<EmbeddedTestServer>(GetParam().type,
138 GetParam().protocol);
139 server_->AddDefaultHandlers();
140 server_->SetConnectionListener(&connection_listener_);
141 }
142
TearDown()143 void TearDown() override {
144 if (server_->Started())
145 ASSERT_TRUE(server_->ShutdownAndWaitUntilComplete());
146 }
147
148 // Handles |request| sent to |path| and returns the response per |content|,
149 // |content type|, and |code|. Saves the request URL for verification.
HandleRequest(const std::string & path,const std::string & content,const std::string & content_type,HttpStatusCode code,const HttpRequest & request)150 std::unique_ptr<HttpResponse> HandleRequest(const std::string& path,
151 const std::string& content,
152 const std::string& content_type,
153 HttpStatusCode code,
154 const HttpRequest& request) {
155 request_relative_url_ = request.relative_url;
156 request_absolute_url_ = request.GetURL();
157
158 if (request_absolute_url_.path() == path) {
159 auto http_response = std::make_unique<BasicHttpResponse>();
160 http_response->set_code(code);
161 http_response->set_content(content);
162 http_response->set_content_type(content_type);
163 return http_response;
164 }
165
166 return nullptr;
167 }
168
169 protected:
170 std::string request_relative_url_;
171 GURL request_absolute_url_;
172 std::unique_ptr<URLRequestContext> context_;
173 TestConnectionListener connection_listener_;
174 std::unique_ptr<EmbeddedTestServer> server_;
175 base::OnceClosure quit_run_loop_;
176 };
177
TEST_P(EmbeddedTestServerTest,GetBaseURL)178 TEST_P(EmbeddedTestServerTest, GetBaseURL) {
179 ASSERT_TRUE(server_->Start());
180 if (GetParam().type == EmbeddedTestServer::TYPE_HTTPS) {
181 EXPECT_EQ(base::StringPrintf("https://127.0.0.1:%u/", server_->port()),
182 server_->base_url().spec());
183 } else {
184 EXPECT_EQ(base::StringPrintf("http://127.0.0.1:%u/", server_->port()),
185 server_->base_url().spec());
186 }
187 }
188
TEST_P(EmbeddedTestServerTest,GetURL)189 TEST_P(EmbeddedTestServerTest, GetURL) {
190 ASSERT_TRUE(server_->Start());
191 if (GetParam().type == EmbeddedTestServer::TYPE_HTTPS) {
192 EXPECT_EQ(base::StringPrintf("https://127.0.0.1:%u/path?query=foo",
193 server_->port()),
194 server_->GetURL("/path?query=foo").spec());
195 } else {
196 EXPECT_EQ(base::StringPrintf("http://127.0.0.1:%u/path?query=foo",
197 server_->port()),
198 server_->GetURL("/path?query=foo").spec());
199 }
200 }
201
TEST_P(EmbeddedTestServerTest,GetURLWithHostname)202 TEST_P(EmbeddedTestServerTest, GetURLWithHostname) {
203 ASSERT_TRUE(server_->Start());
204 if (GetParam().type == EmbeddedTestServer::TYPE_HTTPS) {
205 EXPECT_EQ(base::StringPrintf("https://foo.com:%d/path?query=foo",
206 server_->port()),
207 server_->GetURL("foo.com", "/path?query=foo").spec());
208 } else {
209 EXPECT_EQ(
210 base::StringPrintf("http://foo.com:%d/path?query=foo", server_->port()),
211 server_->GetURL("foo.com", "/path?query=foo").spec());
212 }
213 }
214
TEST_P(EmbeddedTestServerTest,RegisterRequestHandler)215 TEST_P(EmbeddedTestServerTest, RegisterRequestHandler) {
216 server_->RegisterRequestHandler(base::BindRepeating(
217 &EmbeddedTestServerTest::HandleRequest, base::Unretained(this), "/test",
218 "<b>Worked!</b>", "text/html", HTTP_OK));
219 ASSERT_TRUE(server_->Start());
220
221 TestDelegate delegate;
222 std::unique_ptr<URLRequest> request(
223 context_->CreateRequest(server_->GetURL("/test?q=foo"), DEFAULT_PRIORITY,
224 &delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
225
226 request->Start();
227 delegate.RunUntilComplete();
228
229 EXPECT_EQ(net::OK, delegate.request_status());
230 ASSERT_TRUE(request->response_headers());
231 EXPECT_EQ(HTTP_OK, request->response_headers()->response_code());
232 EXPECT_EQ("<b>Worked!</b>", delegate.data_received());
233 std::string content_type;
234 ASSERT_TRUE(request->response_headers()->GetNormalizedHeader("Content-Type",
235 &content_type));
236 EXPECT_EQ("text/html", content_type);
237
238 EXPECT_EQ("/test?q=foo", request_relative_url_);
239 EXPECT_EQ(server_->GetURL("/test?q=foo"), request_absolute_url_);
240 }
241
TEST_P(EmbeddedTestServerTest,ServeFilesFromDirectory)242 TEST_P(EmbeddedTestServerTest, ServeFilesFromDirectory) {
243 base::FilePath src_dir;
244 ASSERT_TRUE(base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &src_dir));
245 server_->ServeFilesFromDirectory(
246 src_dir.AppendASCII("net").AppendASCII("data"));
247 ASSERT_TRUE(server_->Start());
248
249 TestDelegate delegate;
250 std::unique_ptr<URLRequest> request(
251 context_->CreateRequest(server_->GetURL("/test.html"), DEFAULT_PRIORITY,
252 &delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
253
254 request->Start();
255 delegate.RunUntilComplete();
256
257 EXPECT_EQ(net::OK, delegate.request_status());
258 ASSERT_TRUE(request->response_headers());
259 EXPECT_EQ(HTTP_OK, request->response_headers()->response_code());
260 EXPECT_EQ("<p>Hello World!</p>", delegate.data_received());
261 std::string content_type;
262 ASSERT_TRUE(request->response_headers()->GetNormalizedHeader("Content-Type",
263 &content_type));
264 EXPECT_EQ("text/html", content_type);
265 }
266
TEST_P(EmbeddedTestServerTest,MockHeadersWithoutCRLF)267 TEST_P(EmbeddedTestServerTest, MockHeadersWithoutCRLF) {
268 // Messing with raw headers isn't compatible with HTTP/2
269 if (GetParam().protocol == HttpConnection::Protocol::kHttp2)
270 return;
271
272 base::FilePath src_dir;
273 ASSERT_TRUE(base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &src_dir));
274 server_->ServeFilesFromDirectory(
275 src_dir.AppendASCII("net").AppendASCII("data").AppendASCII(
276 "embedded_test_server"));
277 ASSERT_TRUE(server_->Start());
278
279 TestDelegate delegate;
280 std::unique_ptr<URLRequest> request(context_->CreateRequest(
281 server_->GetURL("/mock-headers-without-crlf.html"), DEFAULT_PRIORITY,
282 &delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
283
284 request->Start();
285 delegate.RunUntilComplete();
286
287 EXPECT_EQ(net::OK, delegate.request_status());
288 ASSERT_TRUE(request->response_headers());
289 EXPECT_EQ(HTTP_OK, request->response_headers()->response_code());
290 EXPECT_EQ("<p>Hello World!</p>", delegate.data_received());
291 std::string content_type;
292 ASSERT_TRUE(request->response_headers()->GetNormalizedHeader("Content-Type",
293 &content_type));
294 EXPECT_EQ("text/html", content_type);
295 }
296
TEST_P(EmbeddedTestServerTest,DefaultNotFoundResponse)297 TEST_P(EmbeddedTestServerTest, DefaultNotFoundResponse) {
298 ASSERT_TRUE(server_->Start());
299
300 TestDelegate delegate;
301 std::unique_ptr<URLRequest> request(context_->CreateRequest(
302 server_->GetURL("/non-existent"), DEFAULT_PRIORITY, &delegate,
303 TRAFFIC_ANNOTATION_FOR_TESTS));
304
305 request->Start();
306 delegate.RunUntilComplete();
307
308 EXPECT_EQ(net::OK, delegate.request_status());
309 ASSERT_TRUE(request->response_headers());
310 EXPECT_EQ(HTTP_NOT_FOUND, request->response_headers()->response_code());
311 }
312
TEST_P(EmbeddedTestServerTest,ConnectionListenerAccept)313 TEST_P(EmbeddedTestServerTest, ConnectionListenerAccept) {
314 ASSERT_TRUE(server_->Start());
315
316 net::AddressList address_list;
317 EXPECT_TRUE(server_->GetAddressList(&address_list));
318
319 std::unique_ptr<StreamSocket> socket =
320 ClientSocketFactory::GetDefaultFactory()->CreateTransportClientSocket(
321 address_list, nullptr, nullptr, NetLog::Get(), NetLogSource());
322 TestCompletionCallback callback;
323 ASSERT_THAT(callback.GetResult(socket->Connect(callback.callback())), IsOk());
324
325 connection_listener_.WaitUntilFirstConnectionAccepted();
326
327 EXPECT_EQ(1u, connection_listener_.SocketAcceptedCount());
328 EXPECT_FALSE(connection_listener_.DidReadFromSocket());
329 EXPECT_FALSE(connection_listener_.DidGetSocketOnComplete());
330 }
331
TEST_P(EmbeddedTestServerTest,ConnectionListenerRead)332 TEST_P(EmbeddedTestServerTest, ConnectionListenerRead) {
333 ASSERT_TRUE(server_->Start());
334
335 TestDelegate delegate;
336 std::unique_ptr<URLRequest> request(context_->CreateRequest(
337 server_->GetURL("/non-existent"), DEFAULT_PRIORITY, &delegate,
338 TRAFFIC_ANNOTATION_FOR_TESTS));
339
340 request->Start();
341 delegate.RunUntilComplete();
342
343 EXPECT_EQ(1u, connection_listener_.SocketAcceptedCount());
344 EXPECT_TRUE(connection_listener_.DidReadFromSocket());
345 }
346
347 // TODO(http://crbug.com/1166868): Flaky on ChromeOS.
348 #if BUILDFLAG(IS_CHROMEOS)
349 #define MAYBE_ConnectionListenerComplete DISABLED_ConnectionListenerComplete
350 #else
351 #define MAYBE_ConnectionListenerComplete ConnectionListenerComplete
352 #endif
TEST_P(EmbeddedTestServerTest,MAYBE_ConnectionListenerComplete)353 TEST_P(EmbeddedTestServerTest, MAYBE_ConnectionListenerComplete) {
354 // OnResponseCompletedSuccessfully() makes the assumption that a connection is
355 // "finished" before the socket is closed, and in the case of HTTP/2 this is
356 // not supported
357 if (GetParam().protocol == HttpConnection::Protocol::kHttp2)
358 return;
359
360 ASSERT_TRUE(server_->Start());
361
362 TestDelegate delegate;
363 // Need to send a Keep-Alive response header since the EmbeddedTestServer only
364 // invokes OnResponseCompletedSuccessfully() if the socket is still open, and
365 // the network stack will close the socket if not reuable, resulting in
366 // potentially racilly closing the socket before
367 // OnResponseCompletedSuccessfully() is invoked.
368 std::unique_ptr<URLRequest> request(context_->CreateRequest(
369 server_->GetURL("/set-header?Connection: Keep-Alive"), DEFAULT_PRIORITY,
370 &delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
371
372 request->Start();
373 delegate.RunUntilComplete();
374
375 EXPECT_EQ(1u, connection_listener_.SocketAcceptedCount());
376 EXPECT_TRUE(connection_listener_.DidReadFromSocket());
377
378 connection_listener_.WaitUntilGotSocketFromResponseCompleted();
379 EXPECT_TRUE(connection_listener_.DidGetSocketOnComplete());
380 }
381
TEST_P(EmbeddedTestServerTest,ConcurrentFetches)382 TEST_P(EmbeddedTestServerTest, ConcurrentFetches) {
383 server_->RegisterRequestHandler(base::BindRepeating(
384 &EmbeddedTestServerTest::HandleRequest, base::Unretained(this), "/test1",
385 "Raspberry chocolate", "text/html", HTTP_OK));
386 server_->RegisterRequestHandler(base::BindRepeating(
387 &EmbeddedTestServerTest::HandleRequest, base::Unretained(this), "/test2",
388 "Vanilla chocolate", "text/html", HTTP_OK));
389 server_->RegisterRequestHandler(base::BindRepeating(
390 &EmbeddedTestServerTest::HandleRequest, base::Unretained(this), "/test3",
391 "No chocolates", "text/plain", HTTP_NOT_FOUND));
392 ASSERT_TRUE(server_->Start());
393
394 TestDelegate delegate1;
395 std::unique_ptr<URLRequest> request1(
396 context_->CreateRequest(server_->GetURL("/test1"), DEFAULT_PRIORITY,
397 &delegate1, TRAFFIC_ANNOTATION_FOR_TESTS));
398 TestDelegate delegate2;
399 std::unique_ptr<URLRequest> request2(
400 context_->CreateRequest(server_->GetURL("/test2"), DEFAULT_PRIORITY,
401 &delegate2, TRAFFIC_ANNOTATION_FOR_TESTS));
402 TestDelegate delegate3;
403 std::unique_ptr<URLRequest> request3(
404 context_->CreateRequest(server_->GetURL("/test3"), DEFAULT_PRIORITY,
405 &delegate3, TRAFFIC_ANNOTATION_FOR_TESTS));
406
407 // Fetch the three URLs concurrently. Have to manually create RunLoops when
408 // running multiple requests simultaneously, to avoid the deprecated
409 // RunUntilIdle() path.
410 base::RunLoop run_loop1;
411 base::RunLoop run_loop2;
412 base::RunLoop run_loop3;
413 delegate1.set_on_complete(run_loop1.QuitClosure());
414 delegate2.set_on_complete(run_loop2.QuitClosure());
415 delegate3.set_on_complete(run_loop3.QuitClosure());
416 request1->Start();
417 request2->Start();
418 request3->Start();
419 run_loop1.Run();
420 run_loop2.Run();
421 run_loop3.Run();
422
423 EXPECT_EQ(net::OK, delegate2.request_status());
424 ASSERT_TRUE(request1->response_headers());
425 EXPECT_EQ(HTTP_OK, request1->response_headers()->response_code());
426 EXPECT_EQ("Raspberry chocolate", delegate1.data_received());
427 std::string content_type1;
428 ASSERT_TRUE(request1->response_headers()->GetNormalizedHeader(
429 "Content-Type", &content_type1));
430 EXPECT_EQ("text/html", content_type1);
431
432 EXPECT_EQ(net::OK, delegate2.request_status());
433 ASSERT_TRUE(request2->response_headers());
434 EXPECT_EQ(HTTP_OK, request2->response_headers()->response_code());
435 EXPECT_EQ("Vanilla chocolate", delegate2.data_received());
436 std::string content_type2;
437 ASSERT_TRUE(request2->response_headers()->GetNormalizedHeader(
438 "Content-Type", &content_type2));
439 EXPECT_EQ("text/html", content_type2);
440
441 EXPECT_EQ(net::OK, delegate3.request_status());
442 ASSERT_TRUE(request3->response_headers());
443 EXPECT_EQ(HTTP_NOT_FOUND, request3->response_headers()->response_code());
444 EXPECT_EQ("No chocolates", delegate3.data_received());
445 std::string content_type3;
446 ASSERT_TRUE(request3->response_headers()->GetNormalizedHeader(
447 "Content-Type", &content_type3));
448 EXPECT_EQ("text/plain", content_type3);
449 }
450
451 namespace {
452
453 class CancelRequestDelegate : public TestDelegate {
454 public:
CancelRequestDelegate()455 CancelRequestDelegate() { set_on_complete(base::DoNothing()); }
456
457 CancelRequestDelegate(const CancelRequestDelegate&) = delete;
458 CancelRequestDelegate& operator=(const CancelRequestDelegate&) = delete;
459
460 ~CancelRequestDelegate() override = default;
461
OnResponseStarted(URLRequest * request,int net_error)462 void OnResponseStarted(URLRequest* request, int net_error) override {
463 TestDelegate::OnResponseStarted(request, net_error);
464 base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
465 FROM_HERE, run_loop_.QuitClosure(), base::Seconds(1));
466 }
467
WaitUntilDone()468 void WaitUntilDone() { run_loop_.Run(); }
469
470 private:
471 base::RunLoop run_loop_;
472 };
473
474 class InfiniteResponse : public BasicHttpResponse {
475 public:
476 InfiniteResponse() = default;
477
478 InfiniteResponse(const InfiniteResponse&) = delete;
479 InfiniteResponse& operator=(const InfiniteResponse&) = delete;
480
SendResponse(base::WeakPtr<HttpResponseDelegate> delegate)481 void SendResponse(base::WeakPtr<HttpResponseDelegate> delegate) override {
482 delegate->SendResponseHeaders(code(), GetHttpReasonPhrase(code()),
483 BuildHeaders());
484 SendInfinite(delegate);
485 }
486
487 private:
SendInfinite(base::WeakPtr<HttpResponseDelegate> delegate)488 void SendInfinite(base::WeakPtr<HttpResponseDelegate> delegate) {
489 delegate->SendContents("echo", base::DoNothing());
490 base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
491 FROM_HERE, base::BindOnce(&InfiniteResponse::SendInfinite,
492 weak_ptr_factory_.GetWeakPtr(), delegate));
493 }
494
495 base::WeakPtrFactory<InfiniteResponse> weak_ptr_factory_{this};
496 };
497
HandleInfiniteRequest(const HttpRequest & request)498 std::unique_ptr<HttpResponse> HandleInfiniteRequest(
499 const HttpRequest& request) {
500 return std::make_unique<InfiniteResponse>();
501 }
502
503 } // anonymous namespace
504
505 // Tests the case the connection is closed while the server is sending a
506 // response. May non-deterministically end up at one of three paths
507 // (Discover the close event synchronously, asynchronously, or server
508 // shutting down before it is discovered).
TEST_P(EmbeddedTestServerTest,CloseDuringWrite)509 TEST_P(EmbeddedTestServerTest, CloseDuringWrite) {
510 CancelRequestDelegate cancel_delegate;
511 cancel_delegate.set_cancel_in_response_started(true);
512 server_->RegisterRequestHandler(
513 base::BindRepeating(&HandlePrefixedRequest, "/infinite",
514 base::BindRepeating(&HandleInfiniteRequest)));
515 ASSERT_TRUE(server_->Start());
516
517 std::unique_ptr<URLRequest> request =
518 context_->CreateRequest(server_->GetURL("/infinite"), DEFAULT_PRIORITY,
519 &cancel_delegate, TRAFFIC_ANNOTATION_FOR_TESTS);
520 request->Start();
521 cancel_delegate.WaitUntilDone();
522 }
523
524 const struct CertificateValuesEntry {
525 const EmbeddedTestServer::ServerCertificate server_cert;
526 const bool is_expired;
527 const char* common_name;
528 const char* issuer_common_name;
529 size_t certs_count;
530 } kCertificateValuesEntry[] = {
531 {EmbeddedTestServer::CERT_OK, false, "127.0.0.1", "Test Root CA", 1},
532 {EmbeddedTestServer::CERT_OK_BY_INTERMEDIATE, false, "127.0.0.1",
533 "Test Intermediate CA", 2},
534 {EmbeddedTestServer::CERT_MISMATCHED_NAME, false, "127.0.0.1",
535 "Test Root CA", 1},
536 {EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN, false, "localhost",
537 "Test Root CA", 1},
538 {EmbeddedTestServer::CERT_EXPIRED, true, "127.0.0.1", "Test Root CA", 1},
539 };
540
TEST_P(EmbeddedTestServerTest,GetCertificate)541 TEST_P(EmbeddedTestServerTest, GetCertificate) {
542 if (GetParam().type != EmbeddedTestServer::TYPE_HTTPS)
543 return;
544
545 for (const auto& cert_entry : kCertificateValuesEntry) {
546 SCOPED_TRACE(cert_entry.server_cert);
547 server_->SetSSLConfig(cert_entry.server_cert);
548 scoped_refptr<X509Certificate> cert = server_->GetCertificate();
549 ASSERT_TRUE(cert);
550 EXPECT_EQ(cert->HasExpired(), cert_entry.is_expired);
551 EXPECT_EQ(cert->subject().common_name, cert_entry.common_name);
552 EXPECT_EQ(cert->issuer().common_name, cert_entry.issuer_common_name);
553 EXPECT_EQ(cert->intermediate_buffers().size(), cert_entry.certs_count - 1);
554 }
555 }
556
TEST_P(EmbeddedTestServerTest,AcceptCHFrame)557 TEST_P(EmbeddedTestServerTest, AcceptCHFrame) {
558 // The ACCEPT_CH frame is only supported for HTTP/2 connections
559 if (GetParam().protocol == HttpConnection::Protocol::kHttp1)
560 return;
561
562 server_->SetAlpsAcceptCH("", "foo");
563 server_->SetSSLConfig(net::EmbeddedTestServer::CERT_OK);
564
565 ASSERT_TRUE(server_->Start());
566
567 TestDelegate delegate;
568 std::unique_ptr<URLRequest> request_a(context_->CreateRequest(
569 server_->GetURL("/non-existent"), DEFAULT_PRIORITY, &delegate,
570 TRAFFIC_ANNOTATION_FOR_TESTS));
571 request_a->Start();
572 delegate.RunUntilComplete();
573
574 EXPECT_EQ(1u, delegate.transports().size());
575 EXPECT_EQ("foo", delegate.transports().back().accept_ch_frame);
576 }
577
TEST_P(EmbeddedTestServerTest,AcceptCHFrameDifferentOrigins)578 TEST_P(EmbeddedTestServerTest, AcceptCHFrameDifferentOrigins) {
579 // The ACCEPT_CH frame is only supported for HTTP/2 connections
580 if (GetParam().protocol == HttpConnection::Protocol::kHttp1)
581 return;
582
583 server_->SetAlpsAcceptCH("a.test", "a");
584 server_->SetAlpsAcceptCH("b.test", "b");
585 server_->SetAlpsAcceptCH("c.b.test", "c");
586 server_->SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
587
588 ASSERT_TRUE(server_->Start());
589
590 {
591 TestDelegate delegate;
592 std::unique_ptr<URLRequest> request_a(context_->CreateRequest(
593 server_->GetURL("a.test", "/non-existent"), DEFAULT_PRIORITY, &delegate,
594 TRAFFIC_ANNOTATION_FOR_TESTS));
595 request_a->Start();
596 delegate.RunUntilComplete();
597
598 EXPECT_EQ(1u, delegate.transports().size());
599 EXPECT_EQ("a", delegate.transports().back().accept_ch_frame);
600 }
601
602 {
603 TestDelegate delegate;
604 std::unique_ptr<URLRequest> request_a(context_->CreateRequest(
605 server_->GetURL("b.test", "/non-existent"), DEFAULT_PRIORITY, &delegate,
606 TRAFFIC_ANNOTATION_FOR_TESTS));
607 request_a->Start();
608 delegate.RunUntilComplete();
609
610 EXPECT_EQ(1u, delegate.transports().size());
611 EXPECT_EQ("b", delegate.transports().back().accept_ch_frame);
612 }
613
614 {
615 TestDelegate delegate;
616 std::unique_ptr<URLRequest> request_a(context_->CreateRequest(
617 server_->GetURL("c.b.test", "/non-existent"), DEFAULT_PRIORITY,
618 &delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
619 request_a->Start();
620 delegate.RunUntilComplete();
621
622 EXPECT_EQ(1u, delegate.transports().size());
623 EXPECT_EQ("c", delegate.transports().back().accept_ch_frame);
624 }
625 }
626
TEST_P(EmbeddedTestServerTest,LargePost)627 TEST_P(EmbeddedTestServerTest, LargePost) {
628 // HTTP/2's default flow-control window is 65K. Send a larger request body
629 // than that to verify the server correctly updates flow control.
630 std::string large_post_body(100 * 1024, 'a');
631 server_->RegisterRequestMonitor(
632 base::BindLambdaForTesting([=](const HttpRequest& request) {
633 EXPECT_EQ(request.method, METHOD_POST);
634 EXPECT_TRUE(request.has_content);
635 EXPECT_EQ(large_post_body, request.content);
636 }));
637
638 server_->SetSSLConfig(net::EmbeddedTestServer::CERT_OK);
639 ASSERT_TRUE(server_->Start());
640
641 auto reader = std::make_unique<UploadBytesElementReader>(
642 large_post_body.data(), large_post_body.size());
643 auto stream = ElementsUploadDataStream::CreateWithReader(std::move(reader),
644 /*identifier=*/0);
645
646 TestDelegate delegate;
647 std::unique_ptr<URLRequest> request(
648 context_->CreateRequest(server_->GetURL("/test"), DEFAULT_PRIORITY,
649 &delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
650 request->set_method("POST");
651 request->set_upload(std::move(stream));
652 request->Start();
653 delegate.RunUntilComplete();
654 }
655
656 INSTANTIATE_TEST_SUITE_P(EmbeddedTestServerTestInstantiation,
657 EmbeddedTestServerTest,
658 testing::ValuesIn(EmbeddedTestServerConfigs()));
659 // Below test exercises EmbeddedTestServer's ability to cope with the situation
660 // where there is no MessageLoop available on the thread at EmbeddedTestServer
661 // initialization and/or destruction.
662
663 typedef std::tuple<bool, bool, EmbeddedTestServerConfig> ThreadingTestParams;
664
665 class EmbeddedTestServerThreadingTest
666 : public testing::TestWithParam<ThreadingTestParams>,
667 public WithTaskEnvironment {};
668
669 class EmbeddedTestServerThreadingTestDelegate
670 : public base::PlatformThread::Delegate {
671 public:
EmbeddedTestServerThreadingTestDelegate(bool message_loop_present_on_initialize,bool message_loop_present_on_shutdown,EmbeddedTestServerConfig config)672 EmbeddedTestServerThreadingTestDelegate(
673 bool message_loop_present_on_initialize,
674 bool message_loop_present_on_shutdown,
675 EmbeddedTestServerConfig config)
676 : message_loop_present_on_initialize_(message_loop_present_on_initialize),
677 message_loop_present_on_shutdown_(message_loop_present_on_shutdown),
678 type_(config.type),
679 protocol_(config.protocol) {}
680
681 EmbeddedTestServerThreadingTestDelegate(
682 const EmbeddedTestServerThreadingTestDelegate&) = delete;
683 EmbeddedTestServerThreadingTestDelegate& operator=(
684 const EmbeddedTestServerThreadingTestDelegate&) = delete;
685
686 // base::PlatformThread::Delegate:
ThreadMain()687 void ThreadMain() override {
688 std::unique_ptr<base::SingleThreadTaskExecutor> executor;
689 if (message_loop_present_on_initialize_) {
690 executor = std::make_unique<base::SingleThreadTaskExecutor>(
691 base::MessagePumpType::IO);
692 }
693
694 // Create the test server instance.
695 EmbeddedTestServer server(type_, protocol_);
696 base::FilePath src_dir;
697 ASSERT_TRUE(base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &src_dir));
698 ASSERT_TRUE(server.Start());
699
700 // Make a request and wait for the reply.
701 if (!executor) {
702 executor = std::make_unique<base::SingleThreadTaskExecutor>(
703 base::MessagePumpType::IO);
704 }
705
706 auto context = CreateTestURLRequestContextBuilder()->Build();
707 TestDelegate delegate;
708 std::unique_ptr<URLRequest> request(
709 context->CreateRequest(server.GetURL("/test?q=foo"), DEFAULT_PRIORITY,
710 &delegate, TRAFFIC_ANNOTATION_FOR_TESTS));
711
712 request->Start();
713 delegate.RunUntilComplete();
714 request.reset();
715 // Flush the socket pool on the same thread by destroying the context.
716 context.reset();
717
718 // Shut down.
719 if (message_loop_present_on_shutdown_)
720 executor.reset();
721
722 ASSERT_TRUE(server.ShutdownAndWaitUntilComplete());
723 }
724
725 private:
726 const bool message_loop_present_on_initialize_;
727 const bool message_loop_present_on_shutdown_;
728 const EmbeddedTestServer::Type type_;
729 const HttpConnection::Protocol protocol_;
730 };
731
TEST_P(EmbeddedTestServerThreadingTest,RunTest)732 TEST_P(EmbeddedTestServerThreadingTest, RunTest) {
733 // The actual test runs on a separate thread so it can screw with the presence
734 // of a MessageLoop - the test suite already sets up a MessageLoop for the
735 // main test thread.
736 base::PlatformThreadHandle thread_handle;
737 EmbeddedTestServerThreadingTestDelegate delegate(std::get<0>(GetParam()),
738 std::get<1>(GetParam()),
739 std::get<2>(GetParam()));
740 ASSERT_TRUE(base::PlatformThread::Create(0, &delegate, &thread_handle));
741 base::PlatformThread::Join(thread_handle);
742 }
743
744 INSTANTIATE_TEST_SUITE_P(
745 EmbeddedTestServerThreadingTestInstantiation,
746 EmbeddedTestServerThreadingTest,
747 testing::Combine(testing::Bool(),
748 testing::Bool(),
749 testing::ValuesIn(EmbeddedTestServerConfigs())));
750
751 } // namespace net::test_server
752