mirror of
https://github.com/openappsec/attachment.git
synced 2025-08-13 13:25:59 +03:00
sync code
This commit is contained in:
parent
6154961b0b
commit
f450ee82cb
@ -14,7 +14,7 @@ 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) {
|
||||
if (strcasecmp((char*)http_headers->data[i].key.data, header_name) == 0) {
|
||||
return &http_headers->data[i];
|
||||
}
|
||||
}
|
||||
@ -42,11 +42,11 @@ set_response_content_encoding(
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp((char*)content_encoding->value.data, "gzip") == 0) {
|
||||
if (strcasecmp((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) {
|
||||
} else if (strcasecmp((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) {
|
||||
} else if (strcasecmp((char*)content_encoding->value.data, "identity") == 0) {
|
||||
session_data_p->response_data.compression_type = NO_COMPRESSION;
|
||||
} else {
|
||||
write_dbg(
|
||||
|
@ -385,7 +385,7 @@ set_docker_id(NanoAttachment *attachment)
|
||||
}
|
||||
|
||||
if (!uid_read) {
|
||||
const char *env_var_name = "OPENAPPSEC_UID"; // Replace with your environment variable name
|
||||
const char *env_var_name = "CLOUDGUARD_UID"; // Replace with your environment variable name
|
||||
const char *env_value = getenv(env_var_name);
|
||||
|
||||
if (env_value) {
|
||||
|
@ -153,6 +153,47 @@ set_buffer_data(ngx_buf_t *buffer, const ngx_str_t *data)
|
||||
buffer->end = buffer->last;
|
||||
}
|
||||
|
||||
///
|
||||
/// @brief Removes empty chunks from the specified NGINX chain.
|
||||
/// @param[in,out] chain Pointer to the start of the chain to modify.
|
||||
/// @param[in] pool NGINX pool used for allocating and freeing chain links.
|
||||
/// @returns ngx_int_t
|
||||
/// - #NGX_OK
|
||||
/// - #NGX_ERROR
|
||||
///
|
||||
static ngx_int_t
|
||||
ngx_chain_remove_empty_chunks(ngx_chain_t **chain, ngx_pool_t *pool)
|
||||
{
|
||||
ngx_chain_t *prev = NULL;
|
||||
ngx_chain_t *curr = *chain;
|
||||
size_t chunk_num = 0;
|
||||
|
||||
while (curr != NULL) {
|
||||
size_t size = curr->buf->last - curr->buf->pos;
|
||||
if (size == 0) {
|
||||
write_dbg(DBG_LEVEL_WARNING, "Removing empty chunk from the chain, chunk number: %d", chunk_num);
|
||||
if (prev == NULL) {
|
||||
*chain = curr->next;
|
||||
} else {
|
||||
prev->next = curr->next;
|
||||
}
|
||||
ngx_chain_t *tmp = curr;
|
||||
curr = curr->next;
|
||||
ngx_free_chain(pool, tmp);
|
||||
continue;
|
||||
}
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
chunk_num++;
|
||||
}
|
||||
|
||||
if (chunk_num == 0) {
|
||||
write_dbg(DBG_LEVEL_WARNING, "Empty chain after removing empty chunks");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
///
|
||||
/// @brief Decompresses or compresses the provided data.
|
||||
/// @param[in] should_compress Checks if buffer is used for compression or decompression.
|
||||
@ -432,11 +473,17 @@ compress_chain(
|
||||
ngx_pool_t *pool
|
||||
)
|
||||
{
|
||||
ngx_int_t compression_result;
|
||||
ngx_cp_http_compression_params params;
|
||||
params.compression_type = compression_type;
|
||||
params.is_last_part = is_last_part;
|
||||
|
||||
return compression_chain_filter(1, compression_stream, NULL, body, original_body_contents, pool, ¶ms);
|
||||
compression_result = compression_chain_filter(1, compression_stream, NULL, body, original_body_contents, pool, ¶ms);
|
||||
// remove empty chunks from the chain to prevent getting nginx alert: "zero size buf in writer" down the line
|
||||
if (compression_result == NGX_OK) {
|
||||
compression_result = ngx_chain_remove_empty_chunks(body, pool);
|
||||
}
|
||||
return compression_result;
|
||||
}
|
||||
|
||||
///
|
||||
@ -534,6 +581,14 @@ compress_body(
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (compression_type == BROTLI) {
|
||||
// Brotli compression is not supported.
|
||||
// This if statement serves a case that the compression type is set to BROTLI
|
||||
// For now, we should not reach inside this function with a compression type of BROTLI.
|
||||
write_dbg(DBG_LEVEL_WARNING, "Brotli compression is not supported");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
body_type = chunk_type == REQUEST_BODY ? "request" : "response";
|
||||
write_dbg(
|
||||
DBG_LEVEL_TRACE,
|
||||
|
@ -73,6 +73,7 @@ decompress_body(
|
||||
/// @param[in] compression_type Compression type.
|
||||
/// - #GZIP
|
||||
/// - #ZLIB
|
||||
/// - #BROTLI
|
||||
/// - #NO_COMPRESSION - Serves as a sanity check in case this function is called
|
||||
/// on a compression type of data that isn't defined and will return NGX_ERROR.
|
||||
/// @param[in] chunk_type Body chunk type:
|
||||
|
@ -205,11 +205,11 @@ ngx_add_event_id_to_header(ngx_http_request_t *request)
|
||||
}
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_cp_finalize_rejected_request(ngx_http_request_t *request)
|
||||
ngx_http_cp_finalize_rejected_request(ngx_http_request_t *request, int is_response_phase)
|
||||
{
|
||||
static u_char text_html[] = {'t', 'e', 'x', 't', '/', 'h', 't', 'm', 'l'};
|
||||
static size_t size_of_text_html = sizeof(text_html);
|
||||
ngx_int_t http_res_code, rc;
|
||||
ngx_int_t http_res_code, rc = NGX_OK;
|
||||
ngx_table_elt_t *location_header;
|
||||
ngx_chain_t out_chain[7]; // http://lxr.nginx.org/source/src/http/ngx_http_special_response.c#0772
|
||||
int send_response_custom_body = 1;
|
||||
@ -235,6 +235,12 @@ ngx_http_cp_finalize_rejected_request(ngx_http_request_t *request)
|
||||
goto CUSTOM_RES_OUT;
|
||||
}
|
||||
|
||||
if (is_response_phase) {
|
||||
write_dbg(DBG_LEVEL_DEBUG, "Closing connection in response phase");
|
||||
rc = NGX_HTTP_CLOSE;
|
||||
goto CUSTOM_RES_OUT;
|
||||
}
|
||||
|
||||
if (get_response_code() == NGX_HTTP_TEMPORARY_REDIRECT) {
|
||||
// Handling redirect web response.
|
||||
write_dbg(
|
||||
@ -791,7 +797,7 @@ ngx_http_cp_body_modifier(
|
||||
if (curr_modification == NULL) return NGX_OK;
|
||||
if (curr_modification->modification.orig_buff_index != cur_body_chunk) continue;
|
||||
|
||||
cur_chunk_size = body_chain->buf->last - body_chain->buf->pos;
|
||||
cur_chunk_size = chain_iter->buf->last - chain_iter->buf->pos;
|
||||
if (cur_chunk_size == 0) {
|
||||
write_dbg(DBG_LEVEL_TRACE, "No need to modify body chunk of size 0. Chunk index: %d", cur_body_chunk);
|
||||
continue;
|
||||
|
@ -81,7 +81,7 @@ ngx_http_cp_file_response_sender(
|
||||
/// - #NGX_OK
|
||||
/// - #NGX_ERROR
|
||||
///
|
||||
ngx_int_t ngx_http_cp_finalize_rejected_request(ngx_http_request_t *request);
|
||||
ngx_int_t ngx_http_cp_finalize_rejected_request(ngx_http_request_t *request, int is_response_phase);
|
||||
|
||||
///
|
||||
/// @brief Modifies headers with the provided modifiers.
|
||||
|
@ -165,6 +165,7 @@ end_req_header_handler(
|
||||
return ngx_http_cp_reply_receiver(
|
||||
&session_data_p->remaining_messages_to_reply,
|
||||
&session_data_p->verdict,
|
||||
&session_data_p->response_data.inspect_all_response_headers,
|
||||
session_data_p->session_id,
|
||||
request,
|
||||
modifications,
|
||||
@ -189,7 +190,7 @@ ngx_http_cp_req_header_handler_thread(void *_ctx)
|
||||
ngx_uint_t num_messages_sent = 0;
|
||||
ngx_int_t send_header_result;
|
||||
|
||||
send_meta_data_result = ngx_http_cp_meta_data_sender(request, session_data_p->session_id, &num_messages_sent);
|
||||
send_meta_data_result = ngx_http_cp_meta_data_sender(request, session_data_p->session_id, &num_messages_sent, &ctx->waf_tag);
|
||||
if (send_meta_data_result == inspection_irrelevant) {
|
||||
// Ignoring irrelevant requests.
|
||||
session_data_p->verdict = TRAFFIC_VERDICT_IRRELEVANT;
|
||||
@ -223,8 +224,7 @@ ngx_http_cp_req_header_handler_thread(void *_ctx)
|
||||
&(request->headers_in.headers.part),
|
||||
REQUEST_HEADER,
|
||||
session_data_p->session_id,
|
||||
&num_messages_sent,
|
||||
&ctx->waf_tag
|
||||
&num_messages_sent
|
||||
);
|
||||
if (send_header_result != NGX_OK) {
|
||||
write_dbg(
|
||||
@ -281,6 +281,7 @@ ngx_http_cp_req_body_filter_thread(void *_ctx)
|
||||
ctx->res = ngx_http_cp_reply_receiver(
|
||||
&session_data_p->remaining_messages_to_reply,
|
||||
&session_data_p->verdict,
|
||||
&session_data_p->response_data.inspect_all_response_headers,
|
||||
session_data_p->session_id,
|
||||
request,
|
||||
&ctx->modifications,
|
||||
@ -322,6 +323,7 @@ ngx_http_cp_req_end_transaction_thread(void *_ctx)
|
||||
ctx->res = ngx_http_cp_reply_receiver(
|
||||
&session_data_p->remaining_messages_to_reply,
|
||||
&session_data_p->verdict,
|
||||
&session_data_p->response_data.inspect_all_response_headers,
|
||||
session_data_p->session_id,
|
||||
request,
|
||||
&ctx->modifications,
|
||||
@ -407,14 +409,14 @@ ngx_http_cp_res_header_filter_thread(void *_ctx)
|
||||
}
|
||||
session_data_p->response_data.new_compression_type = session_data_p->response_data.original_compression_type;
|
||||
|
||||
if (session_data_p->response_data.inspect_all_response_headers) {
|
||||
// Sends response headers to the nano service.
|
||||
num_messages_sent = 0;
|
||||
send_header_result = ngx_http_cp_header_sender(
|
||||
&request->headers_out.headers.part,
|
||||
RESPONSE_HEADER,
|
||||
session_data_p->session_id,
|
||||
&num_messages_sent,
|
||||
&ctx->waf_tag
|
||||
&num_messages_sent
|
||||
);
|
||||
if (send_header_result != NGX_OK) {
|
||||
write_dbg(
|
||||
@ -430,11 +432,13 @@ ngx_http_cp_res_header_filter_thread(void *_ctx)
|
||||
}
|
||||
|
||||
session_data_p->remaining_messages_to_reply += num_messages_sent;
|
||||
}
|
||||
|
||||
// Fetch nano services' results.
|
||||
ctx->res = ngx_http_cp_reply_receiver(
|
||||
&session_data_p->remaining_messages_to_reply,
|
||||
&session_data_p->verdict,
|
||||
&session_data_p->response_data.inspect_all_response_headers,
|
||||
session_data_p->session_id,
|
||||
request,
|
||||
&ctx->modifications,
|
||||
@ -455,7 +459,13 @@ ngx_http_cp_res_body_filter_thread(void *_ctx)
|
||||
ngx_uint_t num_messages_sent = 0;
|
||||
ngx_int_t is_last_response_part = 0;
|
||||
|
||||
// Send response body data to the nano service.
|
||||
write_dbg(
|
||||
DBG_LEVEL_DEBUG,
|
||||
"Starting response body filter thread for session ID: %d, current verdict: %d",
|
||||
session_data_p->session_id,
|
||||
session_data_p->verdict
|
||||
);
|
||||
|
||||
send_body_result = ngx_http_cp_body_sender(
|
||||
ctx->chain,
|
||||
RESPONSE_BODY,
|
||||
@ -464,6 +474,16 @@ ngx_http_cp_res_body_filter_thread(void *_ctx)
|
||||
&num_messages_sent,
|
||||
&ctx->chain
|
||||
);
|
||||
|
||||
write_dbg(
|
||||
DBG_LEVEL_DEBUG,
|
||||
"Body sender result: %d, num_messages_sent: %d, is_last_response_part: %d for session ID: %d",
|
||||
send_body_result,
|
||||
num_messages_sent,
|
||||
is_last_response_part,
|
||||
session_data_p->session_id
|
||||
);
|
||||
|
||||
if (send_body_result != NGX_OK) {
|
||||
write_dbg(
|
||||
DBG_LEVEL_WARNING,
|
||||
@ -478,9 +498,48 @@ ngx_http_cp_res_body_filter_thread(void *_ctx)
|
||||
}
|
||||
session_data_p->remaining_messages_to_reply += num_messages_sent;
|
||||
|
||||
ctx->res = ngx_http_cp_reply_receiver(
|
||||
&session_data_p->remaining_messages_to_reply,
|
||||
&session_data_p->verdict,
|
||||
&session_data_p->response_data.inspect_all_response_headers,
|
||||
session_data_p->session_id,
|
||||
request,
|
||||
&ctx->modifications,
|
||||
RESPONSE_BODY,
|
||||
session_data_p->processed_res_body_size
|
||||
);
|
||||
|
||||
write_dbg(
|
||||
DBG_LEVEL_DEBUG,
|
||||
"Reply receiver returned: %d, got verdict: %d, remaining messages: %d for session ID: %d",
|
||||
ctx->res,
|
||||
session_data_p->verdict,
|
||||
session_data_p->remaining_messages_to_reply,
|
||||
session_data_p->session_id
|
||||
);
|
||||
|
||||
|
||||
if (session_data_p->verdict == TRAFFIC_VERDICT_WAIT) {
|
||||
if (!ngx_http_cp_hold_verdict(ctx)) {
|
||||
session_data_p->verdict = fail_mode_hold_verdict == NGX_OK ? TRAFFIC_VERDICT_ACCEPT : TRAFFIC_VERDICT_DROP;
|
||||
updateMetricField(HOLD_THREAD_TIMEOUT, 1);
|
||||
handle_inspection_failure(inspection_failure_weight, fail_mode_verdict, session_data_p);
|
||||
if (fail_mode_verdict == NGX_OK) {
|
||||
THREAD_CTX_RETURN_NEXT_FILTER();
|
||||
}
|
||||
THREAD_CTX_RETURN(NGX_HTTP_FORBIDDEN);
|
||||
}
|
||||
}
|
||||
|
||||
num_messages_sent = 0;
|
||||
if (is_last_response_part) {
|
||||
// Signals the nano service that the transaction reached the end.
|
||||
write_dbg(
|
||||
DBG_LEVEL_DEBUG,
|
||||
"This is the last response part, sending RESPONSE_END signal for session ID: %d",
|
||||
session_data_p->session_id
|
||||
);
|
||||
|
||||
if (ngx_http_cp_end_transaction_sender(RESPONSE_END, session_data_p->session_id, &num_messages_sent) != NGX_OK) {
|
||||
write_dbg(
|
||||
DBG_LEVEL_WARNING,
|
||||
@ -493,19 +552,51 @@ ngx_http_cp_res_body_filter_thread(void *_ctx)
|
||||
}
|
||||
THREAD_CTX_RETURN(NGX_HTTP_FORBIDDEN);
|
||||
}
|
||||
session_data_p->remaining_messages_to_reply++;
|
||||
|
||||
if (
|
||||
session_data_p->verdict == TRAFFIC_VERDICT_ACCEPT ||
|
||||
session_data_p->verdict == TRAFFIC_VERDICT_DROP
|
||||
) {
|
||||
write_dbg(
|
||||
DBG_LEVEL_DEBUG,
|
||||
"Will not wait for verdict after RESPONSE_END as we already have verdict %d for session ID %d",
|
||||
session_data_p->session_id,
|
||||
session_data_p->verdict
|
||||
);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Fetch nano services' results.
|
||||
session_data_p->remaining_messages_to_reply += num_messages_sent;
|
||||
ctx->res = ngx_http_cp_reply_receiver(
|
||||
&session_data_p->remaining_messages_to_reply,
|
||||
&session_data_p->verdict,
|
||||
&session_data_p->response_data.inspect_all_response_headers,
|
||||
session_data_p->session_id,
|
||||
request,
|
||||
&ctx->modifications,
|
||||
RESPONSE_BODY,
|
||||
RESPONSE_END,
|
||||
session_data_p->processed_res_body_size
|
||||
);
|
||||
write_dbg(
|
||||
DBG_LEVEL_DEBUG,
|
||||
"Received verdict %d after RESPONSE_END for session ID %d, will proceed normally",
|
||||
session_data_p->verdict,
|
||||
session_data_p->session_id
|
||||
);
|
||||
|
||||
if (session_data_p->verdict == TRAFFIC_VERDICT_WAIT) {
|
||||
if (!ngx_http_cp_hold_verdict(ctx)) {
|
||||
session_data_p->verdict = fail_mode_hold_verdict == NGX_OK ? TRAFFIC_VERDICT_ACCEPT : TRAFFIC_VERDICT_DROP;
|
||||
updateMetricField(HOLD_THREAD_TIMEOUT, 1);
|
||||
handle_inspection_failure(inspection_failure_weight, fail_mode_verdict, session_data_p);
|
||||
if (fail_mode_verdict == NGX_OK) {
|
||||
THREAD_CTX_RETURN_NEXT_FILTER();
|
||||
}
|
||||
THREAD_CTX_RETURN(NGX_HTTP_FORBIDDEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -537,6 +628,7 @@ ngx_http_cp_hold_verdict_thread(void *_ctx)
|
||||
ctx->res = ngx_http_cp_reply_receiver(
|
||||
&session_data_p->remaining_messages_to_reply,
|
||||
&session_data_p->verdict,
|
||||
&session_data_p->response_data.inspect_all_response_headers,
|
||||
session_data_p->session_id,
|
||||
request,
|
||||
&ctx->modifications,
|
||||
|
@ -78,6 +78,7 @@ init_cp_session_data(ngx_http_request_t *request)
|
||||
session_data->response_data.response_data_status = NGX_OK;
|
||||
session_data->response_data.original_compressed_body = NULL;
|
||||
session_data->response_data.request_pool = NULL;
|
||||
session_data->response_data.inspect_all_response_headers = 1;
|
||||
if (!metric_timeout.tv_sec) {
|
||||
metric_timeout = get_timeout_val_sec(METRIC_TIMEOUT_VAL);
|
||||
}
|
||||
@ -86,6 +87,7 @@ init_cp_session_data(ngx_http_request_t *request)
|
||||
session_data->res_proccesing_time = 0;
|
||||
session_data->processed_req_body_size = 0;
|
||||
session_data->processed_res_body_size = 0;
|
||||
session_data->is_res_body_inspected = 0;
|
||||
|
||||
ngx_http_set_ctx(request, session_data, ngx_http_cp_attachment_module);
|
||||
|
||||
@ -334,7 +336,7 @@ ngx_http_cp_finalize_request_headers_hook(
|
||||
|
||||
if (final_res == NGX_HTTP_FORBIDDEN) {
|
||||
handle_inspection_success(session_data_p);
|
||||
return ngx_http_cp_finalize_rejected_request(request);
|
||||
return ngx_http_cp_finalize_rejected_request(request, 0);
|
||||
}
|
||||
|
||||
if (final_res != NGX_OK) {
|
||||
@ -715,6 +717,15 @@ ngx_http_cp_req_body_filter(ngx_http_request_t *request, ngx_chain_t *request_bo
|
||||
return fail_mode_verdict == NGX_OK ? ngx_http_next_request_body_filter(request, request_body_chain) : NGX_HTTP_FORBIDDEN;
|
||||
}
|
||||
|
||||
if (session_data_p->verdict == TRAFFIC_VERDICT_WAIT) {
|
||||
write_dbg(DBG_LEVEL_DEBUG, "spawn ngx_http_cp_hold_verdict");
|
||||
res = ngx_http_cp_hold_verdict(&ctx);
|
||||
if (!res) {
|
||||
write_dbg(DBG_LEVEL_DEBUG, "ngx_http_cp_hold_verdict failed");
|
||||
updateMetricField(HOLD_THREAD_TIMEOUT, 1);
|
||||
}
|
||||
}
|
||||
|
||||
write_dbg(
|
||||
DBG_LEVEL_DEBUG,
|
||||
"finished ngx_http_cp_req_end_transaction_thread successfully. return=%d next_filter=%d res=%d",
|
||||
@ -754,7 +765,7 @@ ngx_http_cp_req_body_filter(ngx_http_request_t *request, ngx_chain_t *request_bo
|
||||
|
||||
if (final_res == NGX_HTTP_FORBIDDEN) {
|
||||
handle_inspection_success(session_data_p);
|
||||
return ngx_http_cp_finalize_rejected_request(request);
|
||||
return ngx_http_cp_finalize_rejected_request(request, 0);
|
||||
}
|
||||
|
||||
if (final_res != NGX_OK) {
|
||||
@ -934,7 +945,7 @@ ngx_http_cp_res_header_filter(ngx_http_request_t *request)
|
||||
|
||||
if (final_res == NGX_HTTP_FORBIDDEN) {
|
||||
handle_inspection_success(session_data_p);
|
||||
return ngx_http_cp_finalize_rejected_request(request);
|
||||
return ngx_http_cp_finalize_rejected_request(request, 0);
|
||||
}
|
||||
|
||||
if (final_res != NGX_OK) {
|
||||
@ -1005,23 +1016,48 @@ ngx_http_cp_res_body_filter(ngx_http_request_t *request, ngx_chain_t *body_chain
|
||||
if (session_data_p->response_data.response_data_status != NGX_OK) {
|
||||
write_dbg(DBG_LEVEL_WARNING, "skipping session with corrupted compression");
|
||||
updateMetricField(CORRUPTED_ZIP_SKIPPED_SESSION_COUNT, 1);
|
||||
if (session_data_p->verdict == TRAFFIC_VERDICT_DROP) request->keepalive = 0;
|
||||
if (session_data_p->verdict == TRAFFIC_VERDICT_DROP) {
|
||||
request->keepalive = 0;
|
||||
}
|
||||
|
||||
if (session_data_p->verdict == TRAFFIC_VERDICT_DROP && session_data_p->is_res_body_inspected) {
|
||||
write_dbg(
|
||||
DBG_LEVEL_DEBUG,
|
||||
"Session with corrupted compression has DROP verdict, returning HTTP_FORBIDDEN. Session ID: %d",
|
||||
session_data_p->session_id
|
||||
);
|
||||
return NGX_HTTP_FORBIDDEN;
|
||||
}
|
||||
return ngx_http_next_response_body_filter(request, body_chain);
|
||||
}
|
||||
|
||||
if (
|
||||
session_data_p->verdict != TRAFFIC_VERDICT_INSPECT &&
|
||||
session_data_p->verdict != TRAFFIC_VERDICT_WAIT &&
|
||||
(
|
||||
session_data_p->verdict != TRAFFIC_VERDICT_ACCEPT ||
|
||||
session_data_p->response_data.new_compression_type == NO_COMPRESSION ||
|
||||
session_data_p->response_data.new_compression_type == BROTLI ||
|
||||
session_data_p->response_data.num_body_chunk == 0
|
||||
)
|
||||
) {
|
||||
write_dbg(DBG_LEVEL_TRACE, "skipping already inspected session");
|
||||
if (session_data_p->verdict == TRAFFIC_VERDICT_DROP) request->keepalive = 0;
|
||||
if (session_data_p->verdict == TRAFFIC_VERDICT_DROP) {
|
||||
request->keepalive = 0;
|
||||
}
|
||||
|
||||
if (session_data_p->verdict == TRAFFIC_VERDICT_DROP && session_data_p->is_res_body_inspected) {
|
||||
write_dbg(
|
||||
DBG_LEVEL_DEBUG,
|
||||
"Session has DROP verdict, returning HTTP_FORBIDDEN instead of streaming. Session ID: %d",
|
||||
session_data_p->session_id
|
||||
);
|
||||
return NGX_HTTP_FORBIDDEN;
|
||||
}
|
||||
return ngx_http_next_response_body_filter(request, body_chain);
|
||||
}
|
||||
|
||||
session_data_p->is_res_body_inspected = 1;
|
||||
session_data_p->response_data.num_body_chunk++;
|
||||
|
||||
if (body_chain == NULL) {
|
||||
@ -1033,7 +1069,7 @@ ngx_http_cp_res_body_filter(ngx_http_request_t *request, ngx_chain_t *body_chain
|
||||
return ngx_http_next_response_body_filter(request, body_chain);
|
||||
}
|
||||
|
||||
if (body_chain->buf->pos != NULL && session_data_p->response_data.new_compression_type != NO_COMPRESSION) {
|
||||
if (body_chain->buf->pos != NULL && session_data_p->response_data.new_compression_type != NO_COMPRESSION && session_data_p->response_data.new_compression_type != BROTLI) {
|
||||
write_dbg(DBG_LEVEL_TRACE, "Decompressing response body");
|
||||
if (init_cp_session_original_body(session_data_p, request->pool) == NGX_OK) {
|
||||
if (session_data_p->response_data.decompression_stream == NULL) {
|
||||
@ -1208,7 +1244,7 @@ ngx_http_cp_res_body_filter(ngx_http_request_t *request, ngx_chain_t *body_chain
|
||||
|
||||
if (final_res == NGX_HTTP_FORBIDDEN) {
|
||||
handle_inspection_success(session_data_p);
|
||||
return ngx_http_cp_finalize_rejected_request(request);
|
||||
return ngx_http_cp_finalize_rejected_request(request, 1);
|
||||
}
|
||||
|
||||
if (final_res != NGX_OK) {
|
||||
@ -1224,7 +1260,7 @@ ngx_http_cp_res_body_filter(ngx_http_request_t *request, ngx_chain_t *body_chain
|
||||
return NGX_HTTP_FORBIDDEN;
|
||||
}
|
||||
|
||||
if (ctx.modifications) {
|
||||
if (ctx.modifications && session_data_p->response_data.new_compression_type != BROTLI) {
|
||||
write_dbg(DBG_LEVEL_TRACE, "Handling response body modification");
|
||||
if (ngx_http_cp_body_modifier(body_chain, ctx.modifications, request->pool) != NGX_OK) {
|
||||
write_dbg(DBG_LEVEL_WARNING, "Failed to modify response body");
|
||||
@ -1237,6 +1273,16 @@ ngx_http_cp_res_body_filter(ngx_http_request_t *request, ngx_chain_t *body_chain
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx.modifications && session_data_p->response_data.new_compression_type == BROTLI) {
|
||||
ngx_http_cp_modification_list *mod = ctx.modifications;
|
||||
while (mod != NULL) {
|
||||
ngx_http_cp_modification_list *next_mod = mod->next;
|
||||
ngx_pfree(request->pool, mod);
|
||||
mod = next_mod;
|
||||
}
|
||||
ctx.modifications = NULL;
|
||||
}
|
||||
|
||||
if (
|
||||
session_data_p->verdict == TRAFFIC_VERDICT_ACCEPT &&
|
||||
session_data_p->response_data.num_body_chunk == 1 &&
|
||||
@ -1249,7 +1295,7 @@ ngx_http_cp_res_body_filter(ngx_http_request_t *request, ngx_chain_t *body_chain
|
||||
return ngx_http_next_response_body_filter(request, body_chain);
|
||||
}
|
||||
|
||||
if (session_data_p->response_data.new_compression_type != NO_COMPRESSION) {
|
||||
if (session_data_p->response_data.new_compression_type != NO_COMPRESSION && session_data_p->response_data.new_compression_type != BROTLI) {
|
||||
if (session_data_p->response_data.compression_stream == NULL) {
|
||||
session_data_p->response_data.compression_stream = initCompressionStream();
|
||||
}
|
||||
@ -1275,5 +1321,23 @@ ngx_http_cp_res_body_filter(ngx_http_request_t *request, ngx_chain_t *body_chain
|
||||
|
||||
print_buffer_chain(body_chain, "outgoing", 32, DBG_LEVEL_TRACE);
|
||||
|
||||
// Check final verdict before streaming data to client
|
||||
// This prevents malicious data from reaching client when verdict is DROP
|
||||
if (session_data_p->verdict == TRAFFIC_VERDICT_DROP) {
|
||||
write_dbg(
|
||||
DBG_LEVEL_DEBUG,
|
||||
"Final verdict is DROP, blocking stream to client. Session ID: %d",
|
||||
session_data_p->session_id
|
||||
);
|
||||
return NGX_HTTP_FORBIDDEN;
|
||||
}
|
||||
|
||||
write_dbg(
|
||||
DBG_LEVEL_DEBUG,
|
||||
"Final verdict is %d, streaming to client. Session ID: %d",
|
||||
session_data_p->verdict,
|
||||
session_data_p->session_id
|
||||
);
|
||||
|
||||
return ngx_http_next_response_body_filter(request, body_chain);
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ typedef struct ngx_http_cp_session_data {
|
||||
double res_proccesing_time; ///< Holds session's response processing time.
|
||||
uint64_t processed_req_body_size; ///< Holds session's request body's size.
|
||||
uint64_t processed_res_body_size; ///< Holds session's response body's size'.
|
||||
ngx_int_t is_res_body_inspected; ///< Holds if the response body was inspected
|
||||
} ngx_http_cp_session_data;
|
||||
|
||||
///
|
||||
|
@ -19,24 +19,31 @@
|
||||
|
||||
static const char *gzip_encoding_string = "gzip";
|
||||
static const char *zlib_encoding_string = "deflate";
|
||||
static const char *brotli_encoding_string = "br";
|
||||
static const char *identity_encoding_string = "identity";
|
||||
|
||||
ngx_int_t
|
||||
parse_content_encoding(CompressionType *response_encoding, const ngx_str_t *content_encoding_header_value)
|
||||
{
|
||||
if (ngx_strcmp(content_encoding_header_value->data, gzip_encoding_string) == 0) {
|
||||
if (ngx_strcasecmp(content_encoding_header_value->data, (u_char*)gzip_encoding_string) == 0) {
|
||||
/// Sets GZIP encoding.
|
||||
*response_encoding = GZIP;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (ngx_strcmp(content_encoding_header_value->data, zlib_encoding_string) == 0) {
|
||||
if (ngx_strcasecmp(content_encoding_header_value->data, (u_char*)zlib_encoding_string) == 0) {
|
||||
/// Sets GZIP encoding.
|
||||
*response_encoding = ZLIB;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (ngx_strcmp(content_encoding_header_value->data, identity_encoding_string) == 0) {
|
||||
if (ngx_strcasecmp(content_encoding_header_value->data, (u_char*)brotli_encoding_string) == 0) {
|
||||
/// Sets Brotli encoding.
|
||||
*response_encoding = BROTLI;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (ngx_strcasecmp(content_encoding_header_value->data, (u_char*)identity_encoding_string) == 0) {
|
||||
/// Sets NO_COMPRESSION encoding.
|
||||
*response_encoding = NO_COMPRESSION;
|
||||
return NGX_OK;
|
||||
|
@ -30,6 +30,11 @@ typedef struct {
|
||||
/// - #NGX_ERROR
|
||||
ngx_int_t response_data_status;
|
||||
|
||||
/// This flag determines whether all response headers should be sent to a service for inspection.
|
||||
/// - If set to 1, all response headers will be sent.
|
||||
/// - If set to 0, only the Content-Length, response code, and encoding checks for the response body will be sent.
|
||||
ngx_int_t inspect_all_response_headers;
|
||||
|
||||
/// Original compression type, can hold the following values:
|
||||
/// - #GZIP
|
||||
/// - #ZLIB
|
||||
@ -58,6 +63,7 @@ typedef struct {
|
||||
/// @param[in, out] response_encoding Returns value of one of the supported encoding:
|
||||
/// - #GZIP
|
||||
/// - #ZLIB
|
||||
/// - #BROTLI
|
||||
/// - #NO_COMPRESSION
|
||||
/// @param[in, out] content_encoding_header_value Encoded value.
|
||||
/// @return ngx_int_t
|
||||
@ -75,6 +81,7 @@ parse_content_encoding(
|
||||
/// @param[in, out] content_encoding Returns variable of one of the supported encoding:
|
||||
/// - #GZIP
|
||||
/// - #ZLIB
|
||||
/// - #BROTLI
|
||||
/// - #NO_COMPRESSION
|
||||
/// @param[in, out] content_encoding_header NGINX table Encoding header.
|
||||
/// @return ngx_int_t
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "ngx_cp_utils.h"
|
||||
#include "ngx_cp_initializer.h"
|
||||
@ -452,6 +453,7 @@ ngx_int_t
|
||||
ngx_http_cp_reply_receiver(
|
||||
ngx_int_t *expected_replies,
|
||||
ngx_http_cp_verdict_e *verdict,
|
||||
ngx_int_t *inspect_all_response_headers,
|
||||
uint32_t cur_session_id,
|
||||
ngx_http_request_t *request,
|
||||
ngx_http_cp_modification_list **modification_list,
|
||||
@ -492,7 +494,7 @@ ngx_http_cp_reply_receiver(
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (reply_p->verdict != TRAFFIC_VERDICT_RECONF) {
|
||||
if (reply_p->verdict != TRAFFIC_VERDICT_RECONF && reply_p->verdict != LIMIT_RESPONSE_HEADERS) {
|
||||
// Handling reconfiguration verdict.
|
||||
if (reply_p->session_id != cur_session_id) {
|
||||
write_dbg(DBG_LEVEL_DEBUG, "Ignoring verdict to an already handled request %d", reply_p->session_id);
|
||||
@ -600,6 +602,12 @@ ngx_http_cp_reply_receiver(
|
||||
updateMetricField(HOLD_VERDICTS_COUNT, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
case LIMIT_RESPONSE_HEADERS: {
|
||||
write_dbg(DBG_LEVEL_DEBUG, "Verdict ignore response headers received from the nano service");
|
||||
*inspect_all_response_headers = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free_data_from_service();
|
||||
@ -662,7 +670,7 @@ convert_sock_addr_to_string(const struct sockaddr *sa, char *ip_addr)
|
||||
}
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_cp_meta_data_sender(ngx_http_request_t *request, uint32_t cur_request_id, ngx_uint_t *num_messages_sent)
|
||||
ngx_http_cp_meta_data_sender(ngx_http_request_t *request, uint32_t cur_request_id, ngx_uint_t *num_messages_sent, ngx_str_t *waf_tag)
|
||||
{
|
||||
char client_ip[INET6_ADDRSTRLEN];
|
||||
char listening_ip[INET6_ADDRSTRLEN];
|
||||
@ -788,6 +796,16 @@ ngx_http_cp_meta_data_sender(ngx_http_request_t *request, uint32_t cur_request_i
|
||||
set_fragment_elem(fragments, fragments_sizes, &parsed_uri.len, sizeof(uint16_t), PARSED_URI_SIZE + 2);
|
||||
set_fragment_elem(fragments, fragments_sizes, parsed_uri.data, parsed_uri.len, PARSED_URI_DATA + 2);
|
||||
|
||||
// Add WAF tag data if provided
|
||||
if (waf_tag != NULL && waf_tag->len > 0) {
|
||||
set_fragment_elem(fragments, fragments_sizes, &waf_tag->len, sizeof(uint16_t), WAF_TAG_SIZE + 2);
|
||||
set_fragment_elem(fragments, fragments_sizes, waf_tag->data, waf_tag->len, WAF_TAG_DATA + 2);
|
||||
} else {
|
||||
uint16_t zero = 0;
|
||||
set_fragment_elem(fragments, fragments_sizes, &zero, sizeof(uint16_t), WAF_TAG_SIZE + 2);
|
||||
set_fragment_elem(fragments, fragments_sizes, "", 0, WAF_TAG_DATA + 2);
|
||||
}
|
||||
|
||||
// Sends all the data to the nano service.
|
||||
res = ngx_http_cp_send_data_to_service(fragments, fragments_sizes, META_DATA_COUNT + 2, cur_request_id, NULL, fail_open_timeout, min_retries_for_verdict);
|
||||
if (res != NGX_OK) {
|
||||
@ -1008,8 +1026,7 @@ ngx_http_cp_header_sender(
|
||||
ngx_list_part_t *headers_list,
|
||||
ngx_http_chunk_type_e header_type,
|
||||
uint32_t cur_request_id,
|
||||
ngx_uint_t *num_messages_sent,
|
||||
ngx_str_t *waf_tag
|
||||
ngx_uint_t *num_messages_sent
|
||||
)
|
||||
{
|
||||
ngx_uint_t header_idx = 0;
|
||||
@ -1025,7 +1042,6 @@ ngx_http_cp_header_sender(
|
||||
const ngx_uint_t max_bulk_size = 10;
|
||||
char *fragments[HEADER_DATA_COUNT * max_bulk_size + 4];
|
||||
uint16_t fragments_sizes[HEADER_DATA_COUNT * max_bulk_size + 4];
|
||||
ngx_flag_t waf_tag_found = 0;
|
||||
|
||||
write_dbg(
|
||||
DBG_LEVEL_TRACE,
|
||||
@ -1036,38 +1052,6 @@ ngx_http_cp_header_sender(
|
||||
// Sets fragments identifier to the provided body type.
|
||||
set_fragments_identifiers(fragments, fragments_sizes, (uint16_t *)&header_type, &cur_request_id);
|
||||
|
||||
// If waf_tag is provided and valid, check for existing x-waf-tag headers
|
||||
if (waf_tag != NULL && waf_tag->len > 0) {
|
||||
for (headers_iter = headers_list; headers_iter; headers_iter = headers_iter->next) {
|
||||
headers_to_inspect = headers_iter->elts;
|
||||
for (header_idx = 0; header_idx < headers_iter->nelts; ++header_idx) {
|
||||
header = headers_to_inspect + header_idx;
|
||||
if (header->key.len == 9 && ngx_strncasecmp(header->key.data, (u_char *)"x-waf-tag", 9) == 0) {
|
||||
// Found existing x-waf-tag header, override its value
|
||||
// header->value = *waf_tag;
|
||||
waf_tag_found = 1;
|
||||
write_dbg(DBG_LEVEL_DEBUG, "Overriding existing x-waf-tag header with value: %.*s", waf_tag->len, waf_tag->data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (waf_tag_found) break;
|
||||
}
|
||||
|
||||
// If no existing x-waf-tag header found, add a new one
|
||||
if (!waf_tag_found) {
|
||||
ngx_table_elt_t waf_header;
|
||||
waf_header.hash = 1;
|
||||
ngx_str_set(&waf_header.key, "x-waf-tag");
|
||||
waf_header.value = *waf_tag;
|
||||
waf_header.lowcase_key = NULL; // Not needed for sending to agent
|
||||
|
||||
add_header_to_bulk(fragments, fragments_sizes, &waf_header, idx_in_bulk);
|
||||
idx_in_bulk++;
|
||||
part_count++;
|
||||
write_dbg(DBG_LEVEL_DEBUG, "Adding new x-waf-tag header with value: %.*s", waf_tag->len, waf_tag->data);
|
||||
}
|
||||
}
|
||||
|
||||
for (headers_iter = headers_list; headers_iter ; headers_iter = headers_iter->next) {
|
||||
// Going over the header list.
|
||||
for (header_idx = 0 ; header_idx < headers_iter->nelts ; ++header_idx) {
|
||||
@ -1085,16 +1069,7 @@ ngx_http_cp_header_sender(
|
||||
|
||||
is_last_part = (headers_iter->next == NULL && header_idx + 1 == headers_iter->nelts) ? 1 : 0;
|
||||
// Create a header bulk to send.
|
||||
if (waf_tag_found && header->key.len == 9 && ngx_strncasecmp(header->key.data, (u_char *)"x-waf-tag", 9) == 0) {
|
||||
ngx_table_elt_t waf_header;
|
||||
waf_header.hash = 1;
|
||||
ngx_str_set(&waf_header.key, "x-waf-tag");
|
||||
waf_header.value = *waf_tag;
|
||||
waf_header.lowcase_key = NULL;
|
||||
add_header_to_bulk(fragments, fragments_sizes, &waf_header, idx_in_bulk);
|
||||
} else {
|
||||
add_header_to_bulk(fragments, fragments_sizes, header, idx_in_bulk);
|
||||
}
|
||||
|
||||
idx_in_bulk++;
|
||||
part_count++;
|
||||
@ -1152,16 +1127,20 @@ ngx_http_cp_body_sender(
|
||||
ngx_int_t res = NGX_ERROR;
|
||||
uint8_t is_last_chunk;
|
||||
uint8_t part_count;
|
||||
size_t buf_size;
|
||||
ngx_int_t tout_retries = min_retries_for_verdict;
|
||||
char *fragments[num_body_chunk_fragments];
|
||||
uint16_t fragments_sizes[num_body_chunk_fragments];
|
||||
int was_waiting = 0;
|
||||
int max_chunks_to_process = (body_type == RESPONSE_BODY) ? 1 : INT_MAX;
|
||||
int chunks_processed = 0;
|
||||
|
||||
write_dbg(
|
||||
DBG_LEVEL_TRACE,
|
||||
"Sending %s body chunk from session id %d for inspection",
|
||||
DBG_LEVEL_DEBUG,
|
||||
"Started %s body sender for session ID %d, max_chunks_to_process: %d",
|
||||
body_type == REQUEST_BODY ? "request" : "response",
|
||||
session_data->session_id
|
||||
session_data->session_id,
|
||||
max_chunks_to_process
|
||||
);
|
||||
|
||||
// Sets fragments identifier to the provided body type.
|
||||
@ -1169,13 +1148,24 @@ ngx_http_cp_body_sender(
|
||||
|
||||
num_parts_sent = 0;
|
||||
part_count = 0;
|
||||
for (chain_iter = input; chain_iter; chain_iter = chain_iter->next) {
|
||||
|
||||
for (chain_iter = input; chain_iter && chunks_processed < max_chunks_to_process; chain_iter = chain_iter->next) {
|
||||
// For each NGINX buffer, fragment the buffer and then send the fragments to the nano service.
|
||||
buf = chain_iter->buf;
|
||||
is_last_chunk = buf->last_buf ? 1 : 0;
|
||||
write_dbg(DBG_LEVEL_TRACE, "Sending last_buf: %d, part_count: %d", buf->last_buf ? 1: 0, part_count);
|
||||
buf_size = buf->last - buf->pos;
|
||||
|
||||
if (buf->last - buf->pos > 0 || is_last_chunk) {
|
||||
write_dbg(
|
||||
DBG_LEVEL_DEBUG,
|
||||
"Processing %s body chunk %d of size: %d, last_chunk: %d for session ID: %d",
|
||||
body_type == REQUEST_BODY ? "request" : "response",
|
||||
part_count,
|
||||
buf_size,
|
||||
is_last_chunk,
|
||||
session_data->session_id
|
||||
);
|
||||
|
||||
if (buf_size > 0 || is_last_chunk) {
|
||||
// Setting the fragments, including in the case of the last chunk.
|
||||
set_fragment_elem(fragments, fragments_sizes, &is_last_chunk, sizeof(is_last_chunk), 2);
|
||||
set_fragment_elem(fragments, fragments_sizes, &part_count, sizeof(part_count), 3);
|
||||
@ -1191,16 +1181,32 @@ ngx_http_cp_body_sender(
|
||||
tout_retries = max_retries_for_verdict;
|
||||
}
|
||||
// Sending the data to the nano service.
|
||||
res = ngx_http_cp_send_data_to_service(fragments, fragments_sizes, num_body_chunk_fragments, session_data->session_id,
|
||||
&was_waiting, fail_open_timeout, tout_retries);
|
||||
res = ngx_http_cp_send_data_to_service(
|
||||
fragments,
|
||||
fragments_sizes,
|
||||
num_body_chunk_fragments,
|
||||
session_data->session_id,
|
||||
&was_waiting,
|
||||
fail_open_timeout,
|
||||
tout_retries
|
||||
);
|
||||
|
||||
if (res != NGX_OK) {
|
||||
// Failed to send the fragments to the nano service.
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
write_dbg(
|
||||
DBG_LEVEL_DEBUG,
|
||||
"Successfully sent %s body chunk %d to service for session ID: %d",
|
||||
body_type == REQUEST_BODY ? "request" : "response",
|
||||
part_count,
|
||||
session_data->session_id
|
||||
);
|
||||
|
||||
num_parts_sent++;
|
||||
is_empty_chain = 0;
|
||||
chunks_processed++;
|
||||
}
|
||||
|
||||
part_count++;
|
||||
@ -1239,3 +1245,4 @@ ngx_http_cp_metric_data_sender()
|
||||
reset_metric_data();
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,7 @@ ngx_int_t
|
||||
ngx_http_cp_reply_receiver(
|
||||
ngx_int_t *expected_replies,
|
||||
ngx_http_cp_verdict_e *verdict,
|
||||
ngx_int_t *inspect_all_response_headers,
|
||||
uint32_t cur_session_id,
|
||||
ngx_http_request_t *request,
|
||||
ngx_http_cp_modification_list **modification_list,
|
||||
@ -70,6 +71,7 @@ ngx_http_cp_reply_receiver(
|
||||
/// @param[in, out] request NGINX request.
|
||||
/// @param[in] cur_request_id Request session's Id.
|
||||
/// @param[in, out] num_messages_sent Number of messages sent will be saved onto this parameter.
|
||||
/// @param[in] waf_tag WAF tag to be sent.
|
||||
/// @returns ngx_int_t
|
||||
/// - #NGX_OK
|
||||
/// - #NGX_ERROR
|
||||
@ -78,7 +80,8 @@ ngx_int_t
|
||||
ngx_http_cp_meta_data_sender(
|
||||
ngx_http_request_t *request,
|
||||
uint32_t cur_request_id,
|
||||
ngx_uint_t *num_messages_sent
|
||||
ngx_uint_t *num_messages_sent,
|
||||
ngx_str_t *waf_tag
|
||||
);
|
||||
|
||||
///
|
||||
@ -138,7 +141,6 @@ ngx_http_cp_content_length_sender(
|
||||
/// - #RESPONSE_HEADER
|
||||
/// @param[in] cur_request_id Request session's Id.
|
||||
/// @param[in, out] num_messages_sent Number of messages sent will be saved onto this parameter.
|
||||
/// @param[in, out] waf_tag WAF tag to be sent.
|
||||
/// @returns ngx_int_t
|
||||
/// - #NGX_OK
|
||||
/// - #NGX_ERROR
|
||||
@ -148,8 +150,7 @@ ngx_http_cp_header_sender(
|
||||
ngx_list_part_t *headers,
|
||||
ngx_http_chunk_type_e header_type,
|
||||
uint32_t cur_request_id,
|
||||
ngx_uint_t *num_messages_sent,
|
||||
ngx_str_t *waf_tag
|
||||
ngx_uint_t *num_messages_sent
|
||||
);
|
||||
|
||||
///
|
||||
|
@ -45,7 +45,8 @@ typedef enum CompressionType
|
||||
{
|
||||
NO_COMPRESSION,
|
||||
GZIP,
|
||||
ZLIB
|
||||
ZLIB,
|
||||
BROTLI
|
||||
} CompressionType;
|
||||
|
||||
typedef struct CompressionResult
|
||||
|
@ -146,7 +146,8 @@ typedef enum ngx_http_cp_verdict
|
||||
TRAFFIC_VERDICT_INJECT,
|
||||
TRAFFIC_VERDICT_IRRELEVANT,
|
||||
TRAFFIC_VERDICT_RECONF,
|
||||
TRAFFIC_VERDICT_WAIT
|
||||
TRAFFIC_VERDICT_WAIT,
|
||||
LIMIT_RESPONSE_HEADERS
|
||||
} ngx_http_cp_verdict_e;
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -190,6 +191,8 @@ typedef enum ngx_http_meta_data
|
||||
PARSED_HOST_DATA,
|
||||
PARSED_URI_SIZE,
|
||||
PARSED_URI_DATA,
|
||||
WAF_TAG_SIZE,
|
||||
WAF_TAG_DATA,
|
||||
|
||||
META_DATA_COUNT
|
||||
} ngx_http_meta_data_e;
|
||||
|
Loading…
x
Reference in New Issue
Block a user