172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/test/test_server.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <algorithm> 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string> 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector> 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "build/build_config.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#if defined(OS_MACOSX) 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/x509_certificate.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "base/base64.h" 183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/command_line.h" 19513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/debug/leak_annotations.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_util.h" 21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/json/json_reader.h" 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/path_service.h" 253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h" 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h" 27201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "base/values.h" 283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "googleurl/src/gurl.h" 293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/base/host_port_pair.h" 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/host_resolver.h" 3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "net/base/net_errors.h" 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/test_completion_callback.h" 3321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/base/test_root_certs.h" 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/socket/tcp_client_socket.h" 353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/test/python_utils.h" 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/platform_test.h" 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 38513209b27ff55e2841eac0e4120199c23acce758Ben Murdochnamespace net { 39513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merricknamespace { 413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Number of connection attempts for tests. 433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst int kServerConnectionAttempts = 10; 443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Connection timeout in milliseconds for tests. 463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst int kServerConnectionTimeoutMs = 1000; 473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 48513209b27ff55e2841eac0e4120199c23acce758Ben Murdochstd::string GetHostname(TestServer::Type type, 49513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const TestServer::HTTPSOptions& options) { 50513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (type == TestServer::TYPE_HTTPS && 51513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch options.server_certificate == 52513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch TestServer::HTTPSOptions::CERT_MISMATCHED_NAME) { 533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Return a different hostname string that resolves to the same hostname. 543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return "localhost"; 553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return "127.0.0.1"; 583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} // namespace 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 62513209b27ff55e2841eac0e4120199c23acce758Ben MurdochTestServer::HTTPSOptions::HTTPSOptions() 63513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch : server_certificate(CERT_OK), 64513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch request_client_certificate(false), 65513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bulk_ciphers(HTTPSOptions::BULK_CIPHER_ANY) {} 66513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 67513209b27ff55e2841eac0e4120199c23acce758Ben MurdochTestServer::HTTPSOptions::HTTPSOptions( 68513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch TestServer::HTTPSOptions::ServerCertificate cert) 69513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch : server_certificate(cert), 70513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch request_client_certificate(false), 71513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bulk_ciphers(HTTPSOptions::BULK_CIPHER_ANY) {} 72513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 73513209b27ff55e2841eac0e4120199c23acce758Ben MurdochTestServer::HTTPSOptions::~HTTPSOptions() {} 74513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 75513209b27ff55e2841eac0e4120199c23acce758Ben MurdochFilePath TestServer::HTTPSOptions::GetCertificateFile() const { 76513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch switch (server_certificate) { 77513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch case CERT_OK: 78513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch case CERT_MISMATCHED_NAME: 79513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return FilePath(FILE_PATH_LITERAL("ok_cert.pem")); 80513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch case CERT_EXPIRED: 81513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return FilePath(FILE_PATH_LITERAL("expired_cert.pem")); 82513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch default: 83513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NOTREACHED(); 84513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 85513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return FilePath(); 86513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 87513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 883345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTestServer::TestServer(Type type, const FilePath& document_root) 894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch : type_(type), 904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch started_(false) { 91513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Init(document_root); 92513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 93513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 94513209b27ff55e2841eac0e4120199c23acce758Ben MurdochTestServer::TestServer(const HTTPSOptions& https_options, 95513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const FilePath& document_root) 964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch : https_options_(https_options), 974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch type_(TYPE_HTTPS), 984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch started_(false) { 99513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Init(document_root); 100513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 101513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 102513209b27ff55e2841eac0e4120199c23acce758Ben MurdochTestServer::~TestServer() { 10321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen TestRootCerts* root_certs = TestRootCerts::GetInstance(); 10421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen root_certs->Clear(); 105513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Stop(); 106513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 107513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 1083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool TestServer::Start() { 109513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (type_ == TYPE_HTTPS) { 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!LoadTestRootCert()) 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Get path to python server script 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath testserver_path; 1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!PathService::Get(base::DIR_SOURCE_ROOT, &testserver_path)) { 1173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOG(ERROR) << "Failed to get DIR_SOURCE_ROOT"; 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 1193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch testserver_path = testserver_path 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch .Append(FILE_PATH_LITERAL("net")) 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch .Append(FILE_PATH_LITERAL("tools")) 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch .Append(FILE_PATH_LITERAL("testserver")) 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch .Append(FILE_PATH_LITERAL("testserver.py")); 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!SetPythonPath()) 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!LaunchPython(testserver_path)) 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!WaitToStart()) { 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Stop(); 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 13721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen allowed_port_.reset(new ScopedPortException(host_port_pair_.port())); 13821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 1394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch started_ = true; 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool TestServer::Stop() { 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!process_handle_) 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1474a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch started_ = false; 1484a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 1493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // First check if the process has already terminated. 1503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool ret = base::WaitForSingleProcess(process_handle_, 0); 1513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!ret) 1523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ret = base::KillProcess(process_handle_, 1, true); 1533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (ret) { 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::CloseProcessHandle(process_handle_); 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch process_handle_ = base::kNullProcessHandle; 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 158731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick VLOG(1) << "Kill failed?"; 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 16121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen allowed_port_.reset(); 16221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ret; 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1664a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochconst HostPortPair& TestServer::host_port_pair() const { 1674a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch DCHECK(started_); 1684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return host_port_pair_; 1694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 1704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 171201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst DictionaryValue& TestServer::server_data() const { 172201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(started_); 173201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return *server_data_; 174201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 175201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstd::string TestServer::GetScheme() const { 1773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick switch (type_) { 1783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case TYPE_FTP: 1793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return "ftp"; 1803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case TYPE_HTTP: 1814a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch case TYPE_SYNC: 1823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return "http"; 1833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case TYPE_HTTPS: 1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return "https"; 1853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick default: 1863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 1873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return std::string(); 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool TestServer::GetAddressList(AddressList* address_list) const { 1923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(address_list); 1933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 194731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<HostResolver> resolver( 195513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch CreateSystemHostResolver(HostResolver::kDefaultParallelism, NULL, NULL)); 1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HostResolver::RequestInfo info(host_port_pair_); 1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = resolver->Resolve(info, address_list, NULL, NULL, BoundNetLog()); 1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (rv != net::OK) { 1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOG(ERROR) << "Failed to resolve hostname: " << host_port_pair_.host(); 2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; 2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return true; 2033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2054a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben MurdochGURL TestServer::GetURL(const std::string& path) const { 2063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return GURL(GetScheme() + "://" + host_port_pair_.ToString() + 2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "/" + path); 2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickGURL TestServer::GetURLWithUser(const std::string& path, 2114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const std::string& user) const { 2123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return GURL(GetScheme() + "://" + user + "@" + 2133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick host_port_pair_.ToString() + 2143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "/" + path); 2153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2173345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickGURL TestServer::GetURLWithUserAndPassword(const std::string& path, 2183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& user, 2194a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const std::string& password) const { 2203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return GURL(GetScheme() + "://" + user + ":" + password + 2213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "@" + host_port_pair_.ToString() + 2223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "/" + path); 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2254a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// static 2264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochbool TestServer::GetFilePathWithReplacements( 2274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const std::string& original_file_path, 2284a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const std::vector<StringPair>& text_to_replace, 2294a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch std::string* replacement_path) { 2304a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch std::string new_file_path = original_file_path; 2314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch bool first_query_parameter = true; 2324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const std::vector<StringPair>::const_iterator end = text_to_replace.end(); 2334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch for (std::vector<StringPair>::const_iterator it = text_to_replace.begin(); 2344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch it != end; 2354a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch ++it) { 2364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const std::string& old_text = it->first; 2374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const std::string& new_text = it->second; 2384a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch std::string base64_old; 2394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch std::string base64_new; 2404a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (!base::Base64Encode(old_text, &base64_old)) 2414a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return false; 2424a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (!base::Base64Encode(new_text, &base64_new)) 2434a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return false; 2444a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (first_query_parameter) { 2454a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch new_file_path += "?"; 2464a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch first_query_parameter = false; 2474a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } else { 2484a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch new_file_path += "&"; 2494a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 2504a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch new_file_path += "replace_text="; 2514a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch new_file_path += base64_old; 2524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch new_file_path += ":"; 2534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch new_file_path += base64_new; 2544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 2554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 2564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch *replacement_path = new_file_path; 2574a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return true; 2584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 2594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 26072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid TestServer::Init(const FilePath& document_root) { 26172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // At this point, the port that the testserver will listen on is unknown. 26272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // The testserver will listen on an ephemeral port, and write the port 26372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // number out over a pipe that this TestServer object will read from. Once 26472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // that is complete, the host_port_pair_ will contain the actual port. 26572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen host_port_pair_ = HostPortPair(GetHostname(type_, https_options_), 0); 26672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen process_handle_ = base::kNullProcessHandle; 26772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 26872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen FilePath src_dir; 26972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen PathService::Get(base::DIR_SOURCE_ROOT, &src_dir); 27072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 27172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen document_root_ = src_dir.Append(document_root); 27272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 27372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen certificates_dir_ = src_dir.Append(FILE_PATH_LITERAL("net")) 27472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen .Append(FILE_PATH_LITERAL("data")) 27572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen .Append(FILE_PATH_LITERAL("ssl")) 27672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen .Append(FILE_PATH_LITERAL("certificates")); 27772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 27872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 2793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool TestServer::SetPythonPath() { 2803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FilePath third_party_dir; 2813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!PathService::Get(base::DIR_SOURCE_ROOT, &third_party_dir)) { 2823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOG(ERROR) << "Failed to get DIR_SOURCE_ROOT"; 2833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; 2843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick third_party_dir = third_party_dir.Append(FILE_PATH_LITERAL("third_party")); 2863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 287201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // For simplejson. (simplejson, unlike all the other python modules 288201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // we include, doesn't have an extra 'simplejson' directory, so we 289201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // need to include its parent directory, i.e. third_party_dir). 290201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch AppendToPythonPath(third_party_dir); 291201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AppendToPythonPath(third_party_dir.Append(FILE_PATH_LITERAL("tlslite"))); 2933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AppendToPythonPath(third_party_dir.Append(FILE_PATH_LITERAL("pyftpdlib"))); 2943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Locate the Python code generated by the protocol buffers compiler. 2964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch FilePath pyproto_code_dir; 2974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (!GetPyProtoPath(&pyproto_code_dir)) { 29872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LOG(WARNING) << "Cannot find pyproto dir for generated code. " 29972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen << "Testserver features that rely on it will not work"; 30072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 3013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 302731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 3034a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch AppendToPythonPath(pyproto_code_dir); 3044a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch AppendToPythonPath(pyproto_code_dir.Append(FILE_PATH_LITERAL("sync_pb"))); 3054a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch AppendToPythonPath(pyproto_code_dir.Append( 3064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch FILE_PATH_LITERAL("device_management_pb"))); 3073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return true; 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 31172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool TestServer::ParseServerData(const std::string& server_data) { 31272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen VLOG(1) << "Server data: " << server_data; 31372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::JSONReader json_reader; 31472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<Value> value(json_reader.JsonToValue(server_data, true, false)); 31572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!value.get() || 31672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen !value->IsType(Value::TYPE_DICTIONARY)) { 31772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LOG(ERROR) << "Could not parse server data: " 31872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen << json_reader.GetErrorMessage(); 31972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 32072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 32172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen server_data_.reset(static_cast<DictionaryValue*>(value.release())); 32272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int port = 0; 32372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!server_data_->GetInteger("port", &port)) { 32472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LOG(ERROR) << "Could not find port value"; 32572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 32672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 32772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if ((port <= 0) || (port > kuint16max)) { 32872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LOG(ERROR) << "Invalid port value: " << port; 32972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 33072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 33172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen host_port_pair_.set_port(port); 33272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 33372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 33472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 33572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenFilePath TestServer::GetRootCertificatePath() const { 3363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return certificates_dir_.AppendASCII("root_ca_cert.crt"); 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool TestServer::LoadTestRootCert() { 34021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen TestRootCerts* root_certs = TestRootCerts::GetInstance(); 34121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return root_certs->AddFromFile(GetRootCertificatePath()); 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 344513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool TestServer::AddCommandLineArguments(CommandLine* command_line) const { 345513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch command_line->AppendSwitchASCII("port", 346513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::IntToString(host_port_pair_.port())); 347513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch command_line->AppendSwitchPath("data-dir", document_root_); 34872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 34972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (logging::GetMinLogLevel() == logging::LOG_VERBOSE) { 35072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen command_line->AppendArg("--log-to-console"); 35172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 352513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 353513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (type_ == TYPE_FTP) { 354513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch command_line->AppendArg("-f"); 3554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } else if (type_ == TYPE_SYNC) { 3564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch command_line->AppendArg("--sync"); 357513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } else if (type_ == TYPE_HTTPS) { 358513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch FilePath certificate_path(certificates_dir_); 359513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch certificate_path = certificate_path.Append( 360513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch https_options_.GetCertificateFile()); 361513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!file_util::PathExists(certificate_path)) { 362513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LOG(ERROR) << "Certificate path " << certificate_path.value() 363513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << " doesn't exist. Can't launch https server."; 364513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 365513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 366513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch command_line->AppendSwitchPath("https", certificate_path); 367513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 368513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (https_options_.request_client_certificate) 369513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch command_line->AppendSwitch("ssl-client-auth"); 370513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 371513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (std::vector<FilePath>::const_iterator it = 372513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch https_options_.client_authorities.begin(); 373513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch it != https_options_.client_authorities.end(); ++it) { 374513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!file_util::PathExists(*it)) { 375513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch LOG(ERROR) << "Client authority path " << it->value() 376513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << " doesn't exist. Can't launch https server."; 377513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 378513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 379513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 380513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch command_line->AppendSwitchPath("ssl-client-ca", *it); 381513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 382513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 383513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const char kBulkCipherSwitch[] = "ssl-bulk-cipher"; 384513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (https_options_.bulk_ciphers & HTTPSOptions::BULK_CIPHER_RC4) 385513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch command_line->AppendSwitchASCII(kBulkCipherSwitch, "rc4"); 386513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (https_options_.bulk_ciphers & HTTPSOptions::BULK_CIPHER_AES128) 387513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch command_line->AppendSwitchASCII(kBulkCipherSwitch, "aes128"); 388513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (https_options_.bulk_ciphers & HTTPSOptions::BULK_CIPHER_AES256) 389513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch command_line->AppendSwitchASCII(kBulkCipherSwitch, "aes256"); 390513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (https_options_.bulk_ciphers & HTTPSOptions::BULK_CIPHER_3DES) 391513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch command_line->AppendSwitchASCII(kBulkCipherSwitch, "3des"); 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 393513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 394513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return true; 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace net 398