From 9de7466f7739b04f4e0f598d21becda0b146928d Mon Sep 17 00:00:00 2001 From: Reyk Floeter Date: Mon, 25 Aug 2014 18:30:26 +0200 Subject: sync --- httpd.conf.5 | 28 ++++++++++++++++------------ httpd.h | 6 +++--- parse.y | 25 +++++++++++++++++++++---- server_fcgi.c | 8 ++++---- server_file.c | 30 +++++++++++++++++------------- server_http.c | 30 ++++++++++++++++++------------ 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 .\" @@ -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 @@ -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 @@ -135,6 +135,7 @@ typedef struct { %type port %type optssl %type timeout +%type 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 @@ -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 @@ -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, "%s/%*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, "%s%*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 @@ -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 */ -- cgit v1.2.3-54-g00ecf