Skip to content

Commit

Permalink
Merge pull request #130 from MortezaBashsiz/morteza/issue_129
Browse files Browse the repository at this point in the history
Morteza/issue 129 #129
  • Loading branch information
MortezaBashsiz authored Nov 25, 2024
2 parents 805bd0f + 06041b4 commit c03ed2f
Show file tree
Hide file tree
Showing 20 changed files with 1,244 additions and 72 deletions.
62 changes: 62 additions & 0 deletions core/src/agenthandler.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
#include "agenthandler.hpp"

/**
* @brief Constructs an AgentHandler object to manage client-agent interactions.
*
* This constructor initializes the AgentHandler with the necessary resources,
* including read and write buffers, configuration, logging, client connection,
* and a unique identifier for the session.
*
* @param readBuffer Reference to the stream buffer used for reading data.
* @param writeBuffer Reference to the stream buffer used for writing data.
* @param config Shared pointer to the configuration object containing system settings.
* @param log Shared pointer to the logging object for recording events and errors.
* @param client Shared pointer to the TCPClient object managing the client connection.
* @param clientConnStr A string representing the client's connection details.
* @param uuid A unique identifier for the session, provided as a Boost UUID.
*
* @details
* - Initializes the HTTP request handler using the provided configuration, logger,
* read buffer, and UUID.
* - Sets the `end_` flag to `false`, indicating the handler is active and ready.
* - Initializes the `connect_` flag to `false`, indicating no active connection initially.
*/
AgentHandler::AgentHandler(boost::asio::streambuf &readBuffer,
boost::asio::streambuf &writeBuffer,
const std::shared_ptr<Config> &config,
Expand All @@ -21,6 +42,26 @@ AgentHandler::AgentHandler(boost::asio::streambuf &readBuffer,

AgentHandler::~AgentHandler() {}

/**
* @brief Handles the processing of incoming requests, encryption, server communication, and response handling.
*
* This function coordinates multiple tasks, including:
* - Encrypting the incoming data.
* - Generating and sending an HTTP request to the server.
* - Receiving and decrypting the server's response.
* - Managing the connection state and logging detailed information at each step.
*
* @details
* - The function ensures thread safety using a mutex lock.
* - The incoming data is encrypted using AES-256 with a token retrieved from the configuration.
* - If encryption is successful, the function builds an HTTP POST request and determines the request type.
* - It establishes a connection to the server if required and sends the encrypted request.
* - The server's response is parsed and decrypted. If successful, the decrypted data is copied to the write buffer.
* - Handles HTTP and non-HTTP responses, including error scenarios and connection cleanup.
* - Maintains logging for debugging and informational purposes throughout the process.
*
* @note In case of any error during encryption, connection, or response handling, the client socket is closed.
*/
void AgentHandler::handle() {
std::lock_guard<std::mutex> lock(mutex_);

Expand Down Expand Up @@ -140,6 +181,27 @@ void AgentHandler::handle() {
}
}

/**
* @brief Continues reading and processing data from the server, handling encryption, decryption, and responses.
*
* This function performs the following tasks:
* - Generates a REST-based HTTP POST request and sends it to the server.
* - Handles the server's response, including parsing, decryption, and processing.
* - Logs detailed information about the request, response, and errors encountered during processing.
*
* @details
* - Thread safety is ensured using a mutex lock.
* - The request data is generated using the `genHttpRestPostReqString` method and sent to the server.
* - Upon receiving the server's response, the function parses it as an HTTP response.
* - The body of the response is decrypted using AES-256, and the decrypted content is stored in the write buffer.
* - If the response indicates the end of a chunked transfer (`chunkHeader` set to "yes"), the `end_` flag is set to `true`.
* - Handles both HTTP and non-HTTP responses, logging any issues encountered.
* - In case of decryption failure or an empty response, the client socket is closed.
*
* @note
* - This function assumes that the client connection is already established and ready for communication.
* - Errors in decryption, parsing, or an empty response buffer will terminate the connection.
*/
void AgentHandler::continueRead() {
std::lock_guard<std::mutex> lock(mutex_);
std::string newReq(
Expand Down
81 changes: 69 additions & 12 deletions core/src/agenthandler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,40 @@
#include "log.hpp"
#include "tcpclient.hpp"

/**
* @brief The `AgentHandler` class manages the interaction between the client and the agent,
* including handling requests, responses, and connection state.
*
* @details
* - This class is derived from `Uncopyable` to prevent copying or assignment.
* - It provides functionality for handling initial requests (`handle`) and continuing
* with subsequent reads and responses (`continueRead`).
* - Uses Boost.Asio stream buffers for managing input and output data streams.
* - Ensures thread safety with an internal mutex.
* - Maintains the connection state with `end_` and `connect_` flags.
* - Supports logging and configuration through shared pointers to external objects.
*
* @note
* - The class uses a `pointer` alias for shared ownership management via `std::shared_ptr`.
* - The `create` static factory method constructs an instance and returns it as a `pointer`.
* - Requires a valid Boost.Asio I/O context and other dependencies to function properly.
*/
class AgentHandler : private Uncopyable {
public:
using pointer = std::shared_ptr<AgentHandler>;


/**
* @brief Factory method to create an instance of `AgentHandler`.
*
* @param readBuffer Reference to the stream buffer for reading data.
* @param writeBuffer Reference to the stream buffer for writing data.
* @param config Shared pointer to the configuration object.
* @param log Shared pointer to the logging object.
* @param client Shared pointer to the `TCPClient` object managing the connection.
* @param clientConnStr String containing the client connection information.
* @param uuid Unique identifier for this handler, represented as a Boost UUID.
* @return A shared pointer to the newly created `AgentHandler` instance.
*/
static pointer create(boost::asio::streambuf &readBuffer,
boost::asio::streambuf &writeBuffer,
const std::shared_ptr<Config> &config,
Expand All @@ -27,16 +56,45 @@ class AgentHandler : private Uncopyable {

~AgentHandler();

/**
* @brief Handles the initial processing of requests, encryption, and server communication.
*/
void handle();

/**
* @brief Continues processing subsequent reads, handling responses, and decryption.
*/
void continueRead();

/**
* @brief Accessor for the HTTP request object.
*
* @return A reference to the HTTP request object.
*/
inline const HTTP::pointer &request() & { return request_; }

/**
* @brief Accessor for the HTTP request object, allowing move semantics.
*
* @return An rvalue reference to the HTTP request object.
*/
inline const HTTP::pointer &&request() && { return std::move(request_); }

bool end_, connect_;
bool end_; ///< Indicates whether the handler has completed its operations.
bool connect_;///< Indicates the connection state.

private:
/**
* @brief Constructs an `AgentHandler` instance with the specified parameters.
*
* @param readBuffer Reference to the stream buffer for reading data.
* @param writeBuffer Reference to the stream buffer for writing data.
* @param config Shared pointer to the configuration object.
* @param log Shared pointer to the logging object.
* @param client Shared pointer to the `TCPClient` object managing the connection.
* @param clientConnStr String containing the client connection information.
* @param uuid Unique identifier for this handler, represented as a Boost UUID.
*/
AgentHandler(boost::asio::streambuf &readBuffer,
boost::asio::streambuf &writeBuffer,
const std::shared_ptr<Config> &config,
Expand All @@ -45,16 +103,15 @@ class AgentHandler : private Uncopyable {
const std::string &clientConnStr,
boost::uuids::uuid uuid);

const std::shared_ptr<Config> &config_;
const std::shared_ptr<Log> &log_;
const TCPClient::pointer &client_;
boost::asio::streambuf &readBuffer_,
&writeBuffer_;
HTTP::pointer request_;
const std::string
&clientConnStr_;
const std::shared_ptr<Config> &config_;///< Configuration object reference.
const std::shared_ptr<Log> &log_; ///< Logging object reference.
const TCPClient::pointer &client_; ///< TCP client managing the connection.
boost::asio::streambuf &readBuffer_; ///< Buffer for reading data.
boost::asio::streambuf &writeBuffer_; ///< Buffer for writing data.
HTTP::pointer request_; ///< HTTP request handler.
const std::string &clientConnStr_; ///< Client connection string.

boost::uuids::uuid uuid_;
boost::uuids::uuid uuid_;///< Unique identifier for this handler.

std::mutex mutex_;
std::mutex mutex_;///< Mutex for ensuring thread safety.
};
73 changes: 72 additions & 1 deletion core/src/config.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
#include "config.hpp"

/**
* @brief Constructs an Config object to manage program configuration.
*
* This constructor initializes the Config with the necessary resources,
* including read and write buffers, configuration, logging, client connection,
* and a unique identifier for the session.
*
* @param mode Reference to the RunMode which program is running.
* @param filePath Reference to config file path.
*
* @details
* - Initializes the config directives.
* - Sets the `runMode_` which defines the mode that program is running Server or Agent mode.
* - Initializes the `configYaml_` which will load config gile in to variables.
*/
Config::Config(const RunMode &mode, const std::string &filePath)
: runMode_(mode),
filePath_(filePath),
Expand Down Expand Up @@ -41,7 +56,15 @@ Config::Config(const RunMode &mode, const std::string &filePath)
}
}


/**
* @brief Constructs an Config object from a config refrence.
*
* This constructor initializes the Config with the necessary resources,
* including read and write buffers, configuration, logging, client connection,
* and a unique identifier for the session.
*
* @param config Reference to the Config pointer.
*/
Config::Config(const Config::pointer &config)
: runMode_(config->runMode()),
configYaml_(YAML::LoadFile(config->filePath())),
Expand All @@ -53,6 +76,9 @@ Config::Config(const Config::pointer &config)

Config::~Config() = default;

/**
* @brief returns Config in string format to print on output.
*/
std::string Config::toString() const {
std::lock_guard<std::mutex> lock(configMutex_);
std::stringstream ss;
Expand Down Expand Up @@ -83,66 +109,111 @@ std::string Config::toString() const {
return ss.str();
}

/**
* @brief returns General struct from Config.
*/
const Config::General &Config::general() const {
std::lock_guard<std::mutex> lock(configMutex_);
return general_;
}

/**
* @brief returns Log struct from Config.
*/
const Config::Log &Config::log() const {
std::lock_guard<std::mutex> lock(configMutex_);
return log_;
}

/**
* @brief returns Server struct from Config.
*/
const Config::Server &Config::server() const {
std::lock_guard<std::mutex> lock(configMutex_);
return server_;
}

/**
* @brief returns Agent struct from Config.
*/
const Config::Agent &Config::agent() const {
std::lock_guard<std::mutex> lock(configMutex_);
return agent_;
}

/**
* @brief returns Threads count from Config.
*/
const unsigned short &Config::threads() const {
std::lock_guard<std::mutex> lock(configMutex_);
return threads_;
}

/**
* @brief sets threads count in Config to specific amount.
*
* @param threads which is threads count.
*/
void Config::threads(unsigned short threads) {
std::lock_guard<std::mutex> lock(configMutex_);
threads_ = threads;
}

/**
* @brief returns listenIp_ from Config.
*/
const std::string &Config::listenIp() const {
std::lock_guard<std::mutex> lock(configMutex_);
return listenIp_;
}

/**
* @brief sets listenIp_ in config
*
* @param refrence to string ip.
*/
void Config::listenIp(const std::string &ip) {
std::lock_guard<std::mutex> lock(configMutex_);
listenIp_ = ip;
}

/**
* @brief returns listenPort_ from Config.
*/
const unsigned short &Config::listenPort() const {
std::lock_guard<std::mutex> lock(configMutex_);
return listenPort_;
}

/**
* @brief sets listenPort_ in config
*
* @param port number.
*/
void Config::listenPort(unsigned short port) {
std::lock_guard<std::mutex> lock(configMutex_);
listenPort_ = port;
}

/**
* @brief returns RunMode struct from Config.
*/
const RunMode &Config::runMode() const {
std::lock_guard<std::mutex> lock(configMutex_);
return runMode_;
}

/**
* @brief returns filePath_ in string format.
*/
const std::string &Config::filePath() const {
std::lock_guard<std::mutex> lock(configMutex_);
return filePath_;
}

/**
* @brief returns runMode in string format.
*/
std::string Config::modeToString() const {
std::lock_guard<std::mutex> lock(configMutex_);
switch (runMode_) {
Expand Down
Loading

0 comments on commit c03ed2f

Please sign in to comment.