aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReyk Floeter <reyk@esdenera.com>2014-08-25 18:30:26 +0200
committerReyk Floeter <reyk@esdenera.com>2014-08-25 18:30:26 +0200
commit9de7466f7739b04f4e0f598d21becda0b146928d (patch)
tree8c6ea73c05bf8d5ac0b9ca481b4723fd79deaeee
parent5eb16802a795fa3c1fcb936f3261776db11a8a3c (diff)
downloadhttpd-9de7466f7739b04f4e0f598d21becda0b146928d.tar.gz
httpd-9de7466f7739b04f4e0f598d21becda0b146928d.zip
sync
-rw-r--r--httpd.conf.528
-rw-r--r--httpd.h6
-rw-r--r--parse.y25
-rw-r--r--server_fcgi.c8
-rw-r--r--server_file.c30
-rw-r--r--server_http.c30
6 files changed, 79 insertions, 48 deletions
diff --git a/httpd.conf.5 b/httpd.conf.5
index 8a539f2..788d0a9 100644
--- a/httpd.conf.5
+++ b/httpd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: httpd.conf.5,v 1.32 2014/08/17 18:46:29 jmc Exp $
+.\" $OpenBSD: httpd.conf.5,v 1.33 2014/08/25 14:27:54 reyk Exp $
.\"
.\" Copyright (c) 2014 Reyk Floeter <reyk@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: August 17 2014 $
+.Dd $Mdocdate: August 25 2014 $
.Dt HTTPD.CONF 5
.Os
.Sh NAME
@@ -324,7 +324,7 @@ The
.Ic types
section must include one or more lines of the following syntax:
.Bl -tag -width Ds
-.It Ar type/subtype Ar name Op Ar name ... ;
+.It Ar type/subtype Ar name Op Ar name ...
Set the media
.Ar type
and
@@ -332,6 +332,10 @@ and
to the specified extension
.Ar name .
One or more names can be specified per line.
+Each line may end with an optional semicolon.
+.It Ic include Ar file
+Include types definitions from an external file, for example
+.Pa /usr/share/misc/mime.types .
.El
.Sh EXAMPLES
The following example will start one server that is pre-forked two
@@ -348,14 +352,14 @@ server "default" {
}
types {
- text/css css;
- text/html htm html;
- text/txt txt;
- image/gif gif;
- image/jpeg jpg jpeg;
- image/png png;
- application/javascript js;
- application/xml xml;
+ text/css css
+ text/html htm html
+ text/txt txt
+ image/gif gif
+ image/jpeg jpg jpeg
+ image/png png
+ application/javascript js
+ application/xml xml
}
.Ed
.Pp
@@ -381,7 +385,7 @@ server "intranet.example.com" {
}
.Ed
.Pp
-The syntax of the types section is compatible with the format used by
+The syntax of the types section is also compatible with the format used by
.Xr nginx 8 ,
so it is possible to include its
.Pa mime.types
diff --git a/httpd.h b/httpd.h
index 371dd1c..6f1b48d 100644
--- a/httpd.h
+++ b/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/parse.y b/parse.y
index d66f207..44cf90c 100644
--- a/parse.y
+++ b/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.35 2014/08/09 07:35:45 reyk Exp $ */
+/* $OpenBSD: parse.y,v 1.36 2014/08/25 14:27:54 reyk Exp $ */
/*
* Copyright (c) 2007 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -135,6 +135,7 @@ typedef struct {
%type <v.port> port
%type <v.number> optssl
%type <v.tv> timeout
+%type <v.string> numberstring
%%
@@ -660,7 +661,7 @@ types : TYPES '{' optnl mediaopts_l '}'
;
mediaopts_l : mediaopts_l mediaoptsl nl
- | mediaoptsl optnl
+ | mediaoptsl nl
;
mediaoptsl : STRING '/' STRING {
@@ -677,14 +678,15 @@ mediaoptsl : STRING '/' STRING {
}
free($1);
free($3);
- } medianames_l ';'
+ } medianames_l optsemicolon
+ | include
;
medianames_l : medianames_l medianamesl
| medianamesl
;
-medianamesl : STRING {
+medianamesl : numberstring {
if (strlcpy(media.media_name, $1,
sizeof(media.media_name)) >=
sizeof(media.media_name)) {
@@ -751,11 +753,26 @@ timeout : NUMBER
}
;
+numberstring : NUMBER {
+ char *s;
+ if (asprintf(&s, "%lld", $1) == -1) {
+ yyerror("asprintf: number");
+ YYERROR;
+ }
+ $$ = s;
+ }
+ | STRING
+ ;
+
comma : ','
| nl
| /* empty */
;
+optsemicolon : ';'
+ |
+ ;
+
optnl : '\n' optnl
|
;
diff --git a/server_fcgi.c b/server_fcgi.c
index 848bae4..6eb668e 100644
--- a/server_fcgi.c
+++ b/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/server_file.c b/server_file.c
index e87bcbd..28b17c7 100644
--- a/server_file.c
+++ b/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/server_http.c b/server_http.c
index 9e09428..af996a5 100644
--- a/server_http.c
+++ b/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 */