mirror of
https://github.com/sheumann/hush.git
synced 2024-10-27 23:26:30 +00:00
httpd: stop adding our own "Content-type:" to CGI output
This commit is contained in:
parent
db6a5c3f9e
commit
6998142998
@ -93,6 +93,11 @@
|
|||||||
|
|
||||||
#include "busybox.h"
|
#include "busybox.h"
|
||||||
|
|
||||||
|
/* amount of buffering in a pipe */
|
||||||
|
#ifndef PIPE_BUF
|
||||||
|
# define PIPE_BUF 4096
|
||||||
|
#endif
|
||||||
|
|
||||||
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";
|
||||||
@ -106,10 +111,7 @@ static const char home[] = "./";
|
|||||||
// is checked rigorously
|
// is checked rigorously
|
||||||
|
|
||||||
//#define DEBUG 1
|
//#define DEBUG 1
|
||||||
|
#define DEBUG 0
|
||||||
#ifndef DEBUG
|
|
||||||
# define DEBUG 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAX_MEMORY_BUFF 8192 /* IO buffer */
|
#define MAX_MEMORY_BUFF 8192 /* IO buffer */
|
||||||
|
|
||||||
@ -885,8 +887,8 @@ static int sendHeaders(HttpResponseNum responseNum)
|
|||||||
/* emit the current date */
|
/* emit the current date */
|
||||||
strftime(timeStr, sizeof(timeStr), RFC1123FMT, gmtime(&timer));
|
strftime(timeStr, sizeof(timeStr), RFC1123FMT, gmtime(&timer));
|
||||||
len = sprintf(buf,
|
len = sprintf(buf,
|
||||||
"HTTP/1.0 %d %s\r\nContent-type: %s\r\n"
|
"HTTP/1.0 %d %s\r\nContent-type: %s\r\n"
|
||||||
"Date: %s\r\nConnection: close\r\n",
|
"Date: %s\r\nConnection: close\r\n",
|
||||||
responseNum, responseString, mime_type, timeStr);
|
responseNum, responseString, mime_type, timeStr);
|
||||||
|
|
||||||
#if ENABLE_FEATURE_HTTPD_BASIC_AUTH
|
#if ENABLE_FEATURE_HTTPD_BASIC_AUTH
|
||||||
@ -986,7 +988,7 @@ static int sendCgi(const char *url,
|
|||||||
int outFd;
|
int outFd;
|
||||||
int firstLine = 1;
|
int firstLine = 1;
|
||||||
int status;
|
int status;
|
||||||
size_t post_readed_size, post_readed_idx;
|
size_t post_read_size, post_read_idx;
|
||||||
|
|
||||||
if (pipe(fromCgi) != 0)
|
if (pipe(fromCgi) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
@ -1000,7 +1002,7 @@ static int sendCgi(const char *url,
|
|||||||
if (!pid) {
|
if (!pid) {
|
||||||
/* child process */
|
/* child process */
|
||||||
char *script;
|
char *script;
|
||||||
char *purl = strdup(url);
|
char *purl = xstrdup(url);
|
||||||
char realpath_buff[MAXPATHLEN];
|
char realpath_buff[MAXPATHLEN];
|
||||||
|
|
||||||
if (purl == NULL)
|
if (purl == NULL)
|
||||||
@ -1129,8 +1131,8 @@ static int sendCgi(const char *url,
|
|||||||
|
|
||||||
/* parent process */
|
/* parent process */
|
||||||
|
|
||||||
post_readed_size = 0;
|
post_read_size = 0;
|
||||||
post_readed_idx = 0;
|
post_read_idx = 0; /* for gcc */
|
||||||
inFd = fromCgi[0];
|
inFd = fromCgi[0];
|
||||||
outFd = toCgi[1];
|
outFd = toCgi[1];
|
||||||
close(fromCgi[1]);
|
close(fromCgi[1]);
|
||||||
@ -1147,95 +1149,108 @@ static int sendCgi(const char *url,
|
|||||||
FD_ZERO(&readSet);
|
FD_ZERO(&readSet);
|
||||||
FD_ZERO(&writeSet);
|
FD_ZERO(&writeSet);
|
||||||
FD_SET(inFd, &readSet);
|
FD_SET(inFd, &readSet);
|
||||||
if (bodyLen > 0 || post_readed_size > 0) {
|
if (bodyLen > 0 || post_read_size > 0) {
|
||||||
FD_SET(outFd, &writeSet);
|
FD_SET(outFd, &writeSet);
|
||||||
nfound = outFd > inFd ? outFd : inFd;
|
nfound = outFd > inFd ? outFd : inFd;
|
||||||
if (post_readed_size == 0) {
|
if (post_read_size == 0) {
|
||||||
FD_SET(config->accepted_socket, &readSet);
|
FD_SET(config->accepted_socket, &readSet);
|
||||||
if (nfound < config->accepted_socket)
|
if (nfound < config->accepted_socket)
|
||||||
nfound = config->accepted_socket;
|
nfound = config->accepted_socket;
|
||||||
}
|
}
|
||||||
/* Now wait on the set of sockets! */
|
/* Now wait on the set of sockets! */
|
||||||
nfound = select(nfound + 1, &readSet, &writeSet, 0, NULL);
|
nfound = select(nfound + 1, &readSet, &writeSet, NULL, NULL);
|
||||||
} else {
|
} else {
|
||||||
if (!bodyLen) {
|
if (!bodyLen) {
|
||||||
close(outFd);
|
close(outFd); /* no more POST data to CGI */
|
||||||
bodyLen = -1;
|
bodyLen = -1;
|
||||||
}
|
}
|
||||||
nfound = select(inFd + 1, &readSet, 0, 0, NULL);
|
nfound = select(inFd + 1, &readSet, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nfound <= 0) {
|
if (nfound <= 0) {
|
||||||
if (waitpid(pid, &status, WNOHANG) > 0) {
|
if (waitpid(pid, &status, WNOHANG) <= 0)
|
||||||
close(inFd);
|
/* Weird. CGI didn't exit and no fd's
|
||||||
if (DEBUG && WIFEXITED(status))
|
* are ready, yet select returned?! */
|
||||||
bb_error_msg("piped has exited with status=%d", WEXITSTATUS(status));
|
continue;
|
||||||
if (DEBUG && WIFSIGNALED(status))
|
close(inFd);
|
||||||
bb_error_msg("piped has exited with signal=%d", WTERMSIG(status));
|
if (DEBUG && WIFEXITED(status))
|
||||||
break;
|
bb_error_msg("piped has exited with status=%d", WEXITSTATUS(status));
|
||||||
}
|
if (DEBUG && WIFSIGNALED(status))
|
||||||
} else if (post_readed_size > 0 && FD_ISSET(outFd, &writeSet)) {
|
bb_error_msg("piped has exited with signal=%d", WTERMSIG(status));
|
||||||
count = full_write(outFd, wbuf + post_readed_idx, post_readed_size);
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (post_read_size > 0 && FD_ISSET(outFd, &writeSet)) {
|
||||||
|
/* Have data from peer and can write to CGI */
|
||||||
|
// huh? why full_write? what if we will block?
|
||||||
|
// (imagine that CGI does not read its stdin...)
|
||||||
|
count = full_write(outFd, wbuf + post_read_idx, post_read_size);
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
post_readed_size -= count;
|
post_read_idx += count;
|
||||||
post_readed_idx += count;
|
post_read_size -= count;
|
||||||
if (post_readed_size == 0)
|
|
||||||
post_readed_idx = 0;
|
|
||||||
} else {
|
} else {
|
||||||
post_readed_size = post_readed_idx = bodyLen = 0; /* broken pipe to CGI */
|
post_read_size = bodyLen = 0; /* broken pipe to CGI */
|
||||||
}
|
}
|
||||||
} else if (bodyLen > 0 && post_readed_size == 0 && FD_ISSET(config->accepted_socket, &readSet)) {
|
} else if (bodyLen > 0 && post_read_size == 0
|
||||||
|
&& FD_ISSET(config->accepted_socket, &readSet)
|
||||||
|
) {
|
||||||
|
/* We expect data, prev data portion is eaten by CGI
|
||||||
|
* and there *is* data to read from the peer
|
||||||
|
* (POST data?) */
|
||||||
count = bodyLen > (int)sizeof(wbuf) ? (int)sizeof(wbuf) : bodyLen;
|
count = bodyLen > (int)sizeof(wbuf) ? (int)sizeof(wbuf) : bodyLen;
|
||||||
count = safe_read(config->accepted_socket, wbuf, count);
|
count = safe_read(config->accepted_socket, wbuf, count);
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
post_readed_size += count;
|
post_read_size = count;
|
||||||
|
post_read_idx = 0;
|
||||||
bodyLen -= count;
|
bodyLen -= count;
|
||||||
} else {
|
} else {
|
||||||
bodyLen = 0; /* closed */
|
bodyLen = 0; /* closed */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FD_ISSET(inFd, &readSet)) {
|
if (FD_ISSET(inFd, &readSet)) {
|
||||||
|
/* There is something to read from CGI */
|
||||||
int s = config->accepted_socket;
|
int s = config->accepted_socket;
|
||||||
char *rbuf = config->buf;
|
char *rbuf = config->buf;
|
||||||
|
#define PIPESIZE PIPE_BUF
|
||||||
#ifndef PIPE_BUF
|
|
||||||
# define PIPESIZE 4096 /* amount of buffering in a pipe */
|
|
||||||
#else
|
|
||||||
# define PIPESIZE PIPE_BUF
|
|
||||||
#endif
|
|
||||||
#if PIPESIZE >= MAX_MEMORY_BUFF
|
#if PIPESIZE >= MAX_MEMORY_BUFF
|
||||||
# error "PIPESIZE >= MAX_MEMORY_BUFF"
|
# error "PIPESIZE >= MAX_MEMORY_BUFF"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* There is something to read */
|
|
||||||
/* NB: was safe_read. If it *has to be* safe_read, */
|
/* NB: was safe_read. If it *has to be* safe_read, */
|
||||||
/* please explain why in this comment... */
|
/* please explain why in this comment... */
|
||||||
count = full_read(inFd, rbuf, PIPESIZE);
|
count = full_read(inFd, rbuf, PIPESIZE);
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
break; /* closed */
|
break; /* closed */
|
||||||
if (count > 0) {
|
if (count < 0)
|
||||||
if (firstLine) {
|
continue; /* huh, error, why continue?? */
|
||||||
/* full_read (above) avoids
|
|
||||||
* "chopped up into small chunks" syndrome here */
|
|
||||||
rbuf[count] = 0;
|
|
||||||
/* check to see if the user script added headers */
|
|
||||||
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);
|
|
||||||
} /* hmm, maybe 'else if'? */
|
|
||||||
if (!strstr(rbuf, "ontent-")) {
|
|
||||||
full_write(s, "Content-type: text/plain\r\n\r\n", 28);
|
|
||||||
}
|
|
||||||
firstLine = 0;
|
|
||||||
}
|
|
||||||
if (full_write(s, rbuf, count) != count)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (DEBUG)
|
if (firstLine) {
|
||||||
fprintf(stderr, "cgi read %d bytes: '%.*s'\n", count, count, rbuf);
|
/* full_read (above) avoids
|
||||||
|
* "chopped up into small chunks" syndrome here */
|
||||||
|
rbuf[count] = '\0';
|
||||||
|
/* check to see if the user script added headers */
|
||||||
|
#define HTTP_200 "HTTP/1.0 200 OK\r\n\r\n"
|
||||||
|
if (memcmp(rbuf, HTTP_200, 4) != 0) {
|
||||||
|
/* there is no "HTTP", do it ourself */
|
||||||
|
full_write(s, HTTP_200, sizeof(HTTP_200)-1);
|
||||||
|
}
|
||||||
|
#undef HTTP_200
|
||||||
|
/* Example of valid GCI without "Content-type:"
|
||||||
|
* echo -en "HTTP/1.0 302 Found\r\n"
|
||||||
|
* echo -en "Location: http://www.busybox.net\r\n"
|
||||||
|
* echo -en "\r\n"
|
||||||
|
*/
|
||||||
|
//if (!strstr(rbuf, "ontent-")) {
|
||||||
|
// full_write(s, "Content-type: text/plain\r\n\r\n", 28);
|
||||||
|
//}
|
||||||
|
firstLine = 0;
|
||||||
}
|
}
|
||||||
}
|
if (full_write(s, rbuf, count) != count)
|
||||||
}
|
break;
|
||||||
|
if (DEBUG)
|
||||||
|
fprintf(stderr, "cgi read %d bytes: '%.*s'\n", count, count, rbuf);
|
||||||
|
} /* if (FD_ISSET(inFd)) */
|
||||||
|
} /* while (1) */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* FEATURE_HTTPD_CGI */
|
#endif /* FEATURE_HTTPD_CGI */
|
||||||
|
Loading…
Reference in New Issue
Block a user