summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchrisz <chrisz@openbsd.org>2014-08-21 19:23:10 +0000
committerchrisz <chrisz@openbsd.org>2014-08-21 19:23:10 +0000
commitbe5ab2e629c2c6900a7923a777068fc434afae47 (patch)
tree4ce00a8b2205a870105b97dc9a47e0c3793d3f1a
parentDocument square brackets for IPv6 addresses. From FreeBSD. (diff)
downloadwireguard-openbsd-be5ab2e629c2c6900a7923a777068fc434afae47.tar.xz
wireguard-openbsd-be5ab2e629c2c6900a7923a777068fc434afae47.zip
Add Last-Modified: HTTP header.
OK reyk@
-rw-r--r--usr.sbin/httpd/httpd.h6
-rw-r--r--usr.sbin/httpd/server_fcgi.c8
-rw-r--r--usr.sbin/httpd/server_file.c30
-rw-r--r--usr.sbin/httpd/server_http.c30
4 files changed, 42 insertions, 32 deletions
diff --git a/usr.sbin/httpd/httpd.h b/usr.sbin/httpd/httpd.h
index 371dd1caac0..6f1b48d95c8 100644
--- a/usr.sbin/httpd/httpd.h
+++ b/usr.sbin/httpd/httpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: httpd.h,v 1.53 2014/08/13 16:04:28 reyk Exp $ */
+/* $OpenBSD: httpd.h,v 1.54 2014/08/21 19:23:10 chrisz Exp $ */
/*
* Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -512,7 +512,7 @@ int server_headers(struct client *,
int (*)(struct client *, struct kv *, void *), void *);
int server_writeresponse_http(struct client *);
int server_response_http(struct client *, u_int, struct media_type *,
- size_t);
+ size_t, time_t);
void server_reset_http(struct client *);
void server_close_http(struct client *);
int server_response(struct httpd *, struct client *);
@@ -520,7 +520,7 @@ struct server_config *
server_getlocation(struct client *, const char *);
const char *
server_http_host(struct sockaddr_storage *, char *, size_t);
-void server_http_date(char *, size_t);
+ssize_t server_http_time(time_t, char *, size_t);
int server_log_http(struct client *, u_int, size_t);
/* server_file.c */
diff --git a/usr.sbin/httpd/server_fcgi.c b/usr.sbin/httpd/server_fcgi.c
index 848bae485f7..6eb668ea72f 100644
--- a/usr.sbin/httpd/server_fcgi.c
+++ b/usr.sbin/httpd/server_fcgi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server_fcgi.c,v 1.33 2014/08/13 18:00:54 chrisz Exp $ */
+/* $OpenBSD: server_fcgi.c,v 1.34 2014/08/21 19:23:10 chrisz Exp $ */
/*
* Copyright (c) 2014 Florian Obser <florian@openbsd.org>
@@ -562,9 +562,9 @@ server_fcgi_header(struct client *clt, u_int code)
} else if (kv_add(&desc->http_headers, "Connection", "close") == NULL)
return (-1);
- /* Date header is mandatory and should be added last */
- server_http_date(tmbuf, sizeof(tmbuf));
- if (kv_add(&desc->http_headers, "Date", tmbuf) == NULL)
+ /* Date header is mandatory and should be added as late as possible */
+ if (server_http_time(time(NULL), tmbuf, sizeof(tmbuf)) <= 0 ||
+ kv_add(&desc->http_headers, "Date", tmbuf) == NULL)
return (-1);
/* Write initial header (fcgi might append more) */
diff --git a/usr.sbin/httpd/server_file.c b/usr.sbin/httpd/server_file.c
index e87bcbdb994..28b17c7273d 100644
--- a/usr.sbin/httpd/server_file.c
+++ b/usr.sbin/httpd/server_file.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server_file.c,v 1.33 2014/08/14 07:50:35 chrisz Exp $ */
+/* $OpenBSD: server_file.c,v 1.34 2014/08/21 19:23:10 chrisz Exp $ */
/*
* Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -49,7 +49,7 @@
int server_file_access(struct httpd *, struct client *, char *, size_t);
int server_file_request(struct httpd *, struct client *, char *,
struct stat *);
-int server_file_index(struct httpd *, struct client *);
+int server_file_index(struct httpd *, struct client *, struct stat *);
int server_file_method(struct client *);
int
@@ -123,7 +123,7 @@ server_file_access(struct httpd *env, struct client *clt,
goto fail;
}
- return (server_file_index(env, clt));
+ return (server_file_index(env, clt, &st));
}
return (ret);
} else if (!S_ISREG(st.st_mode)) {
@@ -220,7 +220,8 @@ server_file_request(struct httpd *env, struct client *clt, char *path,
goto abort;
media = media_find(env->sc_mediatypes, path);
- ret = server_response_http(clt, 200, media, st->st_size);
+ ret = server_response_http(clt, 200, media, st->st_size,
+ MIN(time(NULL), st->st_mtim.tv_sec));
switch (ret) {
case -1:
goto fail;
@@ -267,7 +268,7 @@ server_file_request(struct httpd *env, struct client *clt, char *path,
}
int
-server_file_index(struct httpd *env, struct client *clt)
+server_file_index(struct httpd *env, struct client *clt, struct stat *st)
{
char path[MAXPATHLEN];
char tmstr[21];
@@ -279,9 +280,8 @@ server_file_index(struct httpd *env, struct client *clt)
struct evbuffer *evb = NULL;
struct media_type *media;
const char *style;
- struct stat st;
struct tm tm;
- time_t t;
+ time_t t, dir_mtime;
if ((ret = server_file_method(clt)) != 0) {
code = ret;
@@ -297,6 +297,9 @@ server_file_index(struct httpd *env, struct client *clt)
if ((fd = open(path, O_RDONLY)) == -1)
goto abort;
+ /* Save last modification time */
+ dir_mtime = MIN(time(NULL), st->st_mtim.tv_sec);
+
if ((evb = evbuffer_new()) == NULL)
goto abort;
@@ -328,12 +331,12 @@ server_file_index(struct httpd *env, struct client *clt)
dp = namelist[i];
if (skip ||
- fstatat(fd, dp->d_name, &st, 0) == -1) {
+ fstatat(fd, dp->d_name, st, 0) == -1) {
free(dp);
continue;
}
- t = st.st_mtime;
+ t = st->st_mtime;
localtime_r(&t, &tm);
strftime(tmstr, sizeof(tmstr), "%d-%h-%Y %R", &tm);
namewidth = 51 - strlen(dp->d_name);
@@ -341,18 +344,18 @@ server_file_index(struct httpd *env, struct client *clt)
if (dp->d_name[0] == '.' &&
!(dp->d_name[1] == '.' && dp->d_name[2] == '\0')) {
/* ignore hidden files starting with a dot */
- } else if (S_ISDIR(st.st_mode)) {
+ } else if (S_ISDIR(st->st_mode)) {
namewidth -= 1; /* trailing slash */
if (evbuffer_add_printf(evb,
"<a href=\"%s\">%s/</a>%*s%s%20s\n",
dp->d_name, dp->d_name,
MAX(namewidth, 0), " ", tmstr, "-") == -1)
skip = 1;
- } else if (S_ISREG(st.st_mode)) {
+ } else if (S_ISREG(st->st_mode)) {
if (evbuffer_add_printf(evb,
"<a href=\"%s\">%s</a>%*s%s%20llu\n",
dp->d_name, dp->d_name,
- MAX(namewidth, 0), " ", tmstr, st.st_size) == -1)
+ MAX(namewidth, 0), " ", tmstr, st->st_size) == -1)
skip = 1;
}
free(dp);
@@ -368,7 +371,8 @@ server_file_index(struct httpd *env, struct client *clt)
fd = -1;
media = media_find(env->sc_mediatypes, "index.html");
- ret = server_response_http(clt, 200, media, EVBUFFER_LENGTH(evb));
+ ret = server_response_http(clt, 200, media, EVBUFFER_LENGTH(evb),
+ dir_mtime);
switch (ret) {
case -1:
goto fail;
diff --git a/usr.sbin/httpd/server_http.c b/usr.sbin/httpd/server_http.c
index 9e09428a628..af996a5c4d6 100644
--- a/usr.sbin/httpd/server_http.c
+++ b/usr.sbin/httpd/server_http.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server_http.c,v 1.44 2014/08/08 18:29:42 reyk Exp $ */
+/* $OpenBSD: server_http.c,v 1.45 2014/08/21 19:23:10 chrisz Exp $ */
/*
* Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -534,16 +534,16 @@ server_reset_http(struct client *clt)
server_log(clt, NULL);
}
-void
-server_http_date(char *tmbuf, size_t len)
+ssize_t
+server_http_time(time_t t, char *tmbuf, size_t len)
{
- time_t t;
struct tm tm;
/* New HTTP/1.1 RFC 7231 prefers IMF-fixdate from RFC 5322 */
- time(&t);
- gmtime_r(&t, &tm);
- strftime(tmbuf, len, "%a, %d %h %Y %T %Z", &tm);
+ if (t == -1 || gmtime_r(&t, &tm) == NULL)
+ return (-1);
+ else
+ return (strftime(tmbuf, len, "%a, %d %h %Y %T %Z", &tm));
}
const char *
@@ -602,7 +602,8 @@ server_abort_http(struct client *clt, u_int code, const char *msg)
if (print_host(&srv_conf->ss, hbuf, sizeof(hbuf)) == NULL)
goto done;
- server_http_date(tmbuf, sizeof(tmbuf));
+ if (server_http_time(time(NULL), tmbuf, sizeof(tmbuf)) <= 0)
+ goto done;
/* Do not send details of the Internal Server Error */
switch (code) {
@@ -790,7 +791,7 @@ server_getlocation(struct client *clt, const char *path)
int
server_response_http(struct client *clt, u_int code,
- struct media_type *media, size_t size)
+ struct media_type *media, size_t size, time_t mtime)
{
struct http_descriptor *desc = clt->clt_desc;
const char *error;
@@ -835,9 +836,14 @@ server_response_http(struct client *clt, u_int code,
kv_set(cl, "%ld", size) == -1)
return (-1);
- /* Date header is mandatory and should be added last */
- server_http_date(tmbuf, sizeof(tmbuf));
- if (kv_add(&desc->http_headers, "Date", tmbuf) == NULL)
+ /* Set last modification time */
+ if (server_http_time(mtime, tmbuf, sizeof(tmbuf)) <= 0 ||
+ kv_add(&desc->http_headers, "Last-Modified", tmbuf) == NULL)
+ return (-1);
+
+ /* Date header is mandatory and should be added as late as possible */
+ if (server_http_time(time(NULL), tmbuf, sizeof(tmbuf)) <= 0 ||
+ kv_add(&desc->http_headers, "Date", tmbuf) == NULL)
return (-1);
/* Write completed header */