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