embedded_test_server.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/test/embedded_test_server/embedded_test_server.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/files/file_path.h" 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/file_util.h" 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/path_service.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/run_loop.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/string_util.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stringprintf.h" 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/threading/thread_restrictions.h" 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/base/ip_endpoint.h" 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/base/net_errors.h" 18b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/test/embedded_test_server/http_connection.h" 19b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/test/embedded_test_server/http_request.h" 20b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/test/embedded_test_server/http_response.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/tools/fetch/http_listen_socket.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 23b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)namespace net { 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace test_server { 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Handles |request| by serving a file from under |server_root|. 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)scoped_ptr<HttpResponse> HandleFileRequest( 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::FilePath& server_root, 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const HttpRequest& request) { 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // This is a test-only server. Ignore I/O thread restrictions. 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::ThreadRestrictions::ScopedAllowIO allow_io; 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Trim the first byte ('/'). 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string request_path(request.relative_url.substr(1)); 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Remove the query string if present. 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t query_pos = request_path.find('?'); 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (query_pos != std::string::npos) 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) request_path = request_path.substr(0, query_pos); 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string file_contents; 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!file_util::ReadFileToString( 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) server_root.AppendASCII(request_path), &file_contents)) { 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return scoped_ptr<HttpResponse>(NULL); 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) http_response->set_code(net::test_server::SUCCESS); 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) http_response->set_content(file_contents); 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return http_response.PassAs<HttpResponse>(); 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HttpListenSocket::HttpListenSocket(const SocketDescriptor socket_descriptor, 58b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) StreamListenSocket::Delegate* delegate) 59b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) : TCPListenSocket(socket_descriptor, delegate) { 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HttpListenSocket::Listen() { 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 65b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) TCPListenSocket::Listen(); 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HttpListenSocket::~HttpListenSocket() { 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)EmbeddedTestServer::EmbeddedTestServer( 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const scoped_refptr<base::SingleThreadTaskRunner>& io_thread) 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : io_thread_(io_thread), 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) port_(-1), 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this) { 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(io_thread_); 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 81b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)EmbeddedTestServer::~EmbeddedTestServer() { 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (Started() && !ShutdownAndWaitUntilComplete()) { 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LOG(ERROR) << "EmbeddedTestServer failed to shut down."; 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 89b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)bool EmbeddedTestServer::InitializeAndWaitUntilReady() { 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::RunLoop run_loop; 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!io_thread_->PostTaskAndReply( 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 95b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Bind(&EmbeddedTestServer::InitializeOnIOThread, 96b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Unretained(this)), 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) run_loop.QuitClosure())) { 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) run_loop.Run(); 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return Started() && base_url_.is_valid(); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 105b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)bool EmbeddedTestServer::ShutdownAndWaitUntilComplete() { 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::RunLoop run_loop; 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!io_thread_->PostTaskAndReply( 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 111b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Bind(&EmbeddedTestServer::ShutdownOnIOThread, 112b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Unretained(this)), 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) run_loop.QuitClosure())) { 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) run_loop.Run(); 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 121b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void EmbeddedTestServer::InitializeOnIOThread() { 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(io_thread_->BelongsToCurrentThread()); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!Started()); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SocketDescriptor socket_descriptor = 12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) TCPListenSocket::CreateAndBindAnyPort("127.0.0.1", &port_); 12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (socket_descriptor == TCPListenSocket::kInvalidSocket) 12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) listen_socket_ = new HttpListenSocket(socket_descriptor, this); 13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) listen_socket_->Listen(); 13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) IPEndPoint address; 13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int result = listen_socket_->GetLocalAddress(&address); 13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (result == OK) { 13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base_url_ = GURL(std::string("http://") + address.ToString()); 13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LOG(ERROR) << "GetLocalAddress failed: " << ErrorToString(result); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 142b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void EmbeddedTestServer::ShutdownOnIOThread() { 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(io_thread_->BelongsToCurrentThread()); 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) listen_socket_ = NULL; // Release the listen socket. 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) STLDeleteContainerPairSecondPointers(connections_.begin(), 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connections_.end()); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connections_.clear(); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 151b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void EmbeddedTestServer::HandleRequest(HttpConnection* connection, 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<HttpRequest> request) { 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(io_thread_->BelongsToCurrentThread()); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool request_handled = false; 15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < request_handlers_.size(); ++i) { 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<HttpResponse> response = 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_handlers_[i].Run(*request.get()); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (response.get()) { 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connection->SendResponse(response.Pass()); 16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) request_handled = true; 16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!request_handled) { 16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LOG(WARNING) << "Request not handled. Returning 404: " 16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) << request->relative_url; 17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<BasicHttpResponse> not_found_response(new BasicHttpResponse); 17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) not_found_response->set_code(NOT_FOUND); 17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) connection->SendResponse( 17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) not_found_response.PassAs<HttpResponse>()); 17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Drop the connection, since we do not support multiple requests per 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // connection. 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connections_.erase(connection->socket_.get()); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete connection; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 182b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)GURL EmbeddedTestServer::GetURL(const std::string& relative_url) const { 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(StartsWithASCII(relative_url, "/", true /* case_sensitive */)) 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << relative_url; 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base_url_.Resolve(relative_url); 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void EmbeddedTestServer::ServeFilesFromDirectory( 18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::FilePath& directory) { 19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RegisterRequestHandler(base::Bind(&HandleFileRequest, directory)); 19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 193b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void EmbeddedTestServer::RegisterRequestHandler( 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const HandleRequestCallback& callback) { 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_handlers_.push_back(callback); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 198b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void EmbeddedTestServer::DidAccept(StreamListenSocket* server, 199b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) StreamListenSocket* connection) { 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(io_thread_->BelongsToCurrentThread()); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HttpConnection* http_connection = new HttpConnection( 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connection, 204b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Bind(&EmbeddedTestServer::HandleRequest, 205b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) weak_factory_.GetWeakPtr())); 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connections_[connection] = http_connection; 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 209b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void EmbeddedTestServer::DidRead(StreamListenSocket* connection, 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* data, 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int length) { 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(io_thread_->BelongsToCurrentThread()); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HttpConnection* http_connection = FindConnection(connection); 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (http_connection == NULL) { 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(WARNING) << "Unknown connection."; 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) http_connection->ReceiveData(std::string(data, length)); 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 222b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void EmbeddedTestServer::DidClose(StreamListenSocket* connection) { 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(io_thread_->BelongsToCurrentThread()); 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HttpConnection* http_connection = FindConnection(connection); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (http_connection == NULL) { 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(WARNING) << "Unknown connection."; 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete http_connection; 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connections_.erase(connection); 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 234b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)HttpConnection* EmbeddedTestServer::FindConnection( 235b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) StreamListenSocket* socket) { 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(io_thread_->BelongsToCurrentThread()); 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 238b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) std::map<StreamListenSocket*, HttpConnection*>::iterator it = 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connections_.find(socket); 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it == connections_.end()) { 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return it->second; 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace test_server 247b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} // namespace net 248