|
|
|
@ -36,7 +36,22 @@
|
|
|
|
|
# include <bzlib.h> |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined HAVE_SYS_MMAN_H && defined HAVE_MMAP && defined ENABLE_MMAP |
|
|
|
|
#define USE_MMAP |
|
|
|
|
|
|
|
|
|
#include "sys-mmap.h" |
|
|
|
|
#include <setjmp.h> |
|
|
|
|
#include <signal.h> |
|
|
|
|
|
|
|
|
|
static volatile int sigbus_jmp_valid; |
|
|
|
|
static sigjmp_buf sigbus_jmp; |
|
|
|
|
|
|
|
|
|
static void sigbus_handler(int sig) { |
|
|
|
|
UNUSED(sig); |
|
|
|
|
if (sigbus_jmp_valid) siglongjmp(sigbus_jmp, 1); |
|
|
|
|
log_failed_assert(__FILE__, __LINE__, "SIGBUS"); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/* request: accept-encoding */ |
|
|
|
|
#define HTTP_ACCEPT_ENCODING_IDENTITY BV(0) |
|
|
|
@ -420,6 +435,9 @@ static int deflate_file_to_buffer_bzip2(server *srv, connection *con, plugin_dat
|
|
|
|
|
static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, buffer *fn, stat_cache_entry *sce, int type) { |
|
|
|
|
int ifd, ofd; |
|
|
|
|
int ret; |
|
|
|
|
#ifdef USE_MMAP |
|
|
|
|
volatile int mapped = 0;/* quiet warning: might be clobbered by 'longjmp' */ |
|
|
|
|
#endif |
|
|
|
|
void *start; |
|
|
|
|
const char *filename = fn->ptr; |
|
|
|
|
ssize_t r; |
|
|
|
@ -500,22 +518,30 @@ static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, bu
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef USE_MMAP |
|
|
|
|
if (MAP_FAILED == (start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0))) { |
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sbss", "mmaping", fn, "failed", strerror(errno)); |
|
|
|
|
|
|
|
|
|
close(ofd); |
|
|
|
|
close(ifd); |
|
|
|
|
if (MAP_FAILED != (start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0))) { |
|
|
|
|
mapped = 1; |
|
|
|
|
signal(SIGBUS, sigbus_handler); |
|
|
|
|
sigbus_jmp_valid = 1; |
|
|
|
|
if (0 != sigsetjmp(sigbus_jmp, 1)) { |
|
|
|
|
sigbus_jmp_valid = 0; |
|
|
|
|
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sbd", "SIGBUS in mmap:", |
|
|
|
|
fn, ifd); |
|
|
|
|
|
|
|
|
|
munmap(start, sce->st.st_size); |
|
|
|
|
close(ofd); |
|
|
|
|
close(ifd); |
|
|
|
|
|
|
|
|
|
/* Remove the incomplete cache file, so that later hits aren't served from it */ |
|
|
|
|
if (-1 == unlink(p->ofn->ptr)) { |
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sbss", "unlinking incomplete cachefile", p->ofn, "failed:", strerror(errno)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Remove the incomplete cache file, so that later hits aren't served from it */ |
|
|
|
|
if (-1 == unlink(p->ofn->ptr)) { |
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sbss", "unlinking incomplete cachefile", p->ofn, "failed:", strerror(errno)); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
#else |
|
|
|
|
start = malloc(sce->st.st_size); |
|
|
|
|
if (NULL == start || sce->st.st_size != read(ifd, start, sce->st.st_size)) { |
|
|
|
|
} else |
|
|
|
|
#endif /* FIXME: might attempt to read very large file completely into memory; see compress.max-filesize config option */ |
|
|
|
|
if (NULL == (start = malloc(sce->st.st_size)) || sce->st.st_size != read(ifd, start, sce->st.st_size)) { |
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sbss", "reading", fn, "failed", strerror(errno)); |
|
|
|
|
|
|
|
|
|
close(ofd); |
|
|
|
@ -529,7 +555,6 @@ static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, bu
|
|
|
|
|
|
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
ret = -1; |
|
|
|
|
switch(type) { |
|
|
|
@ -562,10 +587,12 @@ static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, bu
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef USE_MMAP |
|
|
|
|
munmap(start, sce->st.st_size); |
|
|
|
|
#else |
|
|
|
|
free(start); |
|
|
|
|
if (mapped) { |
|
|
|
|
sigbus_jmp_valid = 0; |
|
|
|
|
munmap(start, sce->st.st_size); |
|
|
|
|
} else |
|
|
|
|
#endif |
|
|
|
|
free(start); |
|
|
|
|
|
|
|
|
|
close(ofd); |
|
|
|
|
close(ifd); |
|
|
|
@ -587,6 +614,9 @@ static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, bu
|
|
|
|
|
static int deflate_file_to_buffer(server *srv, connection *con, plugin_data *p, buffer *fn, stat_cache_entry *sce, int type) { |
|
|
|
|
int ifd; |
|
|
|
|
int ret = -1; |
|
|
|
|
#ifdef USE_MMAP |
|
|
|
|
volatile int mapped = 0;/* quiet warning: might be clobbered by 'longjmp' */ |
|
|
|
|
#endif |
|
|
|
|
void *start; |
|
|
|
|
|
|
|
|
|
/* overflow */ |
|
|
|
@ -607,22 +637,29 @@ static int deflate_file_to_buffer(server *srv, connection *con, plugin_data *p,
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef USE_MMAP |
|
|
|
|
if (MAP_FAILED == (start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0))) { |
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sbss", "mmaping", fn, "failed", strerror(errno)); |
|
|
|
|
|
|
|
|
|
close(ifd); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
#else |
|
|
|
|
start = malloc(sce->st.st_size); |
|
|
|
|
if (NULL == start || sce->st.st_size != read(ifd, start, sce->st.st_size)) { |
|
|
|
|
if (MAP_FAILED != (start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0))) { |
|
|
|
|
mapped = 1; |
|
|
|
|
signal(SIGBUS, sigbus_handler); |
|
|
|
|
sigbus_jmp_valid = 1; |
|
|
|
|
if (0 != sigsetjmp(sigbus_jmp, 1)) { |
|
|
|
|
sigbus_jmp_valid = 0; |
|
|
|
|
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sbd", "SIGBUS in mmap:", |
|
|
|
|
fn, ifd); |
|
|
|
|
|
|
|
|
|
munmap(start, sce->st.st_size); |
|
|
|
|
close(ifd); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
} else |
|
|
|
|
#endif /* FIXME: might attempt to read very large file completely into memory; see compress.max-filesize config option */ |
|
|
|
|
if (NULL == (start = malloc(sce->st.st_size)) || sce->st.st_size != read(ifd, start, sce->st.st_size)) { |
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sbss", "reading", fn, "failed", strerror(errno)); |
|
|
|
|
|
|
|
|
|
close(ifd); |
|
|
|
|
free(start); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
switch(type) { |
|
|
|
|
#ifdef USE_ZLIB |
|
|
|
@ -646,10 +683,13 @@ static int deflate_file_to_buffer(server *srv, connection *con, plugin_data *p,
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef USE_MMAP |
|
|
|
|
munmap(start, sce->st.st_size); |
|
|
|
|
#else |
|
|
|
|
free(start); |
|
|
|
|
if (mapped) { |
|
|
|
|
sigbus_jmp_valid = 0; |
|
|
|
|
munmap(start, sce->st.st_size); |
|
|
|
|
} else |
|
|
|
|
#endif |
|
|
|
|
free(start); |
|
|
|
|
|
|
|
|
|
close(ifd); |
|
|
|
|
|
|
|
|
|
if (ret != 0) return -1; |
|
|
|
|