| 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 #include "net/test/embedded_test_server/embedded_test_server.h" | 5 #include "net/test/embedded_test_server/embedded_test_server.h" | 
| 6 | 6 | 
| 7 #include "base/bind.h" | 7 #include "base/bind.h" | 
| 8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" | 
| 9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" | 
| 10 #include "base/location.h" | 10 #include "base/location.h" | 
| 11 #include "base/logging.h" | 11 #include "base/logging.h" | 
| 12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" | 
| 13 #include "base/path_service.h" |  | 
| 14 #include "base/process/process_metrics.h" | 13 #include "base/process/process_metrics.h" | 
| 15 #include "base/run_loop.h" | 14 #include "base/run_loop.h" | 
| 16 #include "base/stl_util.h" | 15 #include "base/stl_util.h" | 
| 17 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" | 
| 18 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" | 
| 19 #include "base/thread_task_runner_handle.h" | 18 #include "base/thread_task_runner_handle.h" | 
| 20 #include "base/threading/thread_restrictions.h" | 19 #include "base/threading/thread_restrictions.h" | 
| 21 #include "crypto/rsa_private_key.h" |  | 
| 22 #include "net/base/ip_endpoint.h" | 20 #include "net/base/ip_endpoint.h" | 
| 23 #include "net/base/net_errors.h" | 21 #include "net/base/net_errors.h" | 
| 24 #include "net/base/test_data_directory.h" |  | 
| 25 #include "net/cert/pem_tokenizer.h" |  | 
| 26 #include "net/cert/test_root_certs.h" |  | 
| 27 #include "net/socket/ssl_server_socket.h" |  | 
| 28 #include "net/socket/stream_socket.h" | 22 #include "net/socket/stream_socket.h" | 
| 29 #include "net/socket/tcp_server_socket.h" | 23 #include "net/socket/tcp_server_socket.h" | 
| 30 #include "net/ssl/ssl_server_config.h" |  | 
| 31 #include "net/test/cert_test_util.h" |  | 
| 32 #include "net/test/embedded_test_server/embedded_test_server_connection_listener
     .h" | 24 #include "net/test/embedded_test_server/embedded_test_server_connection_listener
     .h" | 
| 33 #include "net/test/embedded_test_server/http_connection.h" | 25 #include "net/test/embedded_test_server/http_connection.h" | 
| 34 #include "net/test/embedded_test_server/http_request.h" | 26 #include "net/test/embedded_test_server/http_request.h" | 
| 35 #include "net/test/embedded_test_server/http_response.h" | 27 #include "net/test/embedded_test_server/http_response.h" | 
| 36 #include "net/test/embedded_test_server/request_handler_util.h" |  | 
| 37 | 28 | 
| 38 namespace net { | 29 namespace net { | 
| 39 namespace test_server { | 30 namespace test_server { | 
| 40 | 31 | 
| 41 EmbeddedTestServer::EmbeddedTestServer() : EmbeddedTestServer(TYPE_HTTP) {} | 32 namespace { | 
| 42 | 33 | 
| 43 EmbeddedTestServer::EmbeddedTestServer(Type type) | 34 class CustomHttpResponse : public HttpResponse { | 
| 44     : is_using_ssl_(type == TYPE_HTTPS), | 35  public: | 
| 45       connection_listener_(nullptr), | 36   CustomHttpResponse(const std::string& headers, const std::string& contents) | 
| 46       port_(0), | 37       : headers_(headers), contents_(contents) { | 
| 47       cert_(CERT_OK) { | 38   } | 
|  | 39 | 
|  | 40   std::string ToResponseString() const override { | 
|  | 41     return headers_ + "\r\n" + contents_; | 
|  | 42   } | 
|  | 43 | 
|  | 44  private: | 
|  | 45   std::string headers_; | 
|  | 46   std::string contents_; | 
|  | 47 | 
|  | 48   DISALLOW_COPY_AND_ASSIGN(CustomHttpResponse); | 
|  | 49 }; | 
|  | 50 | 
|  | 51 // Handles |request| by serving a file from under |server_root|. | 
|  | 52 scoped_ptr<HttpResponse> HandleFileRequest( | 
|  | 53     const base::FilePath& server_root, | 
|  | 54     const HttpRequest& request) { | 
|  | 55   // This is a test-only server. Ignore I/O thread restrictions. | 
|  | 56   base::ThreadRestrictions::ScopedAllowIO allow_io; | 
|  | 57 | 
|  | 58   std::string relative_url(request.relative_url); | 
|  | 59   // A proxy request will have an absolute path. Simulate the proxy by stripping | 
|  | 60   // the scheme, host, and port. | 
|  | 61   GURL relative_gurl(relative_url); | 
|  | 62   if (relative_gurl.is_valid()) | 
|  | 63     relative_url = relative_gurl.PathForRequest(); | 
|  | 64 | 
|  | 65   // Trim the first byte ('/'). | 
|  | 66   std::string request_path = relative_url.substr(1); | 
|  | 67 | 
|  | 68   // Remove the query string if present. | 
|  | 69   size_t query_pos = request_path.find('?'); | 
|  | 70   if (query_pos != std::string::npos) | 
|  | 71     request_path = request_path.substr(0, query_pos); | 
|  | 72 | 
|  | 73   base::FilePath file_path(server_root.AppendASCII(request_path)); | 
|  | 74   std::string file_contents; | 
|  | 75   if (!base::ReadFileToString(file_path, &file_contents)) | 
|  | 76     return scoped_ptr<HttpResponse>(); | 
|  | 77 | 
|  | 78   base::FilePath headers_path( | 
|  | 79       file_path.AddExtension(FILE_PATH_LITERAL("mock-http-headers"))); | 
|  | 80 | 
|  | 81   if (base::PathExists(headers_path)) { | 
|  | 82     std::string headers_contents; | 
|  | 83     if (!base::ReadFileToString(headers_path, &headers_contents)) | 
|  | 84       return scoped_ptr<HttpResponse>(); | 
|  | 85 | 
|  | 86     scoped_ptr<CustomHttpResponse> http_response( | 
|  | 87         new CustomHttpResponse(headers_contents, file_contents)); | 
|  | 88     return http_response.Pass(); | 
|  | 89   } | 
|  | 90 | 
|  | 91   scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); | 
|  | 92   http_response->set_code(HTTP_OK); | 
|  | 93   http_response->set_content(file_contents); | 
|  | 94   return http_response.Pass(); | 
|  | 95 } | 
|  | 96 | 
|  | 97 }  // namespace | 
|  | 98 | 
|  | 99 EmbeddedTestServer::EmbeddedTestServer() | 
|  | 100     : connection_listener_(nullptr), port_(0) { | 
| 48   DCHECK(thread_checker_.CalledOnValidThread()); | 101   DCHECK(thread_checker_.CalledOnValidThread()); | 
| 49 |  | 
| 50   if (is_using_ssl_) { |  | 
| 51     TestRootCerts* root_certs = TestRootCerts::GetInstance(); |  | 
| 52     base::FilePath certs_dir(GetTestCertsDirectory()); |  | 
| 53     root_certs->AddFromFile(certs_dir.AppendASCII("root_ca_cert.pem")); |  | 
| 54   } |  | 
| 55 } | 102 } | 
| 56 | 103 | 
| 57 EmbeddedTestServer::~EmbeddedTestServer() { | 104 EmbeddedTestServer::~EmbeddedTestServer() { | 
| 58   DCHECK(thread_checker_.CalledOnValidThread()); | 105   DCHECK(thread_checker_.CalledOnValidThread()); | 
| 59 | 106 | 
| 60   if (Started() && !ShutdownAndWaitUntilComplete()) { | 107   if (Started() && !ShutdownAndWaitUntilComplete()) { | 
| 61     LOG(ERROR) << "EmbeddedTestServer failed to shut down."; | 108     LOG(ERROR) << "EmbeddedTestServer failed to shut down."; | 
| 62   } | 109   } | 
| 63 } | 110 } | 
| 64 | 111 | 
| 65 void EmbeddedTestServer::SetConnectionListener( | 112 void EmbeddedTestServer::SetConnectionListener( | 
| 66     EmbeddedTestServerConnectionListener* listener) { | 113     EmbeddedTestServerConnectionListener* listener) { | 
| 67   DCHECK(!Started()); | 114   DCHECK(!Started()); | 
| 68   connection_listener_ = listener; | 115   connection_listener_ = listener; | 
| 69 } | 116 } | 
| 70 | 117 | 
| 71 bool EmbeddedTestServer::Start() { | 118 bool EmbeddedTestServer::InitializeAndWaitUntilReady() { | 
| 72   bool success = InitializeAndListen(); | 119   bool success = InitializeAndListen(); | 
| 73   if (!success) | 120   if (!success) | 
| 74     return false; | 121     return false; | 
| 75   StartAcceptingConnections(); | 122   StartAcceptingConnections(); | 
| 76   return true; | 123   return true; | 
| 77 } | 124 } | 
| 78 | 125 | 
| 79 bool EmbeddedTestServer::InitializeAndWaitUntilReady() { |  | 
| 80   return Start(); |  | 
| 81 } |  | 
| 82 |  | 
| 83 bool EmbeddedTestServer::InitializeAndListen() { | 126 bool EmbeddedTestServer::InitializeAndListen() { | 
| 84   DCHECK(!Started()); | 127   DCHECK(!Started()); | 
| 85 | 128 | 
| 86   listen_socket_.reset(new TCPServerSocket(nullptr, NetLog::Source())); | 129   listen_socket_.reset(new TCPServerSocket(nullptr, NetLog::Source())); | 
| 87 | 130 | 
| 88   int result = listen_socket_->ListenWithAddressAndPort("127.0.0.1", 0, 10); | 131   int result = listen_socket_->ListenWithAddressAndPort("127.0.0.1", 0, 10); | 
| 89   if (result) { | 132   if (result) { | 
| 90     LOG(ERROR) << "Listen failed: " << ErrorToString(result); | 133     LOG(ERROR) << "Listen failed: " << ErrorToString(result); | 
| 91     listen_socket_.reset(); | 134     listen_socket_.reset(); | 
| 92     return false; | 135     return false; | 
| 93   } | 136   } | 
| 94 | 137 | 
| 95   result = listen_socket_->GetLocalAddress(&local_endpoint_); | 138   result = listen_socket_->GetLocalAddress(&local_endpoint_); | 
| 96   if (result != OK) { | 139   if (result != OK) { | 
| 97     LOG(ERROR) << "GetLocalAddress failed: " << ErrorToString(result); | 140     LOG(ERROR) << "GetLocalAddress failed: " << ErrorToString(result); | 
| 98     listen_socket_.reset(); | 141     listen_socket_.reset(); | 
| 99     return false; | 142     return false; | 
| 100   } | 143   } | 
| 101 | 144 | 
| 102   if (is_using_ssl_) { | 145   base_url_ = GURL(std::string("http://") + local_endpoint_.ToString()); | 
| 103     base_url_ = GURL("https://" + local_endpoint_.ToString()); |  | 
| 104     if (cert_ == CERT_MISMATCHED_NAME || cert_ == CERT_COMMON_NAME_IS_DOMAIN) { |  | 
| 105       base_url_ = GURL( |  | 
| 106           base::StringPrintf("https://localhost:%d", local_endpoint_.port())); |  | 
| 107     } |  | 
| 108   } else { |  | 
| 109     base_url_ = GURL("http://" + local_endpoint_.ToString()); |  | 
| 110   } |  | 
| 111   port_ = local_endpoint_.port(); | 146   port_ = local_endpoint_.port(); | 
| 112 | 147 | 
| 113   listen_socket_->DetachFromThread(); | 148   listen_socket_->DetachFromThread(); | 
| 114   return true; | 149   return true; | 
| 115 } | 150 } | 
| 116 | 151 | 
| 117 void EmbeddedTestServer::StartAcceptingConnections() { | 152 void EmbeddedTestServer::StartAcceptingConnections() { | 
| 118   DCHECK(!io_thread_.get()); | 153   DCHECK(!io_thread_.get()); | 
| 119   base::Thread::Options thread_options; | 154   base::Thread::Options thread_options; | 
| 120   thread_options.message_loop_type = base::MessageLoop::TYPE_IO; | 155   thread_options.message_loop_type = base::MessageLoop::TYPE_IO; | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 141                                        connections_.end()); | 176                                        connections_.end()); | 
| 142   connections_.clear(); | 177   connections_.clear(); | 
| 143 } | 178 } | 
| 144 | 179 | 
| 145 void EmbeddedTestServer::HandleRequest(HttpConnection* connection, | 180 void EmbeddedTestServer::HandleRequest(HttpConnection* connection, | 
| 146                                        scoped_ptr<HttpRequest> request) { | 181                                        scoped_ptr<HttpRequest> request) { | 
| 147   DCHECK(io_thread_->task_runner()->BelongsToCurrentThread()); | 182   DCHECK(io_thread_->task_runner()->BelongsToCurrentThread()); | 
| 148 | 183 | 
| 149   scoped_ptr<HttpResponse> response; | 184   scoped_ptr<HttpResponse> response; | 
| 150 | 185 | 
| 151   for (const auto& handler : request_handlers_) { | 186   for (size_t i = 0; i < request_handlers_.size(); ++i) { | 
| 152     response = handler.Run(*request); | 187     response = request_handlers_[i].Run(*request); | 
| 153     if (response) | 188     if (response) | 
| 154       break; | 189       break; | 
| 155   } | 190   } | 
| 156 | 191 | 
| 157   if (!response) { | 192   if (!response) { | 
| 158     for (const auto& handler : default_request_handlers_) { |  | 
| 159       response = handler.Run(*request); |  | 
| 160       if (response) |  | 
| 161         break; |  | 
| 162     } |  | 
| 163   } |  | 
| 164 |  | 
| 165   if (!response) { |  | 
| 166     LOG(WARNING) << "Request not handled. Returning 404: " | 193     LOG(WARNING) << "Request not handled. Returning 404: " | 
| 167                  << request->relative_url; | 194                  << request->relative_url; | 
| 168     scoped_ptr<BasicHttpResponse> not_found_response(new BasicHttpResponse); | 195     scoped_ptr<BasicHttpResponse> not_found_response(new BasicHttpResponse); | 
| 169     not_found_response->set_code(HTTP_NOT_FOUND); | 196     not_found_response->set_code(HTTP_NOT_FOUND); | 
| 170     response = not_found_response.Pass(); | 197     response = not_found_response.Pass(); | 
| 171   } | 198   } | 
| 172 | 199 | 
| 173   response->SendResponse(base::Bind(&HttpConnection::SendResponseBytes, | 200   connection->SendResponse(response.Pass(), | 
| 174                                     base::Unretained(connection)), | 201                            base::Bind(&EmbeddedTestServer::DidClose, | 
| 175                          base::Bind(&EmbeddedTestServer::DidClose, | 202                                       base::Unretained(this), connection)); | 
| 176                                     base::Unretained(this), connection)); |  | 
| 177 } | 203 } | 
| 178 | 204 | 
| 179 GURL EmbeddedTestServer::GetURL(const std::string& relative_url) const { | 205 GURL EmbeddedTestServer::GetURL(const std::string& relative_url) const { | 
| 180   DCHECK(Started()) << "You must start the server first."; | 206   DCHECK(Started()) << "You must start the server first."; | 
| 181   DCHECK(base::StartsWith(relative_url, "/", base::CompareCase::SENSITIVE)) | 207   DCHECK(base::StartsWith(relative_url, "/", base::CompareCase::SENSITIVE)) | 
| 182       << relative_url; | 208       << relative_url; | 
| 183   return base_url_.Resolve(relative_url); | 209   return base_url_.Resolve(relative_url); | 
| 184 } | 210 } | 
| 185 | 211 | 
| 186 GURL EmbeddedTestServer::GetURL( | 212 GURL EmbeddedTestServer::GetURL( | 
| 187     const std::string& hostname, | 213     const std::string& hostname, | 
| 188     const std::string& relative_url) const { | 214     const std::string& relative_url) const { | 
| 189   GURL local_url = GetURL(relative_url); | 215   GURL local_url = GetURL(relative_url); | 
| 190   GURL::Replacements replace_host; | 216   GURL::Replacements replace_host; | 
| 191   replace_host.SetHostStr(hostname); | 217   replace_host.SetHostStr(hostname); | 
| 192   return local_url.ReplaceComponents(replace_host); | 218   return local_url.ReplaceComponents(replace_host); | 
| 193 } | 219 } | 
| 194 | 220 | 
| 195 bool EmbeddedTestServer::GetAddressList(AddressList* address_list) const { | 221 bool EmbeddedTestServer::GetAddressList(AddressList* address_list) const { | 
| 196   *address_list = AddressList(local_endpoint_); | 222   *address_list = AddressList(local_endpoint_); | 
| 197   return true; | 223   return true; | 
| 198 } | 224 } | 
| 199 | 225 | 
| 200 void EmbeddedTestServer::SetSSLConfig(ServerCertificate cert, |  | 
| 201                                       const SSLServerConfig& ssl_config) { |  | 
| 202   DCHECK(!Started()); |  | 
| 203   cert_ = cert; |  | 
| 204   ssl_config_ = ssl_config; |  | 
| 205 } |  | 
| 206 |  | 
| 207 void EmbeddedTestServer::SetSSLConfig(ServerCertificate cert) { |  | 
| 208   SetSSLConfig(cert, SSLServerConfig()); |  | 
| 209 } |  | 
| 210 |  | 
| 211 std::string EmbeddedTestServer::GetCertificateName() const { |  | 
| 212   DCHECK(is_using_ssl_); |  | 
| 213   switch (cert_) { |  | 
| 214     case CERT_OK: |  | 
| 215     case CERT_MISMATCHED_NAME: |  | 
| 216       return "ok_cert.pem"; |  | 
| 217     case CERT_COMMON_NAME_IS_DOMAIN: |  | 
| 218       return "localhost_cert.pem"; |  | 
| 219     case CERT_EXPIRED: |  | 
| 220       return "expired_cert.pem"; |  | 
| 221     case CERT_CHAIN_WRONG_ROOT: |  | 
| 222       return "redundant-server-chain.pem"; |  | 
| 223     case CERT_BAD_VALIDITY: |  | 
| 224       return "bad_validity.pem"; |  | 
| 225   } |  | 
| 226 |  | 
| 227   return "ok_cert.pem"; |  | 
| 228 } |  | 
| 229 |  | 
| 230 scoped_refptr<X509Certificate> EmbeddedTestServer::GetCertificate() const { |  | 
| 231   DCHECK(is_using_ssl_); |  | 
| 232   base::FilePath certs_dir(GetTestCertsDirectory()); |  | 
| 233   return ImportCertFromFile(certs_dir, GetCertificateName()); |  | 
| 234 } |  | 
| 235 |  | 
| 236 void EmbeddedTestServer::ServeFilesFromDirectory( | 226 void EmbeddedTestServer::ServeFilesFromDirectory( | 
| 237     const base::FilePath& directory) { | 227     const base::FilePath& directory) { | 
| 238   RegisterRequestHandler(base::Bind(&HandleFileRequest, directory)); | 228   RegisterRequestHandler(base::Bind(&HandleFileRequest, directory)); | 
| 239 } | 229 } | 
| 240 | 230 | 
| 241 void EmbeddedTestServer::ServeFilesFromSourceDirectory( |  | 
| 242     const std::string& relative) { |  | 
| 243   base::FilePath test_data_dir; |  | 
| 244   CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir)); |  | 
| 245   ServeFilesFromDirectory(test_data_dir.AppendASCII(relative)); |  | 
| 246 } |  | 
| 247 |  | 
| 248 void EmbeddedTestServer::ServeFilesFromSourceDirectory( |  | 
| 249     const base::FilePath& relative) { |  | 
| 250   base::FilePath test_data_dir; |  | 
| 251   CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir)); |  | 
| 252   ServeFilesFromDirectory(test_data_dir.Append(relative)); |  | 
| 253 } |  | 
| 254 |  | 
| 255 void EmbeddedTestServer::AddDefaultHandlers(const base::FilePath& directory) { |  | 
| 256   // TODO(svaldez): Add additional default handlers. |  | 
| 257   ServeFilesFromSourceDirectory(directory); |  | 
| 258 } |  | 
| 259 |  | 
| 260 void EmbeddedTestServer::RegisterRequestHandler( | 231 void EmbeddedTestServer::RegisterRequestHandler( | 
| 261     const HandleRequestCallback& callback) { | 232     const HandleRequestCallback& callback) { | 
| 262   // TODO(svaldez): Add check to prevent RegisterHandler from being called |  | 
| 263   // after the server has started. https://crbug.com/546060 |  | 
| 264   request_handlers_.push_back(callback); | 233   request_handlers_.push_back(callback); | 
| 265 } | 234 } | 
| 266 | 235 | 
| 267 void EmbeddedTestServer::RegisterDefaultHandler( |  | 
| 268     const HandleRequestCallback& callback) { |  | 
| 269   // TODO(svaldez): Add check to prevent RegisterHandler from being called |  | 
| 270   // after the server has started. https://crbug.com/546060 |  | 
| 271   default_request_handlers_.push_back(callback); |  | 
| 272 } |  | 
| 273 |  | 
| 274 scoped_ptr<StreamSocket> EmbeddedTestServer::DoSSLUpgrade( |  | 
| 275     scoped_ptr<StreamSocket> connection) { |  | 
| 276   DCHECK(io_thread_->task_runner()->BelongsToCurrentThread()); |  | 
| 277 |  | 
| 278   base::FilePath certs_dir(GetTestCertsDirectory()); |  | 
| 279   std::string cert_name = GetCertificateName(); |  | 
| 280 |  | 
| 281   base::FilePath key_path = certs_dir.AppendASCII(cert_name); |  | 
| 282   std::string key_string; |  | 
| 283   CHECK(base::ReadFileToString(key_path, &key_string)); |  | 
| 284   std::vector<std::string> headers; |  | 
| 285   headers.push_back("PRIVATE KEY"); |  | 
| 286   PEMTokenizer pem_tokenizer(key_string, headers); |  | 
| 287   pem_tokenizer.GetNext(); |  | 
| 288   std::vector<uint8_t> key_vector; |  | 
| 289   key_vector.assign(pem_tokenizer.data().begin(), pem_tokenizer.data().end()); |  | 
| 290 |  | 
| 291   scoped_ptr<crypto::RSAPrivateKey> server_key( |  | 
| 292       crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_vector)); |  | 
| 293 |  | 
| 294   return CreateSSLServerSocket(connection.Pass(), GetCertificate().get(), |  | 
| 295                                server_key.get(), ssl_config_); |  | 
| 296 } |  | 
| 297 |  | 
| 298 void EmbeddedTestServer::DoAcceptLoop() { | 236 void EmbeddedTestServer::DoAcceptLoop() { | 
| 299   int rv = OK; | 237   int rv = OK; | 
| 300   while (rv == OK) { | 238   while (rv == OK) { | 
| 301     rv = listen_socket_->Accept( | 239     rv = listen_socket_->Accept( | 
| 302         &accepted_socket_, base::Bind(&EmbeddedTestServer::OnAcceptCompleted, | 240         &accepted_socket_, base::Bind(&EmbeddedTestServer::OnAcceptCompleted, | 
| 303                                       base::Unretained(this))); | 241                                       base::Unretained(this))); | 
| 304     if (rv == ERR_IO_PENDING) | 242     if (rv == ERR_IO_PENDING) | 
| 305       return; | 243       return; | 
| 306     HandleAcceptResult(accepted_socket_.Pass()); | 244     HandleAcceptResult(accepted_socket_.Pass()); | 
| 307   } | 245   } | 
| 308 } | 246 } | 
| 309 | 247 | 
| 310 void EmbeddedTestServer::OnAcceptCompleted(int rv) { | 248 void EmbeddedTestServer::OnAcceptCompleted(int rv) { | 
| 311   DCHECK_NE(ERR_IO_PENDING, rv); | 249   DCHECK_NE(ERR_IO_PENDING, rv); | 
| 312   HandleAcceptResult(accepted_socket_.Pass()); | 250   HandleAcceptResult(accepted_socket_.Pass()); | 
| 313   DoAcceptLoop(); | 251   DoAcceptLoop(); | 
| 314 } | 252 } | 
| 315 | 253 | 
| 316 void EmbeddedTestServer::OnHandshakeDone(HttpConnection* connection, int rv) { |  | 
| 317   if (connection->socket_->IsConnected()) |  | 
| 318     ReadData(connection); |  | 
| 319   else |  | 
| 320     DidClose(connection); |  | 
| 321 } |  | 
| 322 |  | 
| 323 void EmbeddedTestServer::HandleAcceptResult(scoped_ptr<StreamSocket> socket) { | 254 void EmbeddedTestServer::HandleAcceptResult(scoped_ptr<StreamSocket> socket) { | 
| 324   DCHECK(io_thread_->task_runner()->BelongsToCurrentThread()); | 255   DCHECK(io_thread_->task_runner()->BelongsToCurrentThread()); | 
| 325   if (connection_listener_) | 256   if (connection_listener_) | 
| 326     connection_listener_->AcceptedSocket(*socket); | 257     connection_listener_->AcceptedSocket(*socket); | 
| 327 | 258 | 
| 328   if (is_using_ssl_) |  | 
| 329     socket = DoSSLUpgrade(socket.Pass()); |  | 
| 330 |  | 
| 331   HttpConnection* http_connection = new HttpConnection( | 259   HttpConnection* http_connection = new HttpConnection( | 
| 332       socket.Pass(), | 260       socket.Pass(), | 
| 333       base::Bind(&EmbeddedTestServer::HandleRequest, base::Unretained(this))); | 261       base::Bind(&EmbeddedTestServer::HandleRequest, base::Unretained(this))); | 
| 334   connections_[http_connection->socket_.get()] = http_connection; | 262   connections_[http_connection->socket_.get()] = http_connection; | 
| 335 | 263 | 
| 336   if (is_using_ssl_) { | 264   ReadData(http_connection); | 
| 337     SSLServerSocket* ssl_socket = |  | 
| 338         static_cast<SSLServerSocket*>(http_connection->socket_.get()); |  | 
| 339     int rv = ssl_socket->Handshake( |  | 
| 340         base::Bind(&EmbeddedTestServer::OnHandshakeDone, base::Unretained(this), |  | 
| 341                    http_connection)); |  | 
| 342     if (rv != ERR_IO_PENDING) |  | 
| 343       OnHandshakeDone(http_connection, rv); |  | 
| 344   } else { |  | 
| 345     ReadData(http_connection); |  | 
| 346   } |  | 
| 347 } | 265 } | 
| 348 | 266 | 
| 349 void EmbeddedTestServer::ReadData(HttpConnection* connection) { | 267 void EmbeddedTestServer::ReadData(HttpConnection* connection) { | 
| 350   while (true) { | 268   while (true) { | 
| 351     int rv = | 269     int rv = | 
| 352         connection->ReadData(base::Bind(&EmbeddedTestServer::OnReadCompleted, | 270         connection->ReadData(base::Bind(&EmbeddedTestServer::OnReadCompleted, | 
| 353                                         base::Unretained(this), connection)); | 271                                         base::Unretained(this), connection)); | 
| 354     if (rv == ERR_IO_PENDING) | 272     if (rv == ERR_IO_PENDING) | 
| 355       return; | 273       return; | 
| 356     if (!HandleReadResult(connection, rv)) | 274     if (!HandleReadResult(connection, rv)) | 
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 421                                                    run_loop.QuitClosure())) { | 339                                                    run_loop.QuitClosure())) { | 
| 422     return false; | 340     return false; | 
| 423   } | 341   } | 
| 424   run_loop.Run(); | 342   run_loop.Run(); | 
| 425 | 343 | 
| 426   return true; | 344   return true; | 
| 427 } | 345 } | 
| 428 | 346 | 
| 429 }  // namespace test_server | 347 }  // namespace test_server | 
| 430 }  // namespace net | 348 }  // namespace net | 
| OLD | NEW | 
|---|