From 98b8cbc80e14e6b47b13bcddfedc0bdc8d2abf19 Mon Sep 17 00:00:00 2001 From: Zhixiong Chi Date: Mon, 12 Jun 2023 02:23:58 -0700 Subject: [PATCH] check content-length Rebase this local patch for StarlingX. Signed-off-by: zhipengl Signed-off-by: Giao Le Signed-off-by: Zhixiong Chi --- src/request.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/request.c b/src/request.c index 62f2f0cb..e9668d42 100644 --- a/src/request.c +++ b/src/request.c @@ -8,16 +8,48 @@ #include "first.h" #include "request.h" +#include "base.h" #include "burl.h" #include "http_header.h" #include "http_kv.h" #include "log.h" #include "sock_addr.h" +#include #include #include #include #include +#include + +static size_t get_tempdirs_free_space(request_st * const restrict r) +{ + int i; + int valid = 0; + size_t total = 0; + array *dirs = r->con->srv->srvconf.upload_tempdirs; + + for (i = 0; i < (int)dirs->used; ++i) { + struct statvfs stat; + const char *name = ((data_string *)dirs->data[i])->value.ptr; + int ret = statvfs(name, &stat); + + if (ret >= 0) { + size_t df = (size_t)(stat.f_bsize * stat.f_bfree); + total += df; + valid = 1; + } + else { + if (r->conf.log_request_header_on_error) { + log_error(r->conf.errh, __FILE__, __LINE__, + "statvfs error, dir: %s, eno: %s\n", + name, strerror(errno)); + } + } + } + + return (valid) ? total : SSIZE_MAX; +} static int request_check_hostname(buffer * const host) { enum { DOMAINLABEL, TOPLABEL } stage = TOPLABEL; @@ -1260,10 +1292,27 @@ http_request_parse (request_st * const restrict r, const int scheme_port) http_header_request_unset(r, HTTP_HEADER_CONTENT_LENGTH, CONST_STR_LEN("Content-Length")); } } + if (http_method_get_or_head(r->http_method) && !(http_parseopts & HTTP_PARSEOPT_METHOD_GET_BODY)) { return http_request_header_line_invalid(r, 400, "GET/HEAD with content-length -> 400"); } + + /* content-length is larger than 64k */ + if (r->reqbody_length > 64*1024 && HTTP_METHOD_POST == r->http_method) { + size_t disk_free = get_tempdirs_free_space(r); + if (r->reqbody_length > disk_free) { + r->http_status = 413; + r->keep_alive = 0; + if (r->conf.log_request_header_on_error) { + log_error(r->conf.errh, __FILE__, __LINE__, + "not enough free space in tempdirs:\n length =%d\n free=%d\ncontent-length -> 413", + r->reqbody_length, + disk_free); + } + return 0; + } + } } return 0; -- 2.39.0