diff options
author | Jo-Philipp Wich <jow@openwrt.org> | 2012-07-11 09:59:05 +0000 |
---|---|---|
committer | Jo-Philipp Wich <jow@openwrt.org> | 2012-07-11 09:59:05 +0000 |
commit | 0000ce2271077c3d233d8498f7963ad78502a1f2 (patch) | |
tree | fc835f87cc9cc43cf5f8a28643c446f3e40bf729 /package/uhttpd/src | |
parent | b94d9eb3026ca7ebc47a7e529943cb904a782070 (diff) | |
download | master-31e0f0ae-0000ce2271077c3d233d8498f7963ad78502a1f2.tar.gz master-31e0f0ae-0000ce2271077c3d233d8498f7963ad78502a1f2.tar.bz2 master-31e0f0ae-0000ce2271077c3d233d8498f7963ad78502a1f2.zip |
uhttpd: retry parsing the CGI header until the buffer space is exhausted
SVN-Revision: 32662
Diffstat (limited to 'package/uhttpd/src')
-rw-r--r-- | package/uhttpd/src/uhttpd-cgi.c | 25 | ||||
-rw-r--r-- | package/uhttpd/src/uhttpd-cgi.h | 6 | ||||
-rw-r--r-- | package/uhttpd/src/uhttpd-lua.h | 1 |
3 files changed, 22 insertions, 10 deletions
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; }; |