about summary refs log tree commit diff
path: root/src/config
diff options
context:
space:
mode:
Diffstat (limited to 'src/config')
-rw-r--r--src/config/deps-exe/tipidee-config1
-rw-r--r--src/config/headers.c80
-rw-r--r--src/config/lexparse.c24
-rw-r--r--src/config/repo.c4
-rw-r--r--src/config/tipidee-config-internal.h23
-rw-r--r--src/config/util.c15
6 files changed, 115 insertions, 32 deletions
diff --git a/src/config/deps-exe/tipidee-config b/src/config/deps-exe/tipidee-config
index 55cf760..2e844d8 100644
--- a/src/config/deps-exe/tipidee-config
+++ b/src/config/deps-exe/tipidee-config
@@ -1,3 +1,4 @@
+util.o
 node.o
 repo.o
 conftree.o
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) ;
 }
diff --git a/src/config/lexparse.c b/src/config/lexparse.c
index 5fb9b71..27a62df 100644
--- a/src/config/lexparse.c
+++ b/src/config/lexparse.c
@@ -2,7 +2,6 @@
 
 #include <stdint.h>
 #include <string.h>
-#include <stdlib.h>
 #include <errno.h>
 
 #include <skalibs/uint32.h>
@@ -65,27 +64,32 @@ struct directive_s
   enum token_e token ;
 } ;
 
-static int keycmp (void const *a, void const *b)
+static void conftree_checkunique (char const *key, mdt const *md)
 {
-  return strcmp((char const *)a, ((struct directive_s const *)b)->s) ;
+  node const *node = conftree_search(key) ;
+  if (node)
+  {
+    char fmt[UINT32_FMT] ;
+    fmt[uint32_fmt(fmt, node->line)] = 0 ;
+    strerr_diefn(1, 12, "duplicate ", "key ", key, " in file ", g.storage.s + md->filepos, " line ", md->linefmt, ", previously defined", " in file ", g.storage.s + node->filepos, " line ", fmt) ;
+  }
 }
-#define BSEARCH(type, key, array) bsearch(key, (array), sizeof(array)/sizeof(type), sizeof(type), (int (*)(void const *, void const *))&keycmp)
 
-static void check_unique (char const *key, mdt const *md)
+static void headers_checkunique (char const *key, mdt const *md)
 {
-  node const *node = conftree_search(key) ;
+  node const *node = headers_search(key) ;
   if (node)
   {
     char fmt[UINT32_FMT] ;
     fmt[uint32_fmt(fmt, node->line)] = 0 ;
-    strerr_diefn(1, 11, "duplicate key ", key, " in file ", g.storage.s + md->filepos, " line ", md->linefmt, ", previously defined", " in file ", g.storage.s + node->filepos, " line ", fmt) ;
+    strerr_diefn(1, 12, "duplicate ", "header ", key, " in file ", g.storage.s + md->filepos, " line ", md->linefmt, ", previously defined", " in file ", g.storage.s + node->filepos, " line ", fmt) ;
   }
 }
 
 static void add_unique (char const *key, char const *value, size_t valuelen, mdt const *md)
 {
   node node ;
-  check_unique(key, md) ;
+  conftree_checkunique(key, md) ;
   confnode_start(&node, key, md->filepos, md->line) ;
   confnode_add(&node, value, valuelen) ;
   conftree_add(&node) ;
@@ -124,7 +128,7 @@ static inline void parse_global (char const *s, size_t const *word, size_t n, md
     case 1 : /* argv */
     {
       node node ;
-      check_unique(gl->key, md) ;
+      conftree_checkunique(gl->key, md) ;
       confnode_start(&node, gl->key, md->filepos, md->line) ;
       for (size_t i = 1 ; i < n ; i++)
         confnode_add(&node, s + word[i], strlen(s + word[i]) + 1) ;
@@ -218,7 +222,7 @@ static inline void parse_redirect (char const *s, size_t const *word, size_t n,
     memcpy(key + 2, domain, domainlen) ;
     memcpy(key + 2 + domainlen, s + word[0], urlen) ;
     key[2 + domainlen + urlen] = 0 ;
-    check_unique(key, md) ;
+    conftree_checkunique(key, md) ;
     confnode_start(&node, key, md->filepos, md->line) ;
     key[0] = '@' | i ;
     confnode_add(&node, &key[0], 1) ;
diff --git a/src/config/repo.c b/src/config/repo.c
index a3ba390..9b411e8 100644
--- a/src/config/repo.c
+++ b/src/config/repo.c
@@ -26,10 +26,10 @@ node const *repo_search (repo const *r, char const *key)
   return avltree_search(&r->tree, key, &i) ? genalloc_s(node const, &r->ga) + i : 0 ;
 }
 
-void repo_add (repo *r, node const *node)
+void repo_add (repo *r, node const *nod)
 {
   uint32_t i = genalloc_len(node, &r->ga) ;
-  if (!genalloc_append(node, &r->ga, node)) dienomem() ;
+  if (!genalloc_append(node, &r->ga, nod)) dienomem() ;
   if (!avltree_insert(&r->tree, i)) dienomem() ;
 }
 
diff --git a/src/config/tipidee-config-internal.h b/src/config/tipidee-config-internal.h
index 190ac45..3508771 100644
--- a/src/config/tipidee-config-internal.h
+++ b/src/config/tipidee-config-internal.h
@@ -5,6 +5,7 @@
 
 #include <stdint.h>
 #include <string.h>
+#include <stdlib.h>
 
 #include <skalibs/buffer.h>
 #include <skalibs/strerr.h>
@@ -45,6 +46,12 @@ struct global_s
 extern struct global_s g ;
 
 
+ /* util */
+
+extern int keycmp (void const *, void const *) ;  /* for any struct starting with a string key */
+#define BSEARCH(type, key, array) bsearch(key, (array), sizeof(array)/sizeof(type), sizeof(type), &keycmp)
+
+
  /* node */
 
 extern void node_start (stralloc *, node *, char const *, size_t, uint32_t) ;
@@ -68,17 +75,18 @@ extern void confnode_add (node *, char const *, size_t) ;
 extern node const *conftree_search (char const *) ;
 extern void conftree_add (node const *) ;
 extern void conftree_update (node const *) ;
+
 extern int conftree_write (cdbmaker *) ;
 
 
  /* headers */
 
-extern void header_start (node *, char const *, size_t, uint32_t) ;
-extern void header_add (node *, char const *, size_t) ;
+extern void header_canonize (char *) ;
+extern int header_allowed (char const *) ;
 
 extern node const *headers_search (char const *) ;
-extern void headers_add (node const *) ;
-extern int headers_write (void) ;
+extern void headers_add (char const *, char const *, uint8_t, size_t, uint32_t) ;
+extern void headers_finish (void) ;
 
 
  /* lexparse */
@@ -90,11 +98,4 @@ extern void conf_lexparse (buffer *, char const *) ;
 
 extern void conf_defaults (void) ;
 
-
- /* headers */
-
-extern node const *headers_search (char const *) ;
-extern void headers_add (node const *) ;
-extern void headers_finish (void) ;
-
 #endif
diff --git a/src/config/util.c b/src/config/util.c
new file mode 100644
index 0000000..bee1503
--- /dev/null
+++ b/src/config/util.c
@@ -0,0 +1,15 @@
+/* ISC license. */
+
+#include <string.h>
+
+#include "tipidee-config-internal.h"
+
+struct starts_with_a_string_key_s
+{
+  char const *s ;
+} ;
+
+int keycmp (void const *a, void const *b)
+{
+  return strcmp((char const *)a, ((struct starts_with_a_string_key_s const *)b)->s) ;
+}