Skip to content

Commit

Permalink
Adds support for Content-Encoding: gzip to in_http
Browse files Browse the repository at this point in the history
Signed-off-by: Edmund Rhudy <[email protected]>
  • Loading branch information
erhudy committed Jan 17, 2024
1 parent 71746b3 commit 4830228
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 10 deletions.
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>

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

0 comments on commit 4830228

Please sign in to comment.