diff --git a/include/fluent-bit/flb_gzip.h b/include/fluent-bit/flb_gzip.h index f6b942d4da1..b4826283bb2 100644 --- a/include/fluent-bit/flb_gzip.h +++ b/include/fluent-bit/flb_gzip.h @@ -21,7 +21,8 @@ #define FLB_GZIP_H #include -#include +#include +#include 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 diff --git a/plugins/in_http/http_prot.c b/plugins/in_http/http_prot.c index ab16eb328c5..cd48e5236d8 100644 --- a/plugins/in_http/http_prot.c +++ b/plugins/in_http/http_prot.c @@ -21,10 +21,13 @@ #include #include #include +#include #include #include +#include + #include "http.h" #include "http_conn.h" @@ -493,6 +496,12 @@ static int process_payload(struct flb_http *ctx, struct http_conn *conn, { 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) { @@ -510,21 +519,38 @@ 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) { parse_payload_urlencoded(ctx, tag, request->data.data, request->data.len); } + + if (gzip_compressed) { + flb_free(uncompressed_data); + } return 0; } @@ -614,23 +640,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) { @@ -640,16 +661,15 @@ 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); send_response(conn, ctx->successful_response_code, NULL); + return ret; } diff --git a/src/flb_gzip.c b/src/flb_gzip.c index 4b9b761fecb..5702dba5ffc 100644 --- a/src/flb_gzip.c +++ b/src/flb_gzip.c @@ -23,6 +23,7 @@ #include #include #include +#include #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; +} \ No newline at end of file