Hi
I just found out that my previous patch only works for POST data smaller
that hdr_buf. This patch should also work for larger POST data.
> I found a problem with httpd and POST data for cgi programs.
>
> get_line() is used to read the header. This function uses hdr_buf with
> hdr_ptr and hdr_cnt to keep track of the current position. For cgi
> programs cgi_io_loop_and_exit() is called to transfer the POST data to
> the cgi and the result back.
>
> The request variable Content-Length contains the length of the POST
> data. cgi_io_loop_and_exit() tries to send (hdr_cnt + post_len) bytes to
> the cgi. But at this point, the actual header is already read, so
> whatever is left in hdr_cnt ist actally not the header, but (part of)
> the POST data.
>
> In the following (simplified) example, assuming the whole request was
> read in one block, after reading the header, hdr_cnt is 10, and post_len
> is also 10. httpd will write the 10 bytes from hdr_ptr to the cgi (which
> is correct) and then wait for additional 10 bytes (post_len) from the
> network, which will never come, as they are already received. The cgi
> program won't receive EOF and, depending on the program, wait forever
> for more input.
>
> So the bytes transferred from hdr_cnt should be subtracted from
> post_len. I'm not sure whether it might be a legitimate reason for
> (hdr_cnt > post_len), but I included a check for this just in case.
>
> The patch is against SVN 20228.
>
> Regards
> Ralf Friedl
>
>
> POST /cgi-bin/test
> Content-Length: 10
>
> 1234567890
>
>
--- networking/httpd.c
+++ networking/httpd.c
@@ -1051,6 +1051,10 @@
* and send it to the peer. So please no SIGPIPEs! */
signal(SIGPIPE, SIG_IGN);
+ if (post_len >= hdr_cnt)
+ post_len -= hdr_cnt;
+ else
+ post_len = 0;
/* NB: breaking out of this loop jumps to log_and_exit() */
out_cnt = 0;
while (1) {
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox