mirror of
https://github.com/openappsec/attachment.git
synced 2025-11-18 10:10:37 +03:00
pulling from dev
This commit is contained in:
@@ -4,9 +4,10 @@ include_directories(include)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_GNU_SOURCE -lpthread -Wall")
|
||||
|
||||
link_directories(../../core)
|
||||
link_directories(../../core/shmem_ipc)
|
||||
include_directories(../../core/include/attachments)
|
||||
link_directories(${ng_module_osrc_zlib_path}/lib)
|
||||
link_directories(${CMAKE_BINARY_DIR}/core)
|
||||
link_directories(${CMAKE_BINARY_DIR}/core/shmem_ipc)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/core/include/attachments)
|
||||
|
||||
|
||||
add_library(
|
||||
@@ -21,9 +22,10 @@ add_library(
|
||||
nano_attachment_sender.c
|
||||
nano_attachment_sender_thread.c
|
||||
nano_attachment_metric.c
|
||||
nano_compression.c
|
||||
)
|
||||
|
||||
target_link_libraries(nano_attachment shmem_ipc_2 nano_attachment_util)
|
||||
target_link_libraries(nano_attachment shmem_ipc_2 nano_attachment_util compression_utils)
|
||||
|
||||
# add_subdirectory(nano_attachment_ut)
|
||||
|
||||
|
||||
72
attachments/nano_attachment/include/mock_nano_compression.h
Executable file
72
attachments/nano_attachment/include/mock_nano_compression.h
Executable file
@@ -0,0 +1,72 @@
|
||||
#ifndef __MOCK_NANO_COMPRESSION_H__
|
||||
#define __MOCK_NANO_COMPRESSION_H__
|
||||
|
||||
#include "cmock.h"
|
||||
#include "nano_attachment_common.h"
|
||||
|
||||
extern "C" {
|
||||
#include "nano_compression.h"
|
||||
}
|
||||
|
||||
class NanoCompressionMocker : public CMockMocker<NanoCompressionMocker>
|
||||
{
|
||||
public:
|
||||
MOCK_METHOD3(
|
||||
nano_compress_body,
|
||||
HttpBody*(
|
||||
NanoAttachment *attachment,
|
||||
HttpBody *bodies,
|
||||
HttpSessionData *session_data_p
|
||||
)
|
||||
);
|
||||
|
||||
MOCK_METHOD3(
|
||||
nano_decompress_body,
|
||||
HttpBody*(
|
||||
NanoAttachment *attachment,
|
||||
HttpBody *bodies,
|
||||
HttpSessionData *session_data_p
|
||||
)
|
||||
);
|
||||
|
||||
MOCK_METHOD3(
|
||||
nano_free_compressed_body,
|
||||
void(
|
||||
NanoAttachment *attachment,
|
||||
HttpBody *bodies,
|
||||
HttpSessionData *session_data_p
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
CMOCK_MOCK_FUNCTION3(
|
||||
NanoCompressionMocker,
|
||||
nano_compress_body,
|
||||
HttpBody*(
|
||||
NanoAttachment *attachment,
|
||||
HttpBody *bodies,
|
||||
HttpSessionData *session_data_p
|
||||
)
|
||||
);
|
||||
|
||||
CMOCK_MOCK_FUNCTION3(
|
||||
NanoCompressionMocker,
|
||||
nano_decompress_body,
|
||||
HttpBody*(
|
||||
NanoAttachment *attachment,
|
||||
HttpBody *bodies,
|
||||
HttpSessionData *session_data_p
|
||||
)
|
||||
);
|
||||
|
||||
CMOCK_MOCK_FUNCTION3(
|
||||
NanoCompressionMocker,
|
||||
nano_free_compressed_body,
|
||||
void(
|
||||
NanoAttachment *attachment,
|
||||
HttpBody *bodies,
|
||||
HttpSessionData *session_data_p
|
||||
)
|
||||
);
|
||||
|
||||
#endif // __MOCK_NANO_COMPRESSION_H__
|
||||
@@ -15,17 +15,18 @@
|
||||
#include "nano_utils.h"
|
||||
#include "attachment_types.h"
|
||||
#include "nano_blockpage.h"
|
||||
#include "compression_utils.h"
|
||||
#include "nano_compression.h"
|
||||
|
||||
NanoAttachment *
|
||||
InitNanoAttachment(uint8_t attachment_type, int worker_id, int num_of_workers, int logging_fd)
|
||||
{
|
||||
// NanoAttachment *attachment = malloc(sizeof(NanoAttachment));
|
||||
NanoAttachment *attachment = calloc(1, sizeof(NanoAttachment));
|
||||
NanoAttachment *attachment = malloc(sizeof(NanoAttachment));
|
||||
if (attachment == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// memset(attachment, 0, sizeof(NanoAttachment));
|
||||
memset(attachment, 0, sizeof(NanoAttachment));
|
||||
|
||||
attachment->shared_verdict_signal_path[0] = '\0';
|
||||
attachment->worker_id = worker_id;
|
||||
@@ -141,6 +142,10 @@ InitSessionData(NanoAttachment *attachment, SessionID session_id)
|
||||
session_data->processed_req_body_size = 0;
|
||||
session_data->processed_res_body_size = 0;
|
||||
|
||||
session_data->response_data.compression_type = NO_COMPRESSION;
|
||||
session_data->response_data.compression_stream = NULL;
|
||||
session_data->response_data.decompression_stream = NULL;
|
||||
|
||||
return session_data;
|
||||
};
|
||||
|
||||
@@ -153,6 +158,16 @@ FiniSessionData(NanoAttachment *attachment, HttpSessionData *session_data)
|
||||
DBG_LEVEL_DEBUG,
|
||||
"Freeing session data for session_id"
|
||||
);
|
||||
|
||||
if (session_data->response_data.compression_stream != NULL) {
|
||||
finiCompressionStream(session_data->response_data.compression_stream);
|
||||
session_data->response_data.compression_stream = NULL;
|
||||
}
|
||||
|
||||
if (session_data->response_data.decompression_stream != NULL) {
|
||||
finiCompressionStream(session_data->response_data.decompression_stream);
|
||||
session_data->response_data.decompression_stream = NULL;
|
||||
}
|
||||
free(session_data);
|
||||
};
|
||||
|
||||
@@ -208,13 +223,6 @@ SendDataNanoAttachment(NanoAttachment *attachment, AttachmentData *data)
|
||||
return response;
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START Reason: Simple wrapper.
|
||||
AttachmentVerdictResponse SendDataNanoAttachmentWrapper(NanoAttachment *attachment, AttachmentData data)
|
||||
{
|
||||
return SendDataNanoAttachment(attachment, &data);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
///
|
||||
/// @brief Connects to the keep-alive socket.
|
||||
///
|
||||
@@ -587,3 +595,22 @@ FreeAttachmentResponseContent(
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
HttpBody *
|
||||
compressBody(NanoAttachment *attachment, HttpSessionData *session_data, HttpBody *bodies)
|
||||
{
|
||||
return nano_compress_body(attachment, bodies, session_data);
|
||||
}
|
||||
|
||||
|
||||
HttpBody *
|
||||
decompressBody(NanoAttachment *attachment, HttpSessionData *session_data, HttpBody *bodies)
|
||||
{
|
||||
return nano_decompress_body(attachment, bodies, session_data);
|
||||
}
|
||||
|
||||
void
|
||||
freeCompressedBody(NanoAttachment *attachment, HttpSessionData *session_data, HttpBody *bodies)
|
||||
{
|
||||
nano_free_compressed_body(attachment, bodies, session_data);
|
||||
}
|
||||
|
||||
@@ -1,217 +0,0 @@
|
||||
#ifndef __NANO_ATTACHMENT_H__
|
||||
#define __NANO_ATTACHMENT_H__
|
||||
|
||||
#include "nano_attachment_common.h"
|
||||
#include "nano_initializer.h"
|
||||
|
||||
///
|
||||
/// @brief Initializes a NanoAttachment structure.
|
||||
///
|
||||
/// This function initializes a NanoAttachment structure with the specified parameters and default values.
|
||||
///
|
||||
/// @param attachment_type The type of attachment to initialize.
|
||||
/// @param worker_id The ID of the worker associated with the attachment.
|
||||
/// @param num_of_workers The total number of workers.
|
||||
/// @param logging_fd The file descriptor for logging.
|
||||
///
|
||||
/// @return A pointer to the initialized NanoAttachment structure if the function completes, NULL otherwise.
|
||||
///
|
||||
NanoAttachment * InitNanoAttachment(uint8_t attachment_type, int worker_id, int num_of_workers, int logging_fd);
|
||||
|
||||
///
|
||||
/// @brief Cleans up resources associated with a NanoAttachment structure and deallocates memory.
|
||||
///
|
||||
/// This function performs cleanup operations on a NanoAttachment structure and deallocates
|
||||
/// the memory associated with it.
|
||||
/// The function closes the logging file descriptor associated with the NanoAttachment
|
||||
/// and frees the memory allocated for the structure.
|
||||
///
|
||||
/// @param attachment A pointer to the NanoAttachment structure to be cleaned up.
|
||||
///
|
||||
void FiniNanoAttachment(NanoAttachment *attachment);
|
||||
|
||||
///
|
||||
/// @brief Restarts the configuration of a NanoAttachment.
|
||||
///
|
||||
/// @param attachment A pointer to the NanoAttachment whose configuration is to be restarted.
|
||||
///
|
||||
/// @return A NanoCommunicationResult indicating the success or failure of the operation.
|
||||
|
||||
NanoCommunicationResult RestartAttachmentConfiguration(NanoAttachment *attachment);
|
||||
|
||||
///
|
||||
/// @brief Initializes a HttpSessionData structure with default values.
|
||||
///
|
||||
/// This function dynamically allocates memory for a HttpSessionData structure
|
||||
/// and initializes its fields with default values.
|
||||
///
|
||||
/// @param attachment A pointer to the NanoAttachment structure associated with the session.
|
||||
/// @param session_id The ID of the session to be initialized.
|
||||
///
|
||||
/// @return A pointer to the initialized HttpSessionData structure if the function completes, NULL otherwise.
|
||||
///
|
||||
HttpSessionData * InitSessionData(NanoAttachment *attachment, SessionID session_id);
|
||||
|
||||
///
|
||||
/// @brief Cleans up and deallocates resources associated with a HttpSessionData structure.
|
||||
///
|
||||
/// This function performs cleanup operations on a HttpSessionData structure and deallocates
|
||||
/// the memory associated with it. It writes a debug message indicating the session ID being
|
||||
/// freed, and then frees the memory allocated for the HttpSessionData structure.
|
||||
///
|
||||
/// @param attachment A pointer to the NanoAttachment structure associated with the session.
|
||||
/// @param session_data A pointer to the HttpSessionData structure to be cleaned up.
|
||||
///
|
||||
void FiniSessionData(NanoAttachment *attachment, HttpSessionData *session_data);
|
||||
|
||||
///
|
||||
/// @brief Updates a metric associated with a NanoAttachment.
|
||||
///
|
||||
/// This function updates a metric associated with a NanoAttachment structure
|
||||
/// based on the provided metric type and value. It delegates the actual updating
|
||||
/// of the metric to the helper function updateMetricField.
|
||||
///
|
||||
/// @param attachment A pointer to the NanoAttachment structure associated with the metric.
|
||||
/// @param metric The type of metric to be updated.
|
||||
/// @param value The value to be incorporated into the metric calculation.
|
||||
///
|
||||
void UpdateMetric(NanoAttachment *attachment, AttachmentMetricType metric, uint64_t value);
|
||||
|
||||
///
|
||||
/// @brief Sends metric data that been accumulated in the attachment to the service.
|
||||
///
|
||||
/// @param attachment A pointer to the NanoAttachment structure associated with the metric.
|
||||
///
|
||||
void SendAccumulatedMetricData(NanoAttachment *attachment);
|
||||
|
||||
///
|
||||
/// @brief Processes and sends attachment data to the appropriate handlers.
|
||||
///
|
||||
/// This function processes the attachment data based on its chunk type and sends
|
||||
/// it to the appropriate handler functions. If the chunk type is not recognized,
|
||||
/// it sets a default verdict of ATTACHMENT_VERDICT_INSPECT and returns an AttachmentVerdictResponse
|
||||
/// structure containing the default verdict and the session ID from the provided AttachmentData.
|
||||
///
|
||||
/// @param attachment A pointer to the NanoAttachment structure associated with the data.
|
||||
/// @param data A pointer to the AttachmentData structure containing the data to be processed.
|
||||
///
|
||||
/// @return An AttachmentVerdictResponse structure containing the verdict and session ID.
|
||||
///
|
||||
AttachmentVerdictResponse SendDataNanoAttachment(NanoAttachment *attachment, AttachmentData *data);
|
||||
|
||||
AttachmentVerdictResponse SendDataNanoAttachmentWrapper(NanoAttachment *attachment, AttachmentData data);
|
||||
|
||||
///
|
||||
/// @brief Sends a keep-alive signal using a socket connection.
|
||||
///
|
||||
/// @param attachment A pointer to a NanoAttachment struct containing attachment information.
|
||||
///
|
||||
void SendKeepAlive(NanoAttachment *attachment);
|
||||
|
||||
///
|
||||
/// @brief Checks if a session is finalized based on the session's verdict.
|
||||
///
|
||||
/// @param attachment The NanoAttachment object associated with the session.
|
||||
/// @param session_data The HttpSessionData object representing the session.
|
||||
///
|
||||
/// @return Returns 0 if the session is not finalized, 1 otherwise.
|
||||
///
|
||||
int IsSessionFinalized(NanoAttachment *attachment, HttpSessionData *session_data);
|
||||
|
||||
///
|
||||
/// @brief Checks if the response contains modifications.
|
||||
///
|
||||
/// This function determines whether the provided response contains modifications.
|
||||
///
|
||||
/// @param attachment A pointer to a NanoAttachment structure representing the attachment.
|
||||
/// @param session_data A pointer to a HttpSessionData structure containing session data.
|
||||
/// @param response A pointer to an AttachmentVerdictResponse structure representing the response.
|
||||
///
|
||||
/// @return 1 if the response contains modifications, 0 otherwise.
|
||||
///
|
||||
int IsResponseWithModification(
|
||||
NanoAttachment *attachment,
|
||||
HttpSessionData *session_data,
|
||||
AttachmentVerdictResponse *response
|
||||
);
|
||||
|
||||
///
|
||||
/// @brief Retrieves response modifications from the given attachment and session data.
|
||||
///
|
||||
/// @param attachment Pointer to a NanoAttachment object.
|
||||
/// @param session_data Pointer to HttpSessionData object containing session information.
|
||||
/// @param response Pointer to an AttachmentVerdictResponse object.
|
||||
///
|
||||
/// @return NanoResponseModifications structure containing response modifications.
|
||||
///
|
||||
NanoResponseModifications GetResponseModifications(
|
||||
NanoAttachment *attachment,
|
||||
HttpSessionData *session_data,
|
||||
AttachmentVerdictResponse *response
|
||||
);
|
||||
|
||||
///
|
||||
/// @brief Retrieves the type of web response associated with the given attachment and session data.
|
||||
///
|
||||
/// This function checks if the provided response object contains valid web response data.
|
||||
/// If the response object is null, it logs a warning and returns NO_WEB_RESPONSE.
|
||||
/// Otherwise, it returns the type of web response contained in the response object.
|
||||
///
|
||||
/// @param attachment Pointer to the NanoAttachment structure associated with the request.
|
||||
/// @param session_data Pointer to the HttpSessionData structure containing session-related data.
|
||||
/// @param response Pointer to the AttachmentVerdictResponse structure containing response data.
|
||||
///
|
||||
/// @return The type of web response, or NO_WEB_RESPONSE if no response object is provided.
|
||||
///
|
||||
NanoWebResponseType GetWebResponseType(
|
||||
NanoAttachment *attachment,
|
||||
HttpSessionData *session_data,
|
||||
AttachmentVerdictResponse *response
|
||||
);
|
||||
|
||||
///
|
||||
/// @brief Retrieves the block page data for a response.
|
||||
///
|
||||
/// @param attachment The NanoAttachment object associated with the session.
|
||||
/// @param session_data The HttpSessionData object representing the session.
|
||||
/// @param response The AttachmentVerdictResponse object containing the verdict.
|
||||
///
|
||||
/// @return
|
||||
///
|
||||
BlockPageData GetBlockPage(
|
||||
NanoAttachment *attachment,
|
||||
HttpSessionData *session_data,
|
||||
AttachmentVerdictResponse *response
|
||||
);
|
||||
|
||||
///
|
||||
/// @brief Retrieves the redict page data for a response.
|
||||
///
|
||||
/// @param attachment The NanoAttachment object associated with the session.
|
||||
/// @param session_data The HttpSessionData object representing the session.
|
||||
/// @param response The AttachmentVerdictResponse object containing the verdict.
|
||||
///
|
||||
/// @return
|
||||
///
|
||||
RedirectPageData GetRedirectPage(
|
||||
NanoAttachment *attachment,
|
||||
HttpSessionData *session_data,
|
||||
AttachmentVerdictResponse *response
|
||||
);
|
||||
|
||||
///
|
||||
/// @brief Free allocated resources of an AttachmentVerdictResponse.
|
||||
///
|
||||
/// This function frees the allocated resources of an AttachmentVerdictResponse.
|
||||
///
|
||||
/// @param attachment The NanoAttachment object associated with the session.
|
||||
/// @param session_data The HttpSessionData object representing the session.
|
||||
/// @param response The AttachmentVerdictResponse object to be freed.
|
||||
///
|
||||
void FreeAttachmentResponseContent(
|
||||
NanoAttachment *attachment,
|
||||
HttpSessionData *session_data,
|
||||
AttachmentVerdictResponse *response
|
||||
);
|
||||
|
||||
#endif // __NANO_ATTACHMENT_H__
|
||||
@@ -50,6 +50,7 @@ notify_signal_to_service(NanoAttachment *attachment, uint32_t cur_session_id)
|
||||
|
||||
s_poll.fd = attachment->comm_socket;
|
||||
s_poll.events = POLLOUT;
|
||||
s_poll.revents = 0;
|
||||
res = poll(&s_poll, 1, 0);
|
||||
if (res > 0 && s_poll.revents & POLLHUP) {
|
||||
write_dbg(
|
||||
@@ -470,7 +471,7 @@ create_modification_node(NanoAttachment *attachment, SessionID session_id, HttpI
|
||||
"Injection position: %d, "
|
||||
"Injection size: %d, "
|
||||
"Original buffer index: %d, "
|
||||
"Data: %s, "
|
||||
"Modification data: %s, "
|
||||
"Should change data: %d",
|
||||
modification_node->modification.is_header,
|
||||
modification_node->modification.injection_pos,
|
||||
@@ -513,6 +514,15 @@ handle_inject_response(
|
||||
for (modification_index = 0; modification_index < modification_count; modification_index++) {
|
||||
// Go over the modifications and create nodes.
|
||||
new_modification = create_modification_node(attachment, session_id, inject_data);
|
||||
write_dbg(
|
||||
attachment,
|
||||
session_id,
|
||||
DBG_LEVEL_DEBUG,
|
||||
"create modification node %d out of %d",
|
||||
modification_index,
|
||||
modification_count
|
||||
);
|
||||
|
||||
if (new_modification == NULL) {
|
||||
write_dbg(attachment, session_id, DBG_LEVEL_WARNING, "Failed to create modification node");
|
||||
while (*modification_list) {
|
||||
@@ -527,6 +537,10 @@ handle_inject_response(
|
||||
*modification_list = new_modification;
|
||||
current_modification = *modification_list;
|
||||
} else {
|
||||
while (*modification_list) {
|
||||
current_modification = *modification_list;
|
||||
*modification_list = (*modification_list)->next;
|
||||
}
|
||||
current_modification->next = new_modification;
|
||||
current_modification = current_modification->next;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,64 @@
|
||||
#include "nano_attachment_sender_thread.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "nano_initializer.h"
|
||||
#include "nano_attachment_sender.h"
|
||||
#include "nano_attachment_common.h"
|
||||
#include "nano_attachment_io.h"
|
||||
#include "nano_utils.h"
|
||||
#include "nano_compression.h"
|
||||
|
||||
static HttpHeaderData *
|
||||
get_http_header(HttpHeaders *http_headers, const char *header_name) {
|
||||
size_t i;
|
||||
for (i = 0; i < http_headers->headers_count; ++i) {
|
||||
if (strcmp((char*)http_headers->data[i].key.data, header_name) == 0) {
|
||||
return &http_headers->data[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
set_response_content_encoding(
|
||||
NanoAttachment *attachment,
|
||||
HttpSessionData *session_data_p,
|
||||
HttpHeaders *http_headers
|
||||
)
|
||||
{
|
||||
write_dbg(
|
||||
attachment,
|
||||
session_data_p->session_id,
|
||||
DBG_LEVEL_TRACE,
|
||||
"Determining response body's content encoding"
|
||||
);
|
||||
|
||||
const HttpHeaderData *content_encoding = get_http_header(http_headers, "content-encoding");
|
||||
|
||||
if (content_encoding == NULL) {
|
||||
session_data_p->response_data.compression_type = NO_COMPRESSION;
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp((char*)content_encoding->value.data, "gzip") == 0) {
|
||||
session_data_p->response_data.compression_type = GZIP;
|
||||
} else if (strcmp((char*)content_encoding->value.data, "deflate") == 0) {
|
||||
session_data_p->response_data.compression_type = ZLIB;
|
||||
} else if (strcmp((char*)content_encoding->value.data, "identity") == 0) {
|
||||
session_data_p->response_data.compression_type = NO_COMPRESSION;
|
||||
} else {
|
||||
write_dbg(
|
||||
attachment,
|
||||
session_data_p->session_id,
|
||||
DBG_LEVEL_WARNING,
|
||||
"Unsupported response content encoding: %.*s",
|
||||
content_encoding->value.data
|
||||
);
|
||||
session_data_p->response_data.compression_type = NO_COMPRESSION;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
init_thread_ctx(HttpEventThreadCtx *ctx, NanoAttachment *attachment, AttachmentData *data)
|
||||
@@ -133,7 +188,7 @@ SendResponseHeadersThread(void *_ctx)
|
||||
NanoAttachment *attachment = ctx->attachment;
|
||||
HttpSessionData *session_data_p = ctx->session_data_p;
|
||||
HttpHeaders *http_headers = headers->headers;
|
||||
bool is_verdict_requested = false;
|
||||
bool is_verdict_requested = true;
|
||||
|
||||
nano_send_response_code(
|
||||
attachment,
|
||||
@@ -151,6 +206,12 @@ SendResponseHeadersThread(void *_ctx)
|
||||
&session_data_p->remaining_messages_to_reply
|
||||
);
|
||||
|
||||
set_response_content_encoding(
|
||||
attachment,
|
||||
session_data_p,
|
||||
http_headers
|
||||
);
|
||||
|
||||
nano_header_sender(
|
||||
attachment,
|
||||
http_headers,
|
||||
|
||||
@@ -49,3 +49,9 @@ add_unit_test(
|
||||
"nano_attachment_metrics_ut.cc"
|
||||
"nano_attachment"
|
||||
)
|
||||
|
||||
add_unit_test(
|
||||
nano_compression_ut
|
||||
"nano_compression_ut.cc"
|
||||
"nano_attachment"
|
||||
)
|
||||
|
||||
@@ -25,7 +25,6 @@ public:
|
||||
initializer_mocker,
|
||||
nano_attachment_init_process(_)).WillOnce(Return(NanoCommunicationResult::NANO_OK)
|
||||
);
|
||||
setenv("CLOUDGUARD_UID", "Testing", 1);
|
||||
attachment = InitNanoAttachment(
|
||||
static_cast<uint8_t>(AttachmentType::NGINX_ATT_ID),
|
||||
2,
|
||||
@@ -67,6 +66,10 @@ public:
|
||||
free(reply_from_service_mock);
|
||||
FiniSessionData(attachment, session_data);
|
||||
FiniNanoAttachment(attachment);
|
||||
::testing::Mock::VerifyAndClearExpectations(&initializer_mocker);
|
||||
::testing::Mock::VerifyAndClearExpectations(&mock_shmem_ipc);
|
||||
::testing::Mock::VerifyAndClearExpectations(&mock_nano_socket);
|
||||
::testing::Mock::VerifyAndClearExpectations(&mock_nano_poll);
|
||||
}
|
||||
|
||||
nano_str_t
|
||||
@@ -156,6 +159,8 @@ public:
|
||||
HttpWebResponseData *web_response_data;
|
||||
uint32_t reply_session_id = -1;
|
||||
void *reply_session_id_void = &reply_session_id;
|
||||
struct pollfd fds;
|
||||
struct pollfd *mock_fds = &fds;
|
||||
const char **replay_data_mock;
|
||||
|
||||
NanoAttachment *attachment;
|
||||
@@ -421,7 +426,17 @@ TEST_F(NanoAttachmentIoTest, NanoBodySender)
|
||||
EXPECT_CALL(
|
||||
mock_nano_poll,
|
||||
poll(_, _, _)
|
||||
).WillRepeatedly(Return(1));
|
||||
).WillRepeatedly(
|
||||
DoAll(
|
||||
SaveArg<0>(&mock_fds),
|
||||
InvokeWithoutArgs(
|
||||
[&] () {
|
||||
mock_fds[0].revents = POLLIN;
|
||||
}
|
||||
),
|
||||
Return(1)
|
||||
)
|
||||
);
|
||||
|
||||
EXPECT_CALL(
|
||||
mock_nano_socket,
|
||||
|
||||
@@ -24,7 +24,6 @@ public:
|
||||
).WillOnce(
|
||||
Return(NanoCommunicationResult::NANO_OK)
|
||||
);
|
||||
setenv("CLOUDGUARD_UID", "Testing", 1);
|
||||
attachment = InitNanoAttachment(
|
||||
static_cast<uint8_t>(AttachmentType::NGINX_ATT_ID),
|
||||
2,
|
||||
@@ -32,6 +31,7 @@ public:
|
||||
STDOUT_FILENO
|
||||
);
|
||||
EXPECT_NE(attachment, nullptr);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -26,7 +26,6 @@ public:
|
||||
).WillOnce(
|
||||
Return(NanoCommunicationResult::NANO_OK)
|
||||
);
|
||||
setenv("CLOUDGUARD_UID", "Testing", 1);
|
||||
attachment = InitNanoAttachment(
|
||||
static_cast<uint8_t>(AttachmentType::NGINX_ATT_ID),
|
||||
2,
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "mock_nano_initializer.h"
|
||||
#include "mock_nano_attachment_sender.h"
|
||||
#include "mock_nano_configuration.h"
|
||||
#include "mock_nano_compression.h"
|
||||
|
||||
extern "C" {
|
||||
#include "nano_attachment.h"
|
||||
@@ -26,7 +27,6 @@ public:
|
||||
).WillOnce(
|
||||
Return(NanoCommunicationResult::NANO_OK)
|
||||
);
|
||||
setenv("CLOUDGUARD_UID", "Testing", 1);
|
||||
attachment = InitNanoAttachment(
|
||||
static_cast<uint8_t>(AttachmentType::NGINX_ATT_ID),
|
||||
2,
|
||||
@@ -199,6 +199,7 @@ public:
|
||||
StrictMock<NanoInitializerMocker> initializer_mocker;
|
||||
StrictMock<NanoSocketMocker> socket_mocker;
|
||||
StrictMock<NanoConfigurationMocker> configuration_mocker;
|
||||
StrictMock<NanoCompressionMocker> compression_mocker;
|
||||
};
|
||||
|
||||
TEST_F(NanoAttachmentTest, InitNanoAttachment)
|
||||
@@ -450,3 +451,32 @@ TEST_F(NanoAttachmentTest, SendAccumulatedMetricData)
|
||||
EXPECT_CALL(sender_mocker, SendMetricData(attachment)).WillOnce(Return(NanoCommunicationResult::NANO_OK));
|
||||
SendAccumulatedMetricData(attachment);
|
||||
}
|
||||
|
||||
TEST_F(NanoAttachmentTest, CompressData)
|
||||
{
|
||||
EXPECT_CALL(
|
||||
compression_mocker,
|
||||
nano_compress_body(attachment, &http_body_data, session_data)
|
||||
).WillOnce(Return(nullptr)
|
||||
);
|
||||
compressBody(attachment, session_data, &http_body_data);
|
||||
}
|
||||
|
||||
TEST_F(NanoAttachmentTest, DecompressData)
|
||||
{
|
||||
EXPECT_CALL(
|
||||
compression_mocker,
|
||||
nano_decompress_body(attachment, &http_body_data, session_data)
|
||||
).WillOnce(Return(nullptr)
|
||||
);
|
||||
decompressBody(attachment, session_data, &http_body_data);
|
||||
}
|
||||
|
||||
TEST_F(NanoAttachmentTest, FreeCompressedData)
|
||||
{
|
||||
EXPECT_CALL(
|
||||
compression_mocker,
|
||||
nano_free_compressed_body(attachment, &http_body_data, session_data)
|
||||
);
|
||||
freeCompressedBody(attachment, session_data, &http_body_data);
|
||||
}
|
||||
|
||||
105
attachments/nano_attachment/nano_attachment_ut/nano_compression_ut.cc
Executable file
105
attachments/nano_attachment/nano_attachment_ut/nano_compression_ut.cc
Executable file
@@ -0,0 +1,105 @@
|
||||
#include "cptest.h"
|
||||
#include "nano_attachment_common.h"
|
||||
#include "attachment_types.h"
|
||||
#include "compression_utils.h"
|
||||
|
||||
#include "mock_nano_socket.h"
|
||||
#include "mock_nano_initializer.h"
|
||||
#include "mock_nano_attachment_sender.h"
|
||||
#include "mock_nano_configuration.h"
|
||||
#include "mock_nano_compression.h"
|
||||
|
||||
extern "C" {
|
||||
#include "nano_attachment.h"
|
||||
#include "nano_compression.h"
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
using namespace testing;
|
||||
|
||||
class NanoAttachmentTest : public Test
|
||||
{
|
||||
public:
|
||||
void
|
||||
SetUp() override
|
||||
{
|
||||
EXPECT_CALL(
|
||||
initializer_mocker,
|
||||
nano_attachment_init_process(_)
|
||||
).WillOnce(
|
||||
Return(NanoCommunicationResult::NANO_OK)
|
||||
);
|
||||
attachment = InitNanoAttachment(
|
||||
static_cast<uint8_t>(AttachmentType::NGINX_ATT_ID),
|
||||
2,
|
||||
4,
|
||||
STDOUT_FILENO
|
||||
);
|
||||
EXPECT_NE(attachment, nullptr);
|
||||
|
||||
session_data = InitSessionData(attachment, 1);
|
||||
EXPECT_NE(session_data, nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
TearDown() override
|
||||
{
|
||||
FiniSessionData(attachment, session_data);
|
||||
FiniNanoAttachment(attachment);
|
||||
}
|
||||
|
||||
nano_str_t
|
||||
create_nano_str(const char *str)
|
||||
{
|
||||
nano_str_t nano_str;
|
||||
nano_str.data = reinterpret_cast<unsigned char *>(const_cast<char *>(str));
|
||||
nano_str.len = strlen(str);
|
||||
return nano_str;
|
||||
}
|
||||
|
||||
nano_str_t body[3] = {
|
||||
create_nano_str("Hello"),
|
||||
create_nano_str("World"),
|
||||
create_nano_str("!")
|
||||
};
|
||||
|
||||
HttpBody http_body_data = {
|
||||
body,
|
||||
3
|
||||
};
|
||||
|
||||
AttachmentData req_body_data = {
|
||||
1,
|
||||
HttpChunkType::HTTP_REQUEST_BODY,
|
||||
session_data,
|
||||
(DataBuffer)&http_body_data
|
||||
};
|
||||
|
||||
NanoAttachment *attachment;
|
||||
HttpSessionData *session_data;
|
||||
StrictMock<NanoInitializerMocker> initializer_mocker;
|
||||
};
|
||||
|
||||
TEST_F(NanoAttachmentTest, CompressData)
|
||||
{
|
||||
session_data->response_data.compression_type = CompressionType::GZIP;
|
||||
|
||||
HttpBody * compressed_body_data = nullptr;
|
||||
HttpBody * decompressed_body_data = nullptr;
|
||||
|
||||
compressed_body_data = nano_compress_body(attachment, &http_body_data, session_data);
|
||||
EXPECT_EQ(compressed_body_data->bodies_count, 3u);
|
||||
|
||||
decompressed_body_data = nano_decompress_body(attachment, compressed_body_data, session_data);
|
||||
EXPECT_EQ(decompressed_body_data->bodies_count, 3u);
|
||||
EXPECT_EQ(decompressed_body_data->data[0].len, 5u);
|
||||
EXPECT_EQ(decompressed_body_data->data[1].len, 5u);
|
||||
EXPECT_EQ(decompressed_body_data->data[2].len, 1u);
|
||||
|
||||
EXPECT_EQ(strncmp((char *)decompressed_body_data->data[0].data, "Hello", decompressed_body_data->data[0].len), 0);
|
||||
EXPECT_EQ(strncmp((char *)decompressed_body_data->data[1].data, "World", decompressed_body_data->data[1].len), 0);
|
||||
EXPECT_EQ(strncmp((char *)decompressed_body_data->data[2].data, "!", decompressed_body_data->data[2].len), 0);
|
||||
|
||||
nano_free_compressed_body(attachment, compressed_body_data, session_data);
|
||||
nano_free_compressed_body(attachment, decompressed_body_data, session_data);
|
||||
}
|
||||
@@ -90,7 +90,6 @@ TEST_F(NanoConfigurationTest, InitAttachmentConfiguration)
|
||||
res = set_logging_fd(&attachment, STDOUT_FILENO);
|
||||
EXPECT_EQ(res, NanoCommunicationResult::NANO_OK);
|
||||
|
||||
setenv("CLOUDGUARD_UID", "Testing", 1);
|
||||
res = set_docker_id(&attachment);
|
||||
EXPECT_EQ(res, NanoCommunicationResult::NANO_OK);
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ public:
|
||||
).WillOnce(
|
||||
Return(NanoCommunicationResult::NANO_OK)
|
||||
);
|
||||
setenv("CLOUDGUARD_UID", "Testing", 1);
|
||||
attachment = InitNanoAttachment(
|
||||
static_cast<uint8_t>(AttachmentType::NGINX_ATT_ID),
|
||||
2,
|
||||
@@ -77,7 +76,7 @@ public:
|
||||
create_nano_str("/dogs.html")
|
||||
};
|
||||
|
||||
HttpHeaderData http_headers[3] = {
|
||||
HttpHeaderData http_headers[4] = {
|
||||
{
|
||||
create_nano_str("Host"),
|
||||
create_nano_str("www.nanoattachmentut.com")
|
||||
@@ -89,12 +88,16 @@ public:
|
||||
{
|
||||
create_nano_str("Accept"),
|
||||
create_nano_str("text/html")
|
||||
},
|
||||
{
|
||||
create_nano_str("content-encoding"),
|
||||
create_nano_str("gzip")
|
||||
}
|
||||
};
|
||||
|
||||
HttpHeaders http_headers_data = {
|
||||
http_headers,
|
||||
3
|
||||
4
|
||||
};
|
||||
|
||||
HttpRequestFilterData request_filter_data = {
|
||||
@@ -348,12 +351,14 @@ TEST_F(NanoAttachmentSenderThreadTest, SendResponseHeadersThread)
|
||||
AttachmentDataType::RESPONSE_HEADER,
|
||||
session_data->session_id,
|
||||
&session_data->remaining_messages_to_reply,
|
||||
false
|
||||
true
|
||||
)
|
||||
);
|
||||
|
||||
init_thread_ctx(&ctx, attachment, &res_header_data);
|
||||
SendResponseHeadersThread(&ctx);
|
||||
|
||||
EXPECT_EQ(session_data->response_data.compression_type, CompressionType::GZIP);
|
||||
}
|
||||
|
||||
TEST_F(NanoAttachmentSenderThreadTest, SendRequestBodyThread)
|
||||
|
||||
@@ -27,7 +27,6 @@ public:
|
||||
).WillOnce(
|
||||
Return(NanoCommunicationResult::NANO_OK)
|
||||
);
|
||||
setenv("CLOUDGUARD_UID", "Testing", 1);
|
||||
attachment = InitNanoAttachment(
|
||||
static_cast<uint8_t>(AttachmentType::NGINX_ATT_ID),
|
||||
2,
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
|
||||
link_directories(${BOOST_ROOT}/lib)
|
||||
|
||||
add_definitions(-DUSERSPACE)
|
||||
add_library(nano_attachment_util SHARED nano_attachment_util.cc)
|
||||
target_link_libraries(nano_attachment_util http_configuration)
|
||||
|
||||
130
attachments/nano_attachment/nano_compression.c
Executable file
130
attachments/nano_attachment/nano_compression.c
Executable file
@@ -0,0 +1,130 @@
|
||||
#include "nano_compression.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "nano_attachment_common.h"
|
||||
#include "nano_initializer.h"
|
||||
#include "compression_utils.h"
|
||||
#include "nano_utils.h"
|
||||
|
||||
HttpBody *
|
||||
nano_compress_body(
|
||||
NanoAttachment *attachment,
|
||||
HttpBody *bodies,
|
||||
HttpSessionData *session_data_p
|
||||
)
|
||||
{
|
||||
CompressionResult compression_result;
|
||||
HttpBody *compressed_body;
|
||||
size_t i;
|
||||
|
||||
if (session_data_p->response_data.compression_type == NO_COMPRESSION) {
|
||||
return NULL;
|
||||
}
|
||||
write_dbg(
|
||||
attachment,
|
||||
session_data_p->session_id,
|
||||
DBG_LEVEL_TRACE,
|
||||
"Compressing body"
|
||||
);
|
||||
|
||||
if (session_data_p->response_data.compression_stream == NULL) {
|
||||
session_data_p->response_data.compression_stream = initCompressionStream();
|
||||
}
|
||||
|
||||
compressed_body = malloc(sizeof(HttpBody));
|
||||
if (compressed_body == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
compressed_body->bodies_count = bodies->bodies_count;
|
||||
compressed_body->data = malloc(bodies->bodies_count * sizeof(nano_str_t));
|
||||
if (compressed_body->data == NULL) {
|
||||
free(compressed_body);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < bodies->bodies_count; ++i) {
|
||||
compression_result = compressData(
|
||||
session_data_p->response_data.compression_stream,
|
||||
session_data_p->response_data.compression_type,
|
||||
bodies->data[i].len,
|
||||
bodies->data[i].data,
|
||||
i == bodies->bodies_count - 1
|
||||
);
|
||||
compressed_body->data[i].len = compression_result.num_output_bytes;
|
||||
compressed_body->data[i].data = compression_result.output;
|
||||
}
|
||||
|
||||
return compressed_body;
|
||||
}
|
||||
|
||||
HttpBody *
|
||||
nano_decompress_body(
|
||||
NanoAttachment *attachment,
|
||||
HttpBody *bodies,
|
||||
HttpSessionData *session_data_p
|
||||
)
|
||||
{
|
||||
DecompressionResult decompression_result;
|
||||
HttpBody *decompressed_body;
|
||||
size_t i;
|
||||
|
||||
if (session_data_p->response_data.compression_type == NO_COMPRESSION) {
|
||||
return NULL;
|
||||
}
|
||||
write_dbg(
|
||||
attachment,
|
||||
session_data_p->session_id,
|
||||
DBG_LEVEL_TRACE,
|
||||
"Decompressing body"
|
||||
);
|
||||
|
||||
if (session_data_p->response_data.decompression_stream == NULL) {
|
||||
session_data_p->response_data.decompression_stream = initCompressionStream();
|
||||
}
|
||||
|
||||
decompressed_body = malloc(sizeof(HttpBody));
|
||||
if (decompressed_body == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
decompressed_body->bodies_count = bodies->bodies_count;
|
||||
decompressed_body->data = malloc(bodies->bodies_count * sizeof(nano_str_t));
|
||||
if (decompressed_body->data == NULL) {
|
||||
free(decompressed_body);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < bodies->bodies_count; ++i) {
|
||||
decompression_result = decompressData(
|
||||
session_data_p->response_data.decompression_stream,
|
||||
bodies->data[i].len,
|
||||
bodies->data[i].data
|
||||
);
|
||||
decompressed_body->data[i].len = decompression_result.num_output_bytes;
|
||||
decompressed_body->data[i].data = decompression_result.output;
|
||||
}
|
||||
|
||||
return decompressed_body;
|
||||
}
|
||||
|
||||
void
|
||||
nano_free_compressed_body(
|
||||
NanoAttachment *attachment,
|
||||
HttpBody *bodies,
|
||||
HttpSessionData *session_data_p
|
||||
)
|
||||
{
|
||||
if (bodies == NULL) {
|
||||
return;
|
||||
}
|
||||
write_dbg(
|
||||
attachment,
|
||||
session_data_p->session_id,
|
||||
DBG_LEVEL_TRACE,
|
||||
"Freeing compressed body"
|
||||
);
|
||||
free(bodies->data);
|
||||
free(bodies);
|
||||
}
|
||||
45
attachments/nano_attachment/nano_compression.h
Executable file
45
attachments/nano_attachment/nano_compression.h
Executable file
@@ -0,0 +1,45 @@
|
||||
#ifndef __NANO_COMPRESSION_H__
|
||||
#define __NANO_COMPRESSION_H__
|
||||
|
||||
#include "nano_attachment_sender_thread.h"
|
||||
|
||||
/// @brief Compresses the given HTTP body using the specified compression type in the session data.
|
||||
///
|
||||
/// @param attachment Pointer to the NanoAttachment structure.
|
||||
/// @param bodies Pointer to the HttpBody structure containing the data to be compressed.
|
||||
/// @param session_data_p Pointer to the HttpSessionData structure containing session-specific data.
|
||||
///
|
||||
/// @return Pointer to a new HttpBody structure containing the compressed data,
|
||||
/// or NULL if compression is not needed or fails.
|
||||
HttpBody *nano_compress_body(
|
||||
NanoAttachment *attachment,
|
||||
HttpBody *bodies,
|
||||
HttpSessionData *session_data_p
|
||||
);
|
||||
|
||||
/// @brief Decompresses the given HTTP body using the specified compression type in the session data.
|
||||
///
|
||||
/// @param attachment Pointer to the NanoAttachment structure.
|
||||
/// @param bodies Pointer to the HttpBody structure containing the data to be decompressed.
|
||||
/// @param session_data_p Pointer to the HttpSessionData structure containing session-specific data.
|
||||
///
|
||||
/// @return Pointer to a new HttpBody structure containing the decompressed data,
|
||||
/// or NULL if decompression is not needed or fails.
|
||||
HttpBody *nano_decompress_body(
|
||||
NanoAttachment *attachment,
|
||||
HttpBody *bodies,
|
||||
HttpSessionData *session_data_p
|
||||
);
|
||||
|
||||
/// @brief Frees the memory allocated for the compressed HTTP body.
|
||||
///
|
||||
/// @param attachment Pointer to the NanoAttachment structure.
|
||||
/// @param bodies Pointer to the HttpBody structure containing the compressed data to be freed.
|
||||
/// @param session_data_p Pointer to the HttpSessionData structure containing session-specific data.
|
||||
void nano_free_compressed_body(
|
||||
NanoAttachment *attachment,
|
||||
HttpBody *bodies,
|
||||
HttpSessionData *session_data_p
|
||||
);
|
||||
|
||||
#endif // __NANO_COMPRESSION_H__
|
||||
@@ -400,7 +400,6 @@ set_docker_id(NanoAttachment *attachment)
|
||||
|
||||
if (!uid_read) {
|
||||
write_dbg(attachment, 0, DBG_LEVEL_WARNING, "Severe error - failed to get uid!");
|
||||
return NANO_ERROR;
|
||||
}
|
||||
|
||||
return NANO_OK;
|
||||
|
||||
Reference in New Issue
Block a user