diff --git a/src/chunk.c b/src/chunk.c index fd431a22..df9f44c9 100644 --- a/src/chunk.c +++ b/src/chunk.c @@ -739,3 +739,38 @@ static void chunkqueue_remove_empty_chunks(chunkqueue *cq) { } } } + +int chunkqueue_open_file_chunk(server *srv, chunkqueue *cq) { + chunk* const c = cq->first; + off_t offset, toSend; + struct stat st; + + force_assert(NULL != c); + force_assert(FILE_CHUNK == c->type); + force_assert(c->offset >= 0 && c->offset <= c->file.length); + + offset = c->file.start + c->offset; + toSend = c->file.length - c->offset; + + if (-1 == c->file.fd) { + if (-1 == (c->file.fd = fdevent_open_cloexec(c->file.name->ptr, O_RDONLY, 0))) { + log_error_write(srv, __FILE__, __LINE__, "ssb", "open failed:", strerror(errno), c->file.name); + return -1; + } + } + + /*(skip file size checks if file is temp file created by lighttpd)*/ + if (c->file.is_temp) return 0; + + if (-1 == fstat(c->file.fd, &st)) { + log_error_write(srv, __FILE__, __LINE__, "ss", "fstat failed:", strerror(errno)); + return -1; + } + + if (offset > st.st_size || toSend > st.st_size || offset > st.st_size - toSend) { + log_error_write(srv, __FILE__, __LINE__, "sb", "file shrunk:", c->file.name); + return -1; + } + + return 0; +} diff --git a/src/chunk.h b/src/chunk.h index 651da561..22808edc 100644 --- a/src/chunk.h +++ b/src/chunk.h @@ -87,6 +87,8 @@ void chunkqueue_steal(chunkqueue *dest, chunkqueue *src, off_t len); struct server; int chunkqueue_steal_with_tempfiles(struct server *srv, chunkqueue *dest, chunkqueue *src, off_t len); +int chunkqueue_open_file_chunk(struct server *srv, chunkqueue *cq); + off_t chunkqueue_length(chunkqueue *cq); void chunkqueue_free(chunkqueue *cq); void chunkqueue_reset(chunkqueue *cq); diff --git a/src/mod_cgi.c b/src/mod_cgi.c index 32d2a47f..1ffe27c7 100644 --- a/src/mod_cgi.c +++ b/src/mod_cgi.c @@ -909,7 +909,7 @@ static ssize_t cgi_write_file_chunk_mmap(server *srv, connection *con, int fd, c return 0; } - /*(simplified from network_write_no_mmap.c:network_open_file_chunk())*/ + /*(simplified from chunk.c:chunkqueue_open_file_chunk())*/ UNUSED(con); if (-1 == c->file.fd) { if (-1 == (c->file.fd = fdevent_open_cloexec(c->file.name->ptr, O_RDONLY, 0))) { diff --git a/src/network_darwin_sendfile.c b/src/network_darwin_sendfile.c index 11b1f069..9b4ba6cf 100644 --- a/src/network_darwin_sendfile.c +++ b/src/network_darwin_sendfile.c @@ -4,7 +4,6 @@ #if defined(USE_DARWIN_SENDFILE) -#include "network.h" #include "log.h" #include @@ -33,7 +32,7 @@ int network_write_file_chunk_sendfile(server *srv, connection *con, int fd, chun return 0; } - if (0 != network_open_file_chunk(srv, con, cq)) return -1; + if (0 != chunkqueue_open_file_chunk(srv, cq)) return -1; /* Darwin sendfile() */ written = toSend; diff --git a/src/network_freebsd_sendfile.c b/src/network_freebsd_sendfile.c index f6cfd126..11da4e85 100644 --- a/src/network_freebsd_sendfile.c +++ b/src/network_freebsd_sendfile.c @@ -4,7 +4,6 @@ #if defined(USE_FREEBSD_SENDFILE) -#include "network.h" #include "log.h" #include @@ -33,7 +32,7 @@ int network_write_file_chunk_sendfile(server *srv, connection *con, int fd, chun return 0; } - if (0 != network_open_file_chunk(srv, con, cq)) return -1; + if (0 != chunkqueue_open_file_chunk(srv, cq)) return -1; /* FreeBSD sendfile() */ if (-1 == (r = sendfile(c->file.fd, fd, offset, toSend, NULL, &written, 0))) { diff --git a/src/network_linux_sendfile.c b/src/network_linux_sendfile.c index 0540dd41..a15ef252 100644 --- a/src/network_linux_sendfile.c +++ b/src/network_linux_sendfile.c @@ -4,7 +4,6 @@ #if defined(USE_LINUX_SENDFILE) -#include "network.h" #include "log.h" #include @@ -31,7 +30,7 @@ int network_write_file_chunk_sendfile(server *srv, connection *con, int fd, chun return 0; } - if (0 != network_open_file_chunk(srv, con, cq)) return -1; + if (0 != chunkqueue_open_file_chunk(srv, cq)) return -1; if (-1 == (r = sendfile(fd, c->file.fd, &offset, toSend))) { switch (errno) { diff --git a/src/network_openssl.c b/src/network_openssl.c index 9a9138ed..049fc647 100644 --- a/src/network_openssl.c +++ b/src/network_openssl.c @@ -29,6 +29,7 @@ static int load_next_chunk(server *srv, connection *con, chunkqueue *cq, off_t m * -> we expect a 64k block to 'leak' in valgrind * */ static char *local_send_buffer = NULL; + UNUSED(con); force_assert(NULL != c); @@ -53,7 +54,7 @@ static int load_next_chunk(server *srv, connection *con, chunkqueue *cq, off_t m force_assert(NULL != local_send_buffer); } - if (0 != network_open_file_chunk(srv, con, cq)) return -1; + if (0 != chunkqueue_open_file_chunk(srv, cq)) return -1; { off_t offset, toSend; diff --git a/src/network_solaris_sendfilev.c b/src/network_solaris_sendfilev.c index 697d43f4..d0e5007a 100644 --- a/src/network_solaris_sendfilev.c +++ b/src/network_solaris_sendfilev.c @@ -4,7 +4,6 @@ #if defined(USE_SOLARIS_SENDFILEV) -#include "network.h" #include "log.h" #include @@ -38,7 +37,7 @@ int network_write_file_chunk_sendfile(server *srv, connection *con, int fd, chun return 0; } - if (0 != network_open_file_chunk(srv, con, cq)) return -1; + if (0 != chunkqueue_open_file_chunk(srv, cq)) return -1; fvec.sfv_fd = c->file.fd; fvec.sfv_flag = 0; diff --git a/src/network_write_mmap.c b/src/network_write_mmap.c index 83add942..d46c1adf 100644 --- a/src/network_write_mmap.c +++ b/src/network_write_mmap.c @@ -2,7 +2,6 @@ #include "network_backends.h" -#include "network.h" #include "log.h" #include "sys-mmap.h" @@ -47,6 +46,7 @@ int network_write_file_chunk_mmap(server *srv, connection *con, int fd, chunkque ssize_t r; size_t mmap_offset, mmap_avail; const char *data; + UNUSED(con); force_assert(NULL != c); force_assert(FILE_CHUNK == c->type); @@ -62,7 +62,7 @@ int network_write_file_chunk_mmap(server *srv, connection *con, int fd, chunkque return 0; } - if (0 != network_open_file_chunk(srv, con, cq)) return -1; + if (0 != chunkqueue_open_file_chunk(srv, cq)) return -1; /* setup SIGBUS handler, but don't activate sigbus_jmp_valid yet */ if (0 != sigsetjmp(sigbus_jmp, 1)) { diff --git a/src/network_write_no_mmap.c b/src/network_write_no_mmap.c index 80426548..2268cc93 100644 --- a/src/network_write_no_mmap.c +++ b/src/network_write_no_mmap.c @@ -1,64 +1,18 @@ #include "first.h" #include "network_backends.h" - -#include "network.h" -#include "fdevent.h" #include "log.h" -#include "stat_cache.h" - #include "sys-socket.h" -#include -#include - -#include -#include #include - #include #include -int network_open_file_chunk(server *srv, connection *con, chunkqueue *cq) { - chunk* const c = cq->first; - off_t offset, toSend; - struct stat st; - UNUSED(con); - - force_assert(NULL != c); - force_assert(FILE_CHUNK == c->type); - force_assert(c->offset >= 0 && c->offset <= c->file.length); - - offset = c->file.start + c->offset; - toSend = c->file.length - c->offset; - - if (-1 == c->file.fd) { - if (-1 == (c->file.fd = fdevent_open_cloexec(c->file.name->ptr, O_RDONLY, 0))) { - log_error_write(srv, __FILE__, __LINE__, "ssb", "open failed:", strerror(errno), c->file.name); - return -1; - } - } - - /*(skip file size checks if file is temp file created by lighttpd)*/ - if (c->file.is_temp) return 0; - - if (-1 == fstat(c->file.fd, &st)) { - log_error_write(srv, __FILE__, __LINE__, "ss", "fstat failed:", strerror(errno)); - return -1; - } - - if (offset > st.st_size || toSend > st.st_size || offset > st.st_size - toSend) { - log_error_write(srv, __FILE__, __LINE__, "sb", "file shrunk:", c->file.name); - return -1; - } - - return 0; -} - int network_write_file_chunk_no_mmap(server *srv, connection *con, int fd, chunkqueue *cq, off_t *p_max_bytes) { chunk* const c = cq->first; off_t offset, toSend; ssize_t r; + UNUSED(con); force_assert(NULL != c); force_assert(FILE_CHUNK == c->type); @@ -74,7 +28,7 @@ int network_write_file_chunk_no_mmap(server *srv, connection *con, int fd, chunk return 0; } - if (0 != network_open_file_chunk(srv, con, cq)) return -1; + if (0 != chunkqueue_open_file_chunk(srv, cq)) return -1; buffer_string_prepare_copy(srv->tmp_buf, toSend);