From ac448a74d0c0c0947c32be65f64dd56c3cd2bab4 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 15 Feb 2016 03:26:40 +0300 Subject: [PATCH] http: take EVHTTP_CON_LINGERING_CLOSE into account for "Expect: 100-Continue" Also since after this patch code became more generic, we now respond with HTTP_ENTITYTOOLARGE even without "Expect: 100-Continue", which is correct by RFC. Refs: #321 v2: remove EVHTTP_CON_ABOUT_TO_CLOSE --- http.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/http.c b/http.c index 5df8791d..26032b0f 100644 --- a/http.c +++ b/http.c @@ -640,6 +640,14 @@ static int evhttp_connection_incoming_fail(struct evhttp_request *req, enum evhttp_request_error error) { + switch (error) { + case EVREQ_HTTP_DATA_TOO_LONG: + req->response_code = HTTP_ENTITYTOOLARGE; + break; + default: + req->response_code = HTTP_BADREQUEST; + } + switch (error) { case EVREQ_HTTP_TIMEOUT: case EVREQ_HTTP_EOF: @@ -985,7 +993,8 @@ evhttp_read_trailer(struct evhttp_connection *evcon, struct evhttp_request *req) } static void -evhttp_lingering_close(struct evhttp_connection *evcon, struct evhttp_request *req) +evhttp_lingering_close(struct evhttp_connection *evcon, + struct evhttp_request *req) { struct evbuffer *buf = bufferevent_get_input(evcon->bufev); @@ -1002,6 +1011,15 @@ evhttp_lingering_close(struct evhttp_connection *evcon, struct evhttp_request *r if (!req->ntoread) evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG); } +static void +evhttp_lingering_fail(struct evhttp_connection *evcon, + struct evhttp_request *req) +{ + if (evcon->flags & EVHTTP_CON_LINGERING_CLOSE) + evhttp_lingering_close(evcon, req); + else + evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG); +} static void evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req) @@ -1057,11 +1075,7 @@ evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req) /* XXX: The above casted comparison must checked for overflow */ /* failed body length test */ - if (evcon->flags & EVHTTP_CON_LINGERING_CLOSE) - evhttp_lingering_close(evcon, req); - else - evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG); - + evhttp_lingering_fail(evcon, req); return; } @@ -2179,7 +2193,7 @@ evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req) if (req->ntoread > 0) { /* ntoread is ev_int64_t, max_body_size is ev_uint64_t */ if ((req->evcon->max_body_size <= EV_INT64_MAX) && (ev_uint64_t)req->ntoread > req->evcon->max_body_size) { - evhttp_send_error(req, HTTP_ENTITYTOOLARGE, NULL); + evhttp_lingering_fail(evcon, req); return; } } @@ -3352,7 +3366,7 @@ evhttp_handle_request(struct evhttp_request *req, void *arg) req->userdone = 0; if (req->type == 0 || req->uri == NULL) { - evhttp_send_error(req, HTTP_BADREQUEST, NULL); + evhttp_send_error(req, req->response_code, NULL); return; }