#include "apr_mmap.h"
#include "apr_strings.h"
-module MODULE_VAR_EXPORT file_cache_module;
-static int once_through = 0;
+module AP_MODULE_DECLARE_DATA file_cache_module;
typedef struct {
#if APR_HAS_SENDFILE
return sconf;
}
+#if APR_HAS_SENDFILE
static apr_status_t open_file(apr_file_t **file, const char *filename, int flg1, int flg2,
apr_pool_t *p)
{
return rv;
}
+#endif /* APR_HAS_SENDFILE */
static apr_status_t cleanup_file_cache(void *sconfv)
{
/* canonicalize the file name? */
/* os_canonical... */
- if (apr_stat(&tmp.finfo, filename, cmd->temp_pool) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, errno, cmd->server,
- "file_cache: unable to stat(%s), skipping", filename);
+ if ((rc = apr_stat(&tmp.finfo, filename, cmd->temp_pool)) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, rc, cmd->server,
+ "mod_file_cache: unable to stat(%s), skipping", filename);
return NULL;
}
if (tmp.finfo.filetype != APR_REG) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, errno, cmd->server,
- "file_cache: %s isn't a regular file, skipping", filename);
+ ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, cmd->server,
+ "mod_file_cache: %s isn't a regular file, skipping", filename);
return NULL;
}
rc = open_file(&fd, filename, APR_READ, APR_OS_DEFAULT, cmd->pool);
if (rc != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_WARNING, rc, cmd->server,
- "file_cache: unable to open(%s, O_RDONLY), skipping", filename);
+ "mod_file_cache: unable to open(%s, O_RDONLY), skipping", filename);
return NULL;
}
tmp.file = fd;
return NULL;
#else
/* Sendfile not supported on this platform */
- ap_log_error(APLOG_MARK, APLOG_WARNING, errno, cmd->server,
+ ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, cmd->server,
"mod_file_cache: unable to cache file: %s. Sendfile is not supported on this OS", filename);
return NULL;
#endif
a_file *new_file;
a_file tmp;
apr_file_t *fd = NULL;
+ apr_status_t rc;
const char *fspec;
fspec = ap_os_case_canonical_filename(cmd->pool, filename);
- if (apr_stat(&tmp.finfo, fspec, cmd->temp_pool) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, errno, cmd->server,
+ if ((rc = apr_stat(&tmp.finfo, fspec, cmd->temp_pool)) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, rc, cmd->server,
"mod_file_cache: unable to stat(%s), skipping", filename);
return NULL;
}
if ((tmp.finfo.filetype) != APR_REG) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, errno, cmd->server,
+ ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, cmd->server,
"mod_file_cache: %s isn't a regular file, skipping", filename);
return NULL;
}
- if (apr_open(&fd, fspec, APR_READ, APR_OS_DEFAULT, cmd->temp_pool)
- != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, errno, cmd->server,
- "mod_file_cache: unable to open(%s, O_RDONLY), skipping", filename);
+ if ((rc = apr_open(&fd, fspec, APR_READ, APR_OS_DEFAULT,
+ cmd->temp_pool)) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, rc, cmd->server,
+ "mod_file_cache: unable to open %s, skipping",
+ filename);
return NULL;
}
- if (apr_mmap_create(&tmp.mm, fd, 0, tmp.finfo.size, cmd->pool) != APR_SUCCESS) {
- int save_errno = errno;
+ if ((rc = apr_mmap_create(&tmp.mm, fd, 0, tmp.finfo.size, APR_MMAP_READ, cmd->pool)) != APR_SUCCESS) {
apr_close(fd);
- errno = save_errno;
- ap_log_error(APLOG_MARK, APLOG_WARNING, errno, cmd->server,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, rc, cmd->server,
"mod_file_cache: unable to mmap %s, skipping", filename);
return NULL;
}
a_file *elts;
int nelts;
- once_through++;
-
/* sort the elements of the main_server, by filename */
sconf = ap_get_module_config(s->module_config, &file_cache_module);
elts = (a_file *)sconf->files->elts;
}
-static int mmap_handler(request_rec *r, a_file *file, int rangestatus)
+static int mmap_handler(request_rec *r, a_file *file)
{
#if APR_HAS_MMAP
- if (!rangestatus) {
- ap_send_mmap (file->mm, r, 0, file->finfo.size);
- }
- else {
- apr_size_t length;
- apr_off_t offset;
- while (ap_each_byterange(r, &offset, &length)) {
- ap_send_mmap(file->mm, r, offset, length);
- }
- }
+ ap_send_mmap (file->mm, r, 0, file->finfo.size);
#endif
return OK;
}
-static int sendfile_handler(request_rec *r, a_file *file, int rangestatus)
+static int sendfile_handler(request_rec *r, a_file *file)
{
#if APR_HAS_SENDFILE
- apr_size_t length, nbytes;
- apr_off_t offset = 0;
+ apr_size_t nbytes;
apr_status_t rv = APR_EINIT;
+ apr_off_t offset = 0;
- if (!rangestatus) {
- rv = ap_send_fd(file->file, r, 0, file->finfo.size, &nbytes);
- }
- else {
- while (ap_each_byterange(r, &offset, &length)) {
- if ((rv = ap_send_fd(file->file, r, offset, length, &nbytes)) != APR_SUCCESS)
- break;
- }
+ rv = apr_seek(file->file, APR_SET, &offset);
+ if (rv != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+ "seek failed");
+ return HTTP_INTERNAL_SERVER_ERROR;
}
+
+ rv = ap_send_fd(file->file, r, 0, file->finfo.size, &nbytes);
if (rv != APR_SUCCESS) {
/* ap_send_fd will log the error */
return HTTP_INTERNAL_SERVER_ERROR;
static int file_cache_handler(request_rec *r)
{
a_file *match;
- int rangestatus, errstatus;
+ int errstatus;
int rc = OK;
+ if (strcmp(r->handler, "*.*")) {
+ return DECLINED;
+ }
+
/* we don't handle anything but GET */
if (r->method_number != M_GET) return DECLINED;
ap_update_mtime(r, match->finfo.mtime);
ap_set_last_modified(r);
ap_set_etag(r);
- if (((errstatus = ap_meets_conditions(r)) != OK)
- || (errstatus = ap_set_content_length (r, match->finfo.size))) {
- return errstatus;
+ if ((errstatus = ap_meets_conditions(r)) != OK) {
+ return errstatus;
}
+ ap_set_content_length(r, match->finfo.size);
- rangestatus = ap_set_byterange(r);
ap_send_http_header(r);
/* Call appropriate handler */
if (!r->header_only) {
if (match->is_mmapped == TRUE)
- rc = mmap_handler(r, match, rangestatus);
+ rc = mmap_handler(r, match);
else
- rc = sendfile_handler(r, match, rangestatus);
+ rc = sendfile_handler(r, match);
}
return rc;
static command_rec file_cache_cmds[] =
{
AP_INIT_ITERATE("cachefile", cachefile, NULL, RSRC_CONF,
- "A space seperated list of files to add to the file handle cache at config time"),
+ "A space separated list of files to add to the file handle cache at config time"),
AP_INIT_ITERATE("mmapfile", mmapfile, NULL, RSRC_CONF,
- "A space seperated list of files to mmap at config time"),
+ "A space separated list of files to mmap at config time"),
{NULL}
};
static void register_hooks(void)
{
+ ap_hook_handler(file_cache_handler, NULL, NULL, AP_HOOK_MIDDLE);
ap_hook_post_config(file_cache_post_config, NULL, NULL, AP_HOOK_MIDDLE);
ap_hook_translate_name(file_cache_xlat, NULL, NULL, AP_HOOK_MIDDLE);
/* This trick doesn't work apparently because the translate hooks
}
-static const handler_rec file_cache_handlers[] =
-{
- { "*/*", file_cache_handler },
- { NULL }
-};
-
-module MODULE_VAR_EXPORT file_cache_module =
+module AP_MODULE_DECLARE_DATA file_cache_module =
{
STANDARD20_MODULE_STUFF,
NULL, /* create per-directory config structure */
create_server_config, /* create per-server config structure */
NULL, /* merge per-server config structures */
file_cache_cmds, /* command handlers */
- file_cache_handlers, /* handlers */
register_hooks /* register hooks */
};