summaryrefslogtreecommitdiff
path: root/src/tipideed/responses.c
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/tipideed/responses.c
parent24fb88dbb023ae08adc9989bf19e0c6c569a6607 (diff)
downloadtipidee-1a7e3d00588725da3d8764fa9d624bc8611be070.tar.xz
Add infrastructure for custom error files
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src/tipideed/responses.c')
-rw-r--r--src/tipideed/responses.c80
1 files changed, 67 insertions, 13 deletions
diff --git a/src/tipideed/responses.c b/src/tipideed/responses.c
index e5706e2..0d0840c 100644
--- a/src/tipideed/responses.c
+++ b/src/tipideed/responses.c
@@ -1,44 +1,99 @@
/* ISC license. */
+#include <skalibs/bsdsnowflake.h>
+
#include <unistd.h>
+#include <skalibs/stat.h>
#include <skalibs/types.h>
#include <skalibs/buffer.h>
#include <skalibs/strerr.h>
#include <skalibs/tai.h>
+#include <skalibs/djbunix.h>
#include <skalibs/unix-timed.h>
-#include <tipidee/rql.h>
#include <tipidee/log.h>
+#include <tipidee/util.h>
#include <tipidee/response.h>
#include "tipideed-internal.h"
-void response_error (tipidee_rql const *rql, unsigned int status, char const *rsl, char const *text, uint32_t options)
+void response_error_early (tipidee_rql const *rql, unsigned int status, char const *reason, char const *text, uint32_t options)
{
tain deadline ;
- tipidee_response_error(buffer_1, rql, status, rsl, text, options & 1 || !g.cont) ;
+ tipidee_response_error_nofile_g(buffer_1, rql, status, reason, text, options & 1 || !g.cont) ;
+ tain_add_g(&deadline, &g.writetto) ;
+ if (!buffer_timed_flush_g(buffer_1, &deadline))
+ strerr_diefu1sys(111, "write to stdout") ;
+}
+
+void response_error_early_and_exit (tipidee_rql const *rql, unsigned int status, char const *reason, char const *text)
+{
+ response_error_early(rql, status, reason, text, 1) ;
+ log_and_exit(1) ;
+}
+
+void response_error (tipidee_rql const *rql, char const *docroot, unsigned int status, uint32_t options)
+{
+ tain deadline ;
+ tipidee_defaulttext dt ;
+ char const *file = tipidee_conf_get_errorfile(&g.conf, docroot, status) ;
+ if (!tipidee_util_defaulttext(status, &dt))
+ {
+ char fmt[UINT_FMT] ;
+ fmt[uint_fmt(fmt, status)] = 0 ;
+ strerr_dief2x(101, "can't happen: unknown response code ", fmt) ;
+ }
+
+ if (file)
+ {
+ int fd = open_read(file) ;
+ if (fd == -1) strerr_warnwu3sys("open ", "custom error file ", file) ;
+ else
+ {
+ struct stat st ;
+ if (fstat(fd, &st) == -1)
+ {
+ fd_close(fd) ;
+ strerr_warnwu3sys("stat ", "custom error file ", file) ;
+ }
+ else if (!S_ISREG(st.st_mode))
+ {
+ fd_close(fd) ;
+ strerr_warnw3x("custom error file ", file, " is not a regular file") ;
+ }
+ else
+ {
+ tipidee_response_file_g(buffer_1, rql, status, dt.reason, &st, tipidee_conf_get_content_type(&g.conf, file), options) ;
+ tipidee_log_answer(g.logv, rql, status, st.st_size) ;
+ send_file(fd, st.st_size, file) ;
+ fd_close(fd) ;
+ return ;
+ }
+ }
+ }
+
+ tipidee_response_error_nofile_g(buffer_1, rql, status, dt.reason, dt.text, options & 1 || !g.cont) ;
+ tipidee_log_answer(g.logv, rql, status, 0) ;
tain_add_g(&deadline, &g.writetto) ;
- if (!(options & 2)) tipidee_log_answer(g.logv, rql, status, 0) ;
if (!buffer_timed_flush_g(buffer_1, &deadline))
strerr_diefu1sys(111, "write to stdout") ;
}
-void response_error_and_exit (tipidee_rql const *rql, unsigned int status, char const *rsl, char const *text, uint32_t options)
+void response_error_and_exit (tipidee_rql const *rql, char const *docroot, unsigned int status)
{
- response_error(rql, status, rsl, text, options | 1) ;
- tipidee_log_exit(g.logv, 0) ;
- _exit(0) ;
+ response_error(rql, docroot, status, 1) ;
+ log_and_exit(0) ;
}
-void response_error_and_die (tipidee_rql const *rql, int e, unsigned int status, char const *rsl, char const *text, char const *const *v, unsigned int n, uint32_t options)
+void response_error_and_die (tipidee_rql const *rql, int e, char const *docroot, unsigned int status, char const *const *v, unsigned int n, uint32_t options)
{
- response_error(rql, status, rsl, text, options | 1) ;
+ response_error(rql, docroot, status, options | 1) ;
if (options & 1) strerr_dievsys(e, v, n) ;
else strerr_diev(e, v, n) ;
}
-void exit_405 (tipidee_rql const *rql, uint32_t options)
+void exit_405_ (tipidee_rql const *rql, uint32_t options)
{
tain deadline ;
tipidee_response_status(buffer_1, rql, 405, "Method Not Allowed") ;
@@ -50,8 +105,7 @@ void exit_405 (tipidee_rql const *rql, uint32_t options)
tain_add_g(&deadline, &g.writetto) ;
if (!buffer_timed_flush_g(buffer_1, &deadline))
strerr_diefu1sys(111, "write to stdout") ;
- tipidee_log_exit(g.logv, 0) ;
- _exit(0) ;
+ log_and_exit(0) ;
}
void respond_30x (tipidee_rql const *rql, tipidee_redirection const *rd)