summaryrefslogtreecommitdiff
path: root/src/libtipidee
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2023-10-18 13:07:23 +0000
committerLaurent Bercot <ska@appnovation.com>2023-10-18 13:07:23 +0000
commit1a7e3d00588725da3d8764fa9d624bc8611be070 (patch)
tree65d28b52bd1d4ccdbeb418d4d681b1999ed46b7a /src/libtipidee
parent24fb88dbb023ae08adc9989bf19e0c6c569a6607 (diff)
downloadtipidee-1a7e3d00588725da3d8764fa9d624bc8611be070.tar.xz
Add infrastructure for custom error files
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src/libtipidee')
-rw-r--r--src/libtipidee/deps-lib/tipidee4
-rw-r--r--src/libtipidee/tipidee_conf_get_errorfile.c24
-rw-r--r--src/libtipidee/tipidee_log_request.c2
-rw-r--r--src/libtipidee/tipidee_log_resource.c13
-rw-r--r--src/libtipidee/tipidee_response_error.c41
-rw-r--r--src/libtipidee/tipidee_response_error_nofile.c35
-rw-r--r--src/libtipidee/tipidee_response_file.c31
-rw-r--r--src/libtipidee/tipidee_response_header_common_put.c17
-rw-r--r--src/libtipidee/tipidee_response_status.c4
-rw-r--r--src/libtipidee/tipidee_rql_read.c5
10 files changed, 114 insertions, 62 deletions
diff --git a/src/libtipidee/deps-lib/tipidee b/src/libtipidee/deps-lib/tipidee
index cba7e43..93e261a 100644
--- a/src/libtipidee/deps-lib/tipidee
+++ b/src/libtipidee/deps-lib/tipidee
@@ -2,6 +2,7 @@ tipidee_conf_free.o
tipidee_conf_get.o
tipidee_conf_get_argv.o
tipidee_conf_get_content_type.o
+tipidee_conf_get_errorfile.o
tipidee_conf_get_redirection.o
tipidee_conf_get_string.o
tipidee_conf_get_uint32.o
@@ -16,7 +17,8 @@ tipidee_log_resource.o
tipidee_log_request.o
tipidee_log_start.o
tipidee_method.o
-tipidee_response_error.o
+tipidee_response_error_nofile.o
+tipidee_response_file.o
tipidee_response_header_builtin.o
tipidee_response_header_common_put.o
tipidee_response_header_date.o
diff --git a/src/libtipidee/tipidee_conf_get_errorfile.c b/src/libtipidee/tipidee_conf_get_errorfile.c
new file mode 100644
index 0000000..732ff9d
--- /dev/null
+++ b/src/libtipidee/tipidee_conf_get_errorfile.c
@@ -0,0 +1,24 @@
+/* ISC license. */
+
+#include <string.h>
+#include <errno.h>
+
+#include <skalibs/types.h>
+
+#include <tipidee/conf.h>
+
+char const *tipidee_conf_get_errorfile (tipidee_conf const *conf, char const *docroot, unsigned int status)
+{
+ size_t docrootlen = strlen(docroot) ;
+ char key[7 + docrootlen] ;
+ if (status < 100 || status > 999) goto err ;
+ key[0] = 'E' ; key[1] = ':' ;
+ uint_fmt(key + 2, status) ;
+ key[5] = ':' ;
+ memcpy(key + 6, docroot, docrootlen + 1) ;
+ return tipidee_conf_get_string(conf, key) ;
+
+ err:
+ errno = EINVAL ;
+ return 0 ;
+}
diff --git a/src/libtipidee/tipidee_log_request.c b/src/libtipidee/tipidee_log_request.c
index a50169d..d633f0b 100644
--- a/src/libtipidee/tipidee_log_request.c
+++ b/src/libtipidee/tipidee_log_request.c
@@ -17,7 +17,7 @@ void tipidee_log_request (uint32_t v, tipidee_rql const *rql, tipidee_headers co
size_t start = sa->len ; /* assert: not zero */
size_t refpos = 0, uapos = 0 ;
if (!(v & TIPIDEE_LOG_REQUEST)) return ;
- if (!string_quotes(sa, rql->uri.path)) goto eerr ;
+ if (!string_quotes(sa, rql->uri.path) || !stralloc_0(sa)) goto eerr ;
if (v & TIPIDEE_LOG_REFERRER)
{
char const *x = tipidee_headers_search(hdr, "Referrer") ;
diff --git a/src/libtipidee/tipidee_log_resource.c b/src/libtipidee/tipidee_log_resource.c
index b730612..75196b0 100644
--- a/src/libtipidee/tipidee_log_resource.c
+++ b/src/libtipidee/tipidee_log_resource.c
@@ -6,9 +6,9 @@
#include <tipidee/log.h>
-void tipidee_log_resource (uint32_t v, tipidee_rql const *rql, char const *docroot, char const *file, tipidee_resattr const *ra)
+void tipidee_log_resource (uint32_t v, tipidee_rql const *rql, char const *file, tipidee_resattr const *ra, char const *infopath)
{
- char const *a[8] = { PROG, ": info:" } ;
+ char const *a[10] = { PROG, ": info:" } ;
size_t m = 2 ;
if (!(v & TIPIDEE_LOG_RESOURCE)) return ;
if (v & TIPIDEE_LOG_HOSTASPREFIX)
@@ -16,11 +16,14 @@ void tipidee_log_resource (uint32_t v, tipidee_rql const *rql, char const *docro
a[m++] = " host " ;
a[m++] = rql->uri.host ;
}
- a[m++] = " resource docroot " ;
- a[m++] = docroot ;
- a[m++] = " 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++] = " path_info /" ;
+ a[m++] = infopath ;
+ }
strerr_warnv(a, m) ;
}
diff --git a/src/libtipidee/tipidee_response_error.c b/src/libtipidee/tipidee_response_error.c
deleted file mode 100644
index 7c77e80..0000000
--- a/src/libtipidee/tipidee_response_error.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* ISC license. */
-
-#include <stddef.h>
-
-#include <skalibs/types.h>
-#include <skalibs/buffer.h>
-
-#include <tipidee/method.h>
-#include <tipidee/rql.h>
-#include <tipidee/response.h>
-
-size_t tipidee_response_error (buffer *b, tipidee_rql const *rql, unsigned int status, char const *rsl, char const *text, uint32_t options)
-{
- size_t n = 0 ;
- static char const txt1[] = "<html>\n<head><title>" ;
- static char const txt2[] = "</title></head>\n<body>\n<h1> " ;
- static char const txt3[] = " </h1>\n<p>\n" ;
- static char const txt4[] = "\n</p>\n</body>\n</html>\n" ;
- n += tipidee_response_status(b, rql, status, rsl) ;
- n += tipidee_response_header_common_put_g(buffer_1, options) ;
- if (!(options & 2))
- {
- char fmt[SIZE_FMT] ;
- n += buffer_putsnoflush(buffer_1, "Content-Type: text/html; charset=UTF-8\r\n") ;
- n += buffer_putsnoflush(buffer_1, "Content-Length: ") ;
- n += buffer_putnoflush(buffer_1, fmt, size_fmt(fmt, sizeof(txt1) + sizeof(txt2) + sizeof(txt3) + sizeof(txt4) - 4 + 2 * strlen(rsl) + strlen(text))) ;
- n += buffer_putnoflush(buffer_1, "\r\n", 2) ;
- }
- n += buffer_putnoflush(buffer_1, "\r\n", 2) ;
- if (rql->m != TIPIDEE_METHOD_HEAD)
- {
- n += buffer_putsnoflush(buffer_1, txt1) ;
- n += buffer_putsnoflush(buffer_1, rsl) ;
- n += buffer_putsnoflush(buffer_1, txt2) ;
- n += buffer_putsnoflush(buffer_1, rsl) ;
- n += buffer_putsnoflush(buffer_1, txt3) ;
- n += buffer_putsnoflush(buffer_1, text) ;
- n += buffer_putsnoflush(buffer_1, txt4) ;
- }
- return n ;
-}
diff --git a/src/libtipidee/tipidee_response_error_nofile.c b/src/libtipidee/tipidee_response_error_nofile.c
new file mode 100644
index 0000000..4f628ac
--- /dev/null
+++ b/src/libtipidee/tipidee_response_error_nofile.c
@@ -0,0 +1,35 @@
+/* ISC license. */
+
+#include <string.h>
+
+#include <skalibs/types.h>
+#include <skalibs/buffer.h>
+
+#include <tipidee/method.h>
+#include <tipidee/response.h>
+
+size_t tipidee_response_error_nofile (buffer *b, tipidee_rql const *rql, unsigned int status, char const *reason, char const *text, uint32_t options, tain const *stamp)
+{
+ static char const txt1[] = "<html>\n<head><title>" ;
+ static char const txt2[] = "</title></head>\n<body>\n<h1> " ;
+ static char const txt3[] = " </h1>\n<p>\n" ;
+ static char const txt4[] = "\n</p>\n</body>\n</html>\n" ;
+ char fmt[SIZE_FMT] ;
+ size_t n = tipidee_response_status(b, rql, status, reason) ;
+ n += tipidee_response_header_common_put(b, options, stamp) ;
+ n += buffer_putsnoflush(b, "Content-Type: text/html; charset=UTF-8\r\n") ;
+ n += buffer_putsnoflush(b, "Content-Length: ") ;
+ n += buffer_putnoflush(b, fmt, size_fmt(fmt, text ? sizeof(txt1) + sizeof(txt2) + sizeof(txt3) + sizeof(txt4) - 4 + 2 * strlen(reason) + strlen(text) : 0)) ;
+ n += buffer_putnoflush(b, "\r\n\r\n", 4) ;
+ if (text && rql->m != TIPIDEE_METHOD_HEAD)
+ {
+ n += buffer_putsnoflush(b, txt1) ;
+ n += buffer_putsnoflush(b, reason) ;
+ n += buffer_putsnoflush(b, txt2) ;
+ n += buffer_putsnoflush(b, reason) ;
+ n += buffer_putsnoflush(b, txt3) ;
+ n += buffer_putsnoflush(b, text) ;
+ n += buffer_putsnoflush(b, txt4) ;
+ }
+ return n ;
+}
diff --git a/src/libtipidee/tipidee_response_file.c b/src/libtipidee/tipidee_response_file.c
new file mode 100644
index 0000000..0cbe8f4
--- /dev/null
+++ b/src/libtipidee/tipidee_response_file.c
@@ -0,0 +1,31 @@
+/* ISC license. */
+
+#include <stddef.h>
+
+#include <skalibs/types.h>
+#include <skalibs/buffer.h>
+
+#include <tipidee/conf.h>
+#include <tipidee/method.h>
+#include <tipidee/rql.h>
+#include <tipidee/response.h>
+#include <tipidee/util.h>
+
+size_t tipidee_response_file (buffer *b, tipidee_rql const *rql, unsigned int status, char const *reason, struct stat const *st, char const *ct, uint32_t options, tain const *stamp)
+{
+ char fmt[128] ;
+ size_t n = tipidee_response_status(b, rql, status, reason) ;
+ n += tipidee_response_header_common_put(b, options & 1, stamp) ;
+ if (options & 2)
+ {
+ size_t l = tipidee_response_header_lastmodified(fmt, 128, st) ;
+ if (l) n += buffer_putnoflush(b, fmt, l) ;
+ }
+ n += buffer_putsnoflush(b, "Content-Type: ") ;
+ n += buffer_putsnoflush(b, ct) ;
+ n += buffer_putsnoflush(b, "\r\nContent-Length: ") ;
+ fmt[uint64_fmt(fmt, st->st_size)] = 0 ;
+ n += buffer_putsnoflush(b, fmt) ;
+ n += buffer_putnoflush(b, "\r\n\r\n", 4) ;
+ return n ;
+}
diff --git a/src/libtipidee/tipidee_response_header_common_put.c b/src/libtipidee/tipidee_response_header_common_put.c
index c67cc94..e9a1a07 100644
--- a/src/libtipidee/tipidee_response_header_common_put.c
+++ b/src/libtipidee/tipidee_response_header_common_put.c
@@ -1,23 +1,20 @@
/* ISC license. */
-#include <stdint.h>
-
#include <skalibs/buffer.h>
-#include <tipidee/config.h>
#include <tipidee/response.h>
size_t tipidee_response_header_common_put (buffer *b, uint32_t options, tain const *stamp)
{
char fmt[128] ;
- size_t m = buffer_putnoflush(b, fmt, tipidee_response_header_date(fmt, 128, stamp)) ;
+ size_t n = buffer_putnoflush(b, fmt, tipidee_response_header_date(fmt, 128, stamp)) ;
for (tipidee_response_header_builtin const *p = tipidee_response_header_builtin_table ; p->key ; p++)
{
- m += buffer_putsnoflush(b, p->key) ;
- m += buffer_putnoflush(b, ": ", 2) ;
- m += buffer_putsnoflush(b, p->value) ;
- m += buffer_putnoflush(b, "\r\n", 2) ;
+ n += buffer_putsnoflush(b, p->key) ;
+ n += buffer_putnoflush(b, ": ", 2) ;
+ n += buffer_putsnoflush(b, p->value) ;
+ n += buffer_putnoflush(b, "\r\n", 2) ;
}
- if (options & 1) m += buffer_putsnoflush(b, "Connection: close\r\n") ;
- return m ;
+ if (options & 1) n += buffer_putsnoflush(b, "Connection: close\r\n") ;
+ return n ;
}
diff --git a/src/libtipidee/tipidee_response_status.c b/src/libtipidee/tipidee_response_status.c
index 4315f61..3c8977a 100644
--- a/src/libtipidee/tipidee_response_status.c
+++ b/src/libtipidee/tipidee_response_status.c
@@ -5,7 +5,7 @@
#include <tipidee/response.h>
-size_t tipidee_response_status (buffer *b, tipidee_rql const *rql, unsigned int status, char const *line)
+size_t tipidee_response_status (buffer *b, tipidee_rql const *rql, unsigned int status, char const *reason)
{
size_t n = 0 ;
char fmt[UINT_FMT] ;
@@ -16,7 +16,7 @@ size_t tipidee_response_status (buffer *b, tipidee_rql const *rql, unsigned int
n += buffer_putnoflush(b, " ", 1) ;
n += buffer_putnoflush(b, fmt, uint_fmt(fmt, status)) ;
n += buffer_putnoflush(b, " ", 1) ;
- n += buffer_putsnoflush(b, line) ;
+ n += buffer_putsnoflush(b, reason) ;
n += buffer_putnoflush(b, "\r\n", 2) ;
return n ;
}
diff --git a/src/libtipidee/tipidee_rql_read.c b/src/libtipidee/tipidee_rql_read.c
index fc99f37..fe6091d 100644
--- a/src/libtipidee/tipidee_rql_read.c
+++ b/src/libtipidee/tipidee_rql_read.c
@@ -66,8 +66,9 @@ static inline int get_version (char const *in, tipidee_rql *rql)
int tipidee_rql_read (buffer *b, char *buf, size_t max, size_t *w, tipidee_rql *rql, tain const *deadline, tain *stamp)
{
size_t pos[3] = { 0 } ;
- if (timed_getlnmax(b, buf, max, &pos[0], '\n', deadline, stamp) == -1)
- return errno == ETIMEDOUT ? 99 : -1 ;
+ ssize_t r = timed_getlnmax(b, buf, max, &pos[0], '\n', deadline, stamp) ;
+ if (r == -1) return errno == ETIMEDOUT ? 99 : -1 ;
+ if (!r) return 98 ;
buf[--pos[0]] = 0 ;
if (buf[pos[0] - 1] == '\r') buf[--pos[0]] = 0 ;
if (!rql_tokenize(buf, pos)) return 400 ;