summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--package/deps.mak13
-rw-r--r--src/include/tipidee/response.h6
-rw-r--r--src/include/tipidee/tipidee.h2
-rw-r--r--src/include/tipidee/util.h (renamed from src/include/tipidee/body.h)10
-rw-r--r--src/libtipidee/deps-lib/tipidee5
-rw-r--r--src/libtipidee/tipidee_response_header_common_put.c2
-rw-r--r--src/libtipidee/tipidee_response_header_date.c19
-rw-r--r--src/libtipidee/tipidee_response_header_date_fmt.c11
-rw-r--r--src/libtipidee/tipidee_response_header_lastmodified.c24
-rw-r--r--src/libtipidee/tipidee_util_chunked_read.c (renamed from src/libtipidee/tipidee_chunked_read.c)4
-rw-r--r--src/libtipidee/tipidee_util_httpdate.c22
-rw-r--r--src/tipideed/log.c6
-rw-r--r--src/tipideed/regular.c39
-rw-r--r--src/tipideed/tipideed-internal.h5
-rw-r--r--src/tipideed/tipideed.c19
15 files changed, 149 insertions, 38 deletions
diff --git a/package/deps.mak b/package/deps.mak
index 0dc6776..854c476 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -5,7 +5,7 @@
src/include/tipidee/conf.h: src/include/tipidee/uri.h
src/include/tipidee/response.h: src/include/tipidee/rql.h
src/include/tipidee/rql.h: src/include/tipidee/method.h src/include/tipidee/uri.h
-src/include/tipidee/tipidee.h: src/include/tipidee/body.h src/include/tipidee/conf.h src/include/tipidee/config.h src/include/tipidee/headers.h src/include/tipidee/method.h src/include/tipidee/response.h src/include/tipidee/rql.h src/include/tipidee/uri.h
+src/include/tipidee/tipidee.h: src/include/tipidee/conf.h src/include/tipidee/config.h src/include/tipidee/headers.h src/include/tipidee/method.h src/include/tipidee/response.h src/include/tipidee/rql.h src/include/tipidee/uri.h src/include/tipidee/util.h
src/tipideed/tipideed-internal.h: src/include/tipidee/tipidee.h
src/config/confnode.o src/config/confnode.lo: src/config/confnode.c src/config/tipidee-config-internal.h
src/config/conftree.o src/config/conftree.lo: src/config/conftree.c src/config/tipidee-config-internal.h
@@ -13,7 +13,6 @@ src/config/defaults.o src/config/defaults.lo: src/config/defaults.c src/config/t
src/config/lexparse.o src/config/lexparse.lo: src/config/lexparse.c src/config/tipidee-config-internal.h src/include/tipidee/config.h
src/config/tipidee-config-preprocess.o src/config/tipidee-config-preprocess.lo: src/config/tipidee-config-preprocess.c
src/config/tipidee-config.o src/config/tipidee-config.lo: src/config/tipidee-config.c src/config/tipidee-config-internal.h src/include/tipidee/config.h
-src/libtipidee/tipidee_chunked_read.o src/libtipidee/tipidee_chunked_read.lo: src/libtipidee/tipidee_chunked_read.c src/include/tipidee/body.h
src/libtipidee/tipidee_conf_free.o src/libtipidee/tipidee_conf_free.lo: src/libtipidee/tipidee_conf_free.c src/include/tipidee/conf.h
src/libtipidee/tipidee_conf_get.o src/libtipidee/tipidee_conf_get.lo: src/libtipidee/tipidee_conf_get.c src/include/tipidee/conf.h
src/libtipidee/tipidee_conf_get_argv.o src/libtipidee/tipidee_conf_get_argv.lo: src/libtipidee/tipidee_conf_get_argv.c src/include/tipidee/conf.h
@@ -32,10 +31,14 @@ src/libtipidee/tipidee_method_tostr.o src/libtipidee/tipidee_method_tostr.lo: sr
src/libtipidee/tipidee_response_error.o src/libtipidee/tipidee_response_error.lo: src/libtipidee/tipidee_response_error.c src/include/tipidee/method.h src/include/tipidee/response.h src/include/tipidee/rql.h
src/libtipidee/tipidee_response_header_builtin.o src/libtipidee/tipidee_response_header_builtin.lo: src/libtipidee/tipidee_response_header_builtin.c src/include/tipidee/config.h src/include/tipidee/response.h
src/libtipidee/tipidee_response_header_common_put.o src/libtipidee/tipidee_response_header_common_put.lo: src/libtipidee/tipidee_response_header_common_put.c src/include/tipidee/config.h src/include/tipidee/response.h
+src/libtipidee/tipidee_response_header_date.o src/libtipidee/tipidee_response_header_date.lo: src/libtipidee/tipidee_response_header_date.c src/include/tipidee/response.h
src/libtipidee/tipidee_response_header_date_fmt.o src/libtipidee/tipidee_response_header_date_fmt.lo: src/libtipidee/tipidee_response_header_date_fmt.c src/include/tipidee/response.h
+src/libtipidee/tipidee_response_header_lastmodified.o src/libtipidee/tipidee_response_header_lastmodified.lo: src/libtipidee/tipidee_response_header_lastmodified.c src/include/tipidee/response.h
src/libtipidee/tipidee_response_status.o src/libtipidee/tipidee_response_status.lo: src/libtipidee/tipidee_response_status.c src/include/tipidee/response.h
src/libtipidee/tipidee_rql_read.o src/libtipidee/tipidee_rql_read.lo: src/libtipidee/tipidee_rql_read.c src/include/tipidee/method.h src/include/tipidee/rql.h src/include/tipidee/uri.h
src/libtipidee/tipidee_uri_parse.o src/libtipidee/tipidee_uri_parse.lo: src/libtipidee/tipidee_uri_parse.c src/include/tipidee/uri.h
+src/libtipidee/tipidee_util_chunked_read.o src/libtipidee/tipidee_util_chunked_read.lo: src/libtipidee/tipidee_util_chunked_read.c src/include/tipidee/util.h
+src/libtipidee/tipidee_util_httpdate.o src/libtipidee/tipidee_util_httpdate.lo: src/libtipidee/tipidee_util_httpdate.c src/include/tipidee/util.h
src/tipideed/cgi.o src/tipideed/cgi.lo: src/tipideed/cgi.c src/include/tipidee/headers.h src/include/tipidee/method.h src/include/tipidee/response.h src/include/tipidee/uri.h src/tipideed/tipideed-internal.h
src/tipideed/harden.o src/tipideed/harden.lo: src/tipideed/harden.c src/tipideed/tipideed-internal.h
src/tipideed/log.o src/tipideed/log.lo: src/tipideed/log.c src/include/tipidee/method.h src/tipideed/tipideed-internal.h
@@ -51,12 +54,12 @@ tipidee-config: src/config/tipidee-config.o src/config/confnode.o src/config/con
tipidee-config-preprocess: EXTRA_LIBS := -lskarnet
tipidee-config-preprocess: src/config/tipidee-config-preprocess.o
ifeq ($(strip $(STATIC_LIBS_ARE_PIC)),)
-libtipidee.a.xyzzy: src/libtipidee/tipidee_chunked_read.o src/libtipidee/tipidee_conf_free.o src/libtipidee/tipidee_conf_get.o src/libtipidee/tipidee_conf_get_argv.o src/libtipidee/tipidee_conf_get_content_type.o src/libtipidee/tipidee_conf_get_redirection.o src/libtipidee/tipidee_conf_get_string.o src/libtipidee/tipidee_conf_get_uint32.o src/libtipidee/tipidee_conf_init.o src/libtipidee/tipidee_headers_get_content_length.o src/libtipidee/tipidee_headers_init.o src/libtipidee/tipidee_headers_parse.o src/libtipidee/tipidee_headers_search.o src/libtipidee/tipidee_method_conv_table.o src/libtipidee/tipidee_method_tonum.o src/libtipidee/tipidee_method_tostr.o src/libtipidee/tipidee_response_error.o src/libtipidee/tipidee_response_header_builtin.o src/libtipidee/tipidee_response_header_common_put.o src/libtipidee/tipidee_response_header_date_fmt.o src/libtipidee/tipidee_response_status.o src/libtipidee/tipidee_rql_read.o src/libtipidee/tipidee_uri_parse.o
+libtipidee.a.xyzzy: src/libtipidee/tipidee_conf_free.o src/libtipidee/tipidee_conf_get.o src/libtipidee/tipidee_conf_get_argv.o src/libtipidee/tipidee_conf_get_content_type.o src/libtipidee/tipidee_conf_get_redirection.o src/libtipidee/tipidee_conf_get_string.o src/libtipidee/tipidee_conf_get_uint32.o src/libtipidee/tipidee_conf_init.o src/libtipidee/tipidee_headers_get_content_length.o src/libtipidee/tipidee_headers_init.o src/libtipidee/tipidee_headers_parse.o src/libtipidee/tipidee_headers_search.o src/libtipidee/tipidee_method_conv_table.o src/libtipidee/tipidee_method_tonum.o src/libtipidee/tipidee_method_tostr.o src/libtipidee/tipidee_response_error.o src/libtipidee/tipidee_response_header_builtin.o src/libtipidee/tipidee_response_header_common_put.o src/libtipidee/tipidee_response_header_date.o src/libtipidee/tipidee_response_header_date_fmt.o src/libtipidee/tipidee_response_header_lastmodified.o src/libtipidee/tipidee_response_status.o src/libtipidee/tipidee_rql_read.o src/libtipidee/tipidee_uri_parse.o src/libtipidee/tipidee_util_chunked_read.o src/libtipidee/tipidee_util_httpdate.o
else
-libtipidee.a.xyzzy: src/libtipidee/tipidee_chunked_read.lo src/libtipidee/tipidee_conf_free.lo src/libtipidee/tipidee_conf_get.lo src/libtipidee/tipidee_conf_get_argv.lo src/libtipidee/tipidee_conf_get_content_type.lo src/libtipidee/tipidee_conf_get_redirection.lo src/libtipidee/tipidee_conf_get_string.lo src/libtipidee/tipidee_conf_get_uint32.lo src/libtipidee/tipidee_conf_init.lo src/libtipidee/tipidee_headers_get_content_length.lo src/libtipidee/tipidee_headers_init.lo src/libtipidee/tipidee_headers_parse.lo src/libtipidee/tipidee_headers_search.lo src/libtipidee/tipidee_method_conv_table.lo src/libtipidee/tipidee_method_tonum.lo src/libtipidee/tipidee_method_tostr.lo src/libtipidee/tipidee_response_error.lo src/libtipidee/tipidee_response_header_builtin.lo src/libtipidee/tipidee_response_header_common_put.lo src/libtipidee/tipidee_response_header_date_fmt.lo src/libtipidee/tipidee_response_status.lo src/libtipidee/tipidee_rql_read.lo src/libtipidee/tipidee_uri_parse.lo
+libtipidee.a.xyzzy: src/libtipidee/tipidee_conf_free.lo src/libtipidee/tipidee_conf_get.lo src/libtipidee/tipidee_conf_get_argv.lo src/libtipidee/tipidee_conf_get_content_type.lo src/libtipidee/tipidee_conf_get_redirection.lo src/libtipidee/tipidee_conf_get_string.lo src/libtipidee/tipidee_conf_get_uint32.lo src/libtipidee/tipidee_conf_init.lo src/libtipidee/tipidee_headers_get_content_length.lo src/libtipidee/tipidee_headers_init.lo src/libtipidee/tipidee_headers_parse.lo src/libtipidee/tipidee_headers_search.lo src/libtipidee/tipidee_method_conv_table.lo src/libtipidee/tipidee_method_tonum.lo src/libtipidee/tipidee_method_tostr.lo src/libtipidee/tipidee_response_error.lo src/libtipidee/tipidee_response_header_builtin.lo src/libtipidee/tipidee_response_header_common_put.lo src/libtipidee/tipidee_response_header_date.lo src/libtipidee/tipidee_response_header_date_fmt.lo src/libtipidee/tipidee_response_header_lastmodified.lo src/libtipidee/tipidee_response_status.lo src/libtipidee/tipidee_rql_read.lo src/libtipidee/tipidee_uri_parse.lo src/libtipidee/tipidee_util_chunked_read.lo src/libtipidee/tipidee_util_httpdate.lo
endif
libtipidee.so.xyzzy: EXTRA_LIBS := -lskarnet
-libtipidee.so.xyzzy: src/libtipidee/tipidee_chunked_read.lo src/libtipidee/tipidee_conf_free.lo src/libtipidee/tipidee_conf_get.lo src/libtipidee/tipidee_conf_get_argv.lo src/libtipidee/tipidee_conf_get_content_type.lo src/libtipidee/tipidee_conf_get_redirection.lo src/libtipidee/tipidee_conf_get_string.lo src/libtipidee/tipidee_conf_get_uint32.lo src/libtipidee/tipidee_conf_init.lo src/libtipidee/tipidee_headers_get_content_length.lo src/libtipidee/tipidee_headers_init.lo src/libtipidee/tipidee_headers_parse.lo src/libtipidee/tipidee_headers_search.lo src/libtipidee/tipidee_method_conv_table.lo src/libtipidee/tipidee_method_tonum.lo src/libtipidee/tipidee_method_tostr.lo src/libtipidee/tipidee_response_error.lo src/libtipidee/tipidee_response_header_builtin.lo src/libtipidee/tipidee_response_header_common_put.lo src/libtipidee/tipidee_response_header_date_fmt.lo src/libtipidee/tipidee_response_status.lo src/libtipidee/tipidee_rql_read.lo src/libtipidee/tipidee_uri_parse.lo
+libtipidee.so.xyzzy: src/libtipidee/tipidee_conf_free.lo src/libtipidee/tipidee_conf_get.lo src/libtipidee/tipidee_conf_get_argv.lo src/libtipidee/tipidee_conf_get_content_type.lo src/libtipidee/tipidee_conf_get_redirection.lo src/libtipidee/tipidee_conf_get_string.lo src/libtipidee/tipidee_conf_get_uint32.lo src/libtipidee/tipidee_conf_init.lo src/libtipidee/tipidee_headers_get_content_length.lo src/libtipidee/tipidee_headers_init.lo src/libtipidee/tipidee_headers_parse.lo src/libtipidee/tipidee_headers_search.lo src/libtipidee/tipidee_method_conv_table.lo src/libtipidee/tipidee_method_tonum.lo src/libtipidee/tipidee_method_tostr.lo src/libtipidee/tipidee_response_error.lo src/libtipidee/tipidee_response_header_builtin.lo src/libtipidee/tipidee_response_header_common_put.lo src/libtipidee/tipidee_response_header_date.lo src/libtipidee/tipidee_response_header_date_fmt.lo src/libtipidee/tipidee_response_header_lastmodified.lo src/libtipidee/tipidee_response_status.lo src/libtipidee/tipidee_rql_read.lo src/libtipidee/tipidee_uri_parse.lo src/libtipidee/tipidee_util_chunked_read.lo src/libtipidee/tipidee_util_httpdate.lo
tipideed: EXTRA_LIBS := -lskarnet
tipideed: src/tipideed/tipideed.o src/tipideed/cgi.o src/tipideed/harden.o src/tipideed/log.o src/tipideed/options.o src/tipideed/regular.o src/tipideed/responses.o src/tipideed/send_file.o src/tipideed/tipideed.o src/tipideed/trace.o libtipidee.a.xyzzy
INTERNAL_LIBS :=
diff --git a/src/include/tipidee/response.h b/src/include/tipidee/response.h
index e0a6177..d549532 100644
--- a/src/include/tipidee/response.h
+++ b/src/include/tipidee/response.h
@@ -3,6 +3,7 @@
#ifndef TIPIDEE_RESPONSE_H
#define TIPIDEE_RESPONSE_H
+#include <sys/stat.h>
#include <stddef.h>
#include <stdint.h>
@@ -24,7 +25,10 @@ extern size_t tipidee_response_status (buffer *, tipidee_rql const *, unsigned i
#define tipidee_response_status_line(b, rql, line) tipidee_response_status(b, rql, 0, (line))
extern size_t tipidee_response_header_date_fmt (char *, size_t, tain const *) ;
-#define tipidee_response_header_date_fmt_g(buf, max) tipidee_response_header_date_fmt(buf, (max), &STAMP)
+extern size_t tipidee_response_header_date (char *, size_t, tain const *) ;
+#define tipidee_response_header_date_g(buf, max) tipidee_response_header_date(buf, (max), &STAMP)
+extern size_t tipidee_response_header_lastmodified (char *, size_t, struct stat const *) ;
+
extern size_t tipidee_response_header_common_put (buffer *, uint32_t, tain const *) ;
#define tipidee_response_header_common_put_g(b, options) tipidee_response_header_common_put(b, (options), &STAMP)
diff --git a/src/include/tipidee/tipidee.h b/src/include/tipidee/tipidee.h
index ddd1348..7634366 100644
--- a/src/include/tipidee/tipidee.h
+++ b/src/include/tipidee/tipidee.h
@@ -3,7 +3,6 @@
#ifndef TIPIDEE_H
#define TIPIDEE_H
-#include <tipidee/body.h>
#include <tipidee/config.h>
#include <tipidee/conf.h>
#include <tipidee/headers.h>
@@ -11,5 +10,6 @@
#include <tipidee/response.h>
#include <tipidee/rql.h>
#include <tipidee/uri.h>
+#include <tipidee/util.h>
#endif
diff --git a/src/include/tipidee/body.h b/src/include/tipidee/util.h
index fc8bd9a..5160a69 100644
--- a/src/include/tipidee/body.h
+++ b/src/include/tipidee/util.h
@@ -1,7 +1,7 @@
/* ISC license. */
-#ifndef TIPIDEE_BODY_H
-#define TIPIDEE_BODY_H
+#ifndef TIPIDEE_UTIL_H
+#define TIPIDEE_UTIL_H
#include <stddef.h>
#include <stdint.h>
@@ -19,7 +19,9 @@ enum tipidee_transfercoding_e
TIPIDEE_TRANSFERCODING_UNKNOWN
} ;
-extern int tipidee_chunked_read (buffer *, stralloc *, size_t, tain const *, tain *) ;
-#define tipidee_chunked_read_g(b, sa, max, deadline) tipidee_chunked_read(b, sa, max, (deadline), &STAMP)
+extern int tipidee_util_chunked_read (buffer *, stralloc *, size_t, tain const *, tain *) ;
+#define tipidee_util_chunked_read_g(b, sa, max, deadline) tipidee_util_chunked_read(b, sa, max, (deadline), &STAMP)
+
+extern int tipidee_util_httpdate (char const *, tain *) ;
#endif
diff --git a/src/libtipidee/deps-lib/tipidee b/src/libtipidee/deps-lib/tipidee
index d218af1..81cc5f7 100644
--- a/src/libtipidee/deps-lib/tipidee
+++ b/src/libtipidee/deps-lib/tipidee
@@ -1,4 +1,3 @@
-tipidee_chunked_read.o
tipidee_conf_free.o
tipidee_conf_get.o
tipidee_conf_get_argv.o
@@ -17,8 +16,12 @@ tipidee_method_tostr.o
tipidee_response_error.o
tipidee_response_header_builtin.o
tipidee_response_header_common_put.o
+tipidee_response_header_date.o
tipidee_response_header_date_fmt.o
+tipidee_response_header_lastmodified.o
tipidee_response_status.o
tipidee_rql_read.o
tipidee_uri_parse.o
+tipidee_util_chunked_read.o
+tipidee_util_httpdate.o
-lskarnet
diff --git a/src/libtipidee/tipidee_response_header_common_put.c b/src/libtipidee/tipidee_response_header_common_put.c
index 8352ba9..c67cc94 100644
--- a/src/libtipidee/tipidee_response_header_common_put.c
+++ b/src/libtipidee/tipidee_response_header_common_put.c
@@ -10,7 +10,7 @@
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(fmt, 128, stamp)) ;
+ size_t m = 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) ;
diff --git a/src/libtipidee/tipidee_response_header_date.c b/src/libtipidee/tipidee_response_header_date.c
new file mode 100644
index 0000000..d350d2c
--- /dev/null
+++ b/src/libtipidee/tipidee_response_header_date.c
@@ -0,0 +1,19 @@
+/* ISC license. */
+
+#include <errno.h>
+#include <string.h>
+
+#include <tipidee/response.h>
+
+size_t tipidee_response_header_date (char *s, size_t max, tain const *stamp)
+{
+ size_t l ;
+ if (max < 8) return (errno = ENOBUFS, 0) ;
+ memcpy(s, "Date: ", 6) ;
+ l = tipidee_response_header_date_fmt(s + 6, max - 6, stamp) ;
+ if (!l) return 0 ;
+ if (l + 8 > max) return (errno = ENOBUFS, 0) ;
+ l += 6 ;
+ s[l++] = '\r' ; s[l++] = '\n' ;
+ return l ;
+}
diff --git a/src/libtipidee/tipidee_response_header_date_fmt.c b/src/libtipidee/tipidee_response_header_date_fmt.c
index df19673..ca4cdd9 100644
--- a/src/libtipidee/tipidee_response_header_date_fmt.c
+++ b/src/libtipidee/tipidee_response_header_date_fmt.c
@@ -1,6 +1,5 @@
/* ISC license. */
-#include <string.h>
#include <time.h>
#include <skalibs/tai.h>
@@ -10,15 +9,7 @@
size_t tipidee_response_header_date_fmt (char *s, size_t max, tain const *stamp)
{
- size_t m = 0, l ;
struct tm tm ;
- if (m + 6 > max) return 0 ;
if (!localtm_from_tai(&tm, tain_secp(stamp), 0)) return 0 ;
- memcpy(s, "Date: ", 6) ; m += 6 ;
- l = strftime(s + m, max - m, "%a, %d %b %Y %T GMT", &tm) ;
- if (!l) return 0 ;
- m += l ;
- if (m + 2 > max) return 0 ;
- s[m++] = '\r' ; s[m++] = '\n' ;
- return m ;
+ return strftime(s, max, "%a, %d %b %Y %T GMT", &tm) ;
}
diff --git a/src/libtipidee/tipidee_response_header_lastmodified.c b/src/libtipidee/tipidee_response_header_lastmodified.c
new file mode 100644
index 0000000..3b3caa6
--- /dev/null
+++ b/src/libtipidee/tipidee_response_header_lastmodified.c
@@ -0,0 +1,24 @@
+/* ISC license. */
+
+#include <skalibs/bsdsnowflake.h>
+
+#include <sys/stat.h>
+#include <errno.h>
+#include <string.h>
+
+#include <tipidee/response.h>
+
+size_t tipidee_response_header_lastmodified (char *s, size_t max, struct stat const *st)
+{
+ tain t ;
+ size_t l ;
+ if (max < 17) return (errno = ENOBUFS, 0) ;
+ if (!tain_from_timespec(&t, &st->st_mtim)) return 0 ;
+ memcpy(s, "Last-Modified: ", 15) ;
+ l = tipidee_response_header_date_fmt(s + 15, max - 15, &t) ;
+ if (!l) return 0 ;
+ if (l + 17 > max) return (errno = ENOBUFS, 0) ;
+ l += 15 ;
+ s[l++] = '\r' ; s[l++] = '\n' ;
+ return l ;
+}
diff --git a/src/libtipidee/tipidee_chunked_read.c b/src/libtipidee/tipidee_util_chunked_read.c
index 66d5d80..850ffae 100644
--- a/src/libtipidee/tipidee_chunked_read.c
+++ b/src/libtipidee/tipidee_util_chunked_read.c
@@ -7,11 +7,11 @@
#include <skalibs/stralloc.h>
#include <skalibs/unix-timed.h>
-#include <tipidee/body.h>
+#include <tipidee/util.h>
#include <skalibs/posixishard.h>
-int tipidee_chunked_read (buffer *b, stralloc *sa, size_t maxlen, tain const *deadline, tain *stamp)
+int tipidee_util_chunked_read (buffer *b, stralloc *sa, size_t maxlen, tain const *deadline, tain *stamp)
{
char line[512] ;
for (;;)
diff --git a/src/libtipidee/tipidee_util_httpdate.c b/src/libtipidee/tipidee_util_httpdate.c
new file mode 100644
index 0000000..cce735d
--- /dev/null
+++ b/src/libtipidee/tipidee_util_httpdate.c
@@ -0,0 +1,22 @@
+/* ISC license. */
+
+#include <errno.h>
+#include <time.h>
+
+#include <skalibs/djbtime.h>
+
+#include <tipidee/util.h>
+
+int tipidee_util_httpdate (char const *s, tain *stamp)
+{
+ struct tm tm ;
+ if (strptime(s, "%a, %d %b %Y %T GMT", &tm)) goto got ;
+ if (strptime(s, "%a, %d-%b-%y %T GMT", &tm)) goto got ;
+ if (strptime(s, "%a %b %d %T %Y", &tm)) goto got ;
+ return (errno = EINVAL, 0) ;
+
+ got:
+ if (!tai_from_localtm(tain_secp(stamp), &tm)) return 0 ;
+ stamp->nano = 0 ;
+ return 1 ;
+}
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") ;