OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/test/test_server.h" | 5 #include "net/test/test_server.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 12 matching lines...) Expand all Loading... |
23 #include "base/utf_string_conversions.h" | 23 #include "base/utf_string_conversions.h" |
24 #include "googleurl/src/gurl.h" | 24 #include "googleurl/src/gurl.h" |
25 #include "net/base/cert_test_util.h" | 25 #include "net/base/cert_test_util.h" |
26 #include "net/base/host_port_pair.h" | 26 #include "net/base/host_port_pair.h" |
27 #include "net/base/host_resolver.h" | 27 #include "net/base/host_resolver.h" |
28 #include "net/base/test_completion_callback.h" | 28 #include "net/base/test_completion_callback.h" |
29 #include "net/socket/tcp_client_socket.h" | 29 #include "net/socket/tcp_client_socket.h" |
30 #include "net/test/python_utils.h" | 30 #include "net/test/python_utils.h" |
31 #include "testing/platform_test.h" | 31 #include "testing/platform_test.h" |
32 | 32 |
| 33 namespace net { |
| 34 |
33 namespace { | 35 namespace { |
34 | 36 |
35 // Number of connection attempts for tests. | 37 // Number of connection attempts for tests. |
36 const int kServerConnectionAttempts = 10; | 38 const int kServerConnectionAttempts = 10; |
37 | 39 |
38 // Connection timeout in milliseconds for tests. | 40 // Connection timeout in milliseconds for tests. |
39 const int kServerConnectionTimeoutMs = 1000; | 41 const int kServerConnectionTimeoutMs = 1000; |
40 | 42 |
41 const char kTestServerShardFlag[] = "test-server-shard"; | 43 const char kTestServerShardFlag[] = "test-server-shard"; |
42 | 44 |
43 int GetPortBase(net::TestServer::Type type) { | 45 int GetHTTPSPortBase(const TestServer::HTTPSOptions& options) { |
44 switch (type) { | 46 if (options.request_client_certificate) |
45 case net::TestServer::TYPE_FTP: | 47 return 9543; |
46 return 3117; | 48 |
47 case net::TestServer::TYPE_HTTP: | 49 switch (options.server_certificate) { |
48 return 1337; | 50 case TestServer::HTTPSOptions::CERT_OK: |
49 case net::TestServer::TYPE_HTTPS: | |
50 return 9443; | 51 return 9443; |
51 case net::TestServer::TYPE_HTTPS_CLIENT_AUTH: | 52 case TestServer::HTTPSOptions::CERT_MISMATCHED_NAME: |
52 return 9543; | 53 return 9643; |
53 case net::TestServer::TYPE_HTTPS_EXPIRED_CERTIFICATE: | 54 case TestServer::HTTPSOptions::CERT_EXPIRED: |
54 // TODO(phajdan.jr): Some tests rely on this hardcoded value. | 55 // TODO(phajdan.jr): Some tests rely on this hardcoded value. |
55 // Some uses of this are actually in .html/.js files. | 56 // Some uses of this are actually in .html/.js files. |
56 return 9666; | 57 return 9666; |
57 case net::TestServer::TYPE_HTTPS_MISMATCHED_HOSTNAME: | |
58 return 9643; | |
59 default: | 58 default: |
60 NOTREACHED(); | 59 NOTREACHED(); |
61 } | 60 } |
62 return -1; | 61 return -1; |
63 } | 62 } |
64 | 63 |
65 int GetPort(net::TestServer::Type type) { | 64 int GetPortBase(TestServer::Type type, |
66 int port = GetPortBase(type); | 65 const TestServer::HTTPSOptions& options) { |
| 66 switch (type) { |
| 67 case TestServer::TYPE_FTP: |
| 68 return 3117; |
| 69 case TestServer::TYPE_HTTP: |
| 70 return 1337; |
| 71 case TestServer::TYPE_HTTPS: |
| 72 return GetHTTPSPortBase(options); |
| 73 default: |
| 74 NOTREACHED(); |
| 75 } |
| 76 return -1; |
| 77 } |
| 78 |
| 79 int GetPort(TestServer::Type type, |
| 80 const TestServer::HTTPSOptions& options) { |
| 81 int port = GetPortBase(type, options); |
67 if (CommandLine::ForCurrentProcess()->HasSwitch(kTestServerShardFlag)) { | 82 if (CommandLine::ForCurrentProcess()->HasSwitch(kTestServerShardFlag)) { |
68 std::string shard_str(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 83 std::string shard_str(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
69 kTestServerShardFlag)); | 84 kTestServerShardFlag)); |
70 int shard = -1; | 85 int shard = -1; |
71 if (base::StringToInt(shard_str, &shard)) { | 86 if (base::StringToInt(shard_str, &shard)) { |
72 port += shard; | 87 port += shard; |
73 } else { | 88 } else { |
74 LOG(FATAL) << "Got invalid " << kTestServerShardFlag << " flag value. " | 89 LOG(FATAL) << "Got invalid " << kTestServerShardFlag << " flag value. " |
75 << "An integer is expected."; | 90 << "An integer is expected."; |
76 } | 91 } |
77 } | 92 } |
78 return port; | 93 return port; |
79 } | 94 } |
80 | 95 |
81 std::string GetHostname(net::TestServer::Type type) { | 96 std::string GetHostname(TestServer::Type type, |
82 if (type == net::TestServer::TYPE_HTTPS_MISMATCHED_HOSTNAME) { | 97 const TestServer::HTTPSOptions& options) { |
| 98 if (type == TestServer::TYPE_HTTPS && |
| 99 options.server_certificate == |
| 100 TestServer::HTTPSOptions::CERT_MISMATCHED_NAME) { |
83 // Return a different hostname string that resolves to the same hostname. | 101 // Return a different hostname string that resolves to the same hostname. |
84 return "localhost"; | 102 return "localhost"; |
85 } | 103 } |
86 | 104 |
87 return "127.0.0.1"; | 105 return "127.0.0.1"; |
88 } | 106 } |
89 | 107 |
90 } // namespace | 108 } // namespace |
91 | 109 |
92 namespace net { | |
93 | |
94 #if defined(OS_MACOSX) | 110 #if defined(OS_MACOSX) |
95 void SetMacTestCertificate(X509Certificate* cert); | 111 void SetMacTestCertificate(X509Certificate* cert); |
96 #endif | 112 #endif |
97 | 113 |
| 114 TestServer::HTTPSOptions::HTTPSOptions() |
| 115 : server_certificate(CERT_OK), |
| 116 request_client_certificate(false), |
| 117 bulk_ciphers(HTTPSOptions::BULK_CIPHER_ANY) {} |
| 118 |
| 119 TestServer::HTTPSOptions::HTTPSOptions( |
| 120 TestServer::HTTPSOptions::ServerCertificate cert) |
| 121 : server_certificate(cert), |
| 122 request_client_certificate(false), |
| 123 bulk_ciphers(HTTPSOptions::BULK_CIPHER_ANY) {} |
| 124 |
| 125 TestServer::HTTPSOptions::~HTTPSOptions() {} |
| 126 |
| 127 FilePath TestServer::HTTPSOptions::GetCertificateFile() const { |
| 128 switch (server_certificate) { |
| 129 case CERT_OK: |
| 130 case CERT_MISMATCHED_NAME: |
| 131 return FilePath(FILE_PATH_LITERAL("ok_cert.pem")); |
| 132 case CERT_EXPIRED: |
| 133 return FilePath(FILE_PATH_LITERAL("expired_cert.pem")); |
| 134 default: |
| 135 NOTREACHED(); |
| 136 } |
| 137 return FilePath(); |
| 138 } |
| 139 |
98 TestServer::TestServer(Type type, const FilePath& document_root) | 140 TestServer::TestServer(Type type, const FilePath& document_root) |
99 : host_port_pair_(GetHostname(type), GetPort(type)), | 141 : type_(type) { |
100 process_handle_(base::kNullProcessHandle), | 142 Init(document_root); |
101 type_(type) { | 143 } |
| 144 |
| 145 TestServer::TestServer(const HTTPSOptions& https_options, |
| 146 const FilePath& document_root) |
| 147 : https_options_(https_options), type_(TYPE_HTTPS) { |
| 148 Init(document_root); |
| 149 } |
| 150 |
| 151 TestServer::~TestServer() { |
| 152 #if defined(OS_MACOSX) |
| 153 SetMacTestCertificate(NULL); |
| 154 #endif |
| 155 Stop(); |
| 156 } |
| 157 |
| 158 void TestServer::Init(const FilePath& document_root) { |
| 159 host_port_pair_ = HostPortPair(GetHostname(type_, https_options_), |
| 160 GetPort(type_, https_options_)); |
| 161 process_handle_ = base::kNullProcessHandle; |
| 162 |
102 FilePath src_dir; | 163 FilePath src_dir; |
103 PathService::Get(base::DIR_SOURCE_ROOT, &src_dir); | 164 PathService::Get(base::DIR_SOURCE_ROOT, &src_dir); |
104 | 165 |
105 document_root_ = src_dir.Append(document_root); | 166 document_root_ = src_dir.Append(document_root); |
106 | 167 |
107 certificates_dir_ = src_dir.Append(FILE_PATH_LITERAL("net")) | 168 certificates_dir_ = src_dir.Append(FILE_PATH_LITERAL("net")) |
108 .Append(FILE_PATH_LITERAL("data")) | 169 .Append(FILE_PATH_LITERAL("data")) |
109 .Append(FILE_PATH_LITERAL("ssl")) | 170 .Append(FILE_PATH_LITERAL("ssl")) |
110 .Append(FILE_PATH_LITERAL("certificates")); | 171 .Append(FILE_PATH_LITERAL("certificates")); |
111 } | 172 } |
112 | 173 |
113 TestServer::~TestServer() { | |
114 #if defined(OS_MACOSX) | |
115 SetMacTestCertificate(NULL); | |
116 #endif | |
117 Stop(); | |
118 } | |
119 | |
120 bool TestServer::Start() { | 174 bool TestServer::Start() { |
121 if (GetScheme() == "https") { | 175 if (type_ == TYPE_HTTPS) { |
122 if (!LoadTestRootCert()) | 176 if (!LoadTestRootCert()) |
123 return false; | 177 return false; |
124 if (!CheckCATrusted()) | 178 if (!CheckCATrusted()) |
125 return false; | 179 return false; |
126 } | 180 } |
127 | 181 |
128 // Get path to python server script | 182 // Get path to python server script |
129 FilePath testserver_path; | 183 FilePath testserver_path; |
130 if (!PathService::Get(base::DIR_SOURCE_ROOT, &testserver_path)) { | 184 if (!PathService::Get(base::DIR_SOURCE_ROOT, &testserver_path)) { |
131 LOG(ERROR) << "Failed to get DIR_SOURCE_ROOT"; | 185 LOG(ERROR) << "Failed to get DIR_SOURCE_ROOT"; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 return ret; | 224 return ret; |
171 } | 225 } |
172 | 226 |
173 std::string TestServer::GetScheme() const { | 227 std::string TestServer::GetScheme() const { |
174 switch (type_) { | 228 switch (type_) { |
175 case TYPE_FTP: | 229 case TYPE_FTP: |
176 return "ftp"; | 230 return "ftp"; |
177 case TYPE_HTTP: | 231 case TYPE_HTTP: |
178 return "http"; | 232 return "http"; |
179 case TYPE_HTTPS: | 233 case TYPE_HTTPS: |
180 case TYPE_HTTPS_CLIENT_AUTH: | |
181 case TYPE_HTTPS_MISMATCHED_HOSTNAME: | |
182 case TYPE_HTTPS_EXPIRED_CERTIFICATE: | |
183 return "https"; | 234 return "https"; |
184 default: | 235 default: |
185 NOTREACHED(); | 236 NOTREACHED(); |
186 } | 237 } |
187 return std::string(); | 238 return std::string(); |
188 } | 239 } |
189 | 240 |
190 bool TestServer::GetAddressList(AddressList* address_list) const { | 241 bool TestServer::GetAddressList(AddressList* address_list) const { |
191 DCHECK(address_list); | 242 DCHECK(address_list); |
192 | 243 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 X509Certificate* cert = LoadTemporaryRootCert(GetRootCertificatePath()); | 336 X509Certificate* cert = LoadTemporaryRootCert(GetRootCertificatePath()); |
286 if (!cert) | 337 if (!cert) |
287 return false; | 338 return false; |
288 SetMacTestCertificate(cert); | 339 SetMacTestCertificate(cert); |
289 return true; | 340 return true; |
290 #else | 341 #else |
291 return true; | 342 return true; |
292 #endif | 343 #endif |
293 } | 344 } |
294 | 345 |
295 FilePath TestServer::GetCertificatePath() { | 346 bool TestServer::AddCommandLineArguments(CommandLine* command_line) const { |
296 switch (type_) { | 347 command_line->AppendSwitchASCII("port", |
297 case TYPE_FTP: | 348 base::IntToString(host_port_pair_.port())); |
298 case TYPE_HTTP: | 349 command_line->AppendSwitchPath("data-dir", document_root_); |
299 return FilePath(); | 350 |
300 case TYPE_HTTPS: | 351 if (type_ == TYPE_FTP) { |
301 case TYPE_HTTPS_CLIENT_AUTH: | 352 command_line->AppendArg("-f"); |
302 case TYPE_HTTPS_MISMATCHED_HOSTNAME: | 353 } else if (type_ == TYPE_HTTPS) { |
303 return certificates_dir_.AppendASCII("ok_cert.pem"); | 354 FilePath certificate_path(certificates_dir_); |
304 case TYPE_HTTPS_EXPIRED_CERTIFICATE: | 355 certificate_path = certificate_path.Append( |
305 return certificates_dir_.AppendASCII("expired_cert.pem"); | 356 https_options_.GetCertificateFile()); |
306 default: | 357 if (!file_util::PathExists(certificate_path)) { |
307 NOTREACHED(); | 358 LOG(ERROR) << "Certificate path " << certificate_path.value() |
| 359 << " doesn't exist. Can't launch https server."; |
| 360 return false; |
| 361 } |
| 362 command_line->AppendSwitchPath("https", certificate_path); |
| 363 |
| 364 if (https_options_.request_client_certificate) |
| 365 command_line->AppendSwitch("ssl-client-auth"); |
| 366 |
| 367 for (std::vector<FilePath>::const_iterator it = |
| 368 https_options_.client_authorities.begin(); |
| 369 it != https_options_.client_authorities.end(); ++it) { |
| 370 if (!file_util::PathExists(*it)) { |
| 371 LOG(ERROR) << "Client authority path " << it->value() |
| 372 << " doesn't exist. Can't launch https server."; |
| 373 return false; |
| 374 } |
| 375 |
| 376 command_line->AppendSwitchPath("ssl-client-ca", *it); |
| 377 } |
| 378 |
| 379 const char kBulkCipherSwitch[] = "ssl-bulk-cipher"; |
| 380 if (https_options_.bulk_ciphers & HTTPSOptions::BULK_CIPHER_RC4) |
| 381 command_line->AppendSwitchASCII(kBulkCipherSwitch, "rc4"); |
| 382 if (https_options_.bulk_ciphers & HTTPSOptions::BULK_CIPHER_AES128) |
| 383 command_line->AppendSwitchASCII(kBulkCipherSwitch, "aes128"); |
| 384 if (https_options_.bulk_ciphers & HTTPSOptions::BULK_CIPHER_AES256) |
| 385 command_line->AppendSwitchASCII(kBulkCipherSwitch, "aes256"); |
| 386 if (https_options_.bulk_ciphers & HTTPSOptions::BULK_CIPHER_3DES) |
| 387 command_line->AppendSwitchASCII(kBulkCipherSwitch, "3des"); |
308 } | 388 } |
309 return FilePath(); | 389 |
| 390 return true; |
310 } | 391 } |
311 | 392 |
312 } // namespace net | 393 } // namespace net |
OLD | NEW |