pulling from dev

This commit is contained in:
wiaamm
2025-01-05 12:01:24 +02:00
parent cfeae10dcf
commit f6d7d09bae
26 changed files with 657 additions and 426 deletions

View File

@@ -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)

View 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__

View File

@@ -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);
}

View File

@@ -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__

View File

@@ -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;
}

View File

@@ -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,

View File

@@ -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"
)

View File

@@ -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,

View File

@@ -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

View File

@@ -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,

View File

@@ -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);
}

View 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);
}

View File

@@ -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);

View File

@@ -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)

View File

@@ -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,

View File

@@ -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)

View 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);
}

View 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__

View File

@@ -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;