| OLD | NEW | 
|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #ifndef NET_TEST_EMBEDDED_TEST_SERVER_EMBEDDED_TEST_SERVER_H_ | 5 #ifndef NET_TEST_EMBEDDED_TEST_SERVER_EMBEDDED_TEST_SERVER_H_ | 
| 6 #define NET_TEST_EMBEDDED_TEST_SERVER_EMBEDDED_TEST_SERVER_H_ | 6 #define NET_TEST_EMBEDDED_TEST_SERVER_EMBEDDED_TEST_SERVER_H_ | 
| 7 | 7 | 
| 8 #include <map> | 8 #include <map> | 
| 9 #include <string> | 9 #include <string> | 
| 10 #include <vector> | 10 #include <vector> | 
| 11 | 11 | 
| 12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" | 
| 13 #include "base/callback.h" | 13 #include "base/callback.h" | 
| 14 #include "base/compiler_specific.h" | 14 #include "base/compiler_specific.h" | 
| 15 #include "base/files/file_path.h" |  | 
| 16 #include "base/memory/ref_counted.h" | 15 #include "base/memory/ref_counted.h" | 
| 17 #include "base/memory/scoped_ptr.h" | 16 #include "base/memory/scoped_ptr.h" | 
| 18 #include "base/threading/thread.h" | 17 #include "base/threading/thread.h" | 
| 19 #include "base/threading/thread_checker.h" | 18 #include "base/threading/thread_checker.h" | 
| 20 #include "crypto/rsa_private_key.h" |  | 
| 21 #include "net/base/address_list.h" | 19 #include "net/base/address_list.h" | 
| 22 #include "net/base/host_port_pair.h" |  | 
| 23 #include "net/base/ip_endpoint.h" | 20 #include "net/base/ip_endpoint.h" | 
| 24 #include "net/cert/x509_certificate.h" |  | 
| 25 #include "net/socket/stream_socket.h" |  | 
| 26 #include "net/socket/tcp_server_socket.h" |  | 
| 27 #include "net/ssl/ssl_server_config.h" |  | 
| 28 #include "url/gurl.h" | 21 #include "url/gurl.h" | 
| 29 | 22 | 
|  | 23 namespace base { | 
|  | 24 class FilePath; | 
|  | 25 } | 
|  | 26 | 
| 30 namespace net { | 27 namespace net { | 
| 31 | 28 | 
| 32 class StreamSocket; | 29 class StreamSocket; | 
| 33 class TCPServerSocket; | 30 class TCPServerSocket; | 
| 34 | 31 | 
| 35 namespace test_server { | 32 namespace test_server { | 
| 36 | 33 | 
| 37 class EmbeddedTestServerConnectionListener; | 34 class EmbeddedTestServerConnectionListener; | 
| 38 class HttpConnection; | 35 class HttpConnection; | 
| 39 class HttpResponse; | 36 class HttpResponse; | 
| 40 struct HttpRequest; | 37 struct HttpRequest; | 
| 41 | 38 | 
| 42 // Class providing an HTTP server for testing purpose. This is a basic server | 39 // Class providing an HTTP server for testing purpose. This is a basic server | 
| 43 // providing only an essential subset of HTTP/1.1 protocol. Especially, | 40 // providing only an essential subset of HTTP/1.1 protocol. Especially, | 
| 44 // it assumes that the request syntax is correct. It *does not* support | 41 // it assumes that the request syntax is correct. It *does not* support | 
| 45 // a Chunked Transfer Encoding. | 42 // a Chunked Transfer Encoding. | 
| 46 // | 43 // | 
| 47 // The common use case for unit tests is below: | 44 // The common use case for unit tests is below: | 
| 48 // | 45 // | 
| 49 // void SetUp() { | 46 // void SetUp() { | 
| 50 //   test_server_.reset(new EmbeddedTestServer()); | 47 //   test_server_.reset(new EmbeddedTestServer()); | 
| 51 //   ASSERT_TRUE(test_server_.Start()); | 48 //   ASSERT_TRUE(test_server_.InitializeAndWaitUntilReady()); | 
| 52 //   test_server_->RegisterRequestHandler( | 49 //   test_server_->RegisterRequestHandler( | 
| 53 //       base::Bind(&FooTest::HandleRequest, base::Unretained(this))); | 50 //       base::Bind(&FooTest::HandleRequest, base::Unretained(this))); | 
| 54 // } | 51 // } | 
| 55 // | 52 // | 
| 56 // scoped_ptr<HttpResponse> HandleRequest(const HttpRequest& request) { | 53 // scoped_ptr<HttpResponse> HandleRequest(const HttpRequest& request) { | 
| 57 //   GURL absolute_url = test_server_->GetURL(request.relative_url); | 54 //   GURL absolute_url = test_server_->GetURL(request.relative_url); | 
| 58 //   if (absolute_url.path() != "/test") | 55 //   if (absolute_url.path() != "/test") | 
| 59 //     return scoped_ptr<HttpResponse>(); | 56 //     return scoped_ptr<HttpResponse>(); | 
| 60 // | 57 // | 
| 61 //   scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse()); | 58 //   scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse()); | 
| 62 //   http_response->set_code(test_server::SUCCESS); | 59 //   http_response->set_code(test_server::SUCCESS); | 
| 63 //   http_response->set_content("hello"); | 60 //   http_response->set_content("hello"); | 
| 64 //   http_response->set_content_type("text/plain"); | 61 //   http_response->set_content_type("text/plain"); | 
| 65 //   return http_response.Pass(); | 62 //   return http_response.Pass(); | 
| 66 // } | 63 // } | 
| 67 // | 64 // | 
| 68 // For a test that spawns another process such as browser_tests, it is | 65 // For a test that spawns another process such as browser_tests, it is | 
| 69 // suggested to call Start in SetUpOnMainThread after the process is spawned. | 66 // suggested to call InitializeAndWaitUntilReady in SetUpOnMainThread after | 
| 70 //  If you have to do it before the process spawns, you need to first setup the | 67 // the process is spawned. If you have to do it before the process spawns, | 
| 71 // listen socket so that there is no no other threads running while spawning | 68 // you need to first setup the listen socket so that there is no no other | 
| 72 // the process. To do so, please follow the following example: | 69 // threads running while spawning the process. To do so, please follow | 
|  | 70 // the following example: | 
| 73 // | 71 // | 
| 74 // void SetUp() { | 72 // void SetUp() { | 
| 75 //   ASSERT_TRUE(embedded_test_server()->InitializeAndListen()); | 73 //   ASSERT_TRUE(embedded_test_server()->InitializeAndListen()); | 
| 76 //   ... | 74 //   ... | 
| 77 //   InProcessBrowserTest::SetUp(); | 75 //   InProcessBrowserTest::SetUp(); | 
| 78 // } | 76 // } | 
| 79 // | 77 // | 
| 80 // void SetUpOnMainThread() { | 78 // void SetUpOnMainThread() { | 
| 81 //   // Starts the accept IO thread. | 79 //   // Starts the accept IO thread. | 
| 82 //   embedded_test_server()->StartAcceptingConnections(); | 80 //   embedded_test_server()->StartAcceptingConnections(); | 
| 83 // } | 81 // } | 
| 84 // | 82 // | 
| 85 class EmbeddedTestServer { | 83 class EmbeddedTestServer { | 
| 86  public: | 84  public: | 
| 87   enum Type { |  | 
| 88     TYPE_HTTP, |  | 
| 89     TYPE_HTTPS, |  | 
| 90   }; |  | 
| 91 |  | 
| 92   enum ServerCertificate { |  | 
| 93     CERT_OK, |  | 
| 94 |  | 
| 95     CERT_MISMATCHED_NAME, |  | 
| 96     CERT_EXPIRED, |  | 
| 97 |  | 
| 98     // A certificate with invalid notBefore and notAfter times. Windows' |  | 
| 99     // certificate library will not parse this certificate. |  | 
| 100     CERT_BAD_VALIDITY, |  | 
| 101 |  | 
| 102     // Cross-signed certificate to test PKIX path building. Contains an |  | 
| 103     // intermediate cross-signed by an unknown root, while the client (via |  | 
| 104     // TestRootStore) is expected to have a self-signed version of the |  | 
| 105     // intermediate. |  | 
| 106     CERT_CHAIN_WRONG_ROOT, |  | 
| 107 |  | 
| 108     // Causes the testserver to use a hostname that is a domain |  | 
| 109     // instead of an IP. |  | 
| 110     CERT_COMMON_NAME_IS_DOMAIN, |  | 
| 111   }; |  | 
| 112 |  | 
| 113   typedef base::Callback<scoped_ptr<HttpResponse>( | 85   typedef base::Callback<scoped_ptr<HttpResponse>( | 
| 114       const HttpRequest& request)> HandleRequestCallback; | 86       const HttpRequest& request)> HandleRequestCallback; | 
| 115 | 87 | 
| 116   // Creates a http test server. Start() must be called to start the server. | 88   // Creates a http test server. InitializeAndWaitUntilReady() must be called | 
| 117   // |type| indicates the protocol type of the server (HTTP/HTTPS). | 89   // to start the server. | 
| 118   EmbeddedTestServer(); | 90   EmbeddedTestServer(); | 
| 119   explicit EmbeddedTestServer(Type type); |  | 
| 120   ~EmbeddedTestServer(); | 91   ~EmbeddedTestServer(); | 
| 121 | 92 | 
| 122   // Sets a connection listener, that would be notified when various connection | 93   // Sets a connection listener, that would be notified when various connection | 
| 123   // events happen. May only be called before the server is started. Caller | 94   // events happen. May only be called before the server is started. Caller | 
| 124   // maintains ownership of the listener. | 95   // maintains ownership of the listener. | 
| 125   void SetConnectionListener(EmbeddedTestServerConnectionListener* listener); | 96   void SetConnectionListener(EmbeddedTestServerConnectionListener* listener); | 
| 126 | 97 | 
| 127   // Initializes and waits until the server is ready to accept requests. | 98   // Initializes and waits until the server is ready to accept requests. | 
| 128   // This is the equivalent of calling InitializeAndListen() followed by | 99   // This is the equivalent of calling InitializeAndListen() followed by | 
| 129   // StartAcceptingConnections(). | 100   // StartAcceptingConnections(). | 
| 130   // Returns whether a listening socket has been successfully created. | 101   // Returns whether a listening socket has been succesfully created. | 
| 131   bool Start(); |  | 
| 132 |  | 
| 133   // Deprecated method that calls Start(). |  | 
| 134   // TODO(svaldez): Remove and replace with Start(). |  | 
| 135   bool InitializeAndWaitUntilReady() WARN_UNUSED_RESULT; | 102   bool InitializeAndWaitUntilReady() WARN_UNUSED_RESULT; | 
| 136 | 103 | 
| 137   // Starts listening for incoming connections but will not yet accept them. | 104   // Starts listening for incoming connections but will not yet accept them. | 
| 138   // Returns whether a listening socket has been succesfully created. | 105   // Returns whether a listening socket has been succesfully created. | 
| 139   bool InitializeAndListen() WARN_UNUSED_RESULT; | 106   bool InitializeAndListen() WARN_UNUSED_RESULT; | 
| 140 | 107 | 
| 141   // Starts the Accept IO Thread and begins accepting connections. | 108   // Starts the Accept IO Thread and begins accepting connections. | 
| 142   void StartAcceptingConnections(); | 109   void StartAcceptingConnections(); | 
| 143 | 110 | 
| 144   // Shuts down the http server and waits until the shutdown is complete. | 111   // Shuts down the http server and waits until the shutdown is complete. | 
| 145   bool ShutdownAndWaitUntilComplete() WARN_UNUSED_RESULT; | 112   bool ShutdownAndWaitUntilComplete() WARN_UNUSED_RESULT; | 
| 146 | 113 | 
| 147   // Checks if the server has started listening for incoming connections. | 114   // Checks if the server has started listening for incoming connections. | 
| 148   bool Started() const { | 115   bool Started() const { | 
| 149     return listen_socket_.get() != NULL; | 116     return listen_socket_.get() != NULL; | 
| 150   } | 117   } | 
| 151 | 118 | 
| 152   HostPortPair host_port_pair() const { |  | 
| 153     return HostPortPair::FromURL(base_url_); |  | 
| 154   } |  | 
| 155 |  | 
| 156   // Returns the base URL to the server, which looks like | 119   // Returns the base URL to the server, which looks like | 
| 157   // http://127.0.0.1:<port>/, where <port> is the actual port number used by | 120   // http://127.0.0.1:<port>/, where <port> is the actual port number used by | 
| 158   // the server. | 121   // the server. | 
| 159   const GURL& base_url() const { return base_url_; } | 122   const GURL& base_url() const { return base_url_; } | 
| 160 | 123 | 
| 161   // Returns a URL to the server based on the given relative URL, which | 124   // Returns a URL to the server based on the given relative URL, which | 
| 162   // should start with '/'. For example: GetURL("/path?query=foo") => | 125   // should start with '/'. For example: GetURL("/path?query=foo") => | 
| 163   // http://127.0.0.1:<port>/path?query=foo. | 126   // http://127.0.0.1:<port>/path?query=foo. | 
| 164   GURL GetURL(const std::string& relative_url) const; | 127   GURL GetURL(const std::string& relative_url) const; | 
| 165 | 128 | 
| 166   // Similar to the above method with the difference that it uses the supplied | 129   // Similar to the above method with the difference that it uses the supplied | 
| 167   // |hostname| for the URL instead of 127.0.0.1. The hostname should be | 130   // |hostname| for the URL instead of 127.0.0.1. The hostname should be | 
| 168   // resolved to 127.0.0.1. | 131   // resolved to 127.0.0.1. | 
| 169   GURL GetURL(const std::string& hostname, | 132   GURL GetURL(const std::string& hostname, | 
| 170               const std::string& relative_url) const; | 133               const std::string& relative_url) const; | 
| 171 | 134 | 
| 172   // Returns the address list needed to connect to the server. | 135   // Returns the address list needed to connect to the server. | 
| 173   bool GetAddressList(AddressList* address_list) const WARN_UNUSED_RESULT; | 136   bool GetAddressList(net::AddressList* address_list) const WARN_UNUSED_RESULT; | 
| 174 | 137 | 
| 175   // Returns the port number used by the server. | 138   // Returns the port number used by the server. | 
| 176   uint16 port() const { return port_; } | 139   uint16 port() const { return port_; } | 
| 177 | 140 | 
| 178   void SetSSLConfig(ServerCertificate cert, const SSLServerConfig& ssl_config); |  | 
| 179   void SetSSLConfig(ServerCertificate cert); |  | 
| 180 |  | 
| 181   // Returns the file name of the certificate the server is using. The test |  | 
| 182   // certificates can be found in net/data/ssl/certificates/. |  | 
| 183   std::string GetCertificateName() const; |  | 
| 184 |  | 
| 185   // Returns the certificate that the server is using. |  | 
| 186   scoped_refptr<X509Certificate> GetCertificate() const; |  | 
| 187 |  | 
| 188   // Registers request handler which serves files from |directory|. | 141   // Registers request handler which serves files from |directory|. | 
| 189   // For instance, a request to "/foo.html" is served by "foo.html" under | 142   // For instance, a request to "/foo.html" is served by "foo.html" under | 
| 190   // |directory|. Files under sub directories are also handled in the same way | 143   // |directory|. Files under sub directories are also handled in the same way | 
| 191   // (i.e. "/foo/bar.html" is served by "foo/bar.html" under |directory|). | 144   // (i.e. "/foo/bar.html" is served by "foo/bar.html" under |directory|). | 
| 192   // TODO(svaldez): Merge ServeFilesFromDirectory and |  | 
| 193   // ServeFilesFromSourceDirectory. |  | 
| 194   void ServeFilesFromDirectory(const base::FilePath& directory); | 145   void ServeFilesFromDirectory(const base::FilePath& directory); | 
| 195 | 146 | 
| 196   // Serves files relative to DIR_SOURCE_ROOT. |  | 
| 197   void ServeFilesFromSourceDirectory(const std::string& relative); |  | 
| 198   void ServeFilesFromSourceDirectory(const base::FilePath& relative); |  | 
| 199 |  | 
| 200   // Registers the default handlers and serve additional files from the |  | 
| 201   // |directory| directory, relative to DIR_SOURCE_ROOT. |  | 
| 202   void AddDefaultHandlers(const base::FilePath& directory); |  | 
| 203 |  | 
| 204   // The most general purpose method. Any request processing can be added using | 147   // The most general purpose method. Any request processing can be added using | 
| 205   // this method. Takes ownership of the object. The |callback| is called | 148   // this method. Takes ownership of the object. The |callback| is called | 
| 206   // on UI thread. | 149   // on UI thread. | 
| 207   void RegisterRequestHandler(const HandleRequestCallback& callback); | 150   void RegisterRequestHandler(const HandleRequestCallback& callback); | 
| 208 | 151 | 
| 209   // Adds default handlers, including those added by AddDefaultHandlers, to be |  | 
| 210   // tried after all other user-specified handlers have been tried. |  | 
| 211   void RegisterDefaultHandler(const HandleRequestCallback& callback); |  | 
| 212 |  | 
| 213  private: | 152  private: | 
| 214   // Shuts down the server. | 153   // Shuts down the server. | 
| 215   void ShutdownOnIOThread(); | 154   void ShutdownOnIOThread(); | 
| 216 | 155 | 
| 217   // Upgrade the TCP connection to one over SSL. |  | 
| 218   scoped_ptr<StreamSocket> DoSSLUpgrade(scoped_ptr<StreamSocket> connection); |  | 
| 219   // Handles async callback when the SSL handshake has been completed. |  | 
| 220   void OnHandshakeDone(HttpConnection* connection, int rv); |  | 
| 221 |  | 
| 222   // Begins accepting new client connections. | 156   // Begins accepting new client connections. | 
| 223   void DoAcceptLoop(); | 157   void DoAcceptLoop(); | 
| 224   // Handles async callback when there is a new client socket. |rv| is the | 158   // Handles async callback when there is a new client socket. |rv| is the | 
| 225   // return value of the socket Accept. | 159   // return value of the socket Accept. | 
| 226   void OnAcceptCompleted(int rv); | 160   void OnAcceptCompleted(int rv); | 
| 227   // Adds the new |socket| to the list of clients and begins the reading | 161   // Adds the new |socket| to the list of clients and begins the reading | 
| 228   // data. | 162   // data. | 
| 229   void HandleAcceptResult(scoped_ptr<StreamSocket> socket); | 163   void HandleAcceptResult(scoped_ptr<StreamSocket> socket); | 
| 230 | 164 | 
| 231   // Attempts to read data from the |connection|'s socket. | 165   // Attempts to read data from the |connection|'s socket. | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 243   // request handlers and sends a http response. | 177   // request handlers and sends a http response. | 
| 244   void HandleRequest(HttpConnection* connection, | 178   void HandleRequest(HttpConnection* connection, | 
| 245                      scoped_ptr<HttpRequest> request); | 179                      scoped_ptr<HttpRequest> request); | 
| 246 | 180 | 
| 247   HttpConnection* FindConnection(StreamSocket* socket); | 181   HttpConnection* FindConnection(StreamSocket* socket); | 
| 248 | 182 | 
| 249   // Posts a task to the |io_thread_| and waits for a reply. | 183   // Posts a task to the |io_thread_| and waits for a reply. | 
| 250   bool PostTaskToIOThreadAndWait( | 184   bool PostTaskToIOThreadAndWait( | 
| 251       const base::Closure& closure) WARN_UNUSED_RESULT; | 185       const base::Closure& closure) WARN_UNUSED_RESULT; | 
| 252 | 186 | 
| 253   const bool is_using_ssl_; |  | 
| 254 |  | 
| 255   scoped_ptr<base::Thread> io_thread_; | 187   scoped_ptr<base::Thread> io_thread_; | 
| 256 | 188 | 
| 257   scoped_ptr<TCPServerSocket> listen_socket_; | 189   scoped_ptr<TCPServerSocket> listen_socket_; | 
| 258   scoped_ptr<StreamSocket> accepted_socket_; | 190   scoped_ptr<StreamSocket> accepted_socket_; | 
| 259 | 191 | 
| 260   EmbeddedTestServerConnectionListener* connection_listener_; | 192   EmbeddedTestServerConnectionListener* connection_listener_; | 
| 261   uint16 port_; | 193   uint16 port_; | 
| 262   GURL base_url_; | 194   GURL base_url_; | 
| 263   IPEndPoint local_endpoint_; | 195   IPEndPoint local_endpoint_; | 
| 264 | 196 | 
| 265   // Owns the HttpConnection objects. | 197   // Owns the HttpConnection objects. | 
| 266   std::map<StreamSocket*, HttpConnection*> connections_; | 198   std::map<StreamSocket*, HttpConnection*> connections_; | 
| 267 | 199 | 
| 268   // Vector of registered and default request handlers. | 200   // Vector of registered request handlers. | 
| 269   std::vector<HandleRequestCallback> request_handlers_; | 201   std::vector<HandleRequestCallback> request_handlers_; | 
| 270   std::vector<HandleRequestCallback> default_request_handlers_; |  | 
| 271 | 202 | 
| 272   base::ThreadChecker thread_checker_; | 203   base::ThreadChecker thread_checker_; | 
| 273 | 204 | 
| 274   net::SSLServerConfig ssl_config_; |  | 
| 275   ServerCertificate cert_; |  | 
| 276 |  | 
| 277   DISALLOW_COPY_AND_ASSIGN(EmbeddedTestServer); | 205   DISALLOW_COPY_AND_ASSIGN(EmbeddedTestServer); | 
| 278 }; | 206 }; | 
| 279 | 207 | 
| 280 }  // namespace test_server | 208 }  // namespace test_server | 
| 281 |  | 
| 282 // TODO(svaldez): Refactor EmbeddedTestServer to be in the net namespace. |  | 
| 283 using test_server::EmbeddedTestServer; |  | 
| 284 |  | 
| 285 }  // namespace net | 209 }  // namespace net | 
| 286 | 210 | 
| 287 #endif  // NET_TEST_EMBEDDED_TEST_SERVER_EMBEDDED_TEST_SERVER_H_ | 211 #endif  // NET_TEST_EMBEDDED_TEST_SERVER_EMBEDDED_TEST_SERVER_H_ | 
| OLD | NEW | 
|---|