]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-http: client: Send empty payload (Content-Length: 0) for requests that normally...
authorStephan Bosch <stephan.bosch@dovecot.fi>
Wed, 20 Sep 2017 22:38:33 +0000 (00:38 +0200)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 15 Nov 2017 16:35:57 +0000 (18:35 +0200)
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.

src/lib-http/http-client-private.h
src/lib-http/http-client-request.c
src/lib-http/http-client.h

index f0ff6411066031d5e3be00f3f30f524d325b5a20..dcdeb387cf76ac42dc71a5129dd773194f14947a 100644 (file)
@@ -134,6 +134,7 @@ struct http_client_request {
        unsigned int payload_sync_continue:1;
        unsigned int payload_chunked:1;
        unsigned int payload_wait:1;
+       unsigned int payload_empty:1;
        unsigned int urgent:1;
        unsigned int submitted:1;
        unsigned int listed:1;
index dd8bec586eefb6b293bb1dc1df38369c95c3bd80..25ef0f9b011ba3b19b293c19a92d540ef19694b5 100644 (file)
@@ -463,6 +463,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)
 {
@@ -1161,20 +1166,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);
                }
index 8b46831fa8004e79b5b34c0044f820f8bf906342..bc63cc1bf9afab34095251b341a0312662794776 100644 (file)
@@ -311,6 +311,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 */