I haven't heard back from anyone. Since the release has passed, has
anyone had time to look at this? 

I think that I should move the time parsing out of server_file 
to server_http so it can be reused later. I'm also not sure about
the placement of the check. Additionally, I'm using timeoff which seems
to not be documented anywhere.

On Sat, Apr 18, 2015 at 04:28:40PM -0500, jmp wrote:
> If-Modified-Since is already sent by most web browsers to httpd. This
> patch adds a check to server_file_access before we send the file back.
> 
> This does not do any checks for autoindex directories as the size and
> last modification dates of files would not get updated properly.
> 
> I separated the logic for checking the header values as it can be
> reused for different side effects of other headers like Range.
> 
> 
> 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