summaryrefslogtreecommitdiff
path: root/src/tipideed/tipideed.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tipideed/tipideed.c')
-rw-r--r--src/tipideed/tipideed.c124
1 files changed, 63 insertions, 61 deletions
diff --git a/src/tipideed/tipideed.c b/src/tipideed/tipideed.c
index b85f509..fb5ede4 100644
--- a/src/tipideed/tipideed.c
+++ b/src/tipideed/tipideed.c
@@ -30,7 +30,7 @@
#include <tipidee/tipidee.h>
#include "tipideed-internal.h"
-#define USAGE "tipideed [ -v verbosity ] [ -f cdbfile ] [ -d basedir ] [ -R ] [ -U ]"
+#define USAGE "tipideed [ -f cdbfile ] [ -d basedir ] [ -R ] [ -U ]"
#define dieusage() strerr_dieusage(100, USAGE)
#define dienomem() strerr_diefu1sys(111, "stralloc_catb")
@@ -45,7 +45,13 @@ static void sigchld_handler (int sig)
wait_reap() ;
}
-static inline void prep_env (void)
+static inline void log_and_exit (int e)
+{
+ tipidee_log_exit(g.logv, e) ;
+ _exit(e) ;
+}
+
+static inline void prep_env (size_t *remoteip, size_t *remotehost)
{
static char const basevars[] = "PROTO\0TCPCONNNUM\0GATEWAY_INTERFACE=CGI/1.1\0SERVER_SOFTWARE=tipidee/" TIPIDEE_VERSION ;
static char const sslvars[] = "SSL_PROTOCOL\0SSL_CIPHER\0SSL_TLS_SNI_SERVERNAME\0SSL_PEER_CERT_HASH\0SSL_PEER_CERT_SUBJECT\0HTTPS=on" ;
@@ -77,7 +83,6 @@ static inline void prep_env (void)
if (!uint160_scan(x, &g.defaultport)) strerr_dieinvalid(100, var) ;
if (!stralloc_catb(&g.sa, var, protolen + 10)
|| !stralloc_catb(&g.sa, "SERVER_PORT=", 12)) dienomem() ;
- g.localport = g.sa.len ;
m = uint16_fmt(fmt, g.defaultport) ; fmt[m++] = 0 ;
if (!stralloc_catb(&g.sa, fmt, m)) dienomem() ;
@@ -87,7 +92,6 @@ static inline void prep_env (void)
if (!ip46_scan(x, &ip)) strerr_dieinvalid(100, var) ;
if (!stralloc_catb(&g.sa, var, protolen + 8)
|| !stralloc_catb(&g.sa, "SERVER_ADDR=", 12)) dienomem() ;
- g.localip = g.sa.len ;
m = ip46_fmt(fmt, &ip) ; fmt[m++] = 0 ;
if (!stralloc_catb(&g.sa, fmt, m)) dienomem() ;
@@ -105,7 +109,6 @@ static inline void prep_env (void)
if (!uint160_scan(x, &port)) strerr_dieinvalid(100, var) ;
if (!stralloc_catb(&g.sa, var, protolen + 11)
|| !stralloc_catb(&g.sa, "REMOTE_PORT=", 12)) dienomem() ;
- g.remoteport = g.sa.len ;
m = uint16_fmt(fmt, port) ; fmt[m++] = 0 ;
if (!stralloc_catb(&g.sa, fmt, m)) dienomem() ;
@@ -115,7 +118,7 @@ static inline void prep_env (void)
if (!ip46_scan(x, &ip)) strerr_dieinvalid(100, var) ;
if (!stralloc_catb(&g.sa, var, protolen + 9)
|| !stralloc_catb(&g.sa, "REMOTE_ADDR=", 12)) dienomem() ;
- g.remoteip = g.sa.len ;
+ *remoteip = g.sa.len ;
m = ip46_fmt(fmt, &ip) ; fmt[m++] = 0 ;
if (!stralloc_catb(&g.sa, fmt, m)) dienomem() ;
@@ -123,7 +126,7 @@ static inline void prep_env (void)
x = getenv(var) ;
if ((x && !stralloc_catb(&g.sa, var, protolen + 11))
|| !stralloc_catb(&g.sa, "REMOTE_HOST=", 12)) dienomem() ;
- g.remotehost = g.sa.len ;
+ *remotehost = g.sa.len ;
if (x)
{
if (!stralloc_cats(&g.sa, x)) dienomem() ;
@@ -132,7 +135,7 @@ static inline void prep_env (void)
{
if (!stralloc_readyplus(&g.sa, m + 2)) dienomem() ;
if (ip46_is6(&ip)) stralloc_catb(&g.sa, "[", 1) ;
- stralloc_catb(&g.sa, g.sa.s + g.remoteip, m) ;
+ stralloc_catb(&g.sa, g.sa.s + *remoteip, m) ;
if (ip46_is6(&ip)) stralloc_catb(&g.sa, "]", 1) ;
}
if (!stralloc_0(&g.sa)) dienomem() ;
@@ -326,8 +329,11 @@ static inline int serve (tipidee_rql *rql, char const *docroot, char *uribuf, ti
}
if (rql->m == TIPIDEE_METHOD_OPTIONS)
- return respond_options(rql, ra.iscgi) ;
- else if (ra.iscgi)
+ return respond_options(rql, 2 | ra.iscgi) ;
+
+ tipidee_log_resource(g.logv, rql, docroot, fn, &ra) ;
+
+ if (ra.iscgi)
return respond_cgi(rql, fn, docrootlen, infopath, uribuf, hdr, &ra, body, bodylen) ;
infopath = tipidee_headers_search(hdr, "If-Modified-Since") ;
@@ -353,24 +359,14 @@ int main (int argc, char const *const *argv, char const *const *envp)
char const *conffile = TIPIDEE_SYSCONFPREFIX "tipidee.conf.cdb" ;
char const *newroot = 0 ;
unsigned int h = 0 ;
- int gotv = 0 ;
subgetopt l = SUBGETOPT_ZERO ;
for (;;)
{
- int opt = subgetopt_r(argc, argv, "v:f:d:RU", &l) ;
+ int opt = subgetopt_r(argc, argv, "f:d:RU", &l) ;
if (opt == -1) break ;
switch (opt)
{
- case 'v' :
- {
- unsigned int n ;
- if (!uint0_scan(l.arg, &n)) dieusage() ;
- if (n > 7) n = 7 ;
- g.verbosity = n ;
- gotv = 1 ;
- break ;
- }
case 'f' : conffile = l.arg ; break ;
case 'd' : newroot = l.arg ; break ;
case 'R' : h |= 3 ; break ;
@@ -386,30 +382,31 @@ int main (int argc, char const *const *argv, char const *const *envp)
if (newroot && chdir(newroot) == -1)
strerr_diefu2sys(111, "chdir to ", newroot) ;
tipideed_harden(h) ;
- if (!gotv) g.verbosity = get_uint32("G:verbosity") ;
}
- prep_env() ;
- inittto(&g.readtto, "G:read_timeout") ;
- inittto(&g.writetto, "G:write_timeout") ;
- inittto(&g.cgitto, "G:cgi_timeout") ;
- g.maxrqbody = get_uint32("G:max_request_body_length") ;
- g.maxcgibody = get_uint32("G:max_cgi_body_length") ;
{
- unsigned int n = tipidee_conf_get_argv(&g.conf, "G:index_file", g.indexnames, 16, &g.indexlen) ;
+ size_t remoteip, remotehost ;
+ unsigned int n ;
+ prep_env(&remoteip, &remotehost) ;
+ inittto(&g.readtto, "G:read_timeout") ;
+ inittto(&g.writetto, "G:write_timeout") ;
+ inittto(&g.cgitto, "G:cgi_timeout") ;
+ g.maxrqbody = get_uint32("G:max_request_body_length") ;
+ g.maxcgibody = get_uint32("G:max_cgi_body_length") ;
+ g.logv = get_uint32("G:logv") ;
+ n = tipidee_conf_get_argv(&g.conf, "G:index_file", g.indexnames, 16, &g.indexlen) ;
if (!n) strerr_dief3x(102, "bad", " config value for ", "G:index_file") ;
g.indexn = n-1 ;
- }
-
- if (ndelay_on(0) == -1 || ndelay_on(1) == -1)
- strerr_diefu1sys(111, "set I/O nonblocking") ;
- init_splice_pipe() ;
- if (!sig_catch(SIGCHLD, &sigchld_handler))
- strerr_diefu1sys(111, "set SIGCHLD handler") ;
- if (!tain_now_set_stopwatch_g())
- strerr_diefu1sys(111, "initialize clock") ;
- log_start() ;
+ if (ndelay_on(0) == -1 || ndelay_on(1) == -1)
+ strerr_diefu1sys(111, "set I/O nonblocking") ;
+ init_splice_pipe() ;
+ if (!sig_catch(SIGCHLD, &sigchld_handler))
+ strerr_diefu1sys(111, "set SIGCHLD handler") ;
+ if (!tain_now_set_stopwatch_g())
+ strerr_diefu1sys(111, "initialize clock") ;
+ tipidee_log_start(g.logv, g.sa.s + remoteip, g.sa.s + remotehost) ;
+ }
/* Main loop */
@@ -436,11 +433,11 @@ int main (int argc, char const *const *argv, char const *const *envp)
case -1 : log_and_exit(1) ; /* Malicious or shitty client */
case 0 : break ;
case 99 : g.cont = 0 ; continue ; /* timeout, it's ok */
- case 400 : exit_400(&rql, "Syntax error in request line") ;
+ case 400 : preexit_400(&rql, "Syntax error in request line") ;
default : strerr_dief2x(101, "can't happen: ", "unknown tipidee_rql_read return code") ;
}
if (rql.http_major != 1) log_and_exit(1) ;
- if (rql.http_minor > 1) exit_400(&rql, "Bad HTTP version") ;
+ if (rql.http_minor > 1) preexit_400(&rql, "Bad HTTP version") ;
content_length = 0 ;
tipidee_headers_init(&hdr, hdrbuf, HDR_BUFSIZE) ;
@@ -449,11 +446,11 @@ int main (int argc, char const *const *argv, char const *const *envp)
{
case -1 : log_and_exit(1) ; /* connection issue, client timeout, etc. */
case 0 : break ;
- case 400 : exit_400(&rql, "Syntax error in headers") ;
- case 408 : exit_408(&rql) ; /* timeout */
- case 413 : exit_413(&rql, hdr.n >= TIPIDEE_HEADERS_MAX ? "Too many headers" : "Too much header data") ;
- case 500 : die500x(&rql, 101, "can't happen: ", "avltreen_insert failed") ;
- default : die500x(&rql, 101, "can't happen: ", "unknown tipidee_headers_parse return code") ;
+ case 400 : preexit_400(&rql, "Syntax error in headers") ;
+ case 408 : preexit_408(&rql) ; /* timeout */
+ case 413 : preexit_413(&rql, hdr.n >= TIPIDEE_HEADERS_MAX ? "Too many headers" : "Too much header data") ;
+ case 500 : strerr_dief2x(101, "can't happen: ", "avltreen_insert failed") ;
+ default : strerr_dief2x(101, "can't happen: ", "unknown tipidee_headers_parse return code") ;
}
if (!rql.http_minor) g.cont = 0 ;
@@ -470,7 +467,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
x = tipidee_headers_search(&hdr, "Transfer-Encoding") ;
if (x)
{
- if (strcasecmp(x, "chunked")) exit_400(&rql, "unsupported Transfer-Encoding") ;
+ if (strcasecmp(x, "chunked")) preexit_400(&rql, "unsupported Transfer-Encoding") ;
else tcoding = TIPIDEE_TRANSFERCODING_CHUNKED ;
}
else
@@ -478,7 +475,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
x = tipidee_headers_search(&hdr, "Content-Length") ;
if (x)
{
- if (!size_scan(x, &content_length)) exit_400(&rql, "Invalid Content-Length") ;
+ if (!size_scan(x, &content_length)) preexit_400(&rql, "Invalid Content-Length") ;
else if (content_length) tcoding = TIPIDEE_TRANSFERCODING_FIXED ;
else tcoding = TIPIDEE_TRANSFERCODING_NONE ;
}
@@ -486,22 +483,22 @@ int main (int argc, char const *const *argv, char const *const *envp)
}
if (tcoding != TIPIDEE_TRANSFERCODING_NONE && rql.m != TIPIDEE_METHOD_POST)
- exit_400(&rql, "only POST requests can have an entity body") ;
+ preexit_400(&rql, "only POST requests can have an entity body") ;
switch (rql.m)
{
case TIPIDEE_METHOD_GET :
case TIPIDEE_METHOD_HEAD :
- case TIPIDEE_METHOD_POST : break ;
+ case TIPIDEE_METHOD_POST :
+ case TIPIDEE_METHOD_TRACE : break ;
case TIPIDEE_METHOD_OPTIONS :
if (!rql.uri.path) { respond_options(&rql, 1) ; continue ; }
break ;
case TIPIDEE_METHOD_PUT :
- case TIPIDEE_METHOD_DELETE : exit_405(&rql, 1) ;
- case TIPIDEE_METHOD_TRACE : respond_trace(hdrbuf, &rql, &hdr) ; continue ;
- case TIPIDEE_METHOD_CONNECT : exit_501(&rql, "CONNECT method unsupported") ;
- case TIPIDEE_METHOD_PRI : exit_501(&rql, "PRI method attempted with HTTP version 1") ;
- default : die500x(&rql, 101, "can't happen: unknown HTTP method") ;
+ case TIPIDEE_METHOD_DELETE : exit_405(&rql, 3) ;
+ case TIPIDEE_METHOD_CONNECT : preexit_501(&rql, "CONNECT method unsupported") ;
+ case TIPIDEE_METHOD_PRI : preexit_501(&rql, "PRI method attempted with HTTP version 1") ;
+ default : strerr_dief2x(101, "can't happen: ", "unknown HTTP method") ;
}
if (rql.http_minor)
@@ -512,16 +509,23 @@ int main (int argc, char const *const *argv, char const *const *envp)
char *p = strchr(x, ':') ;
if (p)
{
- if (!uint160_scan(p+1, &rql.uri.port)) exit_400(&rql, "Invalid Host header") ;
+ if (!uint160_scan(p+1, &rql.uri.port)) preexit_400(&rql, "Invalid Host header") ;
*p = 0 ;
}
- if (!*x || *x == '.') exit_400(&rql, "Invalid Host header") ;
+ if (!*x || *x == '.') preexit_400(&rql, "Invalid Host header") ;
rql.uri.host = x ;
}
- else if (!rql.uri.host) exit_400(&rql, "Missing Host header") ;
+ else if (!rql.uri.host) preexit_400(&rql, "Missing Host header") ;
}
else if (!rql.uri.host) rql.uri.host = g.defaulthost ;
if (!rql.uri.port) rql.uri.port = g.defaultport ;
+ tipidee_log_request(g.logv, &rql, &hdr, &g.sa) ;
+
+ if (rql.m == TIPIDEE_METHOD_TRACE)
+ {
+ respond_trace(hdrbuf, &rql, &hdr) ;
+ continue ;
+ }
{
size_t hostlen = strlen(rql.uri.host) ;
@@ -560,10 +564,8 @@ int main (int argc, char const *const *argv, char const *const *envp)
default : break ;
}
- log_request(&rql) ;
-
- /* And serve the resource. The loop is in case of CGI local-redirection. */
+ /* Find and serve the resource. The loop is in case of CGI local-redirection. */
while (serve(&rql, docroot, uribuf, &hdr, bodysa.s, bodysa.len))
if (localredirs++ >= MAX_LOCALREDIRS)