1 /*
2  *  Copyright 2007 The WebRTC Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "webrtc/base/gunit.h"
12 #include "webrtc/base/httpserver.h"
13 #include "webrtc/base/testutils.h"
14 
15 using namespace testing;
16 
17 namespace rtc {
18 
19 namespace {
20   const char* const kRequest =
21     "GET /index.html HTTP/1.1\r\n"
22     "Host: localhost\r\n"
23     "\r\n";
24 
25   struct HttpServerMonitor : public sigslot::has_slots<> {
26     HttpServerTransaction* transaction;
27     bool server_closed, connection_closed;
28 
HttpServerMonitorrtc::__anon1d65a52c0111::HttpServerMonitor29     HttpServerMonitor(HttpServer* server)
30     : transaction(NULL), server_closed(false), connection_closed(false) {
31       server->SignalCloseAllComplete.connect(this,
32         &HttpServerMonitor::OnClosed);
33       server->SignalHttpRequest.connect(this, &HttpServerMonitor::OnRequest);
34       server->SignalHttpRequestComplete.connect(this,
35         &HttpServerMonitor::OnRequestComplete);
36       server->SignalConnectionClosed.connect(this,
37         &HttpServerMonitor::OnConnectionClosed);
38     }
OnRequestrtc::__anon1d65a52c0111::HttpServerMonitor39     void OnRequest(HttpServer*, HttpServerTransaction* t) {
40       ASSERT_FALSE(transaction);
41       transaction = t;
42       transaction->response.set_success();
43       transaction->response.setHeader(HH_CONNECTION, "Close");
44     }
OnRequestCompletertc::__anon1d65a52c0111::HttpServerMonitor45     void OnRequestComplete(HttpServer*, HttpServerTransaction* t, int) {
46       ASSERT_EQ(transaction, t);
47       transaction = NULL;
48     }
OnClosedrtc::__anon1d65a52c0111::HttpServerMonitor49     void OnClosed(HttpServer*) {
50       server_closed = true;
51     }
OnConnectionClosedrtc::__anon1d65a52c0111::HttpServerMonitor52     void OnConnectionClosed(HttpServer*, int, StreamInterface* stream) {
53       connection_closed = true;
54       delete stream;
55     }
56   };
57 
CreateClientConnection(HttpServer & server,HttpServerMonitor & monitor,bool send_request)58   void CreateClientConnection(HttpServer& server,
59                               HttpServerMonitor& monitor,
60                               bool send_request) {
61     StreamSource* client = new StreamSource;
62     client->SetState(SS_OPEN);
63     server.HandleConnection(client);
64     EXPECT_FALSE(monitor.server_closed);
65     EXPECT_FALSE(monitor.transaction);
66 
67     if (send_request) {
68       // Simulate a request
69       client->QueueString(kRequest);
70       EXPECT_FALSE(monitor.server_closed);
71     }
72   }
73 }  // anonymous namespace
74 
TEST(HttpServer,DoesNotSignalCloseUnlessCloseAllIsCalled)75 TEST(HttpServer, DoesNotSignalCloseUnlessCloseAllIsCalled) {
76   HttpServer server;
77   HttpServerMonitor monitor(&server);
78   // Add an active client connection
79   CreateClientConnection(server, monitor, true);
80   // Simulate a response
81   ASSERT_TRUE(NULL != monitor.transaction);
82   server.Respond(monitor.transaction);
83   EXPECT_FALSE(monitor.transaction);
84   // Connection has closed, but no server close signal
85   EXPECT_FALSE(monitor.server_closed);
86   EXPECT_TRUE(monitor.connection_closed);
87 }
88 
TEST(HttpServer,SignalsCloseWhenNoConnectionsAreActive)89 TEST(HttpServer, SignalsCloseWhenNoConnectionsAreActive) {
90   HttpServer server;
91   HttpServerMonitor monitor(&server);
92   // Add an idle client connection
93   CreateClientConnection(server, monitor, false);
94   // Perform graceful close
95   server.CloseAll(false);
96   // Connections have all closed
97   EXPECT_TRUE(monitor.server_closed);
98   EXPECT_TRUE(monitor.connection_closed);
99 }
100 
TEST(HttpServer,SignalsCloseAfterGracefulCloseAll)101 TEST(HttpServer, SignalsCloseAfterGracefulCloseAll) {
102   HttpServer server;
103   HttpServerMonitor monitor(&server);
104   // Add an active client connection
105   CreateClientConnection(server, monitor, true);
106   // Initiate a graceful close
107   server.CloseAll(false);
108   EXPECT_FALSE(monitor.server_closed);
109   // Simulate a response
110   ASSERT_TRUE(NULL != monitor.transaction);
111   server.Respond(monitor.transaction);
112   EXPECT_FALSE(monitor.transaction);
113   // Connections have all closed
114   EXPECT_TRUE(monitor.server_closed);
115   EXPECT_TRUE(monitor.connection_closed);
116 }
117 
TEST(HttpServer,SignalsCloseAfterForcedCloseAll)118 TEST(HttpServer, SignalsCloseAfterForcedCloseAll) {
119   HttpServer server;
120   HttpServerMonitor monitor(&server);
121   // Add an active client connection
122   CreateClientConnection(server, monitor, true);
123   // Initiate a forceful close
124   server.CloseAll(true);
125   // Connections have all closed
126   EXPECT_TRUE(monitor.server_closed);
127   EXPECT_TRUE(monitor.connection_closed);
128 }
129 
130 } // namespace rtc
131