Adds immediate migration results

This commit is contained in:
torsten committed 2026-08-18 22:12:24 +02:00
1 parent ba4121728b
commit 6a2a0667ab
2395 files changed
+357322 -2524

No files matched your search

@@ -0,0 +1,209 @@
/*
* (c) Copyright, Real-Time Innovations, 2015.
* 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 CIVETWEB_HANDLER_HPP
#define CIVETWEB_HANDLER_HPP
#include <atomic>
#include <CivetServer.h>
#include <civetweb.h>
#include "rti/apputils/http/server/ServerProperty.hpp"
#include "rti/apputils/http/server/Connection.hpp"
#include "rti/apputils/http/server/RequestHandler.hpp"
namespace rti { namespace apputils { namespace http { namespace server {
// Forward declaration
class Server;
/**
* @brief WebHandler implements the handler functions of CivetWeb's API,
* wrapping the calls to the generic RequestHandler. The Request is specialized
* to an specific kind of request handler (e.g., PublisherHandler) whose type is
* specified via template.
*/
class CivetWebHandler : public CivetHandler {
public:
/**
* @brief Constructor of the CivetWebHandler class. It calls the constructor
* of the specific RequestHandler it implements (i.e., handler)
*
* @param web_server_property Reference to the ServerProperty that will
* be used by the RequestHandler.
* @param server Web's server.
*/
explicit CivetWebHandler(
const ServerProperty& web_server_property,
Server& server,
RequestHandler *handler)
: web_server_property_(web_server_property),
server_(server),
handler_(handler),
callbacks_counter_(0)
{ }
/**
* @brief Destructor of the CivetWebHandler class.
*/
virtual ~CivetWebHandler() = default;
/**
* @brief This method handles the POST operation.
*
* @param server CivetWeb's server.
* @param conn CiveWeb's connection.
* @return Always returns true given the fact that the operation is always
* processed by the underlying interfaces.
*/
virtual bool handlePost(CivetServer *, struct mg_connection *conn) final
{
CounterGuard guard { callbacks_counter_ };
Connection connection(conn);
handler_->handle_post(server_, connection, web_server_property_);
return true;
}
/**
* @brief This method handles the PUT operation.
*
* @param server CivetWeb's server.
* @param conn CiveWeb's connection.
* @return Always returns true given the fact that the operation is always
* processed by the underlying interfaces.
*/
virtual bool handlePut(CivetServer *, struct mg_connection *conn) final
{
CounterGuard guard { callbacks_counter_ };
Connection connection(conn);
handler_->handle_put(server_, connection, web_server_property_);
return true;
}
/**
* @brief This method handles the GET operation.
*
* @param server CivetWeb's server.
* @param conn CiveWeb's connection.
* @return Always returns true given the fact that the operation is always
* processed by the underlying interfaces.
*/
virtual bool handleGet(CivetServer *, struct mg_connection *conn) final
{
CounterGuard guard { callbacks_counter_ };
Connection connection(conn);
handler_->handle_get(server_, connection, web_server_property_);
return true;
}
/**
* @brief This method handles the DELETE operation.
*
* @param server CivetWeb's server.
* @param conn CiveWeb's connection.
* @return Always returns true given the fact that the operation is always
* processed by the underlying interfaces.
*/
virtual bool handleDelete(CivetServer *, struct mg_connection *conn) final
{
CounterGuard guard { callbacks_counter_ };
Connection connection(conn);
handler_->handle_delete(server_, connection, web_server_property_);
return true;
}
/**
* @brief This method handles the OPTIONS operation.
*
* @param server CivetWeb's server.
* @param conn CiveWeb's connection.
* @return true if the request was processed by the custom handler,
* otherwise false.
*/
virtual bool handleOptions(CivetServer *, struct mg_connection *conn) final
{
CounterGuard guard { callbacks_counter_ };
if (web_server_property_.handle_options_request()) {
Connection connection(conn);
handler_->handle_options(server_, connection, web_server_property_);
return true;
}
return false;
}
/**
* @brief This method handles the HEAD operation.
*
* @param server CivetWeb's server.
* @param conn CiveWeb's connection.
* @return Always returns true given the fact that the operation is always
* processed by the underlying interfaces.
*/
virtual bool handleHead(CivetServer *, struct mg_connection *conn) final
{
CounterGuard guard { callbacks_counter_ };
Connection connection(conn);
handler_->handle_head(server_, connection, web_server_property_);
return true;
}
/**
* @brief This method handles the PATCH operation.
*
* @param server CivetWeb's server.
* @param conn CiveWeb's connection.
* @return Always returns true given the fact that the operation is always
* processed by the underlying interfaces.
*/
virtual bool handlePatch(CivetServer *, struct mg_connection *conn) final
{
CounterGuard guard { callbacks_counter_ };
Connection connection(conn);
handler_->handle_patch(server_, connection, web_server_property_);
return true;
}
bool callbacks_running() const
{
return callbacks_counter_ != 0;
}
private:
struct CounterGuard {
CounterGuard(std::atomic_short& counter) : counter_(counter)
{
++counter_;
}
~CounterGuard()
{
--counter_;
}
std::atomic_short& counter_;
};
const ServerProperty& web_server_property_;
Server& server_;
std::unique_ptr<RequestHandler> handler_;
std::atomic_short callbacks_counter_;
};
}}}} // namespace rti::apputils::http::server
#endif // CIVETWEB_HANDLER_HPP
@@ -0,0 +1,165 @@
/*
* (c) Copyright, Real-Time Innovations, 2024.
* 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 CIVETWEB_WEBSOCKET_HANDLER_H
#define CIVETWEB_WEBSOCKET_HANDLER_H
#include <CivetServer.h>
#include <civetweb.h>
#include <rti/apputils/http/server/CivetWebSocketConnection.hpp>
#include <rti/apputils/http/server/detail/WebSocketHandler.hpp>
namespace rti { namespace apputils { namespace websocket { namespace civetweb {
/**
* This class implements the CivetWebSocketHandler interface, which is part
* of the CivetWeb API. This class has a WebSocketHandler. It allows us
* to isolate the WebSocket handling that CivetWeb does and the WebSocket
* handling that our WebSocketAPI implements
*/
class CivetWebSocketHandlerImpl : public CivetWebSocketHandler {
public:
CivetWebSocketHandlerImpl(WebSocketHandler& handler) : handler_(handler)
{ }
/**
* This method handles new client connections to the server. For such
* purpose, it creates a new `WebSocketConnection` and attaches it to the
* internal CivetWeb `mg_connection`. This mechanisms allows existing
* connections to be reused in the future.
* @param server CivetWeb server. Unused parameter.
* @param conn CivetWeb connection.
* @return Boolean value indicating the success or failure of the operation.
*/
bool handleConnection(CivetServer *, const struct mg_connection *conn)
{
WebSocketConnection *client_conn =
new CivetWebSocketConnection(const_cast<mg_connection *>(conn));
handler_.handle_connection(*client_conn);
mg_set_user_connection_data(const_cast<mg_connection *>(conn), client_conn);
/*
* client_conn is not being leaked here, it's stored indirectly
* in the user connection data that can be get by calling
* mg_get_user_connection_data as we can see on handleClose.
*/
/* coverity[leaked_storage : FALSE] */
return true;
}
/**
* This method is called when a client connection has ended the handshake
* protocol with success.
* @param server CivetWeb server. Unused parameter.
* @param conn CivetWeb connection
*/
void handleReadyState(CivetServer *, struct mg_connection *conn)
{
WebSocketConnection *client = static_cast<WebSocketConnection *>(
mg_get_user_connection_data(conn));
handler_.handle_ready_state(*client);
}
/**
* This method is called every time a client sends a message to the server
* through the WebSocket connection.
* @param server CivetWeb server. Unused parameter
* @param conn CivetWeb connection
* @param bits A byte with the kind of data (TEXT, PONG, ...)
* @param data String containing the received message, it is not
* null-terminated
* @param data_size String size, the size of the string without the null
* character.
*/
bool handleData(
CivetServer *,
struct mg_connection *conn,
int bits,
char *data,
size_t data_len)
{
StringBuffer msg;
WebSocketConnection *client = static_cast<WebSocketConnection *>(
mg_get_user_connection_data(conn));
// The last byte of the bits say what kind of message it is
switch (((unsigned char) bits) & 0x0F) {
case MG_WEBSOCKET_OPCODE_TEXT:
// This marks the end of the string
*(data + data_len) = '\0';
msg = StringBuffer(data);
try {
handler_.handle_data(*client, msg);
} catch (const RequestException& ex) {
DDSLog_exception(&RTI_LOG_ANY_FAILURE_s, ex.what());
client->send_request_error(ex);
} catch (const rti::apputils::http::HttpException& ex) {
DDSLog_exception(&RTI_LOG_ANY_FAILURE_s, ex.what());
client->send_error(ex);
} catch (...) {
std::string message = "Unexpected exception. The connection will be closed.";
DDSLog_exception(&RTI_LOG_ANY_FAILURE_s, message.c_str());
message.append(": ");
message.append(RTI_FUNCTION_NAME);
client->send(message);
// Close the connection (Especially to avoid vulnerabilities)
client->state(WebSocketStateKind::CLOSE);
client->close();
}
break;
case MG_WEBSOCKET_OPCODE_PING:
// This marks the end of the string
data[data_len] = '\0';
msg = StringBuffer(data);
// just send back the message data in a pong frame
client->send_pong(msg);
break;
default:
break;
}
return true;
}
/**
* This method is called when a client closes the connection. The method
* deletes the connection object.
* @param server CivetWeb Server
* @param conn CivetWeb connection
*/
void handleClose(CivetServer *, const struct mg_connection *conn)
{
struct mg_context *ctx = mg_get_context(conn);
WebSocketConnection *client =
static_cast<WebSocketConnection *>(mg_get_user_connection_data(conn));
if (client->state() != WebSocketStateKind::CLOSE){
handler_.handle_close(*client);
}
mg_lock_context(ctx);
delete client;
mg_set_user_connection_data(const_cast<mg_connection *>(conn), NULL);
mg_unlock_context(ctx);
}
~CivetWebSocketHandlerImpl()
{
}
private:
WebSocketHandler& handler_;
};
}}}} // namespace rti::webdds::websocket::civetweb
#endif
@@ -0,0 +1,63 @@
/*
* (c) Copyright, Real-Time Innovations, 2024.
* 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 WEBSOCKET_HANDLER_HPP
#define WEBSOCKET_HANDLER_HPP
#include <rti/apputils/http/server/WebSocketConnection.hpp>
#include <rti/apputils/StringBuffer.hpp>
namespace rti { namespace apputils { namespace websocket {
/**
* This class is a generic handler for WebSocket communication. It
* implements methods that handle all the different events that can be
* triggered in the context of a WebSocket connection.
*/
class WebSocketHandler {
public:
/**
* This method is called when a client establishes a connection with the
* server. When that happens, we set the status of the WebSocketConnection
* to WebSocketStatus_CREATED.
* @param conn WebSocketConnection connection that will be created
*/
virtual void handle_connection(WebSocketConnection& conn) = 0;
/**
* This method is called when the websocket's handshake protocol has
* ended successfully. The state of the connection is marked as
* WebSocketStateKind::OPEN.
* @param conn WebSocketConnection connection that will be updated
*/
virtual void handle_ready_state(WebSocketConnection& conn) = 0;
/**
* This method is called every time a client sends a message. The message is
* wrapped in a StringBuffer. Upon reception, the method identifies the
* message kind and calls the appropriate Handler for that kind of message.
* @param conn WebSocketConnection connection that sent the message
* @param msg StringBuffer with the corresponding message
*/
virtual void handle_data(
WebSocketConnection& conn,
const StringBuffer& msg) = 0;
/**
* This method is called when a client closes a connection with the server.
* It detaches all conditions that have been previously attached to the
* connection.
* @param conn WebSocketConnection connection that will be closed
*/
virtual void handle_close(WebSocketConnection& conn) = 0;
};
}}} // namespace rti::apputils::websocket
#endif // WEBSOCKET_HANDLER_HPP