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