From 0000ce2271077c3d233d8498f7963ad78502a1f2 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Wed, 11 Jul 2012 09:59:05 +0000 Subject: [PATCH] uhttpd: retry parsing the CGI header until the buffer space is exhausted SVN-Revision: 32662 --- package/uhttpd/Makefile | 2 +- package/uhttpd/src/uhttpd-cgi.c | 25 +++++++++++++++++-------- package/uhttpd/src/uhttpd-cgi.h | 6 +++++- package/uhttpd/src/uhttpd-lua.h | 1 - 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/package/uhttpd/Makefile b/package/uhttpd/Makefile index 89ca4b69e8..cefd30bb8c 100644 --- a/package/uhttpd/Makefile +++ b/package/uhttpd/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=uhttpd -PKG_RELEASE:=38 +PKG_RELEASE:=39 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) PKG_CONFIG_DEPENDS := \ diff --git a/package/uhttpd/src/uhttpd-cgi.c b/package/uhttpd/src/uhttpd-cgi.c index e527922624..b46ebf2bdd 100644 --- a/package/uhttpd/src/uhttpd-cgi.c +++ b/package/uhttpd/src/uhttpd-cgi.c @@ -133,7 +133,7 @@ static void uh_cgi_shutdown(struct uh_cgi_state *state) static bool uh_cgi_socket_cb(struct client *cl) { - int i, len, hdroff; + int i, len, blen, hdroff; char buf[UH_LIMIT_MSGHEAD]; struct uh_cgi_state *state = (struct uh_cgi_state *)cl->priv; @@ -184,15 +184,20 @@ static bool uh_cgi_socket_cb(struct client *cl) } /* try to read data from child */ - while ((len = uh_raw_recv(cl->rpipe.fd, buf, sizeof(buf), -1)) > 0) + while ((len = uh_raw_recv(cl->rpipe.fd, buf, state->header_sent + ? sizeof(buf) : state->httpbuf.len, -1)) > 0) { /* we have not pushed out headers yet, parse input */ if (!state->header_sent) { /* try to parse header ... */ - memcpy(state->httpbuf, buf, len); + memcpy(state->httpbuf.ptr, buf, len); + state->httpbuf.len -= len; + state->httpbuf.ptr += len; - if (uh_cgi_header_parse(res, state->httpbuf, len, &hdroff)) + blen = state->httpbuf.ptr - state->httpbuf.buf; + + if (uh_cgi_header_parse(res, state->httpbuf.buf, blen, &hdroff)) { /* write status */ ensure_out(uh_http_sendf(cl, NULL, @@ -229,18 +234,19 @@ static bool uh_cgi_socket_cb(struct client *cl) state->header_sent = true; /* push out remaining head buffer */ - if (hdroff < len) + if (hdroff < blen) { D("CGI: Child(%d) relaying %d rest bytes\n", - cl->proc.pid, len - hdroff); + cl->proc.pid, blen - hdroff); ensure_out(uh_http_send(cl, req, - &buf[hdroff], len - hdroff)); + state->httpbuf.buf + hdroff, + blen - hdroff)); } } /* ... failed and head buffer exceeded */ - else + else if (!state->httpbuf.len) { /* I would do this ... * @@ -536,6 +542,9 @@ bool uh_cgi_request(struct client *cl, struct path_info *pi, D("CGI: Child(%d) created: rfd(%d) wfd(%d)\n", child, rfd[0], wfd[1]); + state->httpbuf.ptr = state->httpbuf.buf; + state->httpbuf.len = sizeof(state->httpbuf.buf); + state->content_length = cl->httpbuf.len; /* find content length */ diff --git a/package/uhttpd/src/uhttpd-cgi.h b/package/uhttpd/src/uhttpd-cgi.h index fffcc5d353..c7094da424 100644 --- a/package/uhttpd/src/uhttpd-cgi.h +++ b/package/uhttpd/src/uhttpd-cgi.h @@ -28,7 +28,11 @@ struct uh_cgi_state { - char httpbuf[UH_LIMIT_MSGHEAD]; + struct { + char buf[UH_LIMIT_MSGHEAD]; + char *ptr; + int len; + } httpbuf; int content_length; bool header_sent; }; diff --git a/package/uhttpd/src/uhttpd-lua.h b/package/uhttpd/src/uhttpd-lua.h index ae573a3cec..780d845d87 100644 --- a/package/uhttpd/src/uhttpd-lua.h +++ b/package/uhttpd/src/uhttpd-lua.h @@ -33,7 +33,6 @@ struct uh_lua_state { - char httpbuf[UH_LIMIT_MSGHEAD]; int content_length; bool data_sent; }; -- 2.25.1