| /* |
| * Copyright 2007 The WebRTC Project Authors. All rights reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #include "webrtc/base/gunit.h" |
| #include "webrtc/base/httpserver.h" |
| #include "webrtc/base/testutils.h" |
| |
| using namespace webrtc::testing; |
| |
| namespace rtc { |
| |
| namespace { |
| const char* const kRequest = |
| "GET /index.html HTTP/1.1\r\n" |
| "Host: localhost\r\n" |
| "\r\n"; |
| |
| struct HttpServerMonitor : public sigslot::has_slots<> { |
| HttpServerTransaction* transaction; |
| bool server_closed, connection_closed; |
| |
| HttpServerMonitor(HttpServer* server) |
| : transaction(nullptr), server_closed(false), connection_closed(false) { |
| server->SignalCloseAllComplete.connect(this, |
| &HttpServerMonitor::OnClosed); |
| server->SignalHttpRequest.connect(this, &HttpServerMonitor::OnRequest); |
| server->SignalHttpRequestComplete.connect(this, |
| &HttpServerMonitor::OnRequestComplete); |
| server->SignalConnectionClosed.connect(this, |
| &HttpServerMonitor::OnConnectionClosed); |
| } |
| void OnRequest(HttpServer*, HttpServerTransaction* t) { |
| ASSERT_FALSE(transaction); |
| transaction = t; |
| transaction->response.set_success(); |
| transaction->response.setHeader(HH_CONNECTION, "Close"); |
| } |
| void OnRequestComplete(HttpServer*, HttpServerTransaction* t, int) { |
| ASSERT_EQ(transaction, t); |
| transaction = nullptr; |
| } |
| void OnClosed(HttpServer*) { |
| server_closed = true; |
| } |
| void OnConnectionClosed(HttpServer*, int, StreamInterface* stream) { |
| connection_closed = true; |
| delete stream; |
| } |
| }; |
| |
| void CreateClientConnection(HttpServer& server, |
| HttpServerMonitor& monitor, |
| bool send_request) { |
| StreamSource* client = new StreamSource; |
| client->SetState(SS_OPEN); |
| server.HandleConnection(client); |
| EXPECT_FALSE(monitor.server_closed); |
| EXPECT_FALSE(monitor.transaction); |
| |
| if (send_request) { |
| // Simulate a request |
| client->QueueString(kRequest); |
| EXPECT_FALSE(monitor.server_closed); |
| } |
| } |
| } // anonymous namespace |
| |
| TEST(HttpServer, DoesNotSignalCloseUnlessCloseAllIsCalled) { |
| HttpServer server; |
| HttpServerMonitor monitor(&server); |
| // Add an active client connection |
| CreateClientConnection(server, monitor, true); |
| // Simulate a response |
| ASSERT_TRUE(nullptr != monitor.transaction); |
| server.Respond(monitor.transaction); |
| EXPECT_FALSE(monitor.transaction); |
| // Connection has closed, but no server close signal |
| EXPECT_FALSE(monitor.server_closed); |
| EXPECT_TRUE(monitor.connection_closed); |
| } |
| |
| TEST(HttpServer, SignalsCloseWhenNoConnectionsAreActive) { |
| HttpServer server; |
| HttpServerMonitor monitor(&server); |
| // Add an idle client connection |
| CreateClientConnection(server, monitor, false); |
| // Perform graceful close |
| server.CloseAll(false); |
| // Connections have all closed |
| EXPECT_TRUE(monitor.server_closed); |
| EXPECT_TRUE(monitor.connection_closed); |
| } |
| |
| TEST(HttpServer, SignalsCloseAfterGracefulCloseAll) { |
| HttpServer server; |
| HttpServerMonitor monitor(&server); |
| // Add an active client connection |
| CreateClientConnection(server, monitor, true); |
| // Initiate a graceful close |
| server.CloseAll(false); |
| EXPECT_FALSE(monitor.server_closed); |
| // Simulate a response |
| ASSERT_TRUE(nullptr != monitor.transaction); |
| server.Respond(monitor.transaction); |
| EXPECT_FALSE(monitor.transaction); |
| // Connections have all closed |
| EXPECT_TRUE(monitor.server_closed); |
| EXPECT_TRUE(monitor.connection_closed); |
| } |
| |
| TEST(HttpServer, SignalsCloseAfterForcedCloseAll) { |
| HttpServer server; |
| HttpServerMonitor monitor(&server); |
| // Add an active client connection |
| CreateClientConnection(server, monitor, true); |
| // Initiate a forceful close |
| server.CloseAll(true); |
| // Connections have all closed |
| EXPECT_TRUE(monitor.server_closed); |
| EXPECT_TRUE(monitor.connection_closed); |
| } |
| |
| } // namespace rtc |