From 8441c9e8e8ee02aa72e75d11a0094540b015f596 Mon Sep 17 00:00:00 2001 From: Glenn Strauss Date: Thu, 21 Feb 2019 23:55:59 -0500 Subject: [PATCH] [core] config option to allow GET w/ request body server.http-parseopts = ( "method-get-body" = "enable" ) --- src/base.h | 1 + src/burl.h | 1 + src/configfile.c | 7 ++++++- src/request.c | 3 ++- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/base.h b/src/base.h index f2496f19..b7f090f4 100644 --- a/src/base.h +++ b/src/base.h @@ -336,6 +336,7 @@ typedef struct { unsigned short http_host_strict; unsigned short http_host_normalize; unsigned short http_url_normalize; + unsigned short http_method_get_body; unsigned short high_precision_timestamps; time_t loadts; double loadavg[3]; diff --git a/src/burl.h b/src/burl.h index 4eb8f3ea..f4e5f04b 100644 --- a/src/burl.h +++ b/src/burl.h @@ -26,6 +26,7 @@ enum burl_opts_e { ,HTTP_PARSEOPT_URL_NORMALIZE_PATH_DOTSEG_REMOVE =0x400/* "." ".." "//" */ ,HTTP_PARSEOPT_URL_NORMALIZE_PATH_DOTSEG_REJECT =0x800 ,HTTP_PARSEOPT_URL_NORMALIZE_QUERY_20_PLUS =0x1000 + ,HTTP_PARSEOPT_METHOD_GET_BODY =0x8000 }; int burl_normalize (buffer *b, buffer *t, int flags); diff --git a/src/configfile.c b/src/configfile.c index b359dcbe..46a3a8fb 100644 --- a/src/configfile.c +++ b/src/configfile.c @@ -121,6 +121,10 @@ static int config_http_parseopts (server *srv, array *a) { srv->srvconf.http_host_normalize = val; continue; } + else if (buffer_is_equal_string(ds->key, CONST_STR_LEN("method-get-body"))) { + srv->srvconf.http_method_get_body = val; + continue; + } else { log_error_write(srv, __FILE__, __LINE__, "sb", "unrecognized key for server.http-parseopts:", @@ -528,7 +532,8 @@ static int config_insert(server *srv) { (srv->srvconf.http_header_strict ?(HTTP_PARSEOPT_HEADER_STRICT) :0) |(srv->srvconf.http_host_strict ?(HTTP_PARSEOPT_HOST_STRICT |HTTP_PARSEOPT_HOST_NORMALIZE):0) - |(srv->srvconf.http_host_normalize ?(HTTP_PARSEOPT_HOST_NORMALIZE):0); + |(srv->srvconf.http_host_normalize ?(HTTP_PARSEOPT_HOST_NORMALIZE):0) + |(srv->srvconf.http_method_get_body?(HTTP_PARSEOPT_METHOD_GET_BODY):0); s->http_parseopts |= srv->srvconf.http_url_normalize; if (s->log_request_handling || s->log_request_header) diff --git a/src/request.c b/src/request.c index 13b47caa..d25e1e70 100644 --- a/src/request.c +++ b/src/request.c @@ -891,7 +891,8 @@ int http_request_parse(server *srv, connection *con, buffer *hdrs) { case HTTP_METHOD_GET: case HTTP_METHOD_HEAD: /* content-length is forbidden for those */ - if (state.con_length_set && con->request.content_length != 0) { + if (state.con_length_set && 0 != con->request.content_length + && !(con->conf.http_parseopts & HTTP_PARSEOPT_METHOD_GET_BODY)) { return http_request_header_line_invalid(srv, 400, "GET/HEAD with content-length -> 400"); } break;