diff --git a/plugins/in_http/http_prot.c b/plugins/in_http/http_prot.c index b8532e8ac3c..de10697f523 100644 --- a/plugins/in_http/http_prot.c +++ b/plugins/in_http/http_prot.c @@ -61,9 +61,11 @@ static int sds_uri_decode(flb_sds_t s) } *optr++ = hex2nibble(*(iptr+1)) << 4 | hex2nibble(*(iptr+2)); iptr+=2; - } else if (*iptr == '+') { + } + else if (*iptr == '+') { *optr++ = ' '; - } else { + } + else { *optr++ = *iptr; } } @@ -203,8 +205,8 @@ static flb_sds_t tag_key(struct flb_http *ctx, msgpack_object *map) } return tag; } - - + + flb_plg_error(ctx->ins, "Could not find tag_key %s in record", ctx->tag_key); return NULL; } @@ -276,11 +278,10 @@ int process_pack(struct flb_http *ctx, flb_sds_t tag, char *buf, size_t size) } flb_log_event_encoder_reset(&ctx->log_encoder); - } + } else if (result.data.type == MSGPACK_OBJECT_ARRAY) { obj = &result.data; - for (i = 0; i < obj->via.array.size; i++) - { + for (i = 0; i < obj->via.array.size; i++) { record = obj->via.array.ptr[i]; tag_from_record = NULL; @@ -343,7 +344,7 @@ int process_pack(struct flb_http *ctx, flb_sds_t tag, char *buf, size_t size) } break; - } + } else { flb_plg_error(ctx->ins, "skip record from invalid type: %i", result.data.type); @@ -398,15 +399,18 @@ static ssize_t parse_payload_json(struct flb_http *ctx, flb_sds_t tag, static ssize_t parse_payload_urlencoded(struct flb_http *ctx, flb_sds_t tag, char *payload, size_t size) { + int i; + int idx = 0; + int ret = -1; + int len; struct mk_list *kvs; struct mk_list *head = NULL; + struct mk_list *tmp; struct flb_split_entry *cur = NULL; char **keys = NULL; char **vals = NULL; char *sep; char *start; - int idx = 0; - int ret = -1; msgpack_packer pck; msgpack_sbuffer sbuf; @@ -430,38 +434,60 @@ static ssize_t parse_payload_urlencoded(struct flb_http *ctx, flb_sds_t tag, goto vals_calloc_error; } - mk_list_foreach(head, kvs) { + mk_list_foreach_safe(head, tmp, kvs) { cur = mk_list_entry(head, struct flb_split_entry, _head); if (cur->value[0] == '\n') { start = &cur->value[1]; - } else { + } + else { start = cur->value; } + + if (!start || *start == '=' || strlen(start) == 0) { + flb_utils_split_free_entry(cur); + continue; + } + sep = strchr(start, '='); - if (sep == NULL) { - vals[idx] = NULL; + if (sep) { + len = sep - start; + } + else { + /* if no separator is found, just skip the content */ + flb_utils_split_free_entry(cur); continue; } - *sep++ = '\0'; - keys[idx] = flb_sds_create_len(start, strlen(start)); - vals[idx] = flb_sds_create_len(sep, strlen(sep)); + keys[idx] = flb_sds_create_len(start, len); + len++; + + if (start[len] == '\0') { + vals[idx] = flb_sds_create(""); + } + else { + vals[idx] = flb_sds_create(start + len); + } flb_sds_trim(keys[idx]); flb_sds_trim(vals[idx]); idx++; } + if (mk_list_size(kvs) == 0) { + goto decode_error; + } + msgpack_pack_map(&pck, mk_list_size(kvs)); - for (idx = 0; idx < mk_list_size(kvs); idx++) { - msgpack_pack_str(&pck, flb_sds_len(keys[idx])); - msgpack_pack_str_body(&pck, keys[idx], flb_sds_len(keys[idx])); + for (i = 0; i < idx; i++) { + msgpack_pack_str(&pck, flb_sds_len(keys[i])); + msgpack_pack_str_body(&pck, keys[i], flb_sds_len(keys[i])); - if (sds_uri_decode(vals[idx]) != 0) { + if (sds_uri_decode(vals[i]) != 0) { goto decode_error; - } else { - msgpack_pack_str(&pck, flb_sds_len(vals[idx])); - msgpack_pack_str_body(&pck, vals[idx], strlen(vals[idx])); + } + else { + msgpack_pack_str(&pck, flb_sds_len(vals[i])); + msgpack_pack_str_body(&pck, vals[i], flb_sds_len(vals[i])); } } @@ -491,6 +517,7 @@ static int process_payload(struct flb_http *ctx, struct http_conn *conn, struct mk_http_session *session, struct mk_http_request *request) { + int ret; int type = -1; struct mk_http_header *header; @@ -522,8 +549,13 @@ static int process_payload(struct flb_http *ctx, struct http_conn *conn, if (type == HTTP_CONTENT_JSON) { parse_payload_json(ctx, tag, request->data.data, request->data.len); - } else if (type == HTTP_CONTENT_URLENCODED) { - parse_payload_urlencoded(ctx, tag, request->data.data, request->data.len); + } + else if (type == HTTP_CONTENT_URLENCODED) { + ret = parse_payload_urlencoded(ctx, tag, request->data.data, request->data.len); + if (ret != 0) { + send_response(conn, 400, "error: invalid payload\n"); + return -1; + } } return 0; @@ -649,7 +681,11 @@ int http_prot_handle(struct flb_http *ctx, struct http_conn *conn, ret = process_payload(ctx, conn, tag, session, request); flb_sds_destroy(tag); - send_response(conn, ctx->successful_response_code, NULL); + + if (ret == 0) { + send_response(conn, ctx->successful_response_code, NULL); + } + return ret; }