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
Show file tree
Hide file tree
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
5 changes: 4 additions & 1 deletion include/fluent-bit/flb_gzip.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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
Expand Up @@ -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"

Expand Down Expand Up @@ -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) {
Expand All @@ -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);
Expand All @@ -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;
}
Expand Down Expand Up @@ -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) {
Expand All @@ -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);

Expand Down
27 changes: 27 additions & 0 deletions src/flb_gzip.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Loading