commit 26288b110134eea81dc7fd5d158e64bb67692753
parent 1afe8c4a35429773393dc03d1bddfad48e4afaa7
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date: Fri, 18 Jun 2021 22:26:01 +0300
Response: fixed order of the headers
Fixed reversed order of headers in the response.
Is was commented the order of headers should be reversed
before sending response, but it was never implemented before.
Diffstat:
2 files changed, 88 insertions(+), 11 deletions(-)
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
@@ -313,11 +313,16 @@ MHD_DLOG (const struct MHD_Daemon *daemon,
struct MHD_HTTP_Header
{
/**
- * Headers are kept in a linked list.
+ * Headers are kept in a double-linked list.
*/
struct MHD_HTTP_Header *next;
/**
+ * Headers are kept in a double-linked list.
+ */
+ struct MHD_HTTP_Header *prev;
+
+ /**
* The name of the header (key), without the colon.
*/
char *header;
@@ -407,13 +412,16 @@ struct MHD_Response
{
/**
- * Headers to send for the response. Initially
- * the linked list is created in inverse order;
- * the order should be inverted before sending!
+ * Head of double-linked list of headers to send for the response.
*/
struct MHD_HTTP_Header *first_header;
/**
+ * Tail of double-linked list of headers to send for the response.
+ */
+ struct MHD_HTTP_Header *last_header;
+
+ /**
* Buffer pointing to data that we are supposed
* to send as a response.
*/
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c
@@ -44,6 +44,7 @@
#include "memorypool.h"
#include "mhd_send.h"
#include "mhd_compat.h"
+#include "mhd_assert.h"
#if defined(MHD_W32_MUTEX_)
@@ -69,6 +70,78 @@
#endif /* _WIN32 */
#endif /* !MHD_FD_BLOCK_SIZE */
+/**
+ * Insert a new header at the first position of the response
+ */
+#define _MHD_insert_header_first(presponse, phdr) do { \
+ mhd_assert (NULL == phdr->next); \
+ mhd_assert (NULL == phdr->prev); \
+ if (NULL == presponse->first_header) \
+ { \
+ mhd_assert (NULL == presponse->last_header); \
+ presponse->first_header = phdr; \
+ presponse->last_header = phdr; \
+ } \
+ else \
+ { \
+ mhd_assert (NULL != presponse->last_header); \
+ presponse->first_header->prev = phdr; \
+ phdr->next = presponse->first_header; \
+ presponse->first_header = phdr; \
+ } \
+} while (0)
+
+/**
+ * Insert a new header at the last position of the response
+ */
+#define _MHD_insert_header_last(presponse, phdr) do { \
+ mhd_assert (NULL == phdr->next); \
+ mhd_assert (NULL == phdr->prev); \
+ if (NULL == presponse->last_header) \
+ { \
+ mhd_assert (NULL == presponse->first_header); \
+ presponse->last_header = phdr; \
+ presponse->first_header = phdr; \
+ } \
+ else \
+ { \
+ mhd_assert (NULL != presponse->first_header); \
+ presponse->last_header->next = phdr; \
+ phdr->prev = presponse->last_header; \
+ presponse->last_header = phdr; \
+ } \
+} while (0)
+
+
+/**
+ * Remove a header from the response
+ */
+#define _MHD_remove_header(presponse, phdr) do { \
+ mhd_assert (NULL != presponse->first_header); \
+ mhd_assert (NULL != presponse->last_header); \
+ if (NULL == phdr->prev) \
+ { \
+ mhd_assert (phdr == presponse->first_header); \
+ presponse->first_header = phdr->next; \
+ } \
+ else \
+ { \
+ mhd_assert (phdr != presponse->first_header); \
+ mhd_assert (phdr == phdr->prev->next); \
+ phdr->prev->next = phdr->next; \
+ } \
+ if (NULL == phdr->next) \
+ { \
+ mhd_assert (phdr == presponse->last_header); \
+ presponse->last_header = phdr->prev; \
+ } \
+ else \
+ { \
+ mhd_assert (phdr != presponse->last_header); \
+ mhd_assert (phdr == phdr->next->prev); \
+ phdr->next->prev = phdr->prev; \
+ } \
+} while (0)
/**
* Add a header or footer line to the response.
@@ -99,7 +172,7 @@ add_response_entry (struct MHD_Response *response,
(NULL != strchr (content, '\r')) ||
(NULL != strchr (content, '\n')) )
return MHD_NO;
- if (NULL == (hdr = malloc (sizeof (struct MHD_HTTP_Header))))
+ if (NULL == (hdr = MHD_calloc_ (1, sizeof (struct MHD_HTTP_Header))))
return MHD_NO;
if (NULL == (hdr->header = strdup (header)))
{
@@ -115,8 +188,7 @@ add_response_entry (struct MHD_Response *response,
}
hdr->value_size = strlen (content);
hdr->kind = kind;
- hdr->next = response->first_header;
- response->first_header = hdr;
+ _MHD_insert_header_last (response, hdr);
return MHD_YES;
}
@@ -249,12 +321,9 @@ MHD_del_response_header (struct MHD_Response *response,
pos->value,
content_len)))
{
+ _MHD_remove_header (response, pos);
free (pos->header);
free (pos->value);
- if (NULL == prev)
- response->first_header = pos->next;
- else
- prev->next = pos->next;
free (pos);
return MHD_YES;
}