about summary refs log tree commit diff
path: root/src/tipideed/tipideed.c
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2023-10-13 12:17:45 +0000
committerLaurent Bercot <ska@appnovation.com>2023-10-13 12:17:45 +0000
commitff9c276c144bc24c70f1d5b531a8fd412c34c3d9 (patch)
tree428e16ebf99802946e230853c76b2ae3b407c87b /src/tipideed/tipideed.c
parent8179edd85cd504058ec7c569ef87eebf5979646e (diff)
downloadtipidee-ff9c276c144bc24c70f1d5b531a8fd412c34c3d9.tar.gz
tipidee-ff9c276c144bc24c70f1d5b531a8fd412c34c3d9.tar.xz
tipidee-ff9c276c144bc24c70f1d5b531a8fd412c34c3d9.zip
Improved logging system
Signed-off-by: Laurent Bercot <ska@appnovation.com>
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)