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);
> }
> 

Reply via email to