From 1ffb3caae7c73b033285617a6820acb4138f5058 Mon Sep 17 00:00:00 2001 From: Stephan Bosch Date: Tue, 17 Jan 2017 01:36:10 +0100 Subject: [PATCH] lib-http: server: Prevent sending response payload when it is not allowed by the specification. For a HEAD request, the payload is omitted, but the associated headers are generated. For the other cases, an assert failure is now triggered. --- src/lib-http/http-server-response.c | 30 ++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/lib-http/http-server-response.c b/src/lib-http/http-server-response.c index 5fdd4827cc..4998b1c4b7 100644 --- a/src/lib-http/http-server-response.c +++ b/src/lib-http/http-server-response.c @@ -551,6 +551,7 @@ static int http_server_response_send_real(struct http_server_response *resp, struct ostream *output = conn->conn.output; string_t *rtext = t_str_new(256); struct const_iovec iov[3]; + bool is_head = http_request_method_is(&req->req, "HEAD"); int ret = 0; *error_r = NULL; @@ -576,18 +577,24 @@ static int http_server_response_send_real(struct http_server_response *resp, str_append(rtext, "\r\n"); } if (resp->payload_input != NULL || resp->payload_direct) { + i_assert(resp->tunnel_callback == NULL && resp->status / 100 != 1 && + resp->status != 204 && resp->status != 304); if (resp->payload_chunked) { if (http_server_request_version_equals(req, 1, 0)) { - /* cannot use Transfer-Encoding */ - resp->payload_output = output; - o_stream_ref(output); - /* connection close marks end of payload */ - resp->close = TRUE; + if (!is_head) { + /* cannot use Transfer-Encoding */ + resp->payload_output = output; + o_stream_ref(output); + /* connection close marks end of payload */ + resp->close = TRUE; + } } else { if (!resp->have_hdr_body_spec) str_append(rtext, "Transfer-Encoding: chunked\r\n"); - resp->payload_output = - http_transfer_chunked_ostream_create(output); + if (!is_head) { + resp->payload_output = + http_transfer_chunked_ostream_create(output); + } } } else { /* send Content-Length if we have specified a payload, @@ -596,12 +603,13 @@ static int http_server_response_send_real(struct http_server_response *resp, str_printfa(rtext, "Content-Length: %"PRIuUOFF_T"\r\n", resp->payload_size); } - resp->payload_output = output; - o_stream_ref(output); + if (!is_head) { + resp->payload_output = output; + o_stream_ref(output); + } } } else if (resp->tunnel_callback == NULL && resp->status / 100 != 1 - && resp->status != 204 && resp->status != 304 - && !http_request_method_is(&req->req, "HEAD")) { + && resp->status != 204 && resp->status != 304 && !is_head) { /* RFC 7230, Section 3.3: Message Body Responses to the HEAD request method (Section 4.3.2 of [RFC7231])