Adds immediate migration results
This commit is contained in:
2395 files changed
+357322
-2524
No files matched your search
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* (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_CONNECTION_HPP
|
||||
#define HTTP_SERVER_CONNECTION_HPP
|
||||
|
||||
#include <CivetServer.h>
|
||||
#include <civetweb.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "rti/apputils/http/common/HttpUtils.hpp"
|
||||
#include "rti/apputils/http/common/Response.hpp"
|
||||
#include "rti/apputils/http/log/Log.hpp"
|
||||
#include "log.peer.h"
|
||||
|
||||
#include "Request.hpp"
|
||||
|
||||
namespace rti { namespace apputils { namespace http { namespace server {
|
||||
|
||||
/**
|
||||
* @brief This class implements the interfaces defined by rest::Connection to
|
||||
* deal with CivetWeb's native connections.
|
||||
*/
|
||||
class Connection {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor of the Connection class. It saves a reference to
|
||||
* CivetWeb's native connection. It also constructs a Request from
|
||||
* the connection passed by parameter.
|
||||
*
|
||||
* @param conn CivetWeb's connection that is wrapped in this class.
|
||||
*/
|
||||
explicit Connection(mg_connection *conn) : conn_(conn), request_(conn_)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Destructor of the Connection class.
|
||||
*/
|
||||
~Connection()
|
||||
{ }
|
||||
|
||||
/**
|
||||
* @brief This method returns the HTTP request.
|
||||
*
|
||||
* @return The HTTP Request.
|
||||
*/
|
||||
const Request& request() const
|
||||
{
|
||||
return request_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This method returns the CivetWeb's native connection.
|
||||
*
|
||||
* @return The CivetWeb's native connection.
|
||||
*/
|
||||
mg_connection *connection() const
|
||||
{
|
||||
return conn_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This method sends an "Error 501: Not Implemented" response.
|
||||
*/
|
||||
void send_not_implemented(std::string const& message = std::string())
|
||||
{
|
||||
auto response = Response();
|
||||
|
||||
response.http_content_type = HTTP_JSON_CONTENT_TYPE;
|
||||
response.http_status_code =
|
||||
static_cast<unsigned short>(StatusCode::not_implemented);
|
||||
response.http_reason_phrase =
|
||||
status_code_to_string(StatusCode::not_implemented);
|
||||
response.http_content = message;
|
||||
|
||||
this->send_http_response(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This method sends an "OK 204: No Content" response.
|
||||
*/
|
||||
void send_http_ok_no_content()
|
||||
{
|
||||
auto response = Response();
|
||||
|
||||
response.http_content_type = HTTP_JSON_CONTENT_TYPE;
|
||||
response.http_status_code =
|
||||
static_cast<unsigned short>(StatusCode::no_content);
|
||||
response.http_reason_phrase =
|
||||
status_code_to_string(StatusCode::no_content);
|
||||
|
||||
this->send_http_response(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This method sends an "Error 400: Bad Request" response.
|
||||
*/
|
||||
void send_http_bad_request(std::string const& message = std::string())
|
||||
{
|
||||
auto response = Response();
|
||||
|
||||
response.http_content_type = HTTP_JSON_CONTENT_TYPE;
|
||||
response.http_status_code =
|
||||
static_cast<unsigned short>(StatusCode::bad_request);
|
||||
response.http_reason_phrase =
|
||||
status_code_to_string(StatusCode::bad_request);
|
||||
response.http_content = message;
|
||||
|
||||
this->send_http_response(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This method sends an "Error 404: Not Found" response.
|
||||
*/
|
||||
void send_http_not_found(std::string const& message = std::string())
|
||||
{
|
||||
auto response = Response();
|
||||
|
||||
response.http_content_type = HTTP_JSON_CONTENT_TYPE;
|
||||
response.http_status_code =
|
||||
static_cast<unsigned short>(StatusCode::not_found);
|
||||
response.http_reason_phrase =
|
||||
status_code_to_string(StatusCode::not_found);
|
||||
response.http_content = message;
|
||||
|
||||
this->send_http_response(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This method sends an "Error 405: Method Not Allowed" response.
|
||||
*/
|
||||
void send_http_method_not_allowed(
|
||||
std::string const& message = std::string())
|
||||
{
|
||||
auto response = Response();
|
||||
|
||||
response.http_content_type = HTTP_JSON_CONTENT_TYPE;
|
||||
response.http_status_code =
|
||||
static_cast<unsigned short>(StatusCode::not_allowed);
|
||||
response.http_reason_phrase =
|
||||
status_code_to_string(StatusCode::not_allowed);
|
||||
response.http_content = message;
|
||||
|
||||
this->send_http_response(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This method sends an "OK 202: Accepted" response.
|
||||
*/
|
||||
void send_http_accepted(std::string const& message = std::string())
|
||||
{
|
||||
auto response = Response();
|
||||
|
||||
response.http_content_type = HTTP_JSON_CONTENT_TYPE;
|
||||
response.http_status_code =
|
||||
static_cast<unsigned short>(StatusCode::accepted);
|
||||
response.http_reason_phrase =
|
||||
status_code_to_string(StatusCode::accepted);
|
||||
response.http_content = message;
|
||||
|
||||
this->send_http_response(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This method sends an "OK 200: OK" response.
|
||||
*/
|
||||
void send_http_ok(std::string const& message = std::string())
|
||||
{
|
||||
auto response = Response();
|
||||
|
||||
response.http_content_type = HTTP_JSON_CONTENT_TYPE;
|
||||
response.http_status_code = static_cast<unsigned short>(StatusCode::ok);
|
||||
response.http_reason_phrase = status_code_to_string(StatusCode::ok);
|
||||
response.http_content = message;
|
||||
|
||||
this->send_http_response(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This operation constructs an HTTP response given its definition in
|
||||
* Response format. Once the Response is constructed, is sent via CivetWeb's
|
||||
* native APIs.
|
||||
*/
|
||||
void send_http_response(const Response& rpns)
|
||||
{
|
||||
// Constructs headers and body of the HTTP response.
|
||||
auto mg_result = mg_printf(
|
||||
conn_,
|
||||
"HTTP/%s %u %s\r\n"
|
||||
"Content-Type: %s\r\n"
|
||||
"Cache-Control: %s\r\n"
|
||||
"Content-Length: %lu\r\n"
|
||||
"Access-Control-Allow-Origin: *\r\n"
|
||||
"Date: %s\r\n\r\n"
|
||||
"%s",
|
||||
HTTP_VERSION,
|
||||
rpns.http_status_code,
|
||||
rpns.http_reason_phrase.c_str(),
|
||||
rpns.http_content_type.c_str(),
|
||||
HTTP_CACHE_CONTROL_NO_CACHE,
|
||||
rpns.http_content.length(),
|
||||
HttpSettings::get_current_date().c_str(),
|
||||
rpns.http_content.c_str());
|
||||
|
||||
RTI_SERVICE_CHECK_CONDITION_W_EXTRA_INFO(
|
||||
mg_result >= 0,
|
||||
msg_server_error_printf);
|
||||
|
||||
APPUTILSLogMessage_log(
|
||||
RTI_LOG_BIT_LOCAL,
|
||||
&APPUTILS_LOG_HTTP_SENT_RESPONSE_us,
|
||||
rpns.http_status_code,
|
||||
rpns.http_reason_phrase.c_str());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepares and send the body of an HTTP response given an exception.
|
||||
*
|
||||
* @param [in] e Exception to be formatted and sent.
|
||||
*/
|
||||
void send_error_exception_response(const HttpException& e)
|
||||
{
|
||||
auto response = Response();
|
||||
|
||||
response.http_content_type = HTTP_JSON_CONTENT_TYPE;
|
||||
response.http_status_code = static_cast<unsigned short>(e.error_code());
|
||||
response.http_reason_phrase = status_code_to_string(e.error_code());
|
||||
|
||||
nlohmann::json http_content_json;
|
||||
http_content_json["code"] = status_code_to_string(e.error_code());
|
||||
http_content_json["message"] = e.what();
|
||||
response.http_content = http_content_json.dump();
|
||||
|
||||
this->send_http_response(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the content of an HTTP request.
|
||||
*
|
||||
* @param chunk_size size of the chunk to read.
|
||||
* @return std::string with the read content.
|
||||
*/
|
||||
std::string read_content(std::size_t chunk_size = 256)
|
||||
{
|
||||
const auto request_info = mg_get_request_info(conn_);
|
||||
RTI_SERVICE_CHECK_CONDITION_W_EXTRA_INFO(
|
||||
request_info != nullptr,
|
||||
msg_server_error_get_request_info);
|
||||
|
||||
if (request_info->content_length >= 0) {
|
||||
return read_content_with_content_length(
|
||||
conn_,
|
||||
static_cast<std::size_t>(request_info->content_length));
|
||||
}
|
||||
|
||||
return read_content_without_content_length(conn_, chunk_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check that content type is the expected one.
|
||||
*
|
||||
* @param expected_content_type
|
||||
* @return true if the content type is the expected one. otherwise
|
||||
* false.
|
||||
*/
|
||||
bool check_content_type(const std::string& expected_content_type)
|
||||
{
|
||||
auto ret = true;
|
||||
// Check if Content-Type is application/json
|
||||
if (this->request().get_header(
|
||||
rti::apputils::http::HTTP_CONTENT_TYPE_HEADER)
|
||||
!= expected_content_type) {
|
||||
ret = false;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
mg_connection *conn_;
|
||||
Request request_;
|
||||
};
|
||||
|
||||
}}}} // namespace rti::apputils::http::server
|
||||
|
||||
#endif // HTTP_SERVER_CONNECTION_HPP
|
||||
Reference in new issue
Block a user