summaryrefslogtreecommitdiff
path: root/src/config/headers.c
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2023-10-23 12:30:58 +0000
committerLaurent Bercot <ska@appnovation.com>2023-10-23 12:30:58 +0000
commit907f1c64369095b5b2d5f6fb23a8b937720d94cc (patch)
treecb4eebe2b754040af876b3069233b176597b9d4e /src/config/headers.c
parent12891d0e8551e3d6bb7bf1429f936e04be4da8b5 (diff)
downloadtipidee-907f1c64369095b5b2d5f6fb23a8b937720d94cc.tar.xz
More tipidee-config refactoring, headers functions are clean
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src/config/headers.c')
-rw-r--r--src/config/headers.c80
1 files changed, 71 insertions, 9 deletions
diff --git a/src/config/headers.c b/src/config/headers.c
index 7bbb573..b080390 100644
--- a/src/config/headers.c
+++ b/src/config/headers.c
@@ -1,10 +1,37 @@
/* ISC license. */
+#include <string.h>
+#include <ctype.h>
+
+#include <skalibs/strerr.h>
#include <skalibs/genalloc.h>
#include <skalibs/avltree.h>
+#include <tipidee/config.h>
#include "tipidee-config-internal.h"
+struct builtinheaders_s
+{
+ char const *key ;
+ char const *value ;
+ uint8_t overridable : 1 ;
+} ;
+
+static struct builtinheaders_s const builtinheaders[] =
+{
+ { .key = "Accept-Ranges", .value = "none", .overridable = 0 },
+ { .key = "Cache-Control", .value = "private", .overridable = 1 },
+ { .key = "Connection", .value = 0, .overridable = 0 },
+ { .key = "Content-Security-Policy", .value = "default-src 'self'; style-src 'self' 'unsafe-inline';", .overridable = 1 },
+ { .key = "Date", .value = 0, .overridable = 0 },
+ { .key = "Referrer-Policy", .value = "no-referrer-when-downgrade", .overridable = 1 },
+ { .key = "Server", .value = "tipidee/" TIPIDEE_VERSION, .overridable = 0 },
+ { .key = "Status", .value = 0, .overridable = 0 },
+ { .key = "Vary", .value = "Accept-Encoding", .overridable = 0 },
+ { .key = "X-Content-Type-Options", .value = "nosniff", .overridable = 1 },
+ { .key = "X-Frame-Options", .value = "DENY", .overridable = 1 }
+} ;
+
static stralloc headers_storage = GENALLOC_ZERO ;
static repo headers = \
@@ -14,14 +41,21 @@ static repo headers = \
.storage = &headers_storage \
} ;
-void header_start (node *node, char const *key, size_t filepos, uint32_t line)
+int header_allowed (char const *key)
{
- return node_start(&headers_storage, node, key, filepos, line) ;
+ struct builtinheaders_s const *p = BSEARCH(struct builtinheaders_s, key, builtinheaders) ;
+ return !p || p->overridable ;
}
-void header_add (node *node, char const *s, size_t len)
+void header_canonize (char *key)
{
- return node_add(&headers_storage, node, s, len) ;
+ int h = 1 ;
+ size_t len = strlen(key) ;
+ for (size_t i = 0 ; i < len ; i++)
+ {
+ key[i] = h ? toupper(key[i]) : tolower(key[i]) ;
+ h = key[i] == '-' ;
+ }
}
node const *headers_search (char const *key)
@@ -29,18 +63,46 @@ node const *headers_search (char const *key)
return repo_search(&headers, key) ;
}
-void headers_add (node const *node)
+void headers_add (char const *key, char const *value, uint8_t options, size_t filepos, uint32_t line)
{
- return repo_add(&headers, node) ;
+ node node ;
+ node_start(&headers_storage, &node, key, filepos, line) ;
+ node_add(&headers_storage, &node, options & 1 ? "\1" : "", 1) ;
+ node_add(&headers_storage, &node, value, strlen(value) + 1) ;
+ repo_add(&headers, &node) ;
+}
+
+static void headers_defaults (node *node)
+{
+ for (size_t i = 0 ; i < sizeof(builtinheaders) / sizeof(struct builtinheaders_s) ; i++)
+ {
+ struct builtinheaders_s const *p = builtinheaders + i ;
+ if (!p->value) continue ;
+ if (p->overridable && headers_search(p->key)) continue ;
+ confnode_add(node, p->key, strlen(p->key) + 1) ;
+ confnode_add(node, p->overridable ? "\1" : "", 1) ;
+ confnode_add(node, p->value, strlen(p->value) + 1) ;
+ }
}
static int header_write (uint32_t d, unsigned int h, void *data)
{
+ node *confnode = data ;
+ node *const header = genalloc_s(node, &headers.ga) + d ;
+ (void)h ;
+ confnode_add(confnode, headers_storage.s + header->key, header->keylen + 1) ;
+ confnode_add(confnode, headers_storage.s + header->data, header->datalen + 1) ;
return 1 ;
}
-int headers_write (void)
+void headers_finish (void)
{
- if (!avltree_iter(&headers.tree, &header_write, 0)) return 0 ;
- return 1 ;
+ node node ;
+ confnode_start(&node, "G:response-headers", 0, 0) ;
+ headers_defaults(&node) ;
+ (void)avltree_iter(&headers.tree, &header_write, &node) ;
+ conftree_add(&node) ;
+ avltree_free(&headers.tree) ;
+ genalloc_free(node, &headers.ga) ;
+ stralloc_free(&headers_storage) ;
}