uhttpd: retry parsing the CGI header until the buffer space is exhausted

SVN-Revision: 32662
This commit is contained in:
Jo-Philipp Wich 2012-07-11 09:59:05 +00:00
parent b94d9eb302
commit 0000ce2271
4 changed files with 23 additions and 11 deletions

View file

@ -8,7 +8,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=uhttpd PKG_NAME:=uhttpd
PKG_RELEASE:=38 PKG_RELEASE:=39
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
PKG_CONFIG_DEPENDS := \ PKG_CONFIG_DEPENDS := \

View file

@ -133,7 +133,7 @@ static void uh_cgi_shutdown(struct uh_cgi_state *state)
static bool uh_cgi_socket_cb(struct client *cl) static bool uh_cgi_socket_cb(struct client *cl)
{ {
int i, len, hdroff; int i, len, blen, hdroff;
char buf[UH_LIMIT_MSGHEAD]; char buf[UH_LIMIT_MSGHEAD];
struct uh_cgi_state *state = (struct uh_cgi_state *)cl->priv; 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 */ /* 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 */ /* we have not pushed out headers yet, parse input */
if (!state->header_sent) if (!state->header_sent)
{ {
/* try to parse header ... */ /* 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 */ /* write status */
ensure_out(uh_http_sendf(cl, NULL, ensure_out(uh_http_sendf(cl, NULL,
@ -229,18 +234,19 @@ static bool uh_cgi_socket_cb(struct client *cl)
state->header_sent = true; state->header_sent = true;
/* push out remaining head buffer */ /* push out remaining head buffer */
if (hdroff < len) if (hdroff < blen)
{ {
D("CGI: Child(%d) relaying %d rest bytes\n", 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, ensure_out(uh_http_send(cl, req,
&buf[hdroff], len - hdroff)); state->httpbuf.buf + hdroff,
blen - hdroff));
} }
} }
/* ... failed and head buffer exceeded */ /* ... failed and head buffer exceeded */
else else if (!state->httpbuf.len)
{ {
/* I would do this ... /* 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]); 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; state->content_length = cl->httpbuf.len;
/* find content length */ /* find content length */

View file

@ -28,7 +28,11 @@
struct uh_cgi_state { struct uh_cgi_state {
char httpbuf[UH_LIMIT_MSGHEAD]; struct {
char buf[UH_LIMIT_MSGHEAD];
char *ptr;
int len;
} httpbuf;
int content_length; int content_length;
bool header_sent; bool header_sent;
}; };

View file

@ -33,7 +33,6 @@
struct uh_lua_state { struct uh_lua_state {
char httpbuf[UH_LIMIT_MSGHEAD];
int content_length; int content_length;
bool data_sent; bool data_sent;
}; };