changeset 23011:4ea1e4f22a7b

lib-http: http_client_request_add_header() - Replace existing header If header with the same key already exists, just replace the value. HTTP supports having multiple headers with the same key only when they can be rewritten into a single comma-separated header. So practically there's no reason for lib-http to need to support adding multiple headers. Replacing an existing value is more useful generally.
author Timo Sirainen <timo.sirainen@open-xchange.com>
date Mon, 27 May 2019 17:47:16 +0300
parents 727d9990373e
children c3a83810cf5b
files src/lib-http/http-client-request.c src/lib-http/http-client.h
diffstat 2 files changed, 12 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-http/http-client-request.c	Mon May 27 17:46:37 2019 +0300
+++ b/src/lib-http/http-client-request.c	Mon May 27 17:47:16 2019 +0300
@@ -364,6 +364,8 @@
 void http_client_request_add_header(struct http_client_request *req,
 				    const char *key, const char *value)
 {
+	size_t key_pos, value_pos, next_pos;
+
 	i_assert(req->state == HTTP_REQUEST_STATE_NEW ||
 		 /* allow calling for retries */
 		 req->state == HTTP_REQUEST_STATE_GOT_RESPONSE ||
@@ -410,7 +412,14 @@
 	}
 	if (req->headers == NULL)
 		req->headers = str_new(default_pool, 256);
-	str_printfa(req->headers, "%s: %s\r\n", key, value);
+	if (!http_client_request_lookup_header_pos(req, key, &key_pos,
+						   &value_pos, &next_pos))
+		str_printfa(req->headers, "%s: %s\r\n", key, value);
+	else {
+		/* don't delete CRLF */
+		size_t old_value_len = next_pos - value_pos - 2;
+		str_replace(req->headers, value_pos, old_value_len, value);
+	}
 }
 
 void http_client_request_remove_header(struct http_client_request *req,
--- a/src/lib-http/http-client.h	Mon May 27 17:46:37 2019 +0300
+++ b/src/lib-http/http-client.h	Mon May 27 17:47:16 2019 +0300
@@ -280,7 +280,8 @@
 void http_client_request_set_preserve_exact_reason(struct http_client_request *req);
 
 /* add a custom header to the request. This can override headers that are
-   otherwise created implicitly. */
+   otherwise created implicitly. If the same header key was already added,
+   the value is replaced. */
 void http_client_request_add_header(struct http_client_request *req,
 				    const char *key, const char *value);
 /* remove a header added earlier. This has no influence on implicitly created