]> 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)
committerStephan Bosch <stephan.bosch@dovecot.fi>
Thu, 21 Sep 2017 07:02:33 +0000 (09:02 +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 615b088452c6e25a0ed1ad086ca5b09c1739d7c3..270f4dfed7a7548fdd39c6927ecde8f03a21f92c 100644 (file)
@@ -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;
index a49ce510e933e7401ef1e2058ab628d0b08daf6a..352b6ddfa5fcebe026fac636383fbe6691d105c8 100644 (file)
@@ -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);
                }
index 516295edf367de3b192de1922642eb07996f8bde..c1a37602996cd1dbc37b8451499d26c9fed1edf1 100644 (file)
@@ -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 */