From: Timo Sirainen Date: Tue, 3 Dec 2019 18:04:47 +0000 (+0200) Subject: lib-http: Add support for permanent headers X-Git-Tag: 2.3.10~185 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d513aab15fa04b4c92d41783da6357b932548d38;p=thirdparty%2Fdovecot%2Fcore.git lib-http: Add support for permanent headers --- diff --git a/src/lib-http/http-server-private.h b/src/lib-http/http-server-private.h index d50f1d1e03..a51bff7365 100644 --- a/src/lib-http/http-server-private.h +++ b/src/lib-http/http-server-private.h @@ -69,6 +69,7 @@ struct http_server_response { const char *reason; string_t *headers; + ARRAY_TYPE(string) perm_headers; time_t date; ARRAY_TYPE(http_auth_challenge) auth_challenges; diff --git a/src/lib-http/http-server-request.c b/src/lib-http/http-server-request.c index b548b6abf9..0bf5cbfc6d 100644 --- a/src/lib-http/http-server-request.c +++ b/src/lib-http/http-server-request.c @@ -871,3 +871,12 @@ void http_server_request_handle_payload(struct http_server_request *req, payload_handler_raw_input, rhandler); i_stream_set_input_pending(conn->incoming_payload, TRUE); } + +void http_server_request_add_response_header(struct http_server_request *req, + const char *key, const char *value) +{ + struct http_server_response *resp; + + resp = http_server_response_create(req, 0, ""); + http_server_response_add_permanent_header(resp, key, value); +} diff --git a/src/lib-http/http-server-response.c b/src/lib-http/http-server-response.c index 4d5424a52c..0e8b83cfb9 100644 --- a/src/lib-http/http-server-response.c +++ b/src/lib-http/http-server-response.c @@ -76,8 +76,14 @@ http_server_response_create(struct http_server_request *req, start a new one (would usually be a failure response) */ resp = req->response; + + ARRAY_TYPE(string) perm_headers = resp->perm_headers; + i_zero(&resp->perm_headers); + http_server_response_free(resp); i_zero(resp); + + resp->perm_headers = perm_headers; } resp->request = req; @@ -86,6 +92,13 @@ http_server_response_create(struct http_server_request *req, resp->headers = str_new(default_pool, 256); resp->date = (time_t)-1; + if (array_is_created(&resp->perm_headers)) { + unsigned int i, count; + char *const *headers = array_get(&resp->perm_headers, &count); + for (i = 0; i < count; i += 2) + http_server_response_add_header(resp, headers[i], + headers[i+1]); + } return resp; } @@ -98,6 +111,14 @@ void http_server_response_free(struct http_server_response *resp) i_stream_unref(&resp->payload_input); o_stream_unref(&resp->payload_output); str_free(&resp->headers); + + if (array_is_created(&resp->perm_headers)) { + char **headers; + + array_foreach_modifiable(&resp->perm_headers, headers) + i_free(*headers); + array_free(&resp->perm_headers); + } } void http_server_response_add_header(struct http_server_response *resp, @@ -813,3 +834,18 @@ uoff_t http_server_response_get_total_size(struct http_server_response *resp) i_assert(resp != NULL); return resp->payload_size + str_len(resp->headers); } + +void http_server_response_add_permanent_header(struct http_server_response *resp, + const char *key, const char *value) +{ + char *key_dup = i_strdup(key), *value_dup = i_strdup(value); + + http_server_response_add_header(resp, key, value); + + if (!array_is_created(&resp->perm_headers)) + i_array_init(&resp->perm_headers, 4); + key_dup = i_strdup(key); + value_dup = i_strdup(value); + array_push_back(&resp->perm_headers, &key_dup); + array_push_back(&resp->perm_headers, &value_dup); +} diff --git a/src/lib-http/http-server.h b/src/lib-http/http-server.h index eff9286606..78271e7806 100644 --- a/src/lib-http/http-server.h +++ b/src/lib-http/http-server.h @@ -70,6 +70,10 @@ http_server_response_create(struct http_server_request *req, otherwise created implicitly. */ void http_server_response_add_header(struct http_server_response *resp, const char *key, const char *value); +/* Add a header permanently to the response. Even if another response is + created for the request, this header is kept. */ +void http_server_response_add_permanent_header(struct http_server_response *resp, + const char *key, const char *value); /* Change the response code and text, cannot be used after submission */ void http_server_response_update_status(struct http_server_response *resp, unsigned int status, const char *reason); @@ -169,6 +173,10 @@ http_server_request_get_response(struct http_server_request *req); or because the request was aborted. */ bool http_server_request_is_finished(struct http_server_request *req); +/* Add a header to any HTTP response created for the HTTP request. */ +void http_server_request_add_response_header(struct http_server_request *req, + const char *key, const char *value); + /* Return input stream for the request's payload. Optionally, this stream can be made blocking. Do *NOT* meddle with the FD of the http_request payload to achieve the same, because protocol violations will result.