Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/include/rti/apputils/http/server/Server.hpp
T

125 lines
3.4 KiB
C++

/*
* (c) Copyright, Real-Time Innovations, 2019.
* All rights reserved.
*
* No duplications, whole or partial, manual or electronic, may be made
* without express written permission. Any such copies, or
* revisions thereof, must display this notice unaltered.
* This code contains trade secrets of Real-Time Innovations, Inc.
*/
#ifndef HTTP_SERVER_HPP
#define HTTP_SERVER_HPP
#include <memory>
#include <string>
#include <thread>
#include <CivetServer.h>
#include "ServerProperty.hpp"
#include "rti/apputils/http/server/detail/CivetWebHandler.hpp"
namespace rti { namespace apputils { namespace http { namespace server {
/**
* @brief Server defines an interface to CivetWeb::CivetServer and allow us to
* create handlers and close the server thought it.
*/
class Server {
public:
/**
* @brief Constructor of the Server class.
*
* @param options CivetServer options
* @param callbacks Callbacks methods
*/
Server(const ServerProperty& server_property,
const CivetCallbacks *callbacks = nullptr)
: server_(std::unique_ptr<CivetServer>(new CivetServer(
server_property.webserver_options(),
callbacks))),
server_property_(server_property),
handlers_()
{ }
~Server()
{
close();
mg_exit_library();
}
/**
* @brief This method closes the server, i.e. calls CivetServer::close().
*/
void close()
{
constexpr auto num_retries = 10u;
for (auto i = 0u; !can_close() && i < num_retries; ++i) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}
server_->close();
}
/**
* @brief Checks if the server has any callbacks still running so that it
* can be closed.
*
* @return True if the server can be closed. False otherwise.
*/
bool can_close()
{
return std::none_of(
handlers_.begin(),
handlers_.end(),
[](const std::unique_ptr<CivetWebHandler>& handler) {
return handler->callbacks_running();
});
}
template <typename Handler>
void add_handler(Handler *handler)
{
handlers_.emplace_back(std::unique_ptr<CivetWebHandler>(
new CivetWebHandler(server_property_, *this, handler)));
server_->addHandler(Handler::URI_PATTERN, handlers_.back().get());
}
/**
* @brief Adds a URI handler. Existing handlers will be overwritten.
*
* @param uri String with the URI
* @param handler CivetServer pointer to the handler that to be added
*/
template <typename Handler>
void add_handler()
{
add_handler(new Handler());
}
/**
* @brief Adds a URI websocket handler. Existing websocket handlers will be
* overwritten.
*
* @param uri String with the URI
* @param websocket_handler CivetServer pointer to the handler that to be
* added
*/
void add_websocket_handler(const std::string& uri, void *websocket_handler)
{
server_->addWebSocketHandler(
uri,
reinterpret_cast<CivetWebSocketHandler *>(websocket_handler));
}
private:
std::unique_ptr<CivetServer> server_;
const ServerProperty& server_property_;
std::vector<std::unique_ptr<CivetWebHandler>> handlers_;
};
}}}} // namespace rti::apputils::http::server
#endif // HTTP_SERVER_HPP