Sorry for the spam, I submitted the patch during the maintenance period. Any advice on this patch is appreciated.
Kyle Thompson > On Apr 18, 2015, at 12:19 PM, jmp <[email protected]> wrote: > > If-Modified-Since is sent by http clients to be notified if a file has > been changed. This patch adds a function server_file_modified_since > that checks the time of the file from stat with the time sent from the > client. The separate function will help implement proper Range support. > > I found 'timeoff' to be useful for converting to a time_t that is in > GMT; however, did not find documentation on this in the man pages. It > seems to be a function dating back to at least the NetBSD fork. If > there is a better time function I should be using please let me know. > > The logic is separated out so we can reuse this in the future. I was > thinking this should be in http.c instead of server_file.c, but for > right now it is only useful for file operations. If-Modified-Since on > autoindex will not work due to how the index would be checked by this > code. > > There is room for the 'If-Unmodified-Since' header, but it is not > really useful for file operations without Range support. > > > Index: usr.sbin/httpd/server_file.c > =================================================================== > RCS file: /cvs/src/usr.sbin/httpd/server_file.c,v > retrieving revision 1.51 > diff -u -p -r1.51 server_file.c > --- usr.sbin/httpd/server_file.c 12 Feb 2015 10:05:29 -0000 1.51 > +++ usr.sbin/httpd/server_file.c 18 Apr 2015 16:41:55 -0000 > @@ -42,6 +42,7 @@ int server_file_request(struct httpd *, > struct stat *); > int server_file_index(struct httpd *, struct client *, struct stat *); > int server_file_method(struct client *); > +int server_file_modified_since(struct http_descriptor *, struct stat *); > > int > server_file_access(struct httpd *env, struct client *clt, > @@ -123,6 +124,10 @@ server_file_access(struct httpd *env, st > goto fail; > } > > + if ((ret = server_file_modified_since(desc, &st)) != -1) { > + return ret; > + } > + > return (server_file_request(env, clt, path, &st)); > > fail: > @@ -466,4 +471,24 @@ server_file_error(struct bufferevent *be > } > server_close(clt, "unknown event error"); > return; > +} > + > +int > +server_file_modified_since(struct http_descriptor * desc, struct stat * st) > +{ > + struct kv key, *since; > + struct tm tm; > + > + memset(&tm, 0, sizeof(struct tm)); > + > + key.kv_key = "If-Modified-Since"; > + if ((since = kv_find(&desc->http_headers, &key)) != NULL && > + since->kv_value != NULL) { > + if (strptime(since->kv_value, "%a, %d %h %Y %T %Z", &tm) != NULL && > + timeoff(&tm, 0L) >= st->st_mtim.tv_sec) { > + return 304; > + } > + } > + > + return (-1); > } >
