//usage: "\n -d STRING URL decode STRING"
#include "libbb.h"
+#include "common_bufsiz.h"
#if ENABLE_PAM
/* PAM may include <locale.h>. We may need to undefine bbox's stub define: */
# undef setlocale
# include <security/pam_appl.h>
# include <security/pam_misc.h>
#endif
-#if ENABLE_FEATURE_HTTPD_USE_SENDFILE
+#if ENABLE_FEATURE_USE_SENDFILE
# include <sys/sendfile.h>
#endif
/* amount of buffering in a pipe */
Htaccess *script_i; /* config script interpreters */
#endif
char *iobuf; /* [IOBUF_SIZE] */
-#define hdr_buf bb_common_bufsiz1
+#define hdr_buf bb_common_bufsiz1
+#define sizeof_hdr_buf COMMON_BUFSIZE
char *hdr_ptr;
int hdr_cnt;
#if ENABLE_FEATURE_HTTPD_ERROR_PAGES
# define content_gzip 0
#endif
#define INIT_G() do { \
+ setup_common_bufsiz(); \
SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
IF_FEATURE_HTTPD_BASIC_AUTH(g_realm = "Web Server Authentication";) \
IF_FEATURE_HTTPD_RANGES(range_start = -1;) \
goto config_error;
}
*host_port++ = '\0';
- if (strncmp(host_port, "http://", 7) == 0)
+ if (is_prefixed_with(host_port, "http://"))
host_port += 7;
if (*host_port == '\0') {
goto config_error;
}
#endif
if (responseNum == HTTP_MOVED_TEMPORARILY) {
- len += sprintf(iobuf + len, "Location: %s/%s%s\r\n",
+ /* Responding to "GET /dir" with
+ * "HTTP/1.0 302 Found" "Location: /dir/"
+ * - IOW, asking them to repeat with a slash.
+ * Here, overflow IS possible, can't use sprintf:
+ * mkdir test
+ * python -c 'print("get /test?" + ("x" * 8192))' | busybox httpd -i -h .
+ */
+ len += snprintf(iobuf + len, IOBUF_SIZE-3 - len,
+ "Location: %s/%s%s\r\n",
found_moved_temporarily,
(g_query ? "?" : ""),
(g_query ? g_query : ""));
+ if (len > IOBUF_SIZE-3)
+ len = IOBUF_SIZE-3;
}
#if ENABLE_FEATURE_HTTPD_ERROR_PAGES
if (error_page && access(error_page, R_OK) == 0) {
- strcat(iobuf, "\r\n");
- len += 2;
-
- if (DEBUG)
+ iobuf[len++] = '\r';
+ iobuf[len++] = '\n';
+ if (DEBUG) {
+ iobuf[len] = '\0';
fprintf(stderr, "headers: '%s'\n", iobuf);
+ }
full_write(STDOUT_FILENO, iobuf, len);
if (DEBUG)
fprintf(stderr, "writing error page: '%s'\n", error_page);
responseNum, responseString,
responseNum, responseString, infoString);
}
- if (DEBUG)
+ if (DEBUG) {
+ iobuf[len] = '\0';
fprintf(stderr, "headers: '%s'\n", iobuf);
+ }
if (full_write(STDOUT_FILENO, iobuf, len) != len) {
if (verbose > 1)
bb_perror_msg("error");
alarm(HEADER_READ_TIMEOUT);
while (1) {
if (hdr_cnt <= 0) {
- hdr_cnt = safe_read(STDIN_FILENO, hdr_buf, sizeof(hdr_buf));
+ hdr_cnt = safe_read(STDIN_FILENO, hdr_buf, sizeof_hdr_buf);
if (hdr_cnt <= 0)
break;
hdr_ptr = hdr_buf;
/* NB: breaking out of this loop jumps to log_and_exit() */
out_cnt = 0;
+ pfd[FROM_CGI].fd = fromCgi_rd;
+ pfd[FROM_CGI].events = POLLIN;
+ pfd[TO_CGI].fd = toCgi_wr;
while (1) {
- memset(pfd, 0, sizeof(pfd));
-
- pfd[FROM_CGI].fd = fromCgi_rd;
- pfd[FROM_CGI].events = POLLIN;
-
- if (toCgi_wr) {
- pfd[TO_CGI].fd = toCgi_wr;
- if (hdr_cnt > 0) {
- pfd[TO_CGI].events = POLLOUT;
- } else if (post_len > 0) {
- pfd[0].events = POLLIN;
+ /* Note: even pfd[0].events == 0 won't prevent
+ * revents == POLLHUP|POLLERR reports from closed stdin.
+ * Setting fd to -1 works: */
+ pfd[0].fd = -1;
+ pfd[0].events = POLLIN;
+ pfd[0].revents = 0; /* probably not needed, paranoia */
+
+ /* We always poll this fd, thus kernel always sets revents: */
+ /*pfd[FROM_CGI].events = POLLIN; - moved out of loop */
+ /*pfd[FROM_CGI].revents = 0; - not needed */
+
+ /* gcc-4.8.0 still doesnt fill two shorts with one insn :( */
+ /* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47059 */
+ /* hopefully one day it will... */
+ pfd[TO_CGI].events = POLLOUT;
+ pfd[TO_CGI].revents = 0; /* needed! */
+
+ if (toCgi_wr && hdr_cnt <= 0) {
+ if (post_len > 0) {
+ /* Expect more POST data from network */
+ pfd[0].fd = 0;
} else {
/* post_len <= 0 && hdr_cnt <= 0:
* no more POST data to CGI,
}
/* Now wait on the set of sockets */
- count = safe_poll(pfd, toCgi_wr ? TO_CGI+1 : FROM_CGI+1, -1);
+ count = safe_poll(pfd, hdr_cnt > 0 ? TO_CGI+1 : FROM_CGI+1, -1);
if (count <= 0) {
#if 0
if (safe_waitpid(pid, &status, WNOHANG) <= 0) {
}
if (pfd[TO_CGI].revents) {
- /* hdr_cnt > 0 here due to the way pfd[TO_CGI].events set */
+ /* hdr_cnt > 0 here due to the way poll() called */
/* Have data from peer and can write to CGI */
count = safe_write(toCgi_wr, hdr_ptr, hdr_cnt);
/* Doesn't happen, we dont use nonblocking IO here
/* We expect data, prev data portion is eaten by CGI
* and there *is* data to read from the peer
* (POSTDATA) */
- //count = post_len > (int)sizeof(hdr_buf) ? (int)sizeof(hdr_buf) : post_len;
+ //count = post_len > (int)sizeof_hdr_buf ? (int)sizeof_hdr_buf : post_len;
//count = safe_read(STDIN_FILENO, hdr_buf, count);
- count = safe_read(STDIN_FILENO, hdr_buf, sizeof(hdr_buf));
+ count = safe_read(STDIN_FILENO, hdr_buf, sizeof_hdr_buf);
if (count > 0) {
hdr_cnt = count;
hdr_ptr = hdr_buf;
out_cnt += count;
count = 0;
/* "Status" header format is: "Status: 302 Redirected\r\n" */
- if (out_cnt >= 8 && memcmp(rbuf, "Status: ", 8) == 0) {
+ if (out_cnt >= 7 && memcmp(rbuf, "Status:", 7) == 0) {
/* send "HTTP/1.0 " */
if (full_write(STDOUT_FILENO, HTTP_200, 9) != 9)
break;
- rbuf += 8; /* skip "Status: " */
- count = out_cnt - 8;
+ rbuf += 7; /* skip "Status:" */
+ count = out_cnt - 7;
out_cnt = -1; /* buffering off */
} else if (out_cnt >= 4) {
/* Did CGI add "HTTP"? */
#endif
if (what & SEND_HEADERS)
send_headers(HTTP_OK);
-#if ENABLE_FEATURE_HTTPD_USE_SENDFILE
+#if ENABLE_FEATURE_USE_SENDFILE
{
off_t offset = range_start;
while (1) {
break;
}
if (count < 0) {
- IF_FEATURE_HTTPD_USE_SENDFILE(fin:)
+ IF_FEATURE_USE_SENDFILE(fin:)
if (verbose > 1)
bb_perror_msg("error");
}
s = userinfo->pw;
break;
case PAM_ERROR_MSG:
- case PAM_TEXT_INFO:
- s = "";
+ case PAM_TEXT_INFO:
+ s = "";
break;
default:
free(response);
{
Htaccess_Proxy *p;
for (p = proxy; p; p = p->next) {
- if (strncmp(url, p->url_from, strlen(p->url_from)) == 0)
+ if (is_prefixed_with(url, p->url_from))
return p;
}
return NULL;
if (STRNCASECMP(iobuf, "Range:") == 0) {
/* We know only bytes=NNN-[MMM] */
char *s = skip_whitespace(iobuf + sizeof("Range:")-1);
- if (strncmp(s, "bytes=", 6) == 0) {
+ if (is_prefixed_with(s, "bytes=") == 0) {
s += sizeof("bytes=")-1;
range_start = BB_STRTOOFF(s, &s, 10);
if (s[0] != '-' || range_start < 0) {
tptr = urlcopy + 1; /* skip first '/' */
#if ENABLE_FEATURE_HTTPD_CGI
- if (strncmp(tptr, "cgi-bin/", 8) == 0) {
+ if (is_prefixed_with(tptr, "cgi-bin/")) {
if (tptr[8] == '\0') {
/* protect listing "cgi-bin/" */
send_headers_and_exit(HTTP_FORBIDDEN);
continue;
/* set the KEEPALIVE option to cull dead connections */
- setsockopt(n, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1));
+ setsockopt_keepalive(n);
if (fork() == 0) {
/* child */
continue;
/* set the KEEPALIVE option to cull dead connections */
- setsockopt(n, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1));
+ setsockopt_keepalive(n);
if (vfork() == 0) {
/* child */