|
|
|
@ -340,39 +340,13 @@ static int http_response_parse_range(server *srv, connection *con, plugin_data *
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static buffer * strftime_cache_get(server *srv, time_t last_mod) { |
|
|
|
|
struct tm *tm; |
|
|
|
|
size_t i; |
|
|
|
|
|
|
|
|
|
for (i = 0; i < FILE_CACHE_MAX; i++) { |
|
|
|
|
/* found cache-entry */ |
|
|
|
|
if (srv->mtime_cache[i].mtime == last_mod) return srv->mtime_cache[i].str; |
|
|
|
|
|
|
|
|
|
/* found empty slot */ |
|
|
|
|
if (srv->mtime_cache[i].mtime == 0) break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (i == FILE_CACHE_MAX) { |
|
|
|
|
i = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
srv->mtime_cache[i].mtime = last_mod; |
|
|
|
|
buffer_prepare_copy(srv->mtime_cache[i].str, 1024); |
|
|
|
|
tm = gmtime(&(srv->mtime_cache[i].mtime)); |
|
|
|
|
srv->mtime_cache[i].str->used = strftime(srv->mtime_cache[i].str->ptr,
|
|
|
|
|
srv->mtime_cache[i].str->size - 1, |
|
|
|
|
"%a, %d %b %Y %H:%M:%S GMT", tm); |
|
|
|
|
srv->mtime_cache[i].str->used++; |
|
|
|
|
|
|
|
|
|
return srv->mtime_cache[i].str; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
URIHANDLER_FUNC(mod_staticfile_subrequest) { |
|
|
|
|
plugin_data *p = p_d; |
|
|
|
|
size_t k; |
|
|
|
|
int s_len; |
|
|
|
|
buffer *mtime; |
|
|
|
|
stat_cache_entry *sce = NULL; |
|
|
|
|
buffer *mtime; |
|
|
|
|
data_string *ds; |
|
|
|
|
|
|
|
|
|
/* someone else has done a decision for us */ |
|
|
|
|
if (con->http_status != 0) return HANDLER_GO_ON; |
|
|
|
@ -398,8 +372,11 @@ URIHANDLER_FUNC(mod_staticfile_subrequest) {
|
|
|
|
|
|
|
|
|
|
/* ignore certain extensions */ |
|
|
|
|
for (k = 0; k < p->conf.exclude_ext->used; k++) { |
|
|
|
|
data_string *ds = (data_string *)p->conf.exclude_ext->data[k]; |
|
|
|
|
int ct_len = ds->value->used - 1; |
|
|
|
|
int ct_len; |
|
|
|
|
|
|
|
|
|
ds = (data_string *)p->conf.exclude_ext->data[k];
|
|
|
|
|
|
|
|
|
|
ct_len = ds->value->used - 1; |
|
|
|
|
|
|
|
|
|
if (ct_len > s_len) continue; |
|
|
|
|
|
|
|
|
@ -437,24 +414,34 @@ URIHANDLER_FUNC(mod_staticfile_subrequest) {
|
|
|
|
|
|
|
|
|
|
return HANDLER_FINISHED; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* mod_compress might set several data directly, don't overwrite them */ |
|
|
|
|
|
|
|
|
|
/* set response content-type */ |
|
|
|
|
|
|
|
|
|
if (buffer_is_empty(sce->content_type)) { |
|
|
|
|
response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("application/octet-stream")); |
|
|
|
|
} else { |
|
|
|
|
response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type)); |
|
|
|
|
/* set response content-type, if not set already */ |
|
|
|
|
|
|
|
|
|
if (NULL == array_get_element(con->response.headers, "Content-Type")) { |
|
|
|
|
if (buffer_is_empty(sce->content_type)) { |
|
|
|
|
response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("application/octet-stream")); |
|
|
|
|
} else { |
|
|
|
|
response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* generate e-tag */ |
|
|
|
|
etag_mutate(con->physical.etag, sce->etag); |
|
|
|
|
if (NULL == array_get_element(con->response.headers, "ETag")) { |
|
|
|
|
/* generate e-tag */ |
|
|
|
|
etag_mutate(con->physical.etag, sce->etag); |
|
|
|
|
|
|
|
|
|
response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag)); |
|
|
|
|
response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag)); |
|
|
|
|
} |
|
|
|
|
response_header_overwrite(srv, con, CONST_STR_LEN("Accept-Ranges"), CONST_STR_LEN("bytes")); |
|
|
|
|
|
|
|
|
|
/* prepare header */ |
|
|
|
|
mtime = strftime_cache_get(srv, sce->st.st_mtime); |
|
|
|
|
response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime)); |
|
|
|
|
if (NULL == (ds = (data_string *)array_get_element(con->response.headers, "Last-Modified"))) { |
|
|
|
|
mtime = strftime_cache_get(srv, sce->st.st_mtime); |
|
|
|
|
response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime)); |
|
|
|
|
} else { |
|
|
|
|
mtime = ds->value; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 14.26 If-None-Match |
|
|
|
|