• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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