]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-http: Add support for permanent headers
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Tue, 3 Dec 2019 18:04:47 +0000 (20:04 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Fri, 13 Dec 2019 13:14:23 +0000 (13:14 +0000)
src/lib-http/http-server-private.h
src/lib-http/http-server-request.c
src/lib-http/http-server-response.c
src/lib-http/http-server.h

index d50f1d1e035668d7d10681f0f3d77ba5e8052b18..a51bff73652d218d2fd1f0d65fcc9c0794c02e78 100644 (file)
@@ -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;
 
index b548b6abf92fe657d5f359c4b487d6b9b9584d6b..0bf5cbfc6de5c7f3c6cec6692afbb75a7d2d3f1d 100644 (file)
@@ -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);
+}
index 4d5424a52c11022881ccf8eba1ff4101e22ed752..0e8b83cfb98dbf623ca6fda9bd2587d4e3ae8f57 100644 (file)
@@ -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);
+}
index eff92866067857ce04fbd99db70a37b0ada01d03..78271e78061997f761fdd8f75c87612a16eb14be 100644 (file)
@@ -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.