diff options
Diffstat (limited to 'src/config')
-rw-r--r-- | src/config/headers.c | 30 | ||||
-rw-r--r-- | src/config/lexparse.c | 27 | ||||
-rw-r--r-- | src/config/tipidee-config-internal.h | 4 |
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) ; |