mirror of
https://github.com/apache/httpd.git
synced 2025-11-06 16:49:32 +03:00
This time from the top, with three part harmony AND feeling...
Revert the read-while-caching and large-file-crash fixes for mod_disk_cache, ready to start again. Reverted: r450105 r450188 r462571 r462601 r462696 r467655 r467684 r468044 r468373 r468409 r470455 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@502365 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
24
CHANGES
24
CHANGES
@@ -61,15 +61,6 @@ Changes with Apache 2.3.0
|
|||||||
make sense and leads to a division by zero. PR 40576.
|
make sense and leads to a division by zero. PR 40576.
|
||||||
[Xuekun Hu <xuekun.hu gmail.com>]
|
[Xuekun Hu <xuekun.hu gmail.com>]
|
||||||
|
|
||||||
*) mod_cache: Pass the output filter stack through the store_body()
|
|
||||||
hook, giving each cache backend the ability to make a better
|
|
||||||
decision as to how it will allocate the tasks of writing to the
|
|
||||||
cache and writing to the network. Previously the write to the
|
|
||||||
cache task needed to be complete before the same brigade was
|
|
||||||
written to the network, and this caused timing and memory issues
|
|
||||||
on large cached files. This fix replaces the previous fix for this
|
|
||||||
PR below. PR39380 [Graham Leggett]
|
|
||||||
|
|
||||||
*) Fix issue which could cause error messages to be written to access logs
|
*) Fix issue which could cause error messages to be written to access logs
|
||||||
on Win32. PR 40476. [Tom Donovan <Tom.Donovan acm.org>]
|
on Win32. PR 40476. [Tom Donovan <Tom.Donovan acm.org>]
|
||||||
|
|
||||||
@@ -89,28 +80,13 @@ Changes with Apache 2.3.0
|
|||||||
|
|
||||||
*) mod_proxy_fcgi: Added win32 build. [Mladen Turk]
|
*) mod_proxy_fcgi: Added win32 build. [Mladen Turk]
|
||||||
|
|
||||||
*) mod_disk_cache: Implement read-while-caching.
|
|
||||||
[Niklas Edmundsson <nikke acc.umu.se>]
|
|
||||||
|
|
||||||
*) mod_disk_cache: NULL fd pointers when closing them, fix missing
|
|
||||||
close/flush, remove some unneccessary code duplication instead
|
|
||||||
of calling the right helper in replace_brigade_with_cache().
|
|
||||||
[Niklas Edmundsson <nikke acc.umu.se>]
|
|
||||||
|
|
||||||
*) sendfile_nonblocking() takes the _brigade_ as an argument, gets
|
*) sendfile_nonblocking() takes the _brigade_ as an argument, gets
|
||||||
the first bucket from the brigade, finds it not to be a FILE
|
the first bucket from the brigade, finds it not to be a FILE
|
||||||
bucket and barfs. The fix is to pass a bucket rather than a brigade.
|
bucket and barfs. The fix is to pass a bucket rather than a brigade.
|
||||||
[Niklas Edmundsson <nikke acc.umu.se>]
|
[Niklas Edmundsson <nikke acc.umu.se>]
|
||||||
|
|
||||||
*) mod_disk_cache: Do away with the write-to-file-then-move-in-place
|
|
||||||
mentality. [Niklas Edmundsson <nikke acc.umu.se>]
|
|
||||||
|
|
||||||
*) mod_rewrite: support rewritemap by SQL query [Nick Kew]
|
*) mod_rewrite: support rewritemap by SQL query [Nick Kew]
|
||||||
|
|
||||||
*) mod_disk_cache: Make caching of large files possible on 32bit machines
|
|
||||||
by determining whether the cached file should be copied on disk rather
|
|
||||||
than loaded into RAM. PR39380 [Niklas Edmundsson <nikke acc.umu.se>]
|
|
||||||
|
|
||||||
*) mod_proxy: Print the correct error message for erroneous configured
|
*) mod_proxy: Print the correct error message for erroneous configured
|
||||||
ProxyPass directives. PR 40439. [serai lans-tv.com]
|
ProxyPass directives. PR 40439. [serai lans-tv.com]
|
||||||
|
|
||||||
|
|||||||
16
modules/cache/mod_cache.c
vendored
16
modules/cache/mod_cache.c
vendored
@@ -366,7 +366,13 @@ static int cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
|
|||||||
/* pass the brigades into the cache, then pass them
|
/* pass the brigades into the cache, then pass them
|
||||||
* up the filter stack
|
* up the filter stack
|
||||||
*/
|
*/
|
||||||
return cache->provider->store_body(cache->handle, f, in);
|
rv = cache->provider->store_body(cache->handle, r, in);
|
||||||
|
if (rv != APR_SUCCESS) {
|
||||||
|
ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, r->server,
|
||||||
|
"cache: Cache provider's store_body failed!");
|
||||||
|
ap_remove_output_filter(f);
|
||||||
|
}
|
||||||
|
return ap_pass_brigade(f->next, in);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -823,8 +829,14 @@ static int cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
|
|||||||
return ap_pass_brigade(f->next, in);
|
return ap_pass_brigade(f->next, in);
|
||||||
}
|
}
|
||||||
|
|
||||||
return cache->provider->store_body(cache->handle, f, in);
|
rv = cache->provider->store_body(cache->handle, r, in);
|
||||||
|
if (rv != APR_SUCCESS) {
|
||||||
|
ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, r->server,
|
||||||
|
"cache: store_body failed");
|
||||||
|
ap_remove_output_filter(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ap_pass_brigade(f->next, in);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
2
modules/cache/mod_cache.h
vendored
2
modules/cache/mod_cache.h
vendored
@@ -210,7 +210,7 @@ struct cache_handle {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
int (*remove_entity) (cache_handle_t *h);
|
int (*remove_entity) (cache_handle_t *h);
|
||||||
apr_status_t (*store_headers)(cache_handle_t *h, request_rec *r, cache_info *i);
|
apr_status_t (*store_headers)(cache_handle_t *h, request_rec *r, cache_info *i);
|
||||||
apr_status_t (*store_body)(cache_handle_t *h, ap_filter_t *f, apr_bucket_brigade *b);
|
apr_status_t (*store_body)(cache_handle_t *h, request_rec *r, apr_bucket_brigade *b);
|
||||||
apr_status_t (*recall_headers) (cache_handle_t *h, request_rec *r);
|
apr_status_t (*recall_headers) (cache_handle_t *h, request_rec *r);
|
||||||
apr_status_t (*recall_body) (cache_handle_t *h, apr_pool_t *p, apr_bucket_brigade *bb);
|
apr_status_t (*recall_body) (cache_handle_t *h, apr_pool_t *p, apr_bucket_brigade *bb);
|
||||||
int (*create_entity) (cache_handle_t *h, request_rec *r,
|
int (*create_entity) (cache_handle_t *h, request_rec *r,
|
||||||
|
|||||||
1473
modules/cache/mod_disk_cache.c
vendored
1473
modules/cache/mod_disk_cache.c
vendored
File diff suppressed because it is too large
Load Diff
47
modules/cache/mod_disk_cache.h
vendored
47
modules/cache/mod_disk_cache.h
vendored
@@ -22,19 +22,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define VARY_FORMAT_VERSION 3
|
#define VARY_FORMAT_VERSION 3
|
||||||
#define DISK_FORMAT_VERSION_OLD 4
|
#define DISK_FORMAT_VERSION 4
|
||||||
#define DISK_FORMAT_VERSION 5
|
|
||||||
|
|
||||||
#define CACHE_HEADER_SUFFIX ".header"
|
#define CACHE_HEADER_SUFFIX ".header"
|
||||||
#define CACHE_DATA_SUFFIX ".data"
|
#define CACHE_DATA_SUFFIX ".data"
|
||||||
#define CACHE_VDIR_SUFFIX ".vary"
|
#define CACHE_VDIR_SUFFIX ".vary"
|
||||||
|
|
||||||
#define CACHE_BUF_SIZE 65536
|
|
||||||
|
|
||||||
/* How long to sleep before retrying while looping */
|
|
||||||
#define CACHE_LOOP_SLEEP 200000
|
|
||||||
|
|
||||||
|
|
||||||
#define AP_TEMPFILE_PREFIX "/"
|
#define AP_TEMPFILE_PREFIX "/"
|
||||||
#define AP_TEMPFILE_BASE "aptmp"
|
#define AP_TEMPFILE_BASE "aptmp"
|
||||||
#define AP_TEMPFILE_SUFFIX "XXXXXX"
|
#define AP_TEMPFILE_SUFFIX "XXXXXX"
|
||||||
@@ -42,10 +35,9 @@
|
|||||||
#define AP_TEMPFILE_NAMELEN strlen(AP_TEMPFILE_BASE AP_TEMPFILE_SUFFIX)
|
#define AP_TEMPFILE_NAMELEN strlen(AP_TEMPFILE_BASE AP_TEMPFILE_SUFFIX)
|
||||||
#define AP_TEMPFILE AP_TEMPFILE_PREFIX AP_TEMPFILE_BASE AP_TEMPFILE_SUFFIX
|
#define AP_TEMPFILE AP_TEMPFILE_PREFIX AP_TEMPFILE_BASE AP_TEMPFILE_SUFFIX
|
||||||
|
|
||||||
/* Indicates the format of the header struct stored on-disk. */
|
|
||||||
typedef apr_uint32_t disk_cache_format_t;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
/* Indicates the format of the header struct stored on-disk. */
|
||||||
|
apr_uint32_t format;
|
||||||
/* The HTTP status code returned for this response. */
|
/* The HTTP status code returned for this response. */
|
||||||
int status;
|
int status;
|
||||||
/* The size of the entity name that follows. */
|
/* The size of the entity name that follows. */
|
||||||
@@ -57,9 +49,6 @@ typedef struct {
|
|||||||
apr_time_t expire;
|
apr_time_t expire;
|
||||||
apr_time_t request_time;
|
apr_time_t request_time;
|
||||||
apr_time_t response_time;
|
apr_time_t response_time;
|
||||||
/* The body size forced to 64bit to not break when people go from non-LFS
|
|
||||||
* to LFS builds */
|
|
||||||
apr_int64_t file_size;
|
|
||||||
} disk_cache_info_t;
|
} disk_cache_info_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -75,19 +64,12 @@ typedef struct disk_cache_object {
|
|||||||
const char *hdrsfile; /* name of file where the hdrs will go */
|
const char *hdrsfile; /* name of file where the hdrs will go */
|
||||||
const char *hashfile; /* Computed hash key for this URI */
|
const char *hashfile; /* Computed hash key for this URI */
|
||||||
const char *name; /* Requested URI without vary bits - suitable for mortals. */
|
const char *name; /* Requested URI without vary bits - suitable for mortals. */
|
||||||
|
const char *key; /* On-disk prefix; URI with Vary bits (if present) */
|
||||||
apr_file_t *fd; /* data file */
|
apr_file_t *fd; /* data file */
|
||||||
apr_file_t *hfd; /* headers file */
|
apr_file_t *hfd; /* headers file */
|
||||||
apr_file_t *tfd; /* temporary file for data */
|
apr_file_t *tfd; /* temporary file for data */
|
||||||
apr_off_t file_size; /* File size of the cached data file */
|
apr_off_t file_size; /* File size of the cached data file */
|
||||||
apr_off_t initial_size; /* Initial file size reported by caller */
|
|
||||||
disk_cache_info_t disk_info; /* Header information. */
|
disk_cache_info_t disk_info; /* Header information. */
|
||||||
|
|
||||||
apr_interval_time_t updtimeout; /* Cache update timeout */
|
|
||||||
|
|
||||||
int skipstore; /* Set if we should skip storing stuff */
|
|
||||||
int store_body_called; /* Number of times store_body() has executed */
|
|
||||||
apr_bucket_brigade *tmpbb; /* Temporary bucket brigade. */
|
|
||||||
apr_status_t frv; /* Last known status of network write */
|
|
||||||
} disk_cache_object_t;
|
} disk_cache_object_t;
|
||||||
|
|
||||||
|
|
||||||
@@ -100,7 +82,6 @@ typedef struct disk_cache_object {
|
|||||||
#define DEFAULT_DIRLENGTH 2
|
#define DEFAULT_DIRLENGTH 2
|
||||||
#define DEFAULT_MIN_FILE_SIZE 1
|
#define DEFAULT_MIN_FILE_SIZE 1
|
||||||
#define DEFAULT_MAX_FILE_SIZE 1000000
|
#define DEFAULT_MAX_FILE_SIZE 1000000
|
||||||
#define DEFAULT_UPDATE_TIMEOUT apr_time_from_sec(10)
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char* cache_root;
|
const char* cache_root;
|
||||||
@@ -109,26 +90,6 @@ typedef struct {
|
|||||||
int dirlength; /* Length of subdirectory names */
|
int dirlength; /* Length of subdirectory names */
|
||||||
apr_off_t minfs; /* minimum file size for cached files */
|
apr_off_t minfs; /* minimum file size for cached files */
|
||||||
apr_off_t maxfs; /* maximum file size for cached files */
|
apr_off_t maxfs; /* maximum file size for cached files */
|
||||||
apr_interval_time_t updtimeout; /* Cache update timeout */
|
|
||||||
} disk_cache_conf;
|
} disk_cache_conf;
|
||||||
|
|
||||||
#define CACHE_ENODATA (APR_OS_START_USERERR+1)
|
|
||||||
#define CACHE_EDECLINED (APR_OS_START_USERERR+2)
|
|
||||||
#define CACHE_EEXIST (APR_OS_START_USERERR+3)
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct diskcache_bucket_data diskcache_bucket_data;
|
|
||||||
struct diskcache_bucket_data {
|
|
||||||
/* Number of buckets using this memory */
|
|
||||||
apr_bucket_refcount refcount;
|
|
||||||
apr_file_t *fd;
|
|
||||||
/* The pool into which any needed structures should
|
|
||||||
* be created while reading from this file bucket */
|
|
||||||
apr_pool_t *readpool;
|
|
||||||
/* Cache update timeout */
|
|
||||||
apr_interval_time_t updtimeout;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif /*MOD_DISK_CACHE_H*/
|
#endif /*MOD_DISK_CACHE_H*/
|
||||||
|
|||||||
40
modules/cache/mod_mem_cache.c
vendored
40
modules/cache/mod_mem_cache.c
vendored
@@ -71,7 +71,6 @@ typedef struct mem_cache_object {
|
|||||||
long total_refs; /**< total number of references this entry has had */
|
long total_refs; /**< total number of references this entry has had */
|
||||||
|
|
||||||
apr_uint32_t pos; /**< the position of this entry in the cache */
|
apr_uint32_t pos; /**< the position of this entry in the cache */
|
||||||
apr_status_t frv; /* last known status of writing to the output filter */
|
|
||||||
|
|
||||||
} mem_cache_object_t;
|
} mem_cache_object_t;
|
||||||
|
|
||||||
@@ -102,7 +101,7 @@ static mem_cache_conf *sconf;
|
|||||||
/* Forward declarations */
|
/* Forward declarations */
|
||||||
static int remove_entity(cache_handle_t *h);
|
static int remove_entity(cache_handle_t *h);
|
||||||
static apr_status_t store_headers(cache_handle_t *h, request_rec *r, cache_info *i);
|
static apr_status_t store_headers(cache_handle_t *h, request_rec *r, cache_info *i);
|
||||||
static apr_status_t store_body(cache_handle_t *h, ap_filter_t *f, apr_bucket_brigade *b);
|
static apr_status_t store_body(cache_handle_t *h, request_rec *r, apr_bucket_brigade *b);
|
||||||
static apr_status_t recall_headers(cache_handle_t *h, request_rec *r);
|
static apr_status_t recall_headers(cache_handle_t *h, request_rec *r);
|
||||||
static apr_status_t recall_body(cache_handle_t *h, apr_pool_t *p, apr_bucket_brigade *bb);
|
static apr_status_t recall_body(cache_handle_t *h, apr_pool_t *p, apr_bucket_brigade *bb);
|
||||||
|
|
||||||
@@ -621,10 +620,9 @@ static apr_status_t store_headers(cache_handle_t *h, request_rec *r, cache_info
|
|||||||
return APR_SUCCESS;
|
return APR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static apr_status_t store_body(cache_handle_t *h, ap_filter_t *f, apr_bucket_brigade *b)
|
static apr_status_t store_body(cache_handle_t *h, request_rec *r, apr_bucket_brigade *b)
|
||||||
{
|
{
|
||||||
apr_status_t rv;
|
apr_status_t rv;
|
||||||
request_rec *r = f->r;
|
|
||||||
cache_object_t *obj = h->cache_obj;
|
cache_object_t *obj = h->cache_obj;
|
||||||
cache_object_t *tobj = NULL;
|
cache_object_t *tobj = NULL;
|
||||||
mem_cache_object_t *mobj = (mem_cache_object_t*) obj->vobj;
|
mem_cache_object_t *mobj = (mem_cache_object_t*) obj->vobj;
|
||||||
@@ -669,9 +667,7 @@ static apr_status_t store_body(cache_handle_t *h, ap_filter_t *f, apr_bucket_bri
|
|||||||
rv = apr_file_open(&tmpfile, name, mobj->flags,
|
rv = apr_file_open(&tmpfile, name, mobj->flags,
|
||||||
APR_OS_DEFAULT, r->pool);
|
APR_OS_DEFAULT, r->pool);
|
||||||
if (rv != APR_SUCCESS) {
|
if (rv != APR_SUCCESS) {
|
||||||
ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
|
return rv;
|
||||||
"mem_cache: Failed to open file '%s' while attempting to cache the file descriptor.", name);
|
|
||||||
return ap_pass_brigade(f->next, b);
|
|
||||||
}
|
}
|
||||||
apr_file_inherit_unset(tmpfile);
|
apr_file_inherit_unset(tmpfile);
|
||||||
apr_os_file_get(&(mobj->fd), tmpfile);
|
apr_os_file_get(&(mobj->fd), tmpfile);
|
||||||
@@ -680,7 +676,7 @@ static apr_status_t store_body(cache_handle_t *h, ap_filter_t *f, apr_bucket_bri
|
|||||||
ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
|
ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
|
||||||
"mem_cache: Cached file: %s with key: %s", name, obj->key);
|
"mem_cache: Cached file: %s with key: %s", name, obj->key);
|
||||||
obj->complete = 1;
|
obj->complete = 1;
|
||||||
return ap_pass_brigade(f->next, b);
|
return APR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Content not suitable for fd caching. Cache in-memory instead. */
|
/* Content not suitable for fd caching. Cache in-memory instead. */
|
||||||
@@ -694,12 +690,7 @@ static apr_status_t store_body(cache_handle_t *h, ap_filter_t *f, apr_bucket_bri
|
|||||||
if (mobj->m == NULL) {
|
if (mobj->m == NULL) {
|
||||||
mobj->m = malloc(mobj->m_len);
|
mobj->m = malloc(mobj->m_len);
|
||||||
if (mobj->m == NULL) {
|
if (mobj->m == NULL) {
|
||||||
/* we didn't have space to cache it, fall back gracefully */
|
return APR_ENOMEM;
|
||||||
cleanup_cache_object(obj);
|
|
||||||
ap_remove_output_filter(f);
|
|
||||||
ap_log_error(APLOG_MARK, APLOG_ERR, APR_ENOMEM, r->server,
|
|
||||||
"mem_cache: Could not store body - not enough memory.");
|
|
||||||
return ap_pass_brigade(f->next, b);
|
|
||||||
}
|
}
|
||||||
obj->count = 0;
|
obj->count = 0;
|
||||||
}
|
}
|
||||||
@@ -720,12 +711,7 @@ static apr_status_t store_body(cache_handle_t *h, ap_filter_t *f, apr_bucket_bri
|
|||||||
* buffer */
|
* buffer */
|
||||||
mobj->m = realloc(mobj->m, obj->count);
|
mobj->m = realloc(mobj->m, obj->count);
|
||||||
if (!mobj->m) {
|
if (!mobj->m) {
|
||||||
/* we didn't have space to cache it, fall back gracefully */
|
return APR_ENOMEM;
|
||||||
cleanup_cache_object(obj);
|
|
||||||
ap_remove_output_filter(f);
|
|
||||||
ap_log_error(APLOG_MARK, APLOG_ERR, APR_ENOMEM, r->server,
|
|
||||||
"mem_cache: Could not store next bit of body - not enough memory.");
|
|
||||||
return ap_pass_brigade(f->next, b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now comes the crufty part... there is no way to tell the
|
/* Now comes the crufty part... there is no way to tell the
|
||||||
@@ -781,21 +767,12 @@ static apr_status_t store_body(cache_handle_t *h, ap_filter_t *f, apr_bucket_bri
|
|||||||
}
|
}
|
||||||
rv = apr_bucket_read(e, &s, &len, eblock);
|
rv = apr_bucket_read(e, &s, &len, eblock);
|
||||||
if (rv != APR_SUCCESS) {
|
if (rv != APR_SUCCESS) {
|
||||||
cleanup_cache_object(obj);
|
|
||||||
/* not being able to read the bucket is fatal,
|
|
||||||
* return this up the filter stack
|
|
||||||
*/
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
if (len) {
|
if (len) {
|
||||||
/* Check for buffer overflow */
|
/* Check for buffer overflow */
|
||||||
if ((obj->count + len) > mobj->m_len) {
|
if ((obj->count + len) > mobj->m_len) {
|
||||||
/* we didn't have space to cache it, fall back gracefully */
|
return APR_ENOMEM;
|
||||||
cleanup_cache_object(obj);
|
|
||||||
ap_remove_output_filter(f);
|
|
||||||
ap_log_error(APLOG_MARK, APLOG_ERR, APR_ENOMEM, r->server,
|
|
||||||
"mem_cache: Could not store body - buffer overflow.");
|
|
||||||
return ap_pass_brigade(f->next, b);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
memcpy(cur, s, len);
|
memcpy(cur, s, len);
|
||||||
@@ -808,9 +785,8 @@ static apr_status_t store_body(cache_handle_t *h, ap_filter_t *f, apr_bucket_bri
|
|||||||
*/
|
*/
|
||||||
AP_DEBUG_ASSERT(obj->count <= mobj->m_len);
|
AP_DEBUG_ASSERT(obj->count <= mobj->m_len);
|
||||||
}
|
}
|
||||||
return ap_pass_brigade(f->next, b);
|
return APR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration and start-up
|
* Configuration and start-up
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user