blob: 6e12cf5120555a04b01fb37244d8c06bf888f71f [file] [log] [blame]
henrike@webrtc.org0e118e72013-07-10 00:45:36 +00001// Copyright 2007 Google Inc.
2// All Rights Reserved.
3
4
5#include "talk/base/gunit.h"
6#include "talk/base/httpserver.h"
7#include "talk/base/testutils.h"
8
9using namespace testing;
10
11namespace talk_base {
12
13namespace {
14 const char* const kRequest =
15 "GET /index.html HTTP/1.1\r\n"
16 "Host: localhost\r\n"
17 "\r\n";
18
henrike@webrtc.org0e118e72013-07-10 00:45:36 +000019 struct HttpServerMonitor : public sigslot::has_slots<> {
20 HttpServerTransaction* transaction;
21 bool server_closed, connection_closed;
22
23 HttpServerMonitor(HttpServer* server)
24 : transaction(NULL), server_closed(false), connection_closed(false) {
25 server->SignalCloseAllComplete.connect(this,
26 &HttpServerMonitor::OnClosed);
27 server->SignalHttpRequest.connect(this, &HttpServerMonitor::OnRequest);
28 server->SignalHttpRequestComplete.connect(this,
29 &HttpServerMonitor::OnRequestComplete);
30 server->SignalConnectionClosed.connect(this,
31 &HttpServerMonitor::OnConnectionClosed);
32 }
33 void OnRequest(HttpServer*, HttpServerTransaction* t) {
34 ASSERT_FALSE(transaction);
35 transaction = t;
36 transaction->response.set_success();
37 transaction->response.setHeader(HH_CONNECTION, "Close");
38 }
39 void OnRequestComplete(HttpServer*, HttpServerTransaction* t, int) {
40 ASSERT_EQ(transaction, t);
41 transaction = NULL;
42 }
43 void OnClosed(HttpServer*) {
44 server_closed = true;
45 }
46 void OnConnectionClosed(HttpServer*, int, StreamInterface* stream) {
47 connection_closed = true;
48 delete stream;
49 }
50 };
51
52 void CreateClientConnection(HttpServer& server,
53 HttpServerMonitor& monitor,
54 bool send_request) {
55 StreamSource* client = new StreamSource;
56 client->SetState(SS_OPEN);
57 server.HandleConnection(client);
58 EXPECT_FALSE(monitor.server_closed);
59 EXPECT_FALSE(monitor.transaction);
60
61 if (send_request) {
62 // Simulate a request
63 client->QueueString(kRequest);
64 EXPECT_FALSE(monitor.server_closed);
65 }
66 }
67} // anonymous namespace
68
69TEST(HttpServer, DoesNotSignalCloseUnlessCloseAllIsCalled) {
70 HttpServer server;
71 HttpServerMonitor monitor(&server);
72 // Add an active client connection
73 CreateClientConnection(server, monitor, true);
74 // Simulate a response
75 ASSERT_TRUE(NULL != monitor.transaction);
76 server.Respond(monitor.transaction);
77 EXPECT_FALSE(monitor.transaction);
78 // Connection has closed, but no server close signal
79 EXPECT_FALSE(monitor.server_closed);
80 EXPECT_TRUE(monitor.connection_closed);
81}
82
83TEST(HttpServer, SignalsCloseWhenNoConnectionsAreActive) {
84 HttpServer server;
85 HttpServerMonitor monitor(&server);
86 // Add an idle client connection
87 CreateClientConnection(server, monitor, false);
88 // Perform graceful close
89 server.CloseAll(false);
90 // Connections have all closed
91 EXPECT_TRUE(monitor.server_closed);
92 EXPECT_TRUE(monitor.connection_closed);
93}
94
95TEST(HttpServer, SignalsCloseAfterGracefulCloseAll) {
96 HttpServer server;
97 HttpServerMonitor monitor(&server);
98 // Add an active client connection
99 CreateClientConnection(server, monitor, true);
100 // Initiate a graceful close
101 server.CloseAll(false);
102 EXPECT_FALSE(monitor.server_closed);
103 // Simulate a response
104 ASSERT_TRUE(NULL != monitor.transaction);
105 server.Respond(monitor.transaction);
106 EXPECT_FALSE(monitor.transaction);
107 // Connections have all closed
108 EXPECT_TRUE(monitor.server_closed);
109 EXPECT_TRUE(monitor.connection_closed);
110}
111
112TEST(HttpServer, SignalsCloseAfterForcedCloseAll) {
113 HttpServer server;
114 HttpServerMonitor monitor(&server);
115 // Add an active client connection
116 CreateClientConnection(server, monitor, true);
117 // Initiate a forceful close
118 server.CloseAll(true);
119 // Connections have all closed
120 EXPECT_TRUE(monitor.server_closed);
121 EXPECT_TRUE(monitor.connection_closed);
122}
123
124} // namespace talk_base