Skip to content

v0.2.49..v0.2.50 changeset HttpTestServer.cpp

Garret Voltz edited this page Nov 6, 2019 · 1 revision
diff --git a/hoot-core-test/src/test/cpp/hoot/core/util/HttpTestServer.cpp b/hoot-core-test/src/test/cpp/hoot/core/util/HttpTestServer.cpp
index 9f154f3..2add879 100644
--- a/hoot-core-test/src/test/cpp/hoot/core/util/HttpTestServer.cpp
+++ b/hoot-core-test/src/test/cpp/hoot/core/util/HttpTestServer.cpp
@@ -33,13 +33,61 @@
 namespace hoot
 {
 
-const std::string HttpTestServer::HTTP_200_OK =           "HTTP/1.1 200 OK\r\n\r\n";
-const std::string HttpTestServer::HTTP_400_BAD_REQUEST =  "HTTP/1.1 400 Bad Request\r\n\r\n";
-const std::string HttpTestServer::HTTP_404_NOT_FOUND =    "HTTP/1.1 404 Not Found\r\n\r\n";
-const std::string HttpTestServer::HTTP_409_CONFLICT =     "HTTP/1.1 409 Conflict\r\n\r\n";
+HttpResponse::HttpResponse(int status, const std::string& response)
+  : _status(status),
+    _response(response)
+{
+  //  Add some default HTTP headers
+  add_header("Host", "localhost");
+  add_header("Connection", "closed");
+  if (response != "")
+    add_header("Content-Type", "text/xml");
+}
+
+void HttpResponse::add_header(const std::string& header, const std::string& value)
+{
+  //  Add the header to the list of headers we are using if it doesn't already exist
+  if (_header_values.find(header) == _header_values.end())
+    _headers.push_back(header);
+  //  Add the key/value to the map
+  _header_values[header] = value;
+}
+
+std::string HttpResponse::to_string()
+{
+  std::string end_line = "\r\n";
+  std::stringstream ss;
+  //  Add the HTTP status header
+  ss << "HTTP/1.1 " << _status << " " << get_status_text() << end_line;
+  //  Followed by all the other headers added
+  for (std::vector<std::string>::iterator it = _headers.begin(); it != _headers.end(); ++it)
+    ss << *it << ": " << _header_values[*it] << end_line;
+  //  Responses with response text are given the `Content-Length` header
+  if (_response != "")
+    ss << "Content-Length: " << _response.size() << end_line;
+  //  Output the response body (even if it is an empty string)
+  ss << end_line << _response;
+  return ss.str();
+}
+
+std::string HttpResponse::get_status_text()
+{
+  //  Convert the HTTP status code to status text
+  switch (_status)
+  {
+  case 200:   return "OK";
+  case 400:   return "Bad Request";
+  case 404:
+  default:    return "Not Found";
+  case 405:   return "Method Not Allowed";
+  case 409:   return "Conflict";
+  }
+}
+
 
 HttpTestServer::HttpTestServer(int port)
-  : _port(port)
+  : _port(port),
+    _interupt(false)
 {
 }
 
@@ -57,6 +105,10 @@ void HttpTestServer::wait()
 
 void HttpTestServer::shutdown()
 {
+  //  Interupt the threads
+  _interupt = true;
+  //  Cancel the acceptor
+  _acceptor->cancel();
   //  Stop the IO service and wait for the server to stop
   _io_service.stop();
   wait();
@@ -77,11 +129,15 @@ void HttpTestServer::run_server(int port)
   catch (std::exception& e)
   {
     LOG_ERROR(e.what());
+    shutdown();
   }
 }
 
 void HttpTestServer::start_accept()
 {
+  //  Service the interupt
+  if (_interupt)
+    return;
   //  Creat the connection
   HttpConnection::HttpConnectionPtr new_connection(new HttpConnection(_acceptor->get_io_service()));
   //  Accept connections async
@@ -92,27 +148,29 @@ void HttpTestServer::start_accept()
 void HttpTestServer::handle_accept(HttpConnection::HttpConnectionPtr new_connection, const boost::system::error_code& error)
 {
   //  Call the overridden respond() function
-  bool continue_processing = true;
+  bool continue_processing = !error;
   if (!error)
-    continue_processing = respond(new_connection);
+    continue_processing = respond(new_connection) && !_interupt;
   //  Continue processing connections
   if (continue_processing)
     start_accept();
+  else
+  {
+    _interupt = true;
+    _io_service.stop();
+  }
 }
 
 bool HttpTestServer::respond(HttpConnection::HttpConnectionPtr& connection)
 {
-  //  Stop processing by setting this to false
-  bool continue_processing = true;
   //  Read the HTTP request, and ignore them
   read_request_headers(connection);
   //  Respond with HTTP 200 OK
-  std::string message;
-  message = std::string(HTTP_200_OK);
+  HttpResponse response(200);
   //  Write out the response
-  write_response(connection, message);
+  write_response(connection, response.to_string());
   //  Return true if we should continue listening and processing requests
-  return continue_processing;
+  return !_interupt;
 }
 
 std::string HttpTestServer::read_request_headers(HttpConnection::HttpConnectionPtr &connection)
@@ -125,10 +183,10 @@ std::string HttpTestServer::read_request_headers(HttpConnection::HttpConnectionP
 
 void HttpTestServer::write_response(HttpConnection::HttpConnectionPtr& connection, const std::string& response)
 {
+  LOG_TRACE("Response:\n" << response);
   //  Write the response to the socket synchronously
   boost::asio::write(connection->socket(), boost::asio::buffer(response));
   connection->socket().close();
 }
 
-
 }
Clone this wiki locally