summaryrefslogtreecommitdiff
path: root/src/config
diff options
context:
space:
mode:
Diffstat (limited to 'src/config')
-rw-r--r--src/config/headers.c30
-rw-r--r--src/config/lexparse.c27
-rw-r--r--src/config/tipidee-config-internal.h4
3 files changed, 52 insertions, 9 deletions
diff --git a/src/config/headers.c b/src/config/headers.c
index b080390..351b938 100644
--- a/src/config/headers.c
+++ b/src/config/headers.c
@@ -1,8 +1,10 @@
/* ISC license. */
+#include <stdint.h>
#include <string.h>
#include <ctype.h>
+#include <skalibs/uint32.h>
#include <skalibs/strerr.h>
#include <skalibs/genalloc.h>
#include <skalibs/avltree.h>
@@ -47,7 +49,7 @@ int header_allowed (char const *key)
return !p || p->overridable ;
}
-void header_canonize (char *key)
+void header_canonicalize (char *key)
{
int h = 1 ;
size_t len = strlen(key) ;
@@ -63,17 +65,25 @@ node const *headers_search (char const *key)
return repo_search(&headers, key) ;
}
-void headers_add (char const *key, char const *value, uint8_t options, size_t filepos, uint32_t line)
+void headers_addv (char const *key, uint8_t options, char const *s, size_t const *word, size_t n, size_t filepos, uint32_t line)
{
node node ;
+ if (!n) return ;
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) ;
+ node_add(&headers_storage, &node, s + word[0], strlen(s + word[0])) ;
+ for (size_t i = 1 ; i < n ; i++)
+ {
+ node_add(&headers_storage, &node, " ", 1) ;
+ node_add(&headers_storage, &node, s + word[i], strlen(s + word[i])) ;
+ }
+ node_add(&headers_storage, &node, "", 1) ;
repo_add(&headers, &node) ;
}
-static void headers_defaults (node *node)
+static uint32_t headers_defaults (node *node)
{
+ uint32_t n = 0 ;
for (size_t i = 0 ; i < sizeof(builtinheaders) / sizeof(struct builtinheaders_s) ; i++)
{
struct builtinheaders_s const *p = builtinheaders + i ;
@@ -82,7 +92,9 @@ static void headers_defaults (node *node)
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) ;
+ n++ ;
}
+ return n ;
}
static int header_write (uint32_t d, unsigned int h, void *data)
@@ -91,16 +103,20 @@ static int header_write (uint32_t d, unsigned int h, void *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) ;
+ confnode_add(confnode, headers_storage.s + header->data, header->datalen) ;
return 1 ;
}
void headers_finish (void)
{
+ uint32_t n ;
+ char pack[4] ;
node node ;
- confnode_start(&node, "G:response-headers", 0, 0) ;
- headers_defaults(&node) ;
+ confnode_start(&node, "G:response_headers", 0, 0) ;
+ n = avltree_len(&headers.tree) + headers_defaults(&node) ;
(void)avltree_iter(&headers.tree, &header_write, &node) ;
+ uint32_pack_big(pack, n) ;
+ confnode_add(&node, pack, 4) ;
conftree_add(&node) ;
avltree_free(&headers.tree) ;
genalloc_free(node, &headers.ga) ;
diff --git a/src/config/lexparse.c b/src/config/lexparse.c
index 27a62df..783e39f 100644
--- a/src/config/lexparse.c
+++ b/src/config/lexparse.c
@@ -45,6 +45,7 @@ enum token_e
T_GLOBAL,
T_LOG,
T_CONTENTTYPE,
+ T_CUSTOMHEADER,
T_DOMAIN,
T_NPHPREFIX,
T_REDIRECT,
@@ -195,6 +196,27 @@ static inline void parse_contenttype (char const *s, size_t const *word, size_t
}
}
+static inline void parse_customheader (char const *s, size_t const *word, size_t n, mdt const *md)
+{
+ uint8_t options = 0 ;
+ if (n < 3)
+ strerr_dief8x(1, "too ", "few", " arguments to directive ", "custom-header", " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ;
+ if (!strcmp(s + word[0], "weak")) options |= 1 ;
+ else if (!strcmp(s + word[0], "strong")) options &= ~1 ;
+ else strerr_dief7x(1, "type should be weak or strong for", " directive ", "custom-header", " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ;
+ word++ ; n-- ;
+ {
+ size_t len = strlen(s + *word) ;
+ char key[len + 1] ;
+ memcpy(key, s + *word++, len + 1) ; n-- ;
+ header_canonicalize(key) ;
+ if (!header_allowed(key))
+ strerr_dief7x(1, "header ", key, " cannot be customized", " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ;
+ headers_checkunique(key, md) ;
+ headers_addv(key, options, s, word, n, md->filepos, md->line) ;
+ }
+}
+
static inline void parse_redirect (char const *s, size_t const *word, size_t n, char const *domain, size_t domainlen, mdt const *md)
{
static uint32_t const codes[4] = { 307, 308, 302, 301 } ;
@@ -360,6 +382,7 @@ static inline void process_line (char const *s, size_t const *word, size_t n, st
{ .s = "basic-auth", .token = T_BASICAUTH },
{ .s = "cgi", .token = T_CGI },
{ .s = "content-type", .token = T_CONTENTTYPE },
+ { .s = "custom-header", .token = T_CUSTOMHEADER },
{ .s = "custom-response", .token = T_CUSTOMRESPONSE },
{ .s = "domain", .token = T_DOMAIN },
{ .s = "file-type", .token = T_FILETYPE },
@@ -404,6 +427,9 @@ static inline void process_line (char const *s, size_t const *word, size_t n, st
case T_CONTENTTYPE :
parse_contenttype(s, word, n, md) ;
break ;
+ case T_CUSTOMHEADER :
+ parse_customheader(s, word, n, md) ;
+ break ;
case T_DOMAIN :
if (n != 1)
strerr_dief8x(1, "too ", n > 1 ? "many" : "few", " arguments to directive ", "domain", " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ;
@@ -518,4 +544,5 @@ void conf_lexparse (buffer *b, char const *ifile)
stralloc_free(&domain) ;
genalloc_free(size_t, &words) ;
stralloc_free(&sa) ;
+ headers_finish() ;
}
diff --git a/src/config/tipidee-config-internal.h b/src/config/tipidee-config-internal.h
index 3508771..d3977c0 100644
--- a/src/config/tipidee-config-internal.h
+++ b/src/config/tipidee-config-internal.h
@@ -81,11 +81,11 @@ extern int conftree_write (cdbmaker *) ;
/* headers */
-extern void header_canonize (char *) ;
+extern void header_canonicalize (char *) ;
extern int header_allowed (char const *) ;
extern node const *headers_search (char const *) ;
-extern void headers_add (char const *, char const *, uint8_t, size_t, uint32_t) ;
+extern void headers_addv (char const *, uint8_t, char const *, size_t const *, size_t, size_t, uint32_t) ;
extern void headers_finish (void) ;