From: Nick Mathewson Date: Wed, 24 Nov 2010 01:31:28 +0000 (-0500) Subject: Handle evhttp PUT/POST requests with an empty body X-Git-Tag: release-2.0.9-rc~14^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ec5c5aec6d5373e47936891c6b8111716d16f3e6;p=libevent Handle evhttp PUT/POST requests with an empty body When we call evhttp_get_bodylen() [when transfer-encoding isn't set], having req->ntoread == -1 means that we have no content-length. But a request with no content-length has no body! We were treating the absent content-length as meaning "read till closed", which only holds for replies, not requests. This patch also allows PATCH requests to have a body. --- diff --git a/http.c b/http.c index b08e04c5..4464bbeb 100644 --- a/http.c +++ b/http.c @@ -1734,6 +1734,28 @@ evhttp_get_body_length(struct evhttp_request *req) return (0); } +static int +evhttp_method_may_have_body(enum evhttp_cmd_type type) +{ + switch (type) { + case EVHTTP_REQ_POST: + case EVHTTP_REQ_PUT: + case EVHTTP_REQ_PATCH: + return 1; + case EVHTTP_REQ_TRACE: + return 0; + /* XXX May any of the below methods have a body? */ + case EVHTTP_REQ_GET: + case EVHTTP_REQ_HEAD: + case EVHTTP_REQ_DELETE: + case EVHTTP_REQ_OPTIONS: + case EVHTTP_REQ_CONNECT: + return 0; + default: + return 0; + } +} + static void evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req) { @@ -1741,7 +1763,7 @@ evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req) /* If this is a request without a body, then we are done */ if (req->kind == EVHTTP_REQUEST && - (req->type != EVHTTP_REQ_POST && req->type != EVHTTP_REQ_PUT)) { + !evhttp_method_may_have_body(req->type)) { evhttp_connection_done(evcon); return; } @@ -1756,6 +1778,12 @@ evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req) EVCON_HTTP_INVALID_HEADER); return; } + if (req->kind == EVHTTP_REQUEST && req->ntoread < 1) { + /* An incoming request with no content-length and no + * transfer-encoding has no body. */ + evhttp_connection_done(evcon); + return; + } } evhttp_read_body(evcon, req); /* note the request may have been freed in evhttp_read_body */