[multiple] open target file earlier in some cases
open target file earlier in some cases to validate readability
This commit is contained in:
parent
470a692211
commit
44156bbe81
|
@ -15,6 +15,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
|
@ -468,6 +469,17 @@ void http_response_send_file (server *srv, connection *con, buffer *path) {
|
|||
return;
|
||||
}
|
||||
|
||||
/*(Note: O_NOFOLLOW affects only the final path segment,
|
||||
* the target file, not any intermediate symlinks along path)*/
|
||||
const int fd = fdevent_open_cloexec(path->ptr, con->conf.follow_symlink, O_RDONLY, 0);
|
||||
if (fd < 0) {
|
||||
con->http_status = (errno == ENOENT) ? 404 : 403;
|
||||
if (con->conf.log_request_handling) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sbs", "file open failed:", path, strerror(errno));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* mod_compress might set several data directly, don't overwrite them */
|
||||
|
||||
/* set response content-type, if not set already */
|
||||
|
@ -510,6 +522,7 @@ void http_response_send_file (server *srv, connection *con, buffer *path) {
|
|||
}
|
||||
|
||||
if (HANDLER_FINISHED == http_response_handle_cachable(srv, con, mtime)) {
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -557,6 +570,7 @@ void http_response_send_file (server *srv, connection *con, buffer *path) {
|
|||
if (0 == http_response_parse_range(srv, con, path, sce, range->ptr+6)) {
|
||||
con->http_status = 206;
|
||||
}
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -566,12 +580,10 @@ void http_response_send_file (server *srv, connection *con, buffer *path) {
|
|||
/* we add it here for all requests
|
||||
* the HEAD request will drop it afterwards again
|
||||
*/
|
||||
if (0 == sce->st.st_size || 0 == http_chunk_append_file(srv, con, path)) {
|
||||
con->http_status = 200;
|
||||
con->file_finished = 1;
|
||||
} else {
|
||||
con->http_status = 403;
|
||||
}
|
||||
|
||||
http_chunk_append_file_fd(srv, con, path, fd, sce->st.st_size);
|
||||
con->http_status = 200;
|
||||
con->file_finished = 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -467,14 +467,13 @@ static void mod_compress_note_ratio(server *srv, connection *con, off_t in, off_
|
|||
UNUSED(srv);
|
||||
}
|
||||
|
||||
static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, buffer *fn, stat_cache_entry *sce, int type) {
|
||||
int ifd, ofd;
|
||||
static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, int ifd, buffer *fn, stat_cache_entry *sce, int type) {
|
||||
int 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;
|
||||
stat_cache_entry *sce_ofn;
|
||||
ssize_t r;
|
||||
|
||||
|
@ -550,18 +549,6 @@ static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, bu
|
|||
#if 0
|
||||
log_error_write(srv, __FILE__, __LINE__, "bs", p->ofn, "compress-cache miss");
|
||||
#endif
|
||||
if (-1 == (ifd = fdevent_open_cloexec(filename, con->conf.follow_symlink, O_RDONLY, 0))) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sbss", "opening plain-file", fn, "failed", strerror(errno));
|
||||
|
||||
close(ofd);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
#ifdef USE_MMAP
|
||||
if (MAP_FAILED != (start = mmap(NULL, sce->st.st_size, PROT_READ, MAP_SHARED, ifd, 0))
|
||||
|
@ -663,8 +650,7 @@ static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, bu
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int deflate_file_to_buffer(server *srv, connection *con, plugin_data *p, buffer *fn, stat_cache_entry *sce, int type) {
|
||||
int ifd;
|
||||
static int deflate_file_to_buffer(server *srv, connection *con, plugin_data *p, int ifd, buffer *fn, stat_cache_entry *sce, int type) {
|
||||
int ret = -1;
|
||||
#ifdef USE_MMAP
|
||||
volatile int mapped = 0;/* quiet warning: might be clobbered by 'longjmp' */
|
||||
|
@ -685,9 +671,9 @@ static int deflate_file_to_buffer(server *srv, connection *con, plugin_data *p,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (-1 == (ifd = fdevent_open_cloexec(fn->ptr, con->conf.follow_symlink, O_RDONLY, 0))) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sbss", "opening plain-file", fn, "failed", strerror(errno));
|
||||
|
||||
if (-1 == ifd) {
|
||||
/* not called; call exists to de-optimize and avoid "clobbered by 'longjmp'" compiler warning */
|
||||
log_error_write(srv, __FILE__, __LINE__, "s", "");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -942,6 +928,13 @@ PHYSICALPATH_FUNC(mod_compress_physical) {
|
|||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
const int fd = fdevent_open_cloexec(con->physical.path->ptr, con->conf.follow_symlink, O_RDONLY, 0);
|
||||
if (fd < 0) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sbss",
|
||||
"opening plain-file", con->physical.path, "failed", strerror(errno));
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
mtime = strftime_cache_get(srv, sce->st.st_mtime);
|
||||
|
||||
/* try matching original etag of uncompressed version */
|
||||
|
@ -951,6 +944,7 @@ PHYSICALPATH_FUNC(mod_compress_physical) {
|
|||
http_header_response_set(con, HTTP_HEADER_CONTENT_TYPE, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type));
|
||||
http_header_response_set(con, HTTP_HEADER_LAST_MODIFIED, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime));
|
||||
http_header_response_set(con, HTTP_HEADER_ETAG, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag));
|
||||
close(fd);
|
||||
return HANDLER_FINISHED;
|
||||
}
|
||||
}
|
||||
|
@ -989,17 +983,23 @@ PHYSICALPATH_FUNC(mod_compress_physical) {
|
|||
if (use_etag) {
|
||||
http_header_response_set(con, HTTP_HEADER_ETAG, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag));
|
||||
}
|
||||
close(fd);
|
||||
return HANDLER_FINISHED;
|
||||
}
|
||||
|
||||
/* deflate it */
|
||||
if (use_etag && !buffer_string_is_empty(p->conf.compress_cache_dir)) {
|
||||
if (0 != deflate_file_to_file(srv, con, p, con->physical.path, sce, compression_type))
|
||||
if (0 != deflate_file_to_file(srv, con, p, fd, con->physical.path, sce, compression_type)) {
|
||||
close(fd);
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
} else {
|
||||
if (0 != deflate_file_to_buffer(srv, con, p, con->physical.path, sce, compression_type))
|
||||
if (0 != deflate_file_to_buffer(srv, con, p, fd, con->physical.path, sce, compression_type)) {
|
||||
close(fd);
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
http_header_response_set(con, HTTP_HEADER_CONTENT_ENCODING, CONST_STR_LEN("Content-Encoding"), compression_name, strlen(compression_name));
|
||||
http_header_response_set(con, HTTP_HEADER_LAST_MODIFIED, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime));
|
||||
if (use_etag) {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "log.h"
|
||||
#include "buffer.h"
|
||||
#include "http_header.h"
|
||||
#include "stat_cache.h"
|
||||
|
||||
#include "plugin.h"
|
||||
|
||||
|
@ -584,7 +585,13 @@ static int process_ssi_stmt(server *srv, connection *con, handler_ctx *p, const
|
|||
}
|
||||
}
|
||||
|
||||
if (0 == stat(p->stat_fn->ptr, &stb)) {
|
||||
if (!con->conf.follow_symlink
|
||||
&& 0 != stat_cache_path_contains_symlink(srv, p->stat_fn)) {
|
||||
break;
|
||||
}
|
||||
|
||||
int fd = stat_cache_open_rdonly_fstat(p->stat_fn, &stb, con->conf.follow_symlink);
|
||||
if (fd > 0) {
|
||||
time_t t = stb.st_mtime;
|
||||
|
||||
switch (ssicmd) {
|
||||
|
@ -619,7 +626,8 @@ static int process_ssi_stmt(server *srv, connection *con, handler_ctx *p, const
|
|||
|
||||
if (file_path || 0 == p->conf.ssi_recursion_max) {
|
||||
/* don't process if #include file="..." is used */
|
||||
chunkqueue_append_file(con->write_queue, p->stat_fn, 0, stb.st_size);
|
||||
chunkqueue_append_file_fd(con->write_queue, p->stat_fn, fd, 0, stb.st_size);
|
||||
fd = -1;
|
||||
} else {
|
||||
buffer *upsave, *ppsave, *prpsave;
|
||||
|
||||
|
@ -649,6 +657,9 @@ static int process_ssi_stmt(server *srv, connection *con, handler_ctx *p, const
|
|||
|
||||
con->uri.path = con->physical.rel_path = buffer_init_buffer(srv->tmp_buf);
|
||||
|
||||
close(fd);
|
||||
fd = -1;
|
||||
|
||||
/*(ignore return value; muddle along as best we can if error occurs)*/
|
||||
++p->ssi_recursion_depth;
|
||||
mod_ssi_process_file(srv, con, p, &stb);
|
||||
|
@ -665,6 +676,8 @@ static int process_ssi_stmt(server *srv, connection *con, handler_ctx *p, const
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
if (fd > 0) close(fd);
|
||||
} else {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sbs",
|
||||
"ssi: stating failed ",
|
||||
|
|
Loading…
Reference in New Issue