diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2023-09-21 02:18:35 +0000 |
---|---|---|
committer | Laurent Bercot <ska@appnovation.com> | 2023-09-21 02:18:35 +0000 |
commit | 3d334dca671898241732dbc0ef6838b768308da7 (patch) | |
tree | 0cac6b60ea1356455fef2553e41105f3c68bce9d /src/tipideed | |
parent | 6be5496f8a5660875c5f45f915210f69496d231b (diff) | |
download | tipidee-3d334dca671898241732dbc0ef6838b768308da7.tar.xz |
Implement If-Modified-Since
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src/tipideed')
-rw-r--r-- | src/tipideed/log.c | 6 | ||||
-rw-r--r-- | src/tipideed/regular.c | 39 | ||||
-rw-r--r-- | src/tipideed/tipideed-internal.h | 5 | ||||
-rw-r--r-- | src/tipideed/tipideed.c | 19 |
4 files changed, 56 insertions, 13 deletions
diff --git a/src/tipideed/log.c b/src/tipideed/log.c index a257ff5..f5f2e81 100644 --- a/src/tipideed/log.c +++ b/src/tipideed/log.c @@ -44,6 +44,12 @@ void log_regular (char const *fn, char const *sizefmt, int ishead, char const *c strerr_warni8x("sending ", ishead ? "headers for " : "", "regular file ", fn, " (", sizefmt, " bytes) with type ", ct) ; } +void log_304 (char const *fn) +{ + if (g.verbosity >= 2) + strerr_warni2x("answering 304 for regular file ", fn) ; +} + void log_nph (char const *const *argv, char const *const *envp) { if (g.verbosity >= 2) diff --git a/src/tipideed/regular.c b/src/tipideed/regular.c index df4b157..5af364d 100644 --- a/src/tipideed/regular.c +++ b/src/tipideed/regular.c @@ -1,8 +1,11 @@ /* ISC license. */ +#include <skalibs/bsdsnowflake.h> + #include <errno.h> #include <skalibs/uint64.h> +#include <skalibs/stat.h> #include <skalibs/types.h> #include <skalibs/buffer.h> #include <skalibs/djbunix.h> @@ -14,21 +17,23 @@ #include <tipidee/response.h> #include "tipideed-internal.h" -int respond_regular (tipidee_rql const *rql, char const *fn, uint64_t size, tipidee_resattr const *ra) +int respond_regular (tipidee_rql const *rql, char const *fn, struct stat const *st, tipidee_resattr const *ra) { tain deadline ; + char fmt[128] ; size_t n = tipidee_response_status_line(buffer_1, rql, "200 OK") ; n += tipidee_response_header_common_put_g(buffer_1, !g.cont) ; + { + size_t l = tipidee_response_header_lastmodified(fmt, 128, st) ; + if (l) n += buffer_putnoflush(buffer_1, fmt, l) ; + } n += buffer_putsnoflush(buffer_1, "Content-Type: ") ; n += buffer_putsnoflush(buffer_1, ra->content_type) ; n += buffer_putsnoflush(buffer_1, "\r\nContent-Length: ") ; - { - char fmt[UINT64_FMT] ; - fmt[uint64_fmt(fmt, size)] = 0 ; - n += buffer_putsnoflush(buffer_1, fmt) ; - log_regular(fn, fmt, rql->m == TIPIDEE_METHOD_HEAD, ra->content_type) ; - } + fmt[uint64_fmt(fmt, st->st_size)] = 0 ; + n += buffer_putsnoflush(buffer_1, fmt) ; n += buffer_putnoflush(buffer_1, "\r\n\r\n", 4) ; + log_regular(fn, fmt, rql->m == TIPIDEE_METHOD_HEAD, ra->content_type) ; if (rql->m == TIPIDEE_METHOD_HEAD) { tain_add_g(&deadline, &g.writetto) ; @@ -48,8 +53,26 @@ int respond_regular (tipidee_rql const *rql, char const *fn, uint64_t size, tipi } else die500sys(rql, 111, "open ", fn) ; } - send_file(fd, size, fn) ; + send_file(fd, st->st_size, fn) ; fd_close(fd) ; } return 0 ; } + +int respond_304 (tipidee_rql const *rql, char const *fn, struct stat const *st) +{ + tain deadline ; + char fmt[128] ; + size_t n = tipidee_response_status_line(buffer_1, rql, "304 Not Modified") ; + n += tipidee_response_header_common_put_g(buffer_1, !g.cont) ; + { + size_t l = tipidee_response_header_lastmodified(fmt, 128, st) ; + if (l) n += buffer_putnoflush(buffer_1, fmt, l) ; + } + n += buffer_putnoflush(buffer_1, "\r\n", 2) ; + log_304(fn) ; + tain_add_g(&deadline, &g.writetto) ; + if (!buffer_timed_flush_g(buffer_1, &deadline)) + strerr_diefu1sys(111, "write to stdout") ; + return 0 ; +} diff --git a/src/tipideed/tipideed-internal.h b/src/tipideed/tipideed-internal.h index c4ff928..3eb0644 100644 --- a/src/tipideed/tipideed-internal.h +++ b/src/tipideed/tipideed-internal.h @@ -4,6 +4,7 @@ #define TIPIDEED_INTERNAL_H #include <sys/types.h> +#include <sys/stat.h> #include <stdint.h> #include <skalibs/gccattributes.h> @@ -127,7 +128,8 @@ extern void send_file (int, uint64_t, char const *) ; /* regular */ -extern int respond_regular (tipidee_rql const *, char const *, uint64_t, tipidee_resattr const *) ; +extern int respond_regular (tipidee_rql const *, char const *, struct stat const *, tipidee_resattr const *) ; +extern int respond_304 (tipidee_rql const *, char const *, struct stat const *) ; /* cgi */ @@ -141,6 +143,7 @@ extern void log_start (void) ; extern void log_and_exit (int) gccattr_noreturn ; extern void log_request (tipidee_rql const *) ; extern void log_regular (char const *, char const *, int, char const *) ; +extern void log_304 (char const *) ; extern void log_nph (char const *const *, char const *const *) ; extern void log_cgi (char const *const *, char const *const *) ; diff --git a/src/tipideed/tipideed.c b/src/tipideed/tipideed.c index 8c1e16e..5b6db10 100644 --- a/src/tipideed/tipideed.c +++ b/src/tipideed/tipideed.c @@ -1,10 +1,11 @@ /* ISC license. */ +#include <skalibs/bsdsnowflake.h> + #include <unistd.h> #include <string.h> #include <stdlib.h> #include <errno.h> -#include <sys/stat.h> #include <skalibs/env.h> #include <skalibs/uint16.h> @@ -17,6 +18,7 @@ #include <skalibs/tai.h> #include <skalibs/ip46.h> #include <skalibs/sig.h> +#include <skalibs/stat.h> #include <skalibs/stralloc.h> #include <skalibs/djbunix.h> #include <skalibs/avltreen.h> @@ -286,8 +288,17 @@ static inline int serve (tipidee_rql *rql, char const *docroot, size_t docrootle return respond_options(rql, ra.iscgi) ; else if (ra.iscgi) return respond_cgi(rql, fn, docrootlen, infopath, uribuf, hdr, &ra, body, bodylen) ; - else - return respond_regular(rql, fn, st.st_size, &ra) ; + + infopath = tipidee_headers_search(hdr, "If-Modified-Since") ; + if (infopath) + { + tain wanted, actual ; + if (tipidee_util_httpdate(infopath, &wanted) + && tain_from_timespec(&actual, &st.st_mtim) + && tain_less(&actual, &wanted)) + return respond_304(rql, fn, &st) ; + } + return respond_regular(rql, fn, &st, &ra) ; } int main (int argc, char const *const *argv, char const *const *envp) @@ -495,7 +506,7 @@ int main (int argc, char const *const *argv, char const *const *envp) } case TIPIDEE_TRANSFERCODING_CHUNKED : { - if (!tipidee_chunked_read_g(buffer_0, &bodysa, g.maxrqbody, &deadline)) + if (!tipidee_util_chunked_read_g(buffer_0, &bodysa, g.maxrqbody, &deadline)) { if (error_temp(errno)) die500sys(&rql, 111, "decode chunked body") ; else if (errno == EMSGSIZE) exit_413(&rql, "Request body too large") ; |