httpd: read cgi output with full_read, not safe_read

(avoids mangling of HTTP headers)
This commit is contained in:
Denis Vlasenko 2007-01-03 23:02:18 +00:00
parent a8951cbc34
commit a773af3b1d

View File

@ -91,10 +91,8 @@
* *
*/ */
#include "busybox.h" #include "busybox.h"
static const char httpdVersion[] = "busybox httpd/1.35 6-Oct-2004"; static const char httpdVersion[] = "busybox httpd/1.35 6-Oct-2004";
static const char default_path_httpd_conf[] = "/etc"; static const char default_path_httpd_conf[] = "/etc";
static const char httpd_conf[] = "httpd.conf"; static const char httpd_conf[] = "httpd.conf";
@ -1065,7 +1063,7 @@ static int sendCgi(const char *url,
* It should not be decoded in any fashion. This variable * It should not be decoded in any fashion. This variable
* should always be set when there is query information, * should always be set when there is query information,
* regardless of command line decoding. */ * regardless of command line decoding. */
/* (Older versions of bbox seemed to do some decoding) */ /* (Older versions of bbox seem to do some decoding) */
setenv1("QUERY_STRING", config->query); setenv1("QUERY_STRING", config->query);
setenv1("SERVER_SOFTWARE", httpdVersion); setenv1("SERVER_SOFTWARE", httpdVersion);
putenv("SERVER_PROTOCOL=HTTP/1.0"); putenv("SERVER_PROTOCOL=HTTP/1.0");
@ -1097,7 +1095,7 @@ static int sendCgi(const char *url,
goto error_execing_cgi; goto error_execing_cgi;
*script = '\0'; *script = '\0';
if (chdir(realpath_buff) == 0) { if (chdir(realpath_buff) == 0) {
// now run the program. If it fails, // Now run the program. If it fails,
// use _exit() so no destructors // use _exit() so no destructors
// get called and make a mess. // get called and make a mess.
#if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR
@ -1210,21 +1208,22 @@ static int sendCgi(const char *url,
#endif #endif
/* There is something to read */ /* There is something to read */
count = safe_read(inFd, rbuf, PIPESIZE); /* NB: was safe_read. If it *has to be* safe_read, */
/* please explain why in this comment... */
count = full_read(inFd, rbuf, PIPESIZE);
if (count == 0) if (count == 0)
break; /* closed */ break; /* closed */
if (count > 0) { if (count > 0) {
if (firstLine) { if (firstLine) {
/* full_read (above) avoids
* "chopped up into small chunks" syndrome here */
rbuf[count] = 0; rbuf[count] = 0;
/* check to see if the user script added headers */ /* check to see if the user script added headers */
if (strncmp(rbuf, "HTTP/1.0 200 OK\r\n", 4) != 0) { if (strncmp(rbuf, "HTTP/1.0 200 OK\r\n", 4) != 0) {
/* there is no "HTTP", do it ourself */
full_write(s, "HTTP/1.0 200 OK\r\n", 17); full_write(s, "HTTP/1.0 200 OK\r\n", 17);
} } /* hmm, maybe 'else if'? */
/* Sometimes CGI is writing to pipe in small chunks if (!strstr(rbuf, "ontent-")) {
* and we don't see Content-type (because the read
* is too short) and we emit bogus "text/plain"!
* Is it a bug or CGI *has to* write it in one piece? */
if (strstr(rbuf, "ontent-") == 0) {
full_write(s, "Content-type: text/plain\r\n\r\n", 28); full_write(s, "Content-type: text/plain\r\n\r\n", 28);
} }
firstLine = 0; firstLine = 0;