xref: /aosp_15_r20/external/cronet/net/tools/testserver/run_testserver.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include <stdio.h>
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <memory>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include "base/at_exit.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/command_line.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/files/file_path.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/files/file_util.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/message_loop/message_pump_type.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/strings/utf_string_conversions.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_executor.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/test/test_timeouts.h"
19*6777b538SAndroid Build Coastguard Worker #include "net/test/embedded_test_server/embedded_test_server.h"
20*6777b538SAndroid Build Coastguard Worker #include "net/test/spawned_test_server/spawned_test_server.h"
21*6777b538SAndroid Build Coastguard Worker 
PrintUsage()22*6777b538SAndroid Build Coastguard Worker static void PrintUsage() {
23*6777b538SAndroid Build Coastguard Worker   printf(
24*6777b538SAndroid Build Coastguard Worker       "run_testserver --doc-root=relpath\n"
25*6777b538SAndroid Build Coastguard Worker       "               [--http|--https|--ws|--wss]\n"
26*6777b538SAndroid Build Coastguard Worker       "               [--ssl-cert=ok|mismatched-name|expired]\n");
27*6777b538SAndroid Build Coastguard Worker   printf("(NOTE: relpath should be relative to the 'src' directory.\n");
28*6777b538SAndroid Build Coastguard Worker }
29*6777b538SAndroid Build Coastguard Worker 
main(int argc,const char * argv[])30*6777b538SAndroid Build Coastguard Worker int main(int argc, const char* argv[]) {
31*6777b538SAndroid Build Coastguard Worker   base::AtExitManager at_exit_manager;
32*6777b538SAndroid Build Coastguard Worker   base::SingleThreadTaskExecutor io_task_executor(base::MessagePumpType::IO);
33*6777b538SAndroid Build Coastguard Worker 
34*6777b538SAndroid Build Coastguard Worker   // Process command line
35*6777b538SAndroid Build Coastguard Worker   base::CommandLine::Init(argc, argv);
36*6777b538SAndroid Build Coastguard Worker   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
37*6777b538SAndroid Build Coastguard Worker 
38*6777b538SAndroid Build Coastguard Worker   logging::LoggingSettings settings;
39*6777b538SAndroid Build Coastguard Worker   settings.logging_dest = logging::LOG_TO_ALL;
40*6777b538SAndroid Build Coastguard Worker   settings.log_file_path = FILE_PATH_LITERAL("testserver.log");
41*6777b538SAndroid Build Coastguard Worker   if (!logging::InitLogging(settings)) {
42*6777b538SAndroid Build Coastguard Worker     printf("Error: could not initialize logging. Exiting.\n");
43*6777b538SAndroid Build Coastguard Worker     return -1;
44*6777b538SAndroid Build Coastguard Worker   }
45*6777b538SAndroid Build Coastguard Worker 
46*6777b538SAndroid Build Coastguard Worker   TestTimeouts::Initialize();
47*6777b538SAndroid Build Coastguard Worker 
48*6777b538SAndroid Build Coastguard Worker   if (command_line->GetSwitches().empty() ||
49*6777b538SAndroid Build Coastguard Worker       command_line->HasSwitch("help")) {
50*6777b538SAndroid Build Coastguard Worker     PrintUsage();
51*6777b538SAndroid Build Coastguard Worker     return -1;
52*6777b538SAndroid Build Coastguard Worker   }
53*6777b538SAndroid Build Coastguard Worker 
54*6777b538SAndroid Build Coastguard Worker   // If populated, EmbeddedTestServer is used instead of the SpawnedTestServer.
55*6777b538SAndroid Build Coastguard Worker   std::optional<net::EmbeddedTestServer::Type> embedded_test_server_type;
56*6777b538SAndroid Build Coastguard Worker 
57*6777b538SAndroid Build Coastguard Worker   net::SpawnedTestServer::Type server_type;
58*6777b538SAndroid Build Coastguard Worker   if (command_line->HasSwitch("http")) {
59*6777b538SAndroid Build Coastguard Worker     embedded_test_server_type = net::EmbeddedTestServer::TYPE_HTTP;
60*6777b538SAndroid Build Coastguard Worker   } else if (command_line->HasSwitch("https")) {
61*6777b538SAndroid Build Coastguard Worker     embedded_test_server_type = net::EmbeddedTestServer::TYPE_HTTPS;
62*6777b538SAndroid Build Coastguard Worker   } else if (command_line->HasSwitch("ws")) {
63*6777b538SAndroid Build Coastguard Worker     server_type = net::SpawnedTestServer::TYPE_WS;
64*6777b538SAndroid Build Coastguard Worker   } else if (command_line->HasSwitch("wss")) {
65*6777b538SAndroid Build Coastguard Worker     server_type = net::SpawnedTestServer::TYPE_WSS;
66*6777b538SAndroid Build Coastguard Worker   } else {
67*6777b538SAndroid Build Coastguard Worker     // If no scheme switch is specified, select http or https scheme.
68*6777b538SAndroid Build Coastguard Worker     // TODO(toyoshim): Remove this estimation.
69*6777b538SAndroid Build Coastguard Worker     if (command_line->HasSwitch("ssl-cert")) {
70*6777b538SAndroid Build Coastguard Worker       embedded_test_server_type = net::EmbeddedTestServer::TYPE_HTTPS;
71*6777b538SAndroid Build Coastguard Worker     } else {
72*6777b538SAndroid Build Coastguard Worker       embedded_test_server_type = net::EmbeddedTestServer::TYPE_HTTP;
73*6777b538SAndroid Build Coastguard Worker     }
74*6777b538SAndroid Build Coastguard Worker   }
75*6777b538SAndroid Build Coastguard Worker 
76*6777b538SAndroid Build Coastguard Worker   net::SpawnedTestServer::SSLOptions ssl_options;
77*6777b538SAndroid Build Coastguard Worker   net::EmbeddedTestServer::ServerCertificate server_certificate;
78*6777b538SAndroid Build Coastguard Worker   if (command_line->HasSwitch("ssl-cert")) {
79*6777b538SAndroid Build Coastguard Worker     if ((embedded_test_server_type.has_value() &&
80*6777b538SAndroid Build Coastguard Worker          *embedded_test_server_type != net::EmbeddedTestServer::TYPE_HTTPS) ||
81*6777b538SAndroid Build Coastguard Worker         (!embedded_test_server_type.has_value() &&
82*6777b538SAndroid Build Coastguard Worker          !net::SpawnedTestServer::UsingSSL(server_type))) {
83*6777b538SAndroid Build Coastguard Worker       printf("Error: --ssl-cert is specified on non-secure scheme\n");
84*6777b538SAndroid Build Coastguard Worker       PrintUsage();
85*6777b538SAndroid Build Coastguard Worker       return -1;
86*6777b538SAndroid Build Coastguard Worker     }
87*6777b538SAndroid Build Coastguard Worker     std::string cert_option = command_line->GetSwitchValueASCII("ssl-cert");
88*6777b538SAndroid Build Coastguard Worker     if (cert_option == "ok") {
89*6777b538SAndroid Build Coastguard Worker       ssl_options.server_certificate =
90*6777b538SAndroid Build Coastguard Worker           net::SpawnedTestServer::SSLOptions::CERT_OK;
91*6777b538SAndroid Build Coastguard Worker       server_certificate = net::EmbeddedTestServer::CERT_OK;
92*6777b538SAndroid Build Coastguard Worker     } else if (cert_option == "mismatched-name") {
93*6777b538SAndroid Build Coastguard Worker       ssl_options.server_certificate =
94*6777b538SAndroid Build Coastguard Worker           net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
95*6777b538SAndroid Build Coastguard Worker       server_certificate = net::EmbeddedTestServer::CERT_MISMATCHED_NAME;
96*6777b538SAndroid Build Coastguard Worker     } else if (cert_option == "expired") {
97*6777b538SAndroid Build Coastguard Worker       ssl_options.server_certificate =
98*6777b538SAndroid Build Coastguard Worker           net::SpawnedTestServer::SSLOptions::CERT_EXPIRED;
99*6777b538SAndroid Build Coastguard Worker       server_certificate = net::EmbeddedTestServer::CERT_EXPIRED;
100*6777b538SAndroid Build Coastguard Worker     } else {
101*6777b538SAndroid Build Coastguard Worker       printf("Error: --ssl-cert has invalid value %s\n", cert_option.c_str());
102*6777b538SAndroid Build Coastguard Worker       PrintUsage();
103*6777b538SAndroid Build Coastguard Worker       return -1;
104*6777b538SAndroid Build Coastguard Worker     }
105*6777b538SAndroid Build Coastguard Worker   }
106*6777b538SAndroid Build Coastguard Worker 
107*6777b538SAndroid Build Coastguard Worker   base::FilePath doc_root = command_line->GetSwitchValuePath("doc-root");
108*6777b538SAndroid Build Coastguard Worker   if (doc_root.empty()) {
109*6777b538SAndroid Build Coastguard Worker     printf("Error: --doc-root must be specified\n");
110*6777b538SAndroid Build Coastguard Worker     PrintUsage();
111*6777b538SAndroid Build Coastguard Worker     return -1;
112*6777b538SAndroid Build Coastguard Worker   }
113*6777b538SAndroid Build Coastguard Worker 
114*6777b538SAndroid Build Coastguard Worker   base::FilePath full_path =
115*6777b538SAndroid Build Coastguard Worker       net::test_server::EmbeddedTestServer::GetFullPathFromSourceDirectory(
116*6777b538SAndroid Build Coastguard Worker           doc_root);
117*6777b538SAndroid Build Coastguard Worker   if (!base::DirectoryExists(full_path)) {
118*6777b538SAndroid Build Coastguard Worker     printf("Error: invalid doc root: \"%s\" does not exist!\n",
119*6777b538SAndroid Build Coastguard Worker            base::UTF16ToUTF8(full_path.LossyDisplayName()).c_str());
120*6777b538SAndroid Build Coastguard Worker     return -1;
121*6777b538SAndroid Build Coastguard Worker   }
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker   // Use EmbeddedTestServer, if it supports the provided configuration.
124*6777b538SAndroid Build Coastguard Worker   if (embedded_test_server_type.has_value()) {
125*6777b538SAndroid Build Coastguard Worker     net::EmbeddedTestServer embedded_test_server(*embedded_test_server_type);
126*6777b538SAndroid Build Coastguard Worker     if (*embedded_test_server_type == net::EmbeddedTestServer::TYPE_HTTPS) {
127*6777b538SAndroid Build Coastguard Worker       embedded_test_server.SetSSLConfig(server_certificate);
128*6777b538SAndroid Build Coastguard Worker     }
129*6777b538SAndroid Build Coastguard Worker 
130*6777b538SAndroid Build Coastguard Worker     embedded_test_server.AddDefaultHandlers(doc_root);
131*6777b538SAndroid Build Coastguard Worker     if (!embedded_test_server.Start()) {
132*6777b538SAndroid Build Coastguard Worker       printf("Error: failed to start embedded test server. Exiting.\n");
133*6777b538SAndroid Build Coastguard Worker       return -1;
134*6777b538SAndroid Build Coastguard Worker     }
135*6777b538SAndroid Build Coastguard Worker 
136*6777b538SAndroid Build Coastguard Worker     printf("Embedded test server running at %s (type ctrl+c to exit)\n",
137*6777b538SAndroid Build Coastguard Worker            embedded_test_server.host_port_pair().ToString().c_str());
138*6777b538SAndroid Build Coastguard Worker 
139*6777b538SAndroid Build Coastguard Worker     base::RunLoop().Run();
140*6777b538SAndroid Build Coastguard Worker     return 0;
141*6777b538SAndroid Build Coastguard Worker   }
142*6777b538SAndroid Build Coastguard Worker 
143*6777b538SAndroid Build Coastguard Worker   // Otherwise, use the SpawnedTestServer.
144*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<net::SpawnedTestServer> test_server;
145*6777b538SAndroid Build Coastguard Worker   if (net::SpawnedTestServer::UsingSSL(server_type)) {
146*6777b538SAndroid Build Coastguard Worker     test_server = std::make_unique<net::SpawnedTestServer>(
147*6777b538SAndroid Build Coastguard Worker         server_type, ssl_options, doc_root);
148*6777b538SAndroid Build Coastguard Worker   } else {
149*6777b538SAndroid Build Coastguard Worker     test_server =
150*6777b538SAndroid Build Coastguard Worker         std::make_unique<net::SpawnedTestServer>(server_type, doc_root);
151*6777b538SAndroid Build Coastguard Worker   }
152*6777b538SAndroid Build Coastguard Worker 
153*6777b538SAndroid Build Coastguard Worker   if (!test_server->Start()) {
154*6777b538SAndroid Build Coastguard Worker     printf("Error: failed to start test server. Exiting.\n");
155*6777b538SAndroid Build Coastguard Worker     return -1;
156*6777b538SAndroid Build Coastguard Worker   }
157*6777b538SAndroid Build Coastguard Worker 
158*6777b538SAndroid Build Coastguard Worker   printf("testserver running at %s (type ctrl+c to exit)\n",
159*6777b538SAndroid Build Coastguard Worker          test_server->host_port_pair().ToString().c_str());
160*6777b538SAndroid Build Coastguard Worker 
161*6777b538SAndroid Build Coastguard Worker   base::RunLoop().Run();
162*6777b538SAndroid Build Coastguard Worker }
163