diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2023-10-30 11:16:55 +0000 |
---|---|---|
committer | Laurent Bercot <ska@appnovation.com> | 2023-10-30 11:16:55 +0000 |
commit | 1c5f682f4dcbca5afa9dd4a9688bde40efaeb12c (patch) | |
tree | 9c5ac88f1c430686d45de44ee36f29fe26be42b1 | |
parent | ad88c5ec68b1cfd47017face422132ab8c7b2874 (diff) | |
download | tipidee-1c5f682f4dcbca5afa9dd4a9688bde40efaeb12c.tar.gz tipidee-1c5f682f4dcbca5afa9dd4a9688bde40efaeb12c.tar.xz tipidee-1c5f682f4dcbca5afa9dd4a9688bde40efaeb12c.zip |
Revamp (and hopefully fix) resattr management
Signed-off-by: Laurent Bercot <ska@appnovation.com>
-rw-r--r-- | package/deps.mak | 15 | ||||
-rw-r--r-- | src/config/PROTOCOL.txt | 42 | ||||
-rw-r--r-- | src/config/conftree.c | 5 | ||||
-rw-r--r-- | src/config/headers.c | 13 | ||||
-rw-r--r-- | src/config/lexparse.c | 41 | ||||
-rw-r--r-- | src/config/resattr.c | 56 | ||||
-rw-r--r-- | src/include/tipidee/conf.h | 5 | ||||
-rw-r--r-- | src/include/tipidee/log.h | 10 | ||||
-rw-r--r-- | src/include/tipidee/resattr.h | 23 | ||||
-rw-r--r-- | src/include/tipidee/tipidee.h | 1 | ||||
-rw-r--r-- | src/libtipidee/deps-lib/tipidee | 2 | ||||
-rw-r--r-- | src/libtipidee/tipidee_conf_get_resattr.c | 62 | ||||
-rw-r--r-- | src/libtipidee/tipidee_conf_get_resattr1.c | 36 | ||||
-rw-r--r-- | src/libtipidee/tipidee_log_resource.c | 5 | ||||
-rw-r--r-- | src/tipideed/cgi.c | 5 | ||||
-rw-r--r-- | src/tipideed/tipideed.c | 52 |
16 files changed, 237 insertions, 136 deletions
diff --git a/package/deps.mak b/package/deps.mak index b59e573..e4a8166 100644 --- a/package/deps.mak +++ b/package/deps.mak @@ -2,11 +2,11 @@ # This file has been generated by tools/gen-deps.sh # -src/include/tipidee/conf.h: src/include/tipidee/uri.h -src/include/tipidee/log.h: src/include/tipidee/headers.h src/include/tipidee/rql.h +src/include/tipidee/conf.h: src/include/tipidee/resattr.h src/include/tipidee/uri.h +src/include/tipidee/log.h: src/include/tipidee/headers.h src/include/tipidee/resattr.h src/include/tipidee/rql.h src/include/tipidee/response.h: src/include/tipidee/headers.h src/include/tipidee/rql.h src/include/tipidee/rql.h: src/include/tipidee/method.h src/include/tipidee/uri.h -src/include/tipidee/tipidee.h: src/include/tipidee/conf.h src/include/tipidee/config.h src/include/tipidee/headers.h src/include/tipidee/log.h src/include/tipidee/method.h src/include/tipidee/response.h src/include/tipidee/rql.h src/include/tipidee/uri.h src/include/tipidee/util.h +src/include/tipidee/tipidee.h: src/include/tipidee/conf.h src/include/tipidee/config.h src/include/tipidee/headers.h src/include/tipidee/log.h src/include/tipidee/method.h src/include/tipidee/resattr.h src/include/tipidee/response.h src/include/tipidee/rql.h src/include/tipidee/uri.h src/include/tipidee/util.h src/tipideed/tipideed-internal.h: src/include/tipidee/tipidee.h src/config/conftree.o src/config/conftree.lo: src/config/conftree.c src/config/tipidee-config-internal.h src/config/defaults.o src/config/defaults.lo: src/config/defaults.c src/config/tipidee-config-internal.h src/include/tipidee/log.h @@ -14,6 +14,7 @@ src/config/headers.o src/config/headers.lo: src/config/headers.c src/config/tipi src/config/lexparse.o src/config/lexparse.lo: src/config/lexparse.c src/config/tipidee-config-internal.h src/include/tipidee/config.h src/include/tipidee/log.h src/config/node.o src/config/node.lo: src/config/node.c src/config/tipidee-config-internal.h src/config/repo.o src/config/repo.lo: src/config/repo.c src/config/tipidee-config-internal.h +src/config/resattr.o src/config/resattr.lo: src/config/resattr.c src/config/tipidee-config-internal.h src/config/tipidee-config-preprocess.o src/config/tipidee-config-preprocess.lo: src/config/tipidee-config-preprocess.c src/config/tipidee-config.o src/config/tipidee-config.lo: src/config/tipidee-config.c src/config/tipidee-config-internal.h src/include/tipidee/config.h src/config/util.o src/config/util.lo: src/config/util.c src/config/tipidee-config-internal.h @@ -23,6 +24,8 @@ src/libtipidee/tipidee_conf_get_argv.o src/libtipidee/tipidee_conf_get_argv.lo: src/libtipidee/tipidee_conf_get_content_type.o src/libtipidee/tipidee_conf_get_content_type.lo: src/libtipidee/tipidee_conf_get_content_type.c src/include/tipidee/conf.h src/libtipidee/tipidee_conf_get_errorfile.o src/libtipidee/tipidee_conf_get_errorfile.lo: src/libtipidee/tipidee_conf_get_errorfile.c src/include/tipidee/conf.h src/libtipidee/tipidee_conf_get_redirection.o src/libtipidee/tipidee_conf_get_redirection.lo: src/libtipidee/tipidee_conf_get_redirection.c src/include/tipidee/conf.h +src/libtipidee/tipidee_conf_get_resattr.o src/libtipidee/tipidee_conf_get_resattr.lo: src/libtipidee/tipidee_conf_get_resattr.c src/include/tipidee/conf.h src/include/tipidee/resattr.h +src/libtipidee/tipidee_conf_get_resattr1.o src/libtipidee/tipidee_conf_get_resattr1.lo: src/libtipidee/tipidee_conf_get_resattr1.c src/include/tipidee/conf.h src/include/tipidee/resattr.h src/libtipidee/tipidee_conf_get_responseheaders.o src/libtipidee/tipidee_conf_get_responseheaders.lo: src/libtipidee/tipidee_conf_get_responseheaders.c src/include/tipidee/conf.h src/libtipidee/tipidee_conf_get_string.o src/libtipidee/tipidee_conf_get_string.lo: src/libtipidee/tipidee_conf_get_string.c src/include/tipidee/conf.h src/libtipidee/tipidee_conf_get_uint32.o src/libtipidee/tipidee_conf_get_uint32.lo: src/libtipidee/tipidee_conf_get_uint32.c src/include/tipidee/conf.h @@ -65,12 +68,12 @@ tipidee-config: src/config/tipidee-config.o src/config/util.o src/config/node.o tipidee-config-preprocess: EXTRA_LIBS := -lskarnet tipidee-config-preprocess: src/config/tipidee-config-preprocess.o ifeq ($(strip $(STATIC_LIBS_ARE_PIC)),) -libtipidee.a.xyzzy: src/libtipidee/tipidee_conf_free.o src/libtipidee/tipidee_conf_get.o src/libtipidee/tipidee_conf_get_argv.o src/libtipidee/tipidee_conf_get_content_type.o src/libtipidee/tipidee_conf_get_errorfile.o src/libtipidee/tipidee_conf_get_redirection.o src/libtipidee/tipidee_conf_get_responseheaders.o src/libtipidee/tipidee_conf_get_string.o src/libtipidee/tipidee_conf_get_uint32.o src/libtipidee/tipidee_conf_init.o src/libtipidee/tipidee_headers_get_content_length.o src/libtipidee/tipidee_headers_init.o src/libtipidee/tipidee_headers_parse.o src/libtipidee/tipidee_headers_search.o src/libtipidee/tipidee_log_answer.o src/libtipidee/tipidee_log_exit.o src/libtipidee/tipidee_log_resource.o src/libtipidee/tipidee_log_request.o src/libtipidee/tipidee_log_start.o src/libtipidee/tipidee_method.o src/libtipidee/tipidee_response_error_nofile.o src/libtipidee/tipidee_response_file.o src/libtipidee/tipidee_response_header_date.o src/libtipidee/tipidee_response_header_date_fmt.o src/libtipidee/tipidee_response_header_lastmodified.o src/libtipidee/tipidee_response_header_preparebuiltin.o src/libtipidee/tipidee_response_header_writeall.o src/libtipidee/tipidee_response_header_writemerge.o src/libtipidee/tipidee_response_status.o src/libtipidee/tipidee_rql_read.o src/libtipidee/tipidee_uri_parse.o src/libtipidee/tipidee_util_chunked_read.o src/libtipidee/tipidee_util_defaulttext.o src/libtipidee/tipidee_util_httpdate.o +libtipidee.a.xyzzy: src/libtipidee/tipidee_conf_free.o src/libtipidee/tipidee_conf_get.o src/libtipidee/tipidee_conf_get_argv.o src/libtipidee/tipidee_conf_get_content_type.o src/libtipidee/tipidee_conf_get_errorfile.o src/libtipidee/tipidee_conf_get_redirection.o src/libtipidee/tipidee_conf_get_resattr.o src/libtipidee/tipidee_conf_get_resattr1.o src/libtipidee/tipidee_conf_get_responseheaders.o src/libtipidee/tipidee_conf_get_string.o src/libtipidee/tipidee_conf_get_uint32.o src/libtipidee/tipidee_conf_init.o src/libtipidee/tipidee_headers_get_content_length.o src/libtipidee/tipidee_headers_init.o src/libtipidee/tipidee_headers_parse.o src/libtipidee/tipidee_headers_search.o src/libtipidee/tipidee_log_answer.o src/libtipidee/tipidee_log_exit.o src/libtipidee/tipidee_log_resource.o src/libtipidee/tipidee_log_request.o src/libtipidee/tipidee_log_start.o src/libtipidee/tipidee_method.o src/libtipidee/tipidee_response_error_nofile.o src/libtipidee/tipidee_response_file.o src/libtipidee/tipidee_response_header_date.o src/libtipidee/tipidee_response_header_date_fmt.o src/libtipidee/tipidee_response_header_lastmodified.o src/libtipidee/tipidee_response_header_preparebuiltin.o src/libtipidee/tipidee_response_header_writeall.o src/libtipidee/tipidee_response_header_writemerge.o src/libtipidee/tipidee_response_status.o src/libtipidee/tipidee_rql_read.o src/libtipidee/tipidee_uri_parse.o src/libtipidee/tipidee_util_chunked_read.o src/libtipidee/tipidee_util_defaulttext.o src/libtipidee/tipidee_util_httpdate.o else -libtipidee.a.xyzzy: src/libtipidee/tipidee_conf_free.lo src/libtipidee/tipidee_conf_get.lo src/libtipidee/tipidee_conf_get_argv.lo src/libtipidee/tipidee_conf_get_content_type.lo src/libtipidee/tipidee_conf_get_errorfile.lo src/libtipidee/tipidee_conf_get_redirection.lo src/libtipidee/tipidee_conf_get_responseheaders.lo src/libtipidee/tipidee_conf_get_string.lo src/libtipidee/tipidee_conf_get_uint32.lo src/libtipidee/tipidee_conf_init.lo src/libtipidee/tipidee_headers_get_content_length.lo src/libtipidee/tipidee_headers_init.lo src/libtipidee/tipidee_headers_parse.lo src/libtipidee/tipidee_headers_search.lo src/libtipidee/tipidee_log_answer.lo src/libtipidee/tipidee_log_exit.lo src/libtipidee/tipidee_log_resource.lo src/libtipidee/tipidee_log_request.lo src/libtipidee/tipidee_log_start.lo src/libtipidee/tipidee_method.lo src/libtipidee/tipidee_response_error_nofile.lo src/libtipidee/tipidee_response_file.lo src/libtipidee/tipidee_response_header_date.lo src/libtipidee/tipidee_response_header_date_fmt.lo src/libtipidee/tipidee_response_header_lastmodified.lo src/libtipidee/tipidee_response_header_preparebuiltin.lo src/libtipidee/tipidee_response_header_writeall.lo src/libtipidee/tipidee_response_header_writemerge.lo src/libtipidee/tipidee_response_status.lo src/libtipidee/tipidee_rql_read.lo src/libtipidee/tipidee_uri_parse.lo src/libtipidee/tipidee_util_chunked_read.lo src/libtipidee/tipidee_util_defaulttext.lo src/libtipidee/tipidee_util_httpdate.lo +libtipidee.a.xyzzy: src/libtipidee/tipidee_conf_free.lo src/libtipidee/tipidee_conf_get.lo src/libtipidee/tipidee_conf_get_argv.lo src/libtipidee/tipidee_conf_get_content_type.lo src/libtipidee/tipidee_conf_get_errorfile.lo src/libtipidee/tipidee_conf_get_redirection.lo src/libtipidee/tipidee_conf_get_resattr.lo src/libtipidee/tipidee_conf_get_resattr1.lo src/libtipidee/tipidee_conf_get_responseheaders.lo src/libtipidee/tipidee_conf_get_string.lo src/libtipidee/tipidee_conf_get_uint32.lo src/libtipidee/tipidee_conf_init.lo src/libtipidee/tipidee_headers_get_content_length.lo src/libtipidee/tipidee_headers_init.lo src/libtipidee/tipidee_headers_parse.lo src/libtipidee/tipidee_headers_search.lo src/libtipidee/tipidee_log_answer.lo src/libtipidee/tipidee_log_exit.lo src/libtipidee/tipidee_log_resource.lo src/libtipidee/tipidee_log_request.lo src/libtipidee/tipidee_log_start.lo src/libtipidee/tipidee_method.lo src/libtipidee/tipidee_response_error_nofile.lo src/libtipidee/tipidee_response_file.lo src/libtipidee/tipidee_response_header_date.lo src/libtipidee/tipidee_response_header_date_fmt.lo src/libtipidee/tipidee_response_header_lastmodified.lo src/libtipidee/tipidee_response_header_preparebuiltin.lo src/libtipidee/tipidee_response_header_writeall.lo src/libtipidee/tipidee_response_header_writemerge.lo src/libtipidee/tipidee_response_status.lo src/libtipidee/tipidee_rql_read.lo src/libtipidee/tipidee_uri_parse.lo src/libtipidee/tipidee_util_chunked_read.lo src/libtipidee/tipidee_util_defaulttext.lo src/libtipidee/tipidee_util_httpdate.lo endif libtipidee.so.xyzzy: EXTRA_LIBS := -lskarnet -libtipidee.so.xyzzy: src/libtipidee/tipidee_conf_free.lo src/libtipidee/tipidee_conf_get.lo src/libtipidee/tipidee_conf_get_argv.lo src/libtipidee/tipidee_conf_get_content_type.lo src/libtipidee/tipidee_conf_get_errorfile.lo src/libtipidee/tipidee_conf_get_redirection.lo src/libtipidee/tipidee_conf_get_responseheaders.lo src/libtipidee/tipidee_conf_get_string.lo src/libtipidee/tipidee_conf_get_uint32.lo src/libtipidee/tipidee_conf_init.lo src/libtipidee/tipidee_headers_get_content_length.lo src/libtipidee/tipidee_headers_init.lo src/libtipidee/tipidee_headers_parse.lo src/libtipidee/tipidee_headers_search.lo src/libtipidee/tipidee_log_answer.lo src/libtipidee/tipidee_log_exit.lo src/libtipidee/tipidee_log_resource.lo src/libtipidee/tipidee_log_request.lo src/libtipidee/tipidee_log_start.lo src/libtipidee/tipidee_method.lo src/libtipidee/tipidee_response_error_nofile.lo src/libtipidee/tipidee_response_file.lo src/libtipidee/tipidee_response_header_date.lo src/libtipidee/tipidee_response_header_date_fmt.lo src/libtipidee/tipidee_response_header_lastmodified.lo src/libtipidee/tipidee_response_header_preparebuiltin.lo src/libtipidee/tipidee_response_header_writeall.lo src/libtipidee/tipidee_response_header_writemerge.lo src/libtipidee/tipidee_response_status.lo src/libtipidee/tipidee_rql_read.lo src/libtipidee/tipidee_uri_parse.lo src/libtipidee/tipidee_util_chunked_read.lo src/libtipidee/tipidee_util_defaulttext.lo src/libtipidee/tipidee_util_httpdate.lo +libtipidee.so.xyzzy: src/libtipidee/tipidee_conf_free.lo src/libtipidee/tipidee_conf_get.lo src/libtipidee/tipidee_conf_get_argv.lo src/libtipidee/tipidee_conf_get_content_type.lo src/libtipidee/tipidee_conf_get_errorfile.lo src/libtipidee/tipidee_conf_get_redirection.lo src/libtipidee/tipidee_conf_get_resattr.lo src/libtipidee/tipidee_conf_get_resattr1.lo src/libtipidee/tipidee_conf_get_responseheaders.lo src/libtipidee/tipidee_conf_get_string.lo src/libtipidee/tipidee_conf_get_uint32.lo src/libtipidee/tipidee_conf_init.lo src/libtipidee/tipidee_headers_get_content_length.lo src/libtipidee/tipidee_headers_init.lo src/libtipidee/tipidee_headers_parse.lo src/libtipidee/tipidee_headers_search.lo src/libtipidee/tipidee_log_answer.lo src/libtipidee/tipidee_log_exit.lo src/libtipidee/tipidee_log_resource.lo src/libtipidee/tipidee_log_request.lo src/libtipidee/tipidee_log_start.lo src/libtipidee/tipidee_method.lo src/libtipidee/tipidee_response_error_nofile.lo src/libtipidee/tipidee_response_file.lo src/libtipidee/tipidee_response_header_date.lo src/libtipidee/tipidee_response_header_date_fmt.lo src/libtipidee/tipidee_response_header_lastmodified.lo src/libtipidee/tipidee_response_header_preparebuiltin.lo src/libtipidee/tipidee_response_header_writeall.lo src/libtipidee/tipidee_response_header_writemerge.lo src/libtipidee/tipidee_response_status.lo src/libtipidee/tipidee_rql_read.lo src/libtipidee/tipidee_uri_parse.lo src/libtipidee/tipidee_util_chunked_read.lo src/libtipidee/tipidee_util_defaulttext.lo src/libtipidee/tipidee_util_httpdate.lo tipideed: EXTRA_LIBS := -lskarnet tipideed: src/tipideed/tipideed.o src/tipideed/cgi.o src/tipideed/harden.o src/tipideed/options.o src/tipideed/regular.o src/tipideed/responses.o src/tipideed/send_file.o src/tipideed/trace.o libtipidee.a.xyzzy INTERNAL_LIBS := diff --git a/src/config/PROTOCOL.txt b/src/config/PROTOCOL.txt deleted file mode 100644 index f6cc304..0000000 --- a/src/config/PROTOCOL.txt +++ /dev/null @@ -1,42 +0,0 @@ -* Globals - -G:read_timeout -> 4 bytes exit if waiting on client input for read_timeout ms -G:write_timeout -> 4 bytes die if waiting on flush to client for write_timeout ms -G:cgi_timeout -> 4 bytes 504 if CGI hasn't finished answering / die if NPH hasn't finished reading -G:max_request_body_length -> 4 bytes -G:max_cgi_body_length -> 4 bytes -G:index_file -> file1\0file2\0file3\0 list of files to attempt when URL is a directory - -They all need to exist, tipidee-config creates defaults. - - -* Content-Type - -T:extension -> string T:pdf -> application/pdf -or individual Content-Types in resource attributes - -tipidee-config hardcodes a number of default content-types, they -can be overridden. - - -* Individual redirection - -R:vres -> Xurl R:skarnet.org/rickroll.html -> Xhttps://www.youtube.com/watch?v=dQw4w9WgXcQ - X = '@' | redir_type (307=0, 308=1, 302=2, 301=3) - - -* Prefix redirection - -r:prefix -> Xurlprefix r:s6.org -> Xhttps://skarnet.org/software/s6 - X = '@' | redir_type (307=0, 308=1, 302=2, 301=3) - -* Resource attributes - -A:file -> Xstring X = '@' | 1 (iscgi) - if string nonempty: it's the content-type for the resource. If empty, default ctype - -a:prefix -> Xstring same, but for prefixes - -* NPH prefixes - -N:domain -> nphprefix N:skarnet.org -> nph- any CGI under skarnet.org starting with nph diff --git a/src/config/conftree.c b/src/config/conftree.c index d4b01ef..a146188 100644 --- a/src/config/conftree.c +++ b/src/config/conftree.c @@ -42,11 +42,6 @@ static int confnode_write (uint32_t d, unsigned int h, void *data) { node *nod = genalloc_s(node, &conftree.ga) + d ; (void)h ; - if ((conftree.storage->s[nod->key] & ~0x20) == 'A') - { - conftree.storage->s[++nod->data] |= '@' ; - nod->datalen-- ; - } return cdbmake_add((cdbmaker *)data, conftree.storage->s + nod->key, nod->keylen, conftree.storage->s + nod->data, nod->datalen) ; } diff --git a/src/config/headers.c b/src/config/headers.c index 31d3e69..4fcdf7d 100644 --- a/src/config/headers.c +++ b/src/config/headers.c @@ -25,11 +25,8 @@ static struct builtinheaders_s const builtinheaders[] = { .key = "Allow", .value = 0, .overridable = 0 }, { .key = "Cache-Control", .value = "private", .overridable = 1 }, { .key = "Connection", .value = 0, .overridable = 0 }, - { .key = "Content-Length", .value = 0, .overridable = 0 }, { .key = "Content-Security-Policy", .value = "default-src 'self'; style-src 'self' 'unsafe-inline';", .overridable = 1 }, - { .key = "Content-Type", .value = 0, .overridable = 0 }, { .key = "Date", .value = 0, .overridable = 0 }, - { .key = "Location", .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 }, @@ -49,7 +46,15 @@ static repo headers = \ int header_allowed (char const *key) { - struct builtinheaders_s const *p = BSEARCH(struct builtinheaders_s, key, builtinheaders) ; + static char const *const nope[] = + { + "Content-Length", + "Content-Type", + "Location" + } ; + struct builtinheaders_s const *p ; + if (BSEARCH(char const *, key, nope)) return 0 ; + p = BSEARCH(struct builtinheaders_s, key, builtinheaders) ; return !p || p->overridable ; } diff --git a/src/config/lexparse.c b/src/config/lexparse.c index b72182e..afd22a5 100644 --- a/src/config/lexparse.c +++ b/src/config/lexparse.c @@ -273,12 +273,11 @@ static inline void parse_redirect (char const *s, size_t const *word, size_t n, } } -static void parse_bitattr (char const *s, size_t const *word, size_t n, char const *domain, size_t domainlen, mdt const *md, unsigned int bit, int set) +static void parse_bitattr (char const *s, size_t const *word, size_t n, char const *domain, size_t domainlen, mdt const *md, uint8_t bit, int h) { static char const *const attr[3][2] = { { "noncgi", "cgi" }, { "nonnph", "nph", }, { "noauth", "basic-auth" } } ; - uint8_t mask = (uint8_t)0x01 << bit ; if (n != 1) - strerr_dief8x(1, "too ", n > 1 ? "many" : "few", " arguments to directive ", attr[bit][set], " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ; + strerr_dief8x(1, "too ", n > 1 ? "many" : "few", " arguments to directive ", attr[bit][h], " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ; if (!domain) strerr_dief7x(1, "resource attribute ", "definition", " without a domain directive", " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ; if (s[*word] != '/') @@ -294,24 +293,31 @@ static void parse_bitattr (char const *s, size_t const *word, size_t n, char con key[2 + domainlen + arglen] = 0 ; oldnode = conftree_search(key) ; if (oldnode) - if (g.storage.s[oldnode->data] & mask) + { + uint32_t flags, mask ; + uint32_unpack_big(g.storage.s + oldnode->data, &flags) ; + uint32_unpack_big(g.storage.s + oldnode->data + 4, &mask) ; + if (mask & 1 << bit) { char fmt[UINT32_FMT] ; fmt[uint32_fmt(fmt, oldnode->line)] = 0 ; - strerr_diefn(1, 13, "resource attribute ", attr[bit][set], " redefinition", " in file ", g.storage.s + md->filepos, " line ", md->linefmt, "; previous definition", " in file ", g.storage.s + oldnode->filepos, " line ", fmt, " or later") ; - } - else - { - g.storage.s[oldnode->data] |= mask ; - if (set) g.storage.s[oldnode->data + 1] |= mask ; - else g.storage.s[oldnode->data + 1] &= ~mask ; + strerr_diefn(1, 13, "resource attribute ", attr[bit][h], " redefinition", " in file ", g.storage.s + md->filepos, " line ", md->linefmt, "; previous definition", " in file ", g.storage.s + oldnode->filepos, " line ", fmt, " or later") ; } + mask |= 1 << bit ; + if (h) flags |= 1 << bit ; else flags &= ~(1 << bit) ; + uint32_pack_big(g.storage.s + oldnode->data, flags) ; + uint32_pack_big(g.storage.s + oldnode->data + 4, mask) ; + } else { node node ; - char val[3] = { mask, set ? mask : 0, 0 } ; + uint32_t flags = h ? 1 << bit : 0 ; + uint32_t mask = 1 << bit ; + char val[9] = "\0\0\0\0\0\0\0\0" ; + uint32_pack_big(val, flags) ; + uint32_pack_big(val + 4, mask) ; confnode_start(&node, key, md->filepos, md->line) ; - confnode_add(&node, val, 3) ; + confnode_add(&node, val, 9) ; conftree_add(&node) ; } } @@ -337,19 +343,17 @@ static inline void parse_filetype (char const *s, size_t const *word, size_t n, oldnode = conftree_search(key) ; if (oldnode) { - if (g.storage.s[oldnode->data] & 0x80) + if (g.storage.s[oldnode->data + 8]) { char fmt[UINT32_FMT] ; fmt[uint32_fmt(fmt, oldnode->line)] = 0 ; strerr_diefn(1, 12, "file-type", " redefinition", " in file ", g.storage.s + md->filepos, " line ", md->linefmt, "; previous definition", " in file ", g.storage.s + oldnode->filepos, " line ", fmt, " or later") ; } - else { node node ; - char val[2] = { g.storage.s[oldnode->data] | 0x80, g.storage.s[oldnode->data + 1] } ; confnode_start(&node, key, md->filepos, md->line) ; - confnode_add(&node, val, 2) ; + confnode_add(&node, g.storage.s + oldnode->data, 8) ; confnode_add(&node, s + word[1], strlen(s + word[1]) + 1) ; conftree_update(&node) ; } @@ -357,9 +361,8 @@ static inline void parse_filetype (char const *s, size_t const *word, size_t n, else { node node ; - char val[2] = { 0x80, 0x00 } ; confnode_start(&node, key, md->filepos, md->line) ; - confnode_add(&node, val, 2) ; + confnode_add(&node, "\0\0\0\0\0\0\0", 8) ; confnode_add(&node, s + word[1], strlen(s + word[1]) + 1) ; conftree_add(&node) ; } diff --git a/src/config/resattr.c b/src/config/resattr.c new file mode 100644 index 0000000..80bd0e0 --- /dev/null +++ b/src/config/resattr.c @@ -0,0 +1,56 @@ +/* ISC license. */ + +#include <skalibs/genalloc.h> +#include <skalibs/avltree.h> +#include <skalibs/cdbmake.h> + +#include "tipidee-config-internal.h" + +static repo resattr = \ +{ \ + .ga = GENALLOC_ZERO, \ + .tree = AVLTREE_INIT(8, 3, 8, &node_dtok, &node_cmp, &resattr.ga), \ + .storage = &g.storage \ +} ; + +void confnode_start (node *node, char const *key, size_t filepos, uint32_t line) +{ + return node_start(&g.storage, node, key, filepos, line) ; +} + +void confnode_add (node *node, char const *s, size_t len) +{ + return node_add(&g.storage, node, s, len) ; +} + +node const *conftree_search (char const *key) +{ + return repo_search(&conftree, key) ; +} + +void conftree_add (node const *node) +{ + return repo_add(&conftree, node) ; +} + +void conftree_update (node const *node) +{ + return repo_update(&conftree, node) ; +} + +static int confnode_write (uint32_t d, unsigned int h, void *data) +{ + node *nod = genalloc_s(node, &conftree.ga) + d ; + (void)h ; + if ((conftree.storage->s[nod->key] & ~0x20) == 'A') + { + conftree.storage->s[++nod->data] |= '@' ; + nod->datalen-- ; + } + return cdbmake_add((cdbmaker *)data, conftree.storage->s + nod->key, nod->keylen, conftree.storage->s + nod->data, nod->datalen) ; +} + +int conftree_write (cdbmaker *cm) +{ + return avltree_iter(&conftree.tree, &confnode_write, cm) ; +} diff --git a/src/include/tipidee/conf.h b/src/include/tipidee/conf.h index 5f3b697..aa8cb45 100644 --- a/src/include/tipidee/conf.h +++ b/src/include/tipidee/conf.h @@ -7,8 +7,10 @@ #include <stdint.h> #include <skalibs/uint16.h> +#include <skalibs/uint32.h> #include <skalibs/cdb.h> +#include <tipidee/resattr.h> #include <tipidee/uri.h> #define TIPIDEE_CONF_KEY_MAXLEN 0x1000U @@ -44,4 +46,7 @@ extern int tipidee_conf_get_redirection (tipidee_conf const *, char const *, siz extern char const *tipidee_conf_get_content_type (tipidee_conf const *, char const *) ; extern char const *tipidee_conf_get_errorfile (tipidee_conf const *, char const *, unsigned int) ; +extern int tipidee_conf_get_resattr1 (tipidee_conf const *, char const *, tipidee_resattr *) ; /* direct key lookup */ +extern int tipidee_conf_get_resattr (tipidee_conf const *, char const *, tipidee_resattr *) ; /* high-level */ + #endif diff --git a/src/include/tipidee/log.h b/src/include/tipidee/log.h index 0904ca4..93ee386 100644 --- a/src/include/tipidee/log.h +++ b/src/include/tipidee/log.h @@ -11,6 +11,7 @@ #include <tipidee/rql.h> #include <tipidee/headers.h> +#include <tipidee/resattr.h> #define TIPIDEE_LOG_REQUEST 0x0001 #define TIPIDEE_LOG_REFERRER 0x0002 @@ -26,15 +27,6 @@ #define TIPIDEE_LOG_DEFAULT (TIPIDEE_LOG_REQUEST | TIPIDEE_LOG_ANSWER | TIPIDEE_LOG_SIZE) -typedef struct tipidee_resattr_s tipidee_resattr, *tipidee_resattr_ref ; -struct tipidee_resattr_s -{ - char const *content_type ; - uint32_t iscgi : 1 ; - uint32_t isnph : 1 ; -} ; -#define TIPIDEE_RESATTR_ZERO { .content_type = 0, .iscgi = 0, .isnph = 0 } - extern void tipidee_log_start (uint32_t, char const *, char const *) ; extern void tipidee_log_exit (uint32_t, unsigned int) ; diff --git a/src/include/tipidee/resattr.h b/src/include/tipidee/resattr.h new file mode 100644 index 0000000..edd0a41 --- /dev/null +++ b/src/include/tipidee/resattr.h @@ -0,0 +1,23 @@ +/* ISC license. */ + +#ifndef TIPIDEE_RESATTR_H +#define TIPIDEE_RESATTR_H + +#include <stdint.h> + +#define TIPIDEE_RA_FLAG_CGI 0x0001 +#define TIPIDEE_RA_FLAG_NPH 0x0002 +#define TIPIDEE_RA_FLAG_BA 0x0004 + +#define TIPIDEE_RA_BITS 3 + +typedef struct tipidee_resattr_s tipidee_resattr, *tipidee_resattr_ref ; +struct tipidee_resattr_s +{ + uint32_t flags ; + uint32_t mask ; + char const *content_type ; +} ; +#define TIPIDEE_RESATTR_ZERO { .flags = 0, .mask = 0, .content_type = 0 } + +#endif diff --git a/src/include/tipidee/tipidee.h b/src/include/tipidee/tipidee.h index 7153b7d..7c5154c 100644 --- a/src/include/tipidee/tipidee.h +++ b/src/include/tipidee/tipidee.h @@ -8,6 +8,7 @@ #include <tipidee/headers.h> #include <tipidee/log.h> #include <tipidee/method.h> +#include <tipidee/resattr.h> #include <tipidee/response.h> #include <tipidee/rql.h> #include <tipidee/uri.h> diff --git a/src/libtipidee/deps-lib/tipidee b/src/libtipidee/deps-lib/tipidee index b20898b..d71ef89 100644 --- a/src/libtipidee/deps-lib/tipidee +++ b/src/libtipidee/deps-lib/tipidee @@ -4,6 +4,8 @@ tipidee_conf_get_argv.o tipidee_conf_get_content_type.o tipidee_conf_get_errorfile.o tipidee_conf_get_redirection.o +tipidee_conf_get_resattr.o +tipidee_conf_get_resattr1.o tipidee_conf_get_responseheaders.o tipidee_conf_get_string.o tipidee_conf_get_uint32.o diff --git a/src/libtipidee/tipidee_conf_get_resattr.c b/src/libtipidee/tipidee_conf_get_resattr.c new file mode 100644 index 0000000..9b33208 --- /dev/null +++ b/src/libtipidee/tipidee_conf_get_resattr.c @@ -0,0 +1,62 @@ +/* ISC license. */ + +#include <string.h> + +#include <skalibs/bytestr.h> + +#include <tipidee/conf.h> +#include <tipidee/resattr.h> + +#define FULLMASK ((1 << TIPIDEE_RA_BITS) - 1) + +int tipidee_conf_get_resattr (tipidee_conf const *conf, char const *res, tipidee_resattr *ra) +{ + tipidee_resattr rra = TIPIDEE_RESATTR_ZERO ; + size_t len = strlen(res) + 2 ; + char key[len + 1] ; + key[0] = 'A' ; key[1] = ':' ; + memcpy(key + 2, res, len - 2) ; + key[len] = '/' ; + while (len > 2 && (rra.mask & FULLMASK) != FULLMASK) + { + tipidee_resattr atom ; + int r ; + while (len > 2 && key[len] != '/') len-- ; + if (len <= 2) break ; + key[len--] = 0 ; + r = tipidee_conf_get_resattr1(conf, key, &atom) ; + if (r == -1) return 0 ; + if (r) + { + rra.flags = (~rra.mask & atom.mask & atom.flags) | ((rra.mask | ~atom.mask) & rra.flags) ; /* yup */ + rra.mask |= atom.mask ; + if (!rra.content_type) rra.content_type = atom.content_type ; + } + key[0] = 'a' ; + } + + if (!(rra.mask & TIPIDEE_RA_FLAG_NPH)) + { + char const *nphprefix ; + char *p = strchr(key+2, '/') ; + if (p) *p = 0 ; + key[0] = 'N' ; + nphprefix = tipidee_conf_get_string(conf, key) ; + if (nphprefix) + { + char const *base = strrchr(res, '/') ; + if (base && str_start(base + 1, nphprefix)) rra.flags |= 1 << TIPIDEE_RA_FLAG_NPH ; + else rra.flags &= ~(1 << TIPIDEE_RA_FLAG_NPH) ; + rra.mask |= 1 << TIPIDEE_RA_FLAG_NPH ; + } + } + + if (!(rra.flags & TIPIDEE_RA_FLAG_CGI) && !rra.content_type) + { + rra.content_type = tipidee_conf_get_content_type(conf, res) ; + if (!rra.content_type) return 0 ; + } + + *ra = rra ; + return 1 ; +} diff --git a/src/libtipidee/tipidee_conf_get_resattr1.c b/src/libtipidee/tipidee_conf_get_resattr1.c new file mode 100644 index 0000000..182a7ba --- /dev/null +++ b/src/libtipidee/tipidee_conf_get_resattr1.c @@ -0,0 +1,36 @@ +/* ISC license. */ + +#include <stdint.h> +#include <errno.h> +#include <string.h> + +#include <skalibs/uint32.h> +#include <skalibs/cdb.h> + +#include <tipidee/resattr.h> +#include <tipidee/conf.h> + +#include <skalibs/posixishard.h> + +int tipidee_conf_get_resattr1 (tipidee_conf const *conf, char const *key, tipidee_resattr *ra) +{ + tipidee_resattr atom = TIPIDEE_RESATTR_ZERO ; + cdb_data data ; + if (!tipidee_conf_get(conf, key, &data)) return errno == ENOENT ? 0 : -1 ; + if (data.len < 9 || data.s[data.len - 1]) return (errno = EPROTO, -1) ; + uint32_unpack_big(data.s, &atom.flags) ; + uint32_unpack_big(data.s + 4, &atom.mask) ; + data.s += 8 ; data.len -= 8 ; + if (*data.s) + { + size_t len = strlen(data.s) + 1 ; + if (len > data.len) return (errno = EPROTO, -1) ; + atom.content_type = data.s ; + data.s += len ; + data.len -= len ; + } + else data.len-- ; + if (data.len) return (errno = EPROTO, -1) ; + *ra = atom ; + return 1 ; +} diff --git a/src/libtipidee/tipidee_log_resource.c b/src/libtipidee/tipidee_log_resource.c index 75196b0..efdea69 100644 --- a/src/libtipidee/tipidee_log_resource.c +++ b/src/libtipidee/tipidee_log_resource.c @@ -4,6 +4,7 @@ #include <skalibs/strerr.h> +#include <tipidee/resattr.h> #include <tipidee/log.h> void tipidee_log_resource (uint32_t v, tipidee_rql const *rql, char const *file, tipidee_resattr const *ra, char const *infopath) @@ -19,8 +20,8 @@ void tipidee_log_resource (uint32_t v, tipidee_rql const *rql, char const *file, a[m++] = " resource " ; a[m++] = file ; a[m++] = " type " ; - a[m++] = ra->iscgi ? ra->isnph ? "nph" : "cgi" : ra->content_type ; - if (ra->iscgi && infopath) + a[m++] = ra->flags & TIPIDEE_RA_FLAG_CGI ? ra->flags & TIPIDEE_RA_FLAG_NPH ? "nph" : "cgi" : ra->content_type ; + if (ra->flags & TIPIDEE_RA_FLAG_CGI && infopath) { a[m++] = " path_info /" ; a[m++] = infopath ; diff --git a/src/tipideed/cgi.c b/src/tipideed/cgi.c index 9751911..43fb98d 100644 --- a/src/tipideed/cgi.c +++ b/src/tipideed/cgi.c @@ -364,6 +364,7 @@ int respond_cgi (tipidee_rql *rql, char const *docroot, char const *fn, size_t d modify_env(rql, docroot, hdr, bodylen, fn + docrootlen, infopath) ; env_merge(envp, envmax, (char const *const *)environ, g.envlen, g.sa.s + g.cwdlen + 1, g.sa.len - (g.cwdlen+1)) ; g.sa.len = sabase ; - return ra->isnph ? do_nph(rql, docroot, argv, envp, body, bodylen) : - do_cgi(rql, docroot, argv, envp, body, bodylen, uribuf) ; + return ra->flags & TIPIDEE_RA_FLAG_NPH ? + do_nph(rql, docroot, argv, envp, body, bodylen) : + do_cgi(rql, docroot, argv, envp, body, bodylen, uribuf) ; } diff --git a/src/tipideed/tipideed.c b/src/tipideed/tipideed.c index da4724b..4df6e8f 100644 --- a/src/tipideed/tipideed.c +++ b/src/tipideed/tipideed.c @@ -199,50 +199,8 @@ static inline void get_resattr (tipidee_rql const *rql, char const *docroot, cha if (sarealpath(&g.sa, res) == -1 || !stralloc_0(&g.sa)) die500sys(rql, 111, docroot, "realpath ", res) ; if (strncmp(g.sa.s + pos, g.sa.s, g.cwdlen) || g.sa.s[pos + g.cwdlen] != '/') die500x(rql, 102, docroot, "resource ", res, " points outside of the server's root") ; - - { - char const *attr = 0 ; - size_t len = g.sa.len - pos - g.cwdlen + 1 ; - char key[len + 1] ; - key[0] = 'A' ; key[1] = ':' ; - memcpy(key + 2, g.sa.s + pos + 1 + g.cwdlen, len - 2) ; - key[len] = '/' ; - errno = ENOENT ; - while (!attr) - { - if (errno != ENOENT) die500x(rql, 102, docroot, "invalid configuration data for ", key) ; - while (len > 2 && key[len] != '/') len-- ; - if (len <= 2) break ; - key[len--] = 0 ; - attr = tipidee_conf_get_string(&g.conf, key) ; - key[0] = 'a' ; - } - if (attr) - { - if (*attr < '@' || *attr > 'G') die500x(rql, 102, docroot, "invalid configuration data for ", key) ; - ra->iscgi = *attr & ~'@' & 1 ; - if (attr[1]) ra->content_type = attr + 1 ; - if (ra->iscgi) - { - char const *nphprefix ; - char *p ; - key[0] = 'N' ; - p = strchr(key+2, '/') ; - if (p) *p = 0 ; - nphprefix = tipidee_conf_get_string(&g.conf, key) ; - if (nphprefix) - { - char const *base = strrchr(g.sa.s + pos + g.cwdlen, '/') ; - if (str_start(base + 1, nphprefix)) ra->isnph = 1 ; - } - } - } - } - if (!ra->iscgi && !ra->content_type) - { - ra->content_type = tipidee_conf_get_content_type(&g.conf, g.sa.s + pos + g.cwdlen) ; - if (!ra->content_type) die500sys(rql, 111, docroot, "get content type for ", g.sa.s + pos + g.cwdlen) ; - } + if (!tipidee_conf_get_resattr(&g.conf, g.sa.s + pos + g.cwdlen + 1, ra)) + die500sys(rql, 102, docroot, "look up resource attributes for ", g.sa.s + pos + g.cwdlen + 1) ; g.sa.len = pos ; } @@ -321,18 +279,18 @@ static inline int serve (tipidee_rql *rql, char const *docroot, char *uribuf, ti get_resattr(rql, docroot, fn, &ra) ; - if (!ra.iscgi) + if (!ra.flags & TIPIDEE_RA_FLAG_CGI) { if (infopath) { respond_404(rql, docroot) ; return 0 ; } if (rql->m == TIPIDEE_METHOD_POST) exit_405(rql) ; } if (rql->m == TIPIDEE_METHOD_OPTIONS) - return respond_options(rql, 2 | ra.iscgi) ; + return respond_options(rql, 2 | !!(ra.flags & TIPIDEE_RA_FLAG_CGI)) ; tipidee_log_resource(g.logv, rql, fn, &ra, infopath) ; - if (ra.iscgi) + if (ra.flags & TIPIDEE_RA_FLAG_CGI) return respond_cgi(rql, docroot, fn, docrootlen, infopath, uribuf, hdr, &ra, body, bodylen) ; infopath = tipidee_headers_search(hdr, "If-Modified-Since") ; |