Browse Source

[multiple] reduce initial buffer sz if large POST (fixes #2922)

reduce initial buffer size if large POST to backend stored in temp files

regression in lighttpd 1.4.52

(thx rgenoud)

x-ref:
  "[regression] lighttpd gets killed after uploading a big file"
  https://redmine.lighttpd.net/issues/2922
personal/stbuehler/fix-fdevent
Glenn Strauss 3 years ago
parent
commit
a1b527e473
  1. 12
      src/chunk.c
  2. 1
      src/chunk.h
  3. 18
      src/mod_fastcgi.c
  4. 3
      src/mod_proxy.c
  5. 3
      src/mod_scgi.c

12
src/chunk.c

@ -325,6 +325,18 @@ void chunkqueue_append_mem(chunkqueue *cq, const char * mem, size_t len) {
}
void chunkqueue_append_mem_min(chunkqueue *cq, const char * mem, size_t len) {
chunk *c;
if (len < chunk_buf_sz && chunkqueue_append_mem_extend_chunk(cq, mem, len))
return;
c = chunk_init(len+1);
chunkqueue_append_chunk(cq, c);
cq->bytes_in += len;
buffer_copy_string_len(c->mem, mem, len);
}
void chunkqueue_append_chunkqueue(chunkqueue *cq, chunkqueue *src) {
if (src == NULL || NULL == src->first) return;

1
src/chunk.h

@ -60,6 +60,7 @@ void chunkqueue_set_tempdirs_default (array *tempdirs, unsigned int upload_temp_
void chunkqueue_append_file(chunkqueue *cq, buffer *fn, off_t offset, off_t len); /* copies "fn" */
void chunkqueue_append_file_fd(chunkqueue *cq, buffer *fn, int fd, off_t offset, off_t len); /* copies "fn" */
void chunkqueue_append_mem(chunkqueue *cq, const char *mem, size_t len); /* copies memory */
void chunkqueue_append_mem_min(chunkqueue *cq, const char * mem, size_t len); /* copies memory */
void chunkqueue_append_buffer(chunkqueue *cq, buffer *mem); /* may reset "mem" */
void chunkqueue_append_chunkqueue(chunkqueue *cq, chunkqueue *src);

18
src/mod_fastcgi.c

@ -172,17 +172,12 @@ static handler_t fcgi_stdin_append(server *srv, handler_ctx *hctx) {
off_t offset, weWant;
const off_t req_cqlen = req_cq->bytes_in - req_cq->bytes_out;
int request_id = hctx->request_id;
UNUSED(srv);
/* something to send ? */
for (offset = 0; offset != req_cqlen; offset += weWant) {
weWant = req_cqlen - offset > FCGI_MAX_LENGTH ? FCGI_MAX_LENGTH : req_cqlen - offset;
/* we announce toWrite octets
* now take all request_content chunks available
* */
fcgi_header(&(header), FCGI_STDIN, request_id, weWant, 0);
chunkqueue_append_mem(hctx->wb, (const char *)&header, sizeof(header));
if (-1 != hctx->wb_reqlen) {
if (hctx->wb_reqlen >= 0) {
hctx->wb_reqlen += sizeof(header);
@ -191,10 +186,10 @@ static handler_t fcgi_stdin_append(server *srv, handler_ctx *hctx) {
}
}
if (hctx->conf.debug > 10) {
log_error_write(srv, __FILE__, __LINE__, "soso", "tosend:", offset, "/", req_cqlen);
}
fcgi_header(&(header), FCGI_STDIN, request_id, weWant, 0);
hctx->wb->first->type == MEM_CHUNK /* else FILE_CHUNK for temp file */
? chunkqueue_append_mem(hctx->wb, (const char *)&header, sizeof(header))
: chunkqueue_append_mem_min(hctx->wb, (const char *)&header, sizeof(header));
chunkqueue_steal(hctx->wb, req_cq, weWant);
/*(hctx->wb_reqlen already includes content_length)*/
}
@ -227,7 +222,8 @@ static handler_t fcgi_create_env(server *srv, handler_ctx *hctx) {
host->strip_request_uri
};
buffer * const b = chunkqueue_prepend_buffer_open_sz(hctx->wb, (size_t)(con->read_queue->bytes_out - hctx->wb->bytes_in));
size_t rsz = (size_t)(con->read_queue->bytes_out - hctx->wb->bytes_in);
buffer * const b = chunkqueue_prepend_buffer_open_sz(hctx->wb, rsz < 65536 ? rsz : con->header_len);
/* send FCGI_BEGIN_REQUEST */

3
src/mod_proxy.c

@ -715,7 +715,8 @@ static handler_t proxy_create_env(server *srv, gw_handler_ctx *gwhctx) {
|| NULL != hctx->conf.header.hosts_request);
const int upgrade = hctx->conf.header.upgrade
&& (NULL != http_header_request_get(con, HTTP_HEADER_UPGRADE, CONST_STR_LEN("Upgrade")));
buffer * const b = chunkqueue_prepend_buffer_open_sz(hctx->gw.wb, (size_t)(con->read_queue->bytes_out - hctx->gw.wb->bytes_in));
size_t rsz = (size_t)(con->read_queue->bytes_out - hctx->gw.wb->bytes_in);
buffer * const b = chunkqueue_prepend_buffer_open_sz(hctx->gw.wb, rsz < 65536 ? rsz : con->header_len);
/* build header */

3
src/mod_scgi.c

@ -163,7 +163,8 @@ static handler_t scgi_create_env(server *srv, handler_ctx *hctx) {
? scgi_env_add_scgi
: scgi_env_add_uwsgi;
size_t offset;
buffer * const b = chunkqueue_prepend_buffer_open_sz(hctx->wb, (size_t)(con->read_queue->bytes_out - hctx->wb->bytes_in));
size_t rsz = (size_t)(con->read_queue->bytes_out - hctx->wb->bytes_in);
buffer * const b = chunkqueue_prepend_buffer_open_sz(hctx->wb, rsz < 65536 ? rsz : con->header_len);
/* save space for 9 digits (plus ':'), though incoming HTTP request
* currently limited to 64k (65535, so 5 chars) */

Loading…
Cancel
Save