1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/test/chromedriver/net/test_http_server.h"
8 #include "base/location.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/message_loop/message_loop_proxy.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/time/time.h"
13 #include "net/base/ip_endpoint.h"
14 #include "net/base/net_errors.h"
15 #include "net/server/http_server_request_info.h"
16 #include "net/socket/tcp_server_socket.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 const int kBufferSize
= 100 * 1024 * 1024; // 100 MB
21 TestHttpServer::TestHttpServer()
22 : thread_("ServerThread"),
23 all_closed_event_(false, true),
24 request_action_(kAccept
),
25 message_action_(kEchoMessage
) {
28 TestHttpServer::~TestHttpServer() {
31 bool TestHttpServer::Start() {
32 base::Thread::Options
options(base::MessageLoop::TYPE_IO
, 0);
33 bool thread_started
= thread_
.StartWithOptions(options
);
34 EXPECT_TRUE(thread_started
);
38 base::WaitableEvent
event(false, false);
39 thread_
.message_loop_proxy()->PostTask(
41 base::Bind(&TestHttpServer::StartOnServerThread
,
42 base::Unretained(this), &success
, &event
));
47 void TestHttpServer::Stop() {
48 if (!thread_
.IsRunning())
50 base::WaitableEvent
event(false, false);
51 thread_
.message_loop_proxy()->PostTask(
53 base::Bind(&TestHttpServer::StopOnServerThread
,
54 base::Unretained(this), &event
));
59 bool TestHttpServer::WaitForConnectionsToClose() {
60 return all_closed_event_
.TimedWait(base::TimeDelta::FromSeconds(10));
63 void TestHttpServer::SetRequestAction(WebSocketRequestAction action
) {
64 base::AutoLock
lock(action_lock_
);
65 request_action_
= action
;
68 void TestHttpServer::SetMessageAction(WebSocketMessageAction action
) {
69 base::AutoLock
lock(action_lock_
);
70 message_action_
= action
;
73 GURL
TestHttpServer::web_socket_url() const {
74 base::AutoLock
lock(url_lock_
);
75 return web_socket_url_
;
78 void TestHttpServer::OnConnect(int connection_id
) {
79 server_
->SetSendBufferSize(connection_id
, kBufferSize
);
80 server_
->SetReceiveBufferSize(connection_id
, kBufferSize
);
83 void TestHttpServer::OnWebSocketRequest(
85 const net::HttpServerRequestInfo
& info
) {
86 WebSocketRequestAction action
;
88 base::AutoLock
lock(action_lock_
);
89 action
= request_action_
;
91 connections_
.insert(connection_id
);
92 all_closed_event_
.Reset();
96 server_
->AcceptWebSocket(connection_id
, info
);
99 server_
->Send404(connection_id
);
102 server_
->Close(connection_id
);
107 void TestHttpServer::OnWebSocketMessage(int connection_id
,
108 const std::string
& data
) {
109 WebSocketMessageAction action
;
111 base::AutoLock
lock(action_lock_
);
112 action
= message_action_
;
116 server_
->SendOverWebSocket(connection_id
, data
);
118 case kCloseOnMessage
:
119 server_
->Close(connection_id
);
124 void TestHttpServer::OnClose(int connection_id
) {
125 connections_
.erase(connection_id
);
126 if (connections_
.empty())
127 all_closed_event_
.Signal();
130 void TestHttpServer::StartOnServerThread(bool* success
,
131 base::WaitableEvent
* event
) {
132 scoped_ptr
<net::ServerSocket
> server_socket(
133 new net::TCPServerSocket(NULL
, net::NetLog::Source()));
134 server_socket
->ListenWithAddressAndPort("127.0.0.1", 0, 1);
135 server_
.reset(new net::HttpServer(server_socket
.Pass(), this));
137 net::IPEndPoint address
;
138 int error
= server_
->GetLocalAddress(&address
);
139 EXPECT_EQ(net::OK
, error
);
140 if (error
== net::OK
) {
141 base::AutoLock
lock(url_lock_
);
142 web_socket_url_
= GURL(base::StringPrintf("ws://127.0.0.1:%d",
147 *success
= server_
.get();
151 void TestHttpServer::StopOnServerThread(base::WaitableEvent
* event
) {