summaryrefslogtreecommitdiff
path: root/src/http_chunk.c
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2019-05-12 18:31:43 -0400
committerGlenn Strauss <gstrauss@gluelogic.com>2019-05-13 21:01:57 -0400
commita86ea83b5a20eb75bc86a66f6feeb7f3c1520719 (patch)
tree8e0d277ea6053cd1b4093bb085a4028e9bdfde04 /src/http_chunk.c
parent8ae06467481273ab912d92aa083109b31b18d1b7 (diff)
downloadlighttpd-git-a86ea83b5a20eb75bc86a66f6feeb7f3c1520719.tar.gz
[core] chunkqueue perf: read small files into mem
Diffstat (limited to 'src/http_chunk.c')
-rw-r--r--src/http_chunk.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/src/http_chunk.c b/src/http_chunk.c
index 302e94b3..e973d6e0 100644
--- a/src/http_chunk.c
+++ b/src/http_chunk.c
@@ -43,6 +43,36 @@ static int http_chunk_append_file_open_fstat(server *srv, connection *con, buffe
return stat_cache_open_rdonly_fstat(fn, st, con->conf.follow_symlink);
}
+static int http_chunk_append_read_fd_range(server *srv, connection *con, buffer *fn, int fd, off_t offset, off_t len) {
+ /* note: this routine should not be used for range requests
+ * unless the total size of ranges requested is small */
+ /* note: future: could read into existing MEM_CHUNK in cq->last if
+ * there is sufficient space, but would need to adjust for existing
+ * offset in for cq->bytes_in in chunkqueue_append_buffer_commit() */
+ UNUSED(fn);
+
+ if (con->response.send_chunked) {
+ http_chunk_append_len(srv, con, (uintmax_t)len);
+ }
+
+ if (0 != offset && -1 == lseek(fd, offset, SEEK_SET)) return -1;
+ chunkqueue * const cq = con->write_queue;
+ buffer * const b = chunkqueue_append_buffer_open_sz(cq, len+2);
+ ssize_t rd;
+ offset = 0;
+ do {
+ rd = read(fd, b->ptr+offset, len-offset);
+ } while ((rd > 0 && (offset += rd, len -= rd)) || errno == EINTR);
+ buffer_commit(b, offset);
+
+ if (con->response.send_chunked) {
+ buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
+ }
+
+ chunkqueue_append_buffer_commit(cq);
+ return (rd >= 0) ? 0 : -1;
+}
+
static void http_chunk_append_file_fd_range(server *srv, connection *con, buffer *fn, int fd, off_t offset, off_t len) {
chunkqueue *cq = con->write_queue;
@@ -85,11 +115,16 @@ int http_chunk_append_file(server *srv, connection *con, buffer *fn) {
return 0;
}
-void http_chunk_append_file_fd(server *srv, connection *con, buffer *fn, int fd, off_t sz) {
- if (0 != sz) {
+int http_chunk_append_file_fd(server *srv, connection *con, buffer *fn, int fd, off_t sz) {
+ if (sz > 32768) {
http_chunk_append_file_fd_range(srv, con, fn, fd, 0, sz);
+ return 0;
} else {
+ int rc = (0 != sz) /*(read small files into memory)*/
+ ? http_chunk_append_read_fd_range(srv, con, fn, fd, 0, sz)
+ : 0;
close(fd);
+ return rc;
}
}