Home | History | Annotate | Download | only in base
      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 
     29     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     }
     39     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     }
     45     void OnRequestComplete(HttpServer*, HttpServerTransaction* t, int) {
     46       ASSERT_EQ(transaction, t);
     47       transaction = NULL;
     48     }
     49     void OnClosed(HttpServer*) {
     50       server_closed = true;
     51     }
     52     void OnConnectionClosed(HttpServer*, int, StreamInterface* stream) {
     53       connection_closed = true;
     54       delete stream;
     55     }
     56   };
     57 
     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 
     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 
     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 
    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 
    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