| 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 <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| 11 #include "base/files/file_util.h" | 11 #include "base/files/file_util.h" |
| 12 #include "base/location.h" | 12 #include "base/location.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/memory/ptr_util.h" |
| 14 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
| 15 #include "base/path_service.h" | 16 #include "base/path_service.h" |
| 16 #include "base/process/process_metrics.h" | 17 #include "base/process/process_metrics.h" |
| 17 #include "base/run_loop.h" | 18 #include "base/run_loop.h" |
| 18 #include "base/stl_util.h" | |
| 19 #include "base/strings/string_util.h" | 19 #include "base/strings/string_util.h" |
| 20 #include "base/strings/stringprintf.h" | 20 #include "base/strings/stringprintf.h" |
| 21 #include "base/threading/thread_restrictions.h" | 21 #include "base/threading/thread_restrictions.h" |
| 22 #include "base/threading/thread_task_runner_handle.h" | 22 #include "base/threading/thread_task_runner_handle.h" |
| 23 #include "crypto/rsa_private_key.h" | 23 #include "crypto/rsa_private_key.h" |
| 24 #include "net/base/ip_endpoint.h" | 24 #include "net/base/ip_endpoint.h" |
| 25 #include "net/base/net_errors.h" | 25 #include "net/base/net_errors.h" |
| 26 #include "net/cert/pem_tokenizer.h" | 26 #include "net/cert/pem_tokenizer.h" |
| 27 #include "net/cert/test_root_certs.h" | 27 #include "net/cert/test_root_certs.h" |
| 28 #include "net/socket/ssl_server_socket.h" | 28 #include "net/socket/ssl_server_socket.h" |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 DCHECK(thread_checker_.CalledOnValidThread()); | 163 DCHECK(thread_checker_.CalledOnValidThread()); |
| 164 | 164 |
| 165 return PostTaskToIOThreadAndWait(base::Bind( | 165 return PostTaskToIOThreadAndWait(base::Bind( |
| 166 &EmbeddedTestServer::ShutdownOnIOThread, base::Unretained(this))); | 166 &EmbeddedTestServer::ShutdownOnIOThread, base::Unretained(this))); |
| 167 } | 167 } |
| 168 | 168 |
| 169 void EmbeddedTestServer::ShutdownOnIOThread() { | 169 void EmbeddedTestServer::ShutdownOnIOThread() { |
| 170 DCHECK(io_thread_->task_runner()->BelongsToCurrentThread()); | 170 DCHECK(io_thread_->task_runner()->BelongsToCurrentThread()); |
| 171 weak_factory_.InvalidateWeakPtrs(); | 171 weak_factory_.InvalidateWeakPtrs(); |
| 172 listen_socket_.reset(); | 172 listen_socket_.reset(); |
| 173 base::STLDeleteContainerPairSecondPointers(connections_.begin(), | |
| 174 connections_.end()); | |
| 175 connections_.clear(); | 173 connections_.clear(); |
| 176 } | 174 } |
| 177 | 175 |
| 178 void EmbeddedTestServer::HandleRequest(HttpConnection* connection, | 176 void EmbeddedTestServer::HandleRequest(HttpConnection* connection, |
| 179 std::unique_ptr<HttpRequest> request) { | 177 std::unique_ptr<HttpRequest> request) { |
| 180 DCHECK(io_thread_->task_runner()->BelongsToCurrentThread()); | 178 DCHECK(io_thread_->task_runner()->BelongsToCurrentThread()); |
| 181 | 179 |
| 182 for (const auto& monitor : request_monitors_) | 180 for (const auto& monitor : request_monitors_) |
| 183 monitor.Run(*request); | 181 monitor.Run(*request); |
| 184 | 182 |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 } | 334 } |
| 337 } | 335 } |
| 338 | 336 |
| 339 bool EmbeddedTestServer::FlushAllSocketsAndConnectionsOnUIThread() { | 337 bool EmbeddedTestServer::FlushAllSocketsAndConnectionsOnUIThread() { |
| 340 return PostTaskToIOThreadAndWait( | 338 return PostTaskToIOThreadAndWait( |
| 341 base::Bind(&EmbeddedTestServer::FlushAllSocketsAndConnections, | 339 base::Bind(&EmbeddedTestServer::FlushAllSocketsAndConnections, |
| 342 base::Unretained(this))); | 340 base::Unretained(this))); |
| 343 } | 341 } |
| 344 | 342 |
| 345 void EmbeddedTestServer::FlushAllSocketsAndConnections() { | 343 void EmbeddedTestServer::FlushAllSocketsAndConnections() { |
| 346 base::STLDeleteContainerPairSecondPointers(connections_.begin(), | |
| 347 connections_.end()); | |
| 348 connections_.clear(); | 344 connections_.clear(); |
| 349 } | 345 } |
| 350 | 346 |
| 351 void EmbeddedTestServer::OnAcceptCompleted(int rv) { | 347 void EmbeddedTestServer::OnAcceptCompleted(int rv) { |
| 352 DCHECK_NE(ERR_IO_PENDING, rv); | 348 DCHECK_NE(ERR_IO_PENDING, rv); |
| 353 HandleAcceptResult(std::move(accepted_socket_)); | 349 HandleAcceptResult(std::move(accepted_socket_)); |
| 354 DoAcceptLoop(); | 350 DoAcceptLoop(); |
| 355 } | 351 } |
| 356 | 352 |
| 357 void EmbeddedTestServer::OnHandshakeDone(HttpConnection* connection, int rv) { | 353 void EmbeddedTestServer::OnHandshakeDone(HttpConnection* connection, int rv) { |
| 358 if (connection->socket_->IsConnected()) | 354 if (connection->socket_->IsConnected()) |
| 359 ReadData(connection); | 355 ReadData(connection); |
| 360 else | 356 else |
| 361 DidClose(connection); | 357 DidClose(connection); |
| 362 } | 358 } |
| 363 | 359 |
| 364 void EmbeddedTestServer::HandleAcceptResult( | 360 void EmbeddedTestServer::HandleAcceptResult( |
| 365 std::unique_ptr<StreamSocket> socket) { | 361 std::unique_ptr<StreamSocket> socket) { |
| 366 DCHECK(io_thread_->task_runner()->BelongsToCurrentThread()); | 362 DCHECK(io_thread_->task_runner()->BelongsToCurrentThread()); |
| 367 if (connection_listener_) | 363 if (connection_listener_) |
| 368 connection_listener_->AcceptedSocket(*socket); | 364 connection_listener_->AcceptedSocket(*socket); |
| 369 | 365 |
| 370 if (is_using_ssl_) | 366 if (is_using_ssl_) |
| 371 socket = DoSSLUpgrade(std::move(socket)); | 367 socket = DoSSLUpgrade(std::move(socket)); |
| 372 | 368 |
| 373 HttpConnection* http_connection = new HttpConnection( | 369 std::unique_ptr<HttpConnection> http_connection_ptr = |
| 374 std::move(socket), | 370 base::MakeUnique<HttpConnection>( |
| 375 base::Bind(&EmbeddedTestServer::HandleRequest, base::Unretained(this))); | 371 std::move(socket), base::Bind(&EmbeddedTestServer::HandleRequest, |
| 376 connections_[http_connection->socket_.get()] = http_connection; | 372 base::Unretained(this))); |
| 373 HttpConnection* http_connection = http_connection_ptr.get(); |
| 374 connections_[http_connection->socket_.get()] = std::move(http_connection_ptr); |
| 377 | 375 |
| 378 if (is_using_ssl_) { | 376 if (is_using_ssl_) { |
| 379 SSLServerSocket* ssl_socket = | 377 SSLServerSocket* ssl_socket = |
| 380 static_cast<SSLServerSocket*>(http_connection->socket_.get()); | 378 static_cast<SSLServerSocket*>(http_connection->socket_.get()); |
| 381 int rv = ssl_socket->Handshake( | 379 int rv = ssl_socket->Handshake( |
| 382 base::Bind(&EmbeddedTestServer::OnHandshakeDone, base::Unretained(this), | 380 base::Bind(&EmbeddedTestServer::OnHandshakeDone, base::Unretained(this), |
| 383 http_connection)); | 381 http_connection)); |
| 384 if (rv != ERR_IO_PENDING) | 382 if (rv != ERR_IO_PENDING) |
| 385 OnHandshakeDone(http_connection, rv); | 383 OnHandshakeDone(http_connection, rv); |
| 386 } else { | 384 } else { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 | 420 |
| 423 return true; | 421 return true; |
| 424 } | 422 } |
| 425 | 423 |
| 426 void EmbeddedTestServer::DidClose(HttpConnection* connection) { | 424 void EmbeddedTestServer::DidClose(HttpConnection* connection) { |
| 427 DCHECK(io_thread_->task_runner()->BelongsToCurrentThread()); | 425 DCHECK(io_thread_->task_runner()->BelongsToCurrentThread()); |
| 428 DCHECK(connection); | 426 DCHECK(connection); |
| 429 DCHECK_EQ(1u, connections_.count(connection->socket_.get())); | 427 DCHECK_EQ(1u, connections_.count(connection->socket_.get())); |
| 430 | 428 |
| 431 connections_.erase(connection->socket_.get()); | 429 connections_.erase(connection->socket_.get()); |
| 432 delete connection; | |
| 433 } | 430 } |
| 434 | 431 |
| 435 HttpConnection* EmbeddedTestServer::FindConnection(StreamSocket* socket) { | 432 HttpConnection* EmbeddedTestServer::FindConnection(StreamSocket* socket) { |
| 436 DCHECK(io_thread_->task_runner()->BelongsToCurrentThread()); | 433 DCHECK(io_thread_->task_runner()->BelongsToCurrentThread()); |
| 437 | 434 |
| 438 std::map<StreamSocket*, HttpConnection*>::iterator it = | 435 auto it = connections_.find(socket); |
| 439 connections_.find(socket); | |
| 440 if (it == connections_.end()) { | 436 if (it == connections_.end()) { |
| 441 return NULL; | 437 return nullptr; |
| 442 } | 438 } |
| 443 return it->second; | 439 return it->second.get(); |
| 444 } | 440 } |
| 445 | 441 |
| 446 bool EmbeddedTestServer::PostTaskToIOThreadAndWait( | 442 bool EmbeddedTestServer::PostTaskToIOThreadAndWait( |
| 447 const base::Closure& closure) { | 443 const base::Closure& closure) { |
| 448 // Note that PostTaskAndReply below requires | 444 // Note that PostTaskAndReply below requires |
| 449 // base::ThreadTaskRunnerHandle::Get() to return a task runner for posting | 445 // base::ThreadTaskRunnerHandle::Get() to return a task runner for posting |
| 450 // the reply task. However, in order to make EmbeddedTestServer universally | 446 // the reply task. However, in order to make EmbeddedTestServer universally |
| 451 // usable, it needs to cope with the situation where it's running on a thread | 447 // usable, it needs to cope with the situation where it's running on a thread |
| 452 // on which a message loop is not (yet) available or as has been destroyed | 448 // on which a message loop is not (yet) available or as has been destroyed |
| 453 // already. | 449 // already. |
| 454 // | 450 // |
| 455 // To handle this situation, create temporary message loop to support the | 451 // To handle this situation, create temporary message loop to support the |
| 456 // PostTaskAndReply operation if the current thread as no message loop. | 452 // PostTaskAndReply operation if the current thread as no message loop. |
| 457 std::unique_ptr<base::MessageLoop> temporary_loop; | 453 std::unique_ptr<base::MessageLoop> temporary_loop; |
| 458 if (!base::MessageLoop::current()) | 454 if (!base::MessageLoop::current()) |
| 459 temporary_loop.reset(new base::MessageLoop()); | 455 temporary_loop.reset(new base::MessageLoop()); |
| 460 | 456 |
| 461 base::RunLoop run_loop; | 457 base::RunLoop run_loop; |
| 462 if (!io_thread_->task_runner()->PostTaskAndReply(FROM_HERE, closure, | 458 if (!io_thread_->task_runner()->PostTaskAndReply(FROM_HERE, closure, |
| 463 run_loop.QuitClosure())) { | 459 run_loop.QuitClosure())) { |
| 464 return false; | 460 return false; |
| 465 } | 461 } |
| 466 run_loop.Run(); | 462 run_loop.Run(); |
| 467 | 463 |
| 468 return true; | 464 return true; |
| 469 } | 465 } |
| 470 | 466 |
| 471 } // namespace test_server | 467 } // namespace test_server |
| 472 } // namespace net | 468 } // namespace net |
| OLD | NEW |