From: Stephan Bosch Date: Wed, 20 Sep 2017 22:38:33 +0000 (+0200) Subject: lib-http: client: Send empty payload (Content-Length: 0) for requests that normally... X-Git-Tag: 2.3.0.rc1~974 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4d1cc687f40dc2697005a4977e7ac40dda3d7dcf;p=thirdparty%2Fdovecot%2Fcore.git lib-http: client: Send empty payload (Content-Length: 0) for requests that normally expect a payload. This includes the standard POST and PUT methods. Others need to use the new http_client_request_set_payload_empty() function to force sending an empty payload. --- diff --git a/src/lib-http/http-client-private.h b/src/lib-http/http-client-private.h index 615b088452..270f4dfed7 100644 --- a/src/lib-http/http-client-private.h +++ b/src/lib-http/http-client-private.h @@ -134,6 +134,7 @@ struct http_client_request { bool payload_sync_continue:1; bool payload_chunked:1; bool payload_wait:1; + bool payload_empty:1; bool urgent:1; bool submitted:1; bool listed:1; diff --git a/src/lib-http/http-client-request.c b/src/lib-http/http-client-request.c index a49ce510e9..352b6ddfa5 100644 --- a/src/lib-http/http-client-request.c +++ b/src/lib-http/http-client-request.c @@ -461,6 +461,11 @@ void http_client_request_set_payload_data(struct http_client_request *req, i_stream_unref(&input); } +void http_client_request_set_payload_empty(struct http_client_request *req) +{ + req->payload_empty = TRUE; +} + void http_client_request_set_timeout_msecs(struct http_client_request *req, unsigned int msecs) { @@ -1152,20 +1157,25 @@ static int http_client_request_send_real(struct http_client_request *req, if (!req->have_hdr_expect && req->payload_sync) { str_append(rtext, "Expect: 100-continue\r\n"); } - if (req->payload_input != NULL) { - if (req->payload_chunked) { - // FIXME: can't do this for a HTTP/1.0 server - if (!req->have_hdr_body_spec) - str_append(rtext, "Transfer-Encoding: chunked\r\n"); - req->payload_output = - http_transfer_chunked_ostream_create(output); - } else { - /* send Content-Length if we have specified a payload, - even if it's 0 bytes. */ - if (!req->have_hdr_body_spec) { - str_printfa(rtext, "Content-Length: %"PRIuUOFF_T"\r\n", - req->payload_size); - } + if (req->payload_input != NULL && req->payload_chunked) { + // FIXME: can't do this for a HTTP/1.0 server + if (!req->have_hdr_body_spec) + str_append(rtext, "Transfer-Encoding: chunked\r\n"); + req->payload_output = + http_transfer_chunked_ostream_create(output); + } else if (req->payload_input != NULL || + req->payload_empty || + strcasecmp(req->method, "POST") == 0 || + strcasecmp(req->method, "PUT") == 0) { + + /* send Content-Length if we have specified a payload + or when one is normally expected, even if it's 0 bytes. */ + i_assert(req->payload_input != NULL || req->payload_size == 0); + if (!req->have_hdr_body_spec) { + str_printfa(rtext, "Content-Length: %"PRIuUOFF_T"\r\n", + req->payload_size); + } + if (req->payload_input != NULL) { req->payload_output = output; o_stream_ref(output); } diff --git a/src/lib-http/http-client.h b/src/lib-http/http-client.h index 516295edf3..c1a3760299 100644 --- a/src/lib-http/http-client.h +++ b/src/lib-http/http-client.h @@ -308,6 +308,11 @@ void http_client_request_set_payload(struct http_client_request *req, */ void http_client_request_set_payload_data(struct http_client_request *req, const unsigned char *data, size_t size); +/* send an empty payload for this request. This means that a Content-Length + header is generated with zero size. Calling this function is not necessary + for the standard POST and PUT methods, for which this is done implicitly if + there is no payload set. */ +void http_client_request_set_payload_empty(struct http_client_request *req); /* set an absolute timeout for this request specifically, overriding the default client-wide absolute request timeout */