diff options
Diffstat (limited to 'src/config/lexparse.c')
| -rw-r--r-- | src/config/lexparse.c | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/src/config/lexparse.c b/src/config/lexparse.c index ad22762..e87c501 100644 --- a/src/config/lexparse.c +++ b/src/config/lexparse.c @@ -6,6 +6,7 @@ #include <errno.h> #include <skalibs/uint32.h> +#include <skalibs/fmtscan.h> #include <skalibs/buffer.h> #include <skalibs/strerr.h> #include <skalibs/stralloc.h> @@ -45,6 +46,7 @@ enum directivevalue_e T_NPHPREFIX, T_REDIRECT, T_NOREDIRECT, + T_RPROXY, T_CGI, T_NONCGI, T_NPH, @@ -262,7 +264,7 @@ static inline void parse_noredirect (char const *s, size_t const *word, size_t n memcpy(key + 2, domain, domainlen) ; memcpy(key + 2 + domainlen, s + *word, urlen) ; key[2 + domainlen + urlen] = 0 ; - add_unique(key, " ", 2, md) ; + add_unique(key, "\200", 2, md) ; } } @@ -304,6 +306,63 @@ static inline void parse_redirect (char const *s, size_t const *word, size_t n, } } +static inline void parse_rproxy (char const *s, size_t const *word, size_t n, char const *domain, size_t domainlen, mdt const *md) +{ + uint8_t type ; + if (n < 3 || n > 4) + strerr_dief8x(1, "too ", n > 4 ? "many" : "few", " arguments to directive ", "rproxy", " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ; + if (!domain) + strerr_dief6x(1, "rproxy redirection", " without a domain directive", " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ; + if (s[word[0]] != '/') + strerr_dief6x(1, "redirected resource", " must start with /", " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ; + if (!strcmp(s + word[1], "unix")) + type = 48 ; + else if (!strcmp(s + word[1], "tcp")) + type = 32 ; + else + strerr_dief7x(1, "rproxy", " directive", " needs to specify unix or tcp", " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ; + + { + node node ; + size_t urlen = strlen(s + word[0]) ; + char key[3 + domainlen + urlen] ; + if (s[word[0] + urlen - 1] == '/') { key[0] = 'r' ; urlen-- ; } else key[0] = 'R' ; + key[1] = ':' ; + memcpy(key + 2, domain, domainlen) ; + memcpy(key + 2 + domainlen, s + word[0], urlen) ; + key[2 + domainlen + urlen] = 0 ; + conftree_checkunique(key, md) ; + confnode_start(&node, key, md->filepos, md->line) ; + + if (type == 48) + { + if (n != 3) + strerr_dief8x(1, "too ", "many" , " arguments to directive ", "rproxy", " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ; + key[0] = '@' | type ; + confnode_add(&node, &key[0], 1) ; + confnode_add(&node, s + word[2], strlen(s + word[2]) + 1) ; + } + else + { + char ip[16] ; + uint16_t port ; + if (n != 4) + strerr_dief8x(1, "too ", "few" , " arguments to directive ", "rproxy", " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ; + if (ip6_scan(s + word[2], ip)) type |= 8 ; + else if (!ip4_scan(s + word[2], ip)) + strerr_dief8x(1, "invalid ip address ", "in directive ", "rproxy", " tcp", " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ; + if (!uint160_scan(s + word[3], &port)) + strerr_dief8x(1, "invalid port ", "in directive ", "rproxy", " tcp", " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ; + key[0] = '@' | type ; + uint16_pack_big(key+1, port) ; + confnode_add(&node, key, 3) ; + confnode_add(&node, ip, type & 8 ? 16 : 4) ; + } + confnode_add(&node, "", 1) ; + conftree_add(&node) ; + } +} + 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" } } ; @@ -450,6 +509,7 @@ static inline void process_line (char const *s, size_t const *word, size_t n, st { .name = "nph", .value = T_NPH }, { .name = "nph-prefix", .value = T_NPHPREFIX }, { .name = "redirect", .value = T_REDIRECT }, + { .name = "rproxy", .value = T_RPROXY }, } ; struct namevalue_s const *directive ; char const *word0 ; @@ -514,6 +574,9 @@ static inline void process_line (char const *s, size_t const *word, size_t n, st case T_REDIRECT : parse_redirect(s, word, n, domain->s, domain->len, md) ; break ; + case T_RPROXY : + parse_rproxy(s, word, n, domain->s, domain->len, md) ; + break ; case T_NOREDIRECT : parse_noredirect(s, word, n, domain->s, domain->len, md) ; break ; |
