Home | History | Annotate | Download | only in test
      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 
    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