Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds support for Content-Encoding: gzip to in_http #7667

Merged
merged 1 commit into from
Mar 12, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Adds support for Content-Encoding: gzip to in_http
Signed-off-by: Edmund Rhudy <[email protected]>
erhudy committed Jan 21, 2024
commit 61317a5369f3faa9e9133c5ffe7ea4d58612b0dc
5 changes: 4 additions & 1 deletion include/fluent-bit/flb_gzip.h
Original file line number Diff line number Diff line change
@@ -21,7 +21,8 @@
#define FLB_GZIP_H

#include <fluent-bit/flb_info.h>
#include <stdio.h>
#include <fluent-bit/flb_macros.h>
#include <monkey/mk_http.h>

struct flb_decompression_context;

@@ -36,4 +37,6 @@ void flb_gzip_decompression_context_destroy(void *context);
int flb_gzip_decompressor_dispatch(struct flb_decompression_context *context,
void *out_data, size_t *out_size);

int flb_is_http_session_gzip_compressed(struct mk_http_session *session);

#endif
37 changes: 28 additions & 9 deletions plugins/in_http/http_prot.c
Original file line number Diff line number Diff line change
@@ -21,10 +21,13 @@
#include <fluent-bit/flb_version.h>
#include <fluent-bit/flb_error.h>
#include <fluent-bit/flb_pack.h>
#include <fluent-bit/flb_gzip.h>

#include <monkey/monkey.h>
#include <monkey/mk_core.h>

#include <string.h>

#include "http.h"
#include "http_conn.h"

@@ -520,6 +523,12 @@ static int process_payload(struct flb_http *ctx, struct http_conn *conn,
int ret;
int type = -1;
struct mk_http_header *header;
char *uncompressed_data;
size_t uncompressed_size = 0;

/* used when checking content-encoding */
int gzip_compressed = FLB_FALSE;
int gzip_ret;

header = &session->parser.headers[MK_HEADER_CONTENT_TYPE];
if (header->key.data == NULL) {
@@ -537,18 +546,31 @@ static int process_payload(struct flb_http *ctx, struct http_conn *conn,
type = HTTP_CONTENT_URLENCODED;
}

gzip_compressed = flb_is_http_session_gzip_compressed(session);

if (gzip_compressed == FLB_TRUE) {
gzip_ret = flb_gzip_uncompress(request->data.data, request->data.len, (void **)&uncompressed_data, &uncompressed_size);
if (gzip_ret == -1) {
flb_error("[http] gzip decompression failed");
return -1;
}
} else {
uncompressed_data = request->data.data;
uncompressed_size = request->data.len;
}

if (type == -1) {
send_response(conn, 400, "error: invalid 'Content-Type'\n");
return -1;
}

if (request->data.len <= 0) {
if (uncompressed_size <= 0) {
send_response(conn, 400, "error: no payload found\n");
return -1;
}

if (type == HTTP_CONTENT_JSON) {
parse_payload_json(ctx, tag, request->data.data, request->data.len);
parse_payload_json(ctx, tag, uncompressed_data, uncompressed_size);
}
else if (type == HTTP_CONTENT_URLENCODED) {
ret = parse_payload_urlencoded(ctx, tag, request->data.data, request->data.len);
@@ -557,6 +579,10 @@ static int process_payload(struct flb_http *ctx, struct http_conn *conn,
return -1;
}
}

if (gzip_compressed) {
flb_free(uncompressed_data);
}

return 0;
}
@@ -646,23 +672,18 @@ int http_prot_handle(struct flb_http *ctx, struct http_conn *conn,
}

mk_mem_free(uri);

/* Check if we have a Host header: Hostname ; port */
mk_http_point_header(&request->host, &session->parser, MK_HEADER_HOST);

/* Header: Connection */
mk_http_point_header(&request->connection, &session->parser,
MK_HEADER_CONNECTION);

/* HTTP/1.1 needs Host header */
if (!request->host.data && request->protocol == MK_HTTP_PROTOCOL_11) {
flb_sds_destroy(tag);
return -1;
}

/* Should we close the session after this request ? */
mk_http_keepalive_check(session, request, ctx->server);

/* Content Length */
header = &session->parser.headers[MK_HEADER_CONTENT_LENGTH];
if (header->type == MK_HEADER_CONTENT_LENGTH) {
@@ -672,13 +693,11 @@ int http_prot_handle(struct flb_http *ctx, struct http_conn *conn,
else {
request->_content_length.data = NULL;
}

if (request->method != MK_METHOD_POST) {
flb_sds_destroy(tag);
send_response(conn, 400, "error: invalid HTTP method\n");
return -1;
}

ret = process_payload(ctx, conn, tag, session, request);
flb_sds_destroy(tag);

27 changes: 27 additions & 0 deletions src/flb_gzip.c
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@
#include <fluent-bit/flb_gzip.h>
#include <fluent-bit/flb_compression.h>
#include <miniz/miniz.h>
#include <stdbool.h>
erhudy marked this conversation as resolved.
Show resolved Hide resolved

#define FLB_GZIP_HEADER_OFFSET 10
#define FLB_GZIP_HEADER_SIZE FLB_GZIP_HEADER_OFFSET
@@ -745,3 +746,29 @@ void flb_gzip_decompression_context_destroy(void *context)
flb_free(context);
}
}

int flb_is_http_session_gzip_compressed(struct mk_http_session *session)
{
int gzip_compressed = FLB_FALSE;

int i = 0;
int extra_size = -1;
struct mk_http_header *headers_extra;

extra_size = session->parser.headers_extra_count;
if (extra_size > 0) {
for (i = 0; i < extra_size; i++) {
headers_extra = &session->parser.headers_extra[i];
if (headers_extra->key.len == 16 &&
strncasecmp(headers_extra->key.data, "Content-Encoding", 16) == 0) {
if (headers_extra->val.len == 4 &&
strncasecmp(headers_extra->val.data, "gzip", 4) == 0) {
flb_debug("body is gzipped");
gzip_compressed = FLB_TRUE;
}
}
}
}

return gzip_compressed;
}