1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_TEST_TEST_SERVER_H_ 6 #define NET_TEST_TEST_SERVER_H_ 7 #pragma once 8 9 #include <string> 10 #include <utility> 11 #include <vector> 12 13 #include "build/build_config.h" 14 15 #include "base/compiler_specific.h" 16 #include "base/file_path.h" 17 #include "base/file_util.h" 18 #include "base/process_util.h" 19 #include "net/base/host_port_pair.h" 20 #include "net/base/net_util.h" 21 22 #if defined(OS_WIN) 23 #include "base/win/scoped_handle.h" 24 #endif 25 26 class CommandLine; 27 class DictionaryValue; 28 class GURL; 29 30 namespace net { 31 32 class AddressList; 33 34 // This object bounds the lifetime of an external python-based HTTP/FTP server 35 // that can provide various responses useful for testing. 36 class TestServer { 37 public: 38 typedef std::pair<std::string, std::string> StringPair; 39 40 enum Type { 41 TYPE_FTP, 42 TYPE_HTTP, 43 TYPE_HTTPS, 44 TYPE_SYNC, 45 }; 46 47 // Container for various options to control how the HTTPS server is 48 // initialized. 49 struct HTTPSOptions { 50 enum ServerCertificate { 51 CERT_OK, 52 CERT_MISMATCHED_NAME, 53 CERT_EXPIRED, 54 }; 55 56 // Bitmask of bulk encryption algorithms that the test server supports 57 // and that can be selectively enabled or disabled. 58 enum BulkCipher { 59 // Special value used to indicate that any algorithm the server supports 60 // is acceptable. Preferred over explicitly OR-ing all ciphers. 61 BULK_CIPHER_ANY = 0, 62 63 BULK_CIPHER_RC4 = (1 << 0), 64 BULK_CIPHER_AES128 = (1 << 1), 65 BULK_CIPHER_AES256 = (1 << 2), 66 67 // NOTE: 3DES support in the Python test server has external 68 // dependencies and not be available on all machines. Clients may not 69 // be able to connect if only 3DES is specified. 70 BULK_CIPHER_3DES = (1 << 3), 71 }; 72 73 // Initialize a new HTTPSOptions using CERT_OK as the certificate. 74 HTTPSOptions(); 75 76 // Initialize a new HTTPSOptions that will use the specified certificate. 77 explicit HTTPSOptions(ServerCertificate cert); 78 ~HTTPSOptions(); 79 80 // Returns the relative filename of the file that contains the 81 // |server_certificate|. 82 FilePath GetCertificateFile() const; 83 84 // The certificate to use when serving requests. 85 ServerCertificate server_certificate; 86 87 // True if a CertificateRequest should be sent to the client during 88 // handshaking. 89 bool request_client_certificate; 90 91 // If |request_client_certificate| is true, an optional list of files, 92 // each containing a single, PEM-encoded X.509 certificates. The subject 93 // from each certificate will be added to the certificate_authorities 94 // field of the CertificateRequest. 95 std::vector<FilePath> client_authorities; 96 97 // A bitwise-OR of BulkCipher that should be used by the 98 // HTTPS server, or BULK_CIPHER_ANY to indicate that all implemented 99 // ciphers are acceptable. 100 int bulk_ciphers; 101 }; 102 103 TestServer(Type type, const FilePath& document_root); 104 105 // Initialize a HTTPS TestServer with a specific set of HTTPSOptions. 106 TestServer(const HTTPSOptions& https_options, 107 const FilePath& document_root); 108 109 ~TestServer(); 110 111 bool Start() WARN_UNUSED_RESULT; 112 113 // Stop the server started by Start(). 114 bool Stop(); 115 document_root()116 const FilePath& document_root() const { return document_root_; } 117 const HostPortPair& host_port_pair() const; 118 const DictionaryValue& server_data() const; 119 std::string GetScheme() const; 120 bool GetAddressList(AddressList* address_list) const WARN_UNUSED_RESULT; 121 122 GURL GetURL(const std::string& path) const; 123 124 GURL GetURLWithUser(const std::string& path, 125 const std::string& user) const; 126 127 GURL GetURLWithUserAndPassword(const std::string& path, 128 const std::string& user, 129 const std::string& password) const; 130 131 static bool GetFilePathWithReplacements( 132 const std::string& original_path, 133 const std::vector<StringPair>& text_to_replace, 134 std::string* replacement_path); 135 136 private: 137 void Init(const FilePath& document_root); 138 139 // Modify PYTHONPATH to contain libraries we need. 140 bool SetPythonPath() WARN_UNUSED_RESULT; 141 142 // Launches the Python test server. Returns true on success. 143 bool LaunchPython(const FilePath& testserver_path) WARN_UNUSED_RESULT; 144 145 // Waits for the server to start. Returns true on success. 146 bool WaitToStart() WARN_UNUSED_RESULT; 147 148 // Parses the server data read from the test server. Returns true 149 // on success. 150 bool ParseServerData(const std::string& server_data) WARN_UNUSED_RESULT; 151 152 // Returns path to the root certificate. 153 FilePath GetRootCertificatePath() const; 154 155 // Load the test root cert, if it hasn't been loaded yet. 156 bool LoadTestRootCert() WARN_UNUSED_RESULT; 157 158 // Add the command line arguments for the Python test server to 159 // |command_line|. Return true on success. 160 bool AddCommandLineArguments(CommandLine* command_line) const; 161 162 // Document root of the test server. 163 FilePath document_root_; 164 165 // Directory that contains the SSL certificates. 166 FilePath certificates_dir_; 167 168 // Address the test server listens on. 169 HostPortPair host_port_pair_; 170 171 // Holds the data sent from the server (e.g., port number). 172 scoped_ptr<DictionaryValue> server_data_; 173 174 // Handle of the Python process running the test server. 175 base::ProcessHandle process_handle_; 176 177 scoped_ptr<net::ScopedPortException> allowed_port_; 178 179 #if defined(OS_WIN) 180 // JobObject used to clean up orphaned child processes. 181 base::win::ScopedHandle job_handle_; 182 183 // The pipe file handle we read from. 184 base::win::ScopedHandle child_read_fd_; 185 186 // The pipe file handle the child and we write to. 187 base::win::ScopedHandle child_write_fd_; 188 #endif 189 190 #if defined(OS_POSIX) 191 // The file descriptor the child writes to when it starts. 192 int child_fd_; 193 file_util::ScopedFD child_fd_closer_; 194 #endif 195 196 // If |type_| is TYPE_HTTPS, the TLS settings to use for the test server. 197 HTTPSOptions https_options_; 198 199 Type type_; 200 201 // Has the server been started? 202 bool started_; 203 204 DISALLOW_COPY_AND_ASSIGN(TestServer); 205 }; 206 207 } // namespace net 208 209 #endif // NET_TEST_TEST_SERVER_H_ 210