diff options
Diffstat (limited to 'modules/cache/mod_cache_disk.c')
-rw-r--r-- | modules/cache/mod_cache_disk.c | 170 |
1 files changed, 98 insertions, 72 deletions
diff --git a/modules/cache/mod_cache_disk.c b/modules/cache/mod_cache_disk.c index 8427e8fd..2b50aef9 100644 --- a/modules/cache/mod_cache_disk.c +++ b/modules/cache/mod_cache_disk.c @@ -80,7 +80,7 @@ static char *header_file(apr_pool_t *p, disk_cache_conf *conf, } if (dobj->prefix) { - return apr_pstrcat(p, dobj->prefix, CACHE_VDIR_SUFFIX, "/", + return apr_pstrcat(p, dobj->prefix, CACHE_VDIR_SUFFIX "/", dobj->hashfile, CACHE_HEADER_SUFFIX, NULL); } else { @@ -98,7 +98,7 @@ static char *data_file(apr_pool_t *p, disk_cache_conf *conf, } if (dobj->prefix) { - return apr_pstrcat(p, dobj->prefix, CACHE_VDIR_SUFFIX, "/", + return apr_pstrcat(p, dobj->prefix, CACHE_VDIR_SUFFIX "/", dobj->hashfile, CACHE_DATA_SUFFIX, NULL); } else { @@ -385,6 +385,7 @@ static int create_entity(cache_handle_t *h, request_rec *r, const char *key, apr dobj->root_len = conf->cache_root_len; apr_pool_create(&pool, r->pool); + apr_pool_tag(pool, "mod_cache (create_entity)"); file_cache_create(conf, &dobj->hdrs, pool); file_cache_create(conf, &dobj->vary, pool); @@ -511,6 +512,7 @@ static int open_entity(cache_handle_t *h, request_rec *r, const char *key) dobj->name = key; apr_pool_create(&pool, r->pool); + apr_pool_tag(pool, "mod_cache (open_entity)"); file_cache_create(conf, &dobj->hdrs, pool); file_cache_create(conf, &dobj->vary, pool); @@ -841,7 +843,7 @@ static apr_status_t read_table(cache_handle_t *handle, request_rec *r, } *l++ = '\0'; - while (*l && apr_isspace(*l)) { + while (apr_isspace(*l)) { ++l; } @@ -940,6 +942,10 @@ static apr_status_t store_headers(cache_handle_t *h, request_rec *r, cache_info dobj->headers_in = ap_cache_cacheable_headers_in(r); } + if (r->header_only && r->status != HTTP_NOT_MODIFIED) { + dobj->disk_info.header_only = 1; + } + return APR_SUCCESS; } @@ -1188,49 +1194,51 @@ static apr_status_t store_body(cache_handle_t *h, request_rec *r, continue; } - /* Attempt to create the data file at the last possible moment, if - * the body is empty, we don't write a file at all, and save an inode. - */ - if (!dobj->data.tempfd) { - apr_finfo_t finfo; - rv = apr_file_mktemp(&dobj->data.tempfd, dobj->data.tempfile, - APR_CREATE | APR_WRITE | APR_BINARY | - APR_BUFFERED | APR_EXCL, dobj->data.pool); + if (!dobj->disk_info.header_only) { + + /* Attempt to create the data file at the last possible moment, if + * the body is empty, we don't write a file at all, and save an inode. + */ + if (!dobj->data.tempfd) { + apr_finfo_t finfo; + rv = apr_file_mktemp(&dobj->data.tempfd, dobj->data.tempfile, + APR_CREATE | APR_WRITE | APR_BINARY | APR_BUFFERED + | APR_EXCL, dobj->data.pool); + if (rv != APR_SUCCESS) { + apr_pool_destroy(dobj->data.pool); + return rv; + } + dobj->file_size = 0; + rv = apr_file_info_get(&finfo, APR_FINFO_IDENT, + dobj->data.tempfd); + if (rv != APR_SUCCESS) { + apr_pool_destroy(dobj->data.pool); + return rv; + } + dobj->disk_info.device = finfo.device; + dobj->disk_info.inode = finfo.inode; + dobj->disk_info.has_body = 1; + } + + /* write to the cache, leave if we fail */ + rv = apr_file_write_full(dobj->data.tempfd, str, length, &written); if (rv != APR_SUCCESS) { + ap_log_rerror( + APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00731) "Error when writing cache file for URL %s", h->cache_obj->key); + /* Remove the intermediate cache file and return non-APR_SUCCESS */ apr_pool_destroy(dobj->data.pool); return rv; } - dobj->file_size = 0; - rv = apr_file_info_get(&finfo, APR_FINFO_IDENT, - dobj->data.tempfd); - if (rv != APR_SUCCESS) { + dobj->file_size += written; + if (dobj->file_size > dconf->maxfs) { + ap_log_rerror( + APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00732) "URL %s failed the size check " + "(%" APR_OFF_T_FMT ">%" APR_OFF_T_FMT ")", h->cache_obj->key, dobj->file_size, dconf->maxfs); + /* Remove the intermediate cache file and return non-APR_SUCCESS */ apr_pool_destroy(dobj->data.pool); - return rv; + return APR_EGENERAL; } - dobj->disk_info.device = finfo.device; - dobj->disk_info.inode = finfo.inode; - dobj->disk_info.has_body = 1; - } - /* write to the cache, leave if we fail */ - rv = apr_file_write_full(dobj->data.tempfd, str, length, &written); - if (rv != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00731) - "Error when writing cache file for URL %s", - h->cache_obj->key); - /* Remove the intermediate cache file and return non-APR_SUCCESS */ - apr_pool_destroy(dobj->data.pool); - return rv; - } - dobj->file_size += written; - if (dobj->file_size > dconf->maxfs) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00732) - "URL %s failed the size check " - "(%" APR_OFF_T_FMT ">%" APR_OFF_T_FMT ")", - h->cache_obj->key, dobj->file_size, dconf->maxfs); - /* Remove the intermediate cache file and return non-APR_SUCCESS */ - apr_pool_destroy(dobj->data.pool); - return APR_EGENERAL; } /* have we reached the limit of how much we're prepared to write in one @@ -1256,43 +1264,44 @@ static apr_status_t store_body(cache_handle_t *h, request_rec *r, if (seen_eos) { const char *cl_header = apr_table_get(r->headers_out, "Content-Length"); - if (dobj->data.tempfd) { - rv = apr_file_close(dobj->data.tempfd); - if (rv != APR_SUCCESS) { - /* Buffered write failed, abandon attempt to write */ - apr_pool_destroy(dobj->data.pool); - return rv; + if (!dobj->disk_info.header_only) { + + if (dobj->data.tempfd) { + rv = apr_file_close(dobj->data.tempfd); + if (rv != APR_SUCCESS) { + /* Buffered write failed, abandon attempt to write */ + apr_pool_destroy(dobj->data.pool); + return rv; + } } - } - if (r->connection->aborted || r->no_cache) { - ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00733) - "Discarding body for URL %s " - "because connection has been aborted.", - h->cache_obj->key); - /* Remove the intermediate cache file and return non-APR_SUCCESS */ - apr_pool_destroy(dobj->data.pool); - return APR_EGENERAL; - } - if (dobj->file_size < dconf->minfs) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00734) - "URL %s failed the size check " - "(%" APR_OFF_T_FMT "<%" APR_OFF_T_FMT ")", - h->cache_obj->key, dobj->file_size, dconf->minfs); - /* Remove the intermediate cache file and return non-APR_SUCCESS */ - apr_pool_destroy(dobj->data.pool); - return APR_EGENERAL; - } - if (cl_header) { - apr_int64_t cl = apr_atoi64(cl_header); - if ((errno == 0) && (dobj->file_size != cl)) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00735) - "URL %s didn't receive complete response, not caching", - h->cache_obj->key); + if (r->connection->aborted || r->no_cache) { + ap_log_rerror( + APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00733) "Discarding body for URL %s " + "because connection has been aborted.", h->cache_obj->key); /* Remove the intermediate cache file and return non-APR_SUCCESS */ apr_pool_destroy(dobj->data.pool); return APR_EGENERAL; } + if (dobj->file_size < dconf->minfs) { + ap_log_rerror( + APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00734) "URL %s failed the size check " + "(%" APR_OFF_T_FMT "<%" APR_OFF_T_FMT ")", h->cache_obj->key, dobj->file_size, dconf->minfs); + /* Remove the intermediate cache file and return non-APR_SUCCESS */ + apr_pool_destroy(dobj->data.pool); + return APR_EGENERAL; + } + if (cl_header) { + apr_int64_t cl = apr_atoi64(cl_header); + if ((errno == 0) && (dobj->file_size != cl)) { + ap_log_rerror( + APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00735) "URL %s didn't receive complete response, not caching", h->cache_obj->key); + /* Remove the intermediate cache file and return non-APR_SUCCESS */ + apr_pool_destroy(dobj->data.pool); + return APR_EGENERAL; + } + } + } /* All checks were fine, we're good to go when the commit comes */ @@ -1319,7 +1328,12 @@ static apr_status_t commit_entity(cache_handle_t *h, request_rec *r) rv = file_cache_el_final(conf, &dobj->vary, r); } if (APR_SUCCESS == rv) { - rv = file_cache_el_final(conf, &dobj->data, r); + if (!dobj->disk_info.header_only) { + rv = file_cache_el_final(conf, &dobj->data, r); + } + else if (dobj->data.file){ + rv = apr_file_remove(dobj->data.file, dobj->data.pool); + } } /* remove the cached items completely on any failure */ @@ -1342,7 +1356,17 @@ static apr_status_t commit_entity(cache_handle_t *h, request_rec *r) static apr_status_t invalidate_entity(cache_handle_t *h, request_rec *r) { - return APR_ENOTIMPL; + apr_status_t rv; + + rv = recall_headers(h, r); + if (rv != APR_SUCCESS) { + return rv; + } + + /* mark the entity as invalidated */ + h->cache_obj->info.control.invalidated = 1; + + return commit_entity(h, r); } static void *create_dir_config(apr_pool_t *p, char *dummy) @@ -1447,6 +1471,7 @@ static const char { return "CacheMinFileSize argument must be a non-negative integer representing the min size of a file to cache in bytes."; } + dconf->minfs_set = 1; return NULL; } @@ -1460,6 +1485,7 @@ static const char { return "CacheMaxFileSize argument must be a non-negative integer representing the max size of a file to cache in bytes."; } + dconf->maxfs_set = 1; return NULL; } |