214 lines
5.8 KiB
C++
214 lines
5.8 KiB
C++
/*
|
|
* (c) Copyright, Real-Time Innovations, 2022.
|
|
* 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_PROPERTY_HPP
|
|
#define HTTP_SERVER_PROPERTY_HPP
|
|
|
|
#include <algorithm>
|
|
|
|
#include <dds/core/macros.hpp>
|
|
#include <rti/core/NativeValueType.hpp>
|
|
|
|
#include "rti/apputils/util/Path.hpp"
|
|
|
|
#include "rti/apputils/http/common/HttpUtils.hpp"
|
|
|
|
namespace rti { namespace apputils { namespace http { namespace server {
|
|
|
|
/**
|
|
* @brief This class contains the HTTP server properties
|
|
*/
|
|
class ServerProperty {
|
|
public:
|
|
/**
|
|
* @brief ServerProperty constructor
|
|
*/
|
|
ServerProperty(const std::string& ports = HTTP_SERVER_DEFAULT_PORT_STR)
|
|
: handle_options_request_(false)
|
|
{
|
|
listening_ports(ports);
|
|
}
|
|
|
|
/**
|
|
* @brief Destroy the Server Property object
|
|
*/
|
|
virtual ~ServerProperty() = default;
|
|
|
|
/**
|
|
* @brief Return the document root path.
|
|
*
|
|
* @return const std::string&
|
|
*/
|
|
const std::string& document_root() const
|
|
{
|
|
return document_root_;
|
|
}
|
|
|
|
/**
|
|
* @brief Return the web server options.
|
|
*
|
|
* @return const std::vector<std::string>&
|
|
*/
|
|
const std::vector<std::string>& webserver_options() const
|
|
{
|
|
return webserver_options_;
|
|
}
|
|
|
|
/**
|
|
* @brief Return the value of a web server options given it name. If the
|
|
* option is not found, the name will be returned.
|
|
*
|
|
* @return const std::string>& option value, or option name if not found.
|
|
*/
|
|
const std::string& webserver_option(std::string& name) const
|
|
{
|
|
auto it = std::find(
|
|
webserver_options_.begin(),
|
|
webserver_options_.end(),
|
|
name);
|
|
|
|
if (it != webserver_options_.end()
|
|
&& ++it != webserver_options_.end()) {
|
|
return *it;
|
|
}
|
|
|
|
return name;
|
|
}
|
|
|
|
/**
|
|
* @brief This method returns true if the server will handle OPTIONS
|
|
* requests, otherwise false.
|
|
*
|
|
* @return boolean
|
|
*/
|
|
bool handle_options_request() const
|
|
{
|
|
return handle_options_request_;
|
|
}
|
|
|
|
/**
|
|
* @brief Set the document root path.
|
|
*
|
|
* @param document_root
|
|
* @return ServerProperty&
|
|
*/
|
|
ServerProperty& document_root(const std::string& document_root)
|
|
{
|
|
if (!document_root.empty()) {
|
|
document_root_ = util::Path(document_root);
|
|
RTI_SERVICE_CHECK_CONDITION_W_EXTRA_INFO(
|
|
document_root_.exists(),
|
|
"Document root path does not exist");
|
|
set_webserver_option("document_root", document_root_.c_str());
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
/**
|
|
* @brief Set the listening ports.
|
|
*
|
|
* @param listening_ports
|
|
* @return ServerProperty&
|
|
*/
|
|
ServerProperty& listening_ports(const std::string& listening_ports)
|
|
{
|
|
listening_ports_ = listening_ports;
|
|
set_webserver_option("listening_ports", listening_ports.c_str());
|
|
return *this;
|
|
}
|
|
|
|
/**
|
|
* @brief This method enters a key-value pair into the webserver_options
|
|
* array.
|
|
*
|
|
* @param key Name of the option to be set.
|
|
* @param value Value of the option.
|
|
*/
|
|
ServerProperty& set_webserver_option(const char *key, const char *value)
|
|
{
|
|
// Check if the option already exists.
|
|
auto it = std::find(
|
|
webserver_options_.begin(),
|
|
webserver_options_.end(),
|
|
key);
|
|
// if exists modify the value
|
|
if (it != webserver_options_.end()
|
|
&& ++it != webserver_options_.end()) {
|
|
*it = value;
|
|
} else {
|
|
// Add option name
|
|
webserver_options_.emplace_back(key);
|
|
// Add option value
|
|
webserver_options_.emplace_back(value);
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
/**
|
|
* @brief This option enables the server to handle OPTIONS requests if true,
|
|
* otherwise civetweb will handle them.
|
|
*
|
|
* @param handle_options_request boolean value to handle OPTIONS requests.
|
|
* @return ServerProperty&
|
|
*/
|
|
ServerProperty& handle_options_request(bool handle_options_request)
|
|
{
|
|
handle_options_request_ = handle_options_request;
|
|
return *this;
|
|
}
|
|
|
|
static std::string parse_port(const std::string& host)
|
|
{
|
|
std::string::size_type scheme_pos = host.find("://");
|
|
if (scheme_pos == std::string::npos) {
|
|
RTI_THROW_SERVICE_EXCEPTION(
|
|
&RTI_LOG_INIT_FAILURE_s,
|
|
"Invalid scheme format");
|
|
}
|
|
|
|
std::string unformatted_host = host.substr(scheme_pos + 1);
|
|
|
|
std::string::size_type port_pos = unformatted_host.find(":");
|
|
if (port_pos == std::string::npos) {
|
|
RTI_THROW_SERVICE_EXCEPTION(
|
|
&RTI_LOG_INIT_FAILURE_s,
|
|
"Invalid host:port format");
|
|
}
|
|
|
|
std::string port_string = unformatted_host.substr(port_pos + 1);
|
|
|
|
try {
|
|
// Check that port has a valid format
|
|
std::stoi(port_string);
|
|
} catch (...) {
|
|
std::string error_msg;
|
|
error_msg.append("Invalid port value: ").append(port_string);
|
|
RTI_THROW_SERVICE_EXCEPTION(
|
|
&RTI_LOG_INIT_FAILURE_s,
|
|
error_msg.c_str());
|
|
}
|
|
|
|
return port_string;
|
|
}
|
|
|
|
private:
|
|
// Server options
|
|
util::Path document_root_;
|
|
std::string listening_ports_;
|
|
std::vector<std::string> webserver_options_;
|
|
bool handle_options_request_;
|
|
};
|
|
|
|
}}}} // namespace rti::apputils::http::server
|
|
|
|
#endif // HTTP_SERVER_PROPERTY_HPP
|