This patch creates a list of unmatched HTTP headers and sets up environment
variables before running the CGI script. The variables will be named
HTTP_<filtered name> where the filtered name is the header name capitalized
and all characters not matching [a-z] | [A-Z] | [0-9] replaced with '_'.
Bloatcheck
function old new delta
handle_incoming_and_exit 2859 3116 +257
send_cgi_and_exit 1016 1086 +70
static.last - 8 +8
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 2/0 up/down: 335/0) Total: 335
bytes
text data bss dec hex filename
1017044 17695 1888 1036627 fd153 busybox_old
1017371 17695 1896 1036962 fd2a2 busybox_unstripped
diff --git a/networking/httpd.c b/networking/httpd.c
index b52526a78..f29c0a6a0 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -305,6 +305,12 @@ typedef struct Htaccess_Proxy {
char *url_to;
} Htaccess_Proxy;
+typedef struct HTTP_Header {
+ struct HTTP_Header *next;
+ char *name;
+ char *value;
+} HTTP_Header;
+
enum {
HTTP_OK = 200,
HTTP_PARTIAL_CONTENT = 206,
@@ -417,6 +423,7 @@ struct globals {
IF_FEATURE_HTTPD_CGI(char *host;)
IF_FEATURE_HTTPD_CGI(char *http_accept;)
IF_FEATURE_HTTPD_CGI(char *http_accept_language;)
+ IF_FEATURE_HTTPD_CGI(HTTP_Header *hdr_list;)
off_t file_size; /* -1 - unknown */
#if ENABLE_FEATURE_HTTPD_RANGES
@@ -527,6 +534,13 @@ static ALWAYS_INLINE void
free_Htaccess_IP_list(Htaccess_IP **pptr)
free_llist((has_next_ptr**)pptr);
}
+#if ENABLE_FEATURE_HTTPD_CGI
+static ALWAYS_INLINE void free_HTTP_Header_list(HTTP_Header **pptr)
+{
+ free_llist((has_next_ptr**)pptr);
+}
+#endif
+
/* Returns presumed mask width in bits or < 0 on error.
* Updates strp, stores IP at provided pointer */
static int scan_ip(const char **strp, unsigned *ipp, unsigned char endc)
@@ -1554,6 +1568,18 @@ static void send_cgi_and_exit(
/* setenv1("SERVER_NAME", safe_gethostname()); - don't do this,
* just run "env SERVER_NAME=xyz httpd ..." instead */
+ if (G.hdr_list) {
+ HTTP_Header *cur = G.hdr_list;
+ do {
+ setenv1(cur->name, cur->value);
+ //bb_error_msg("test: '%s = %s'", cur->name, cur->value);
+ free(cur->name);
+ free(cur->value);
+ cur = cur->next;
+ } while (cur != G.hdr_list);
+ free_HTTP_Header_list(&G.hdr_list);
+ }
+
xpiped_pair(fromCgi);
xpiped_pair(toCgi);
@@ -2326,6 +2352,9 @@ static void handle_incoming_and_exit(const
len_and_sockaddr *fromAddr)
}
#endif
#if ENABLE_FEATURE_HTTPD_BASIC_AUTH
+#if ENABLE_FEATURE_HTTPD_CGI || ENABLE_FEATURE_HTTPD_PROXY
+ else
+#endif
if (STRNCASECMP(iobuf, "Authorization:") == 0) {
/* We only allow Basic credentials.
* It shows up as "Authorization: Basic <user>:<passwd>" where
@@ -2341,6 +2370,9 @@ static void handle_incoming_and_exit(const
len_and_sockaddr *fromAddr)
}
#endif
#if ENABLE_FEATURE_HTTPD_RANGES
+#if ENABLE_FEATURE_HTTPD_CGI || ENABLE_FEATURE_HTTPD_PROXY ||
ENABLE_FEATURE_HTTPD_BASIC_AUTH
+ else
+#endif
if (STRNCASECMP(iobuf, "Range:") == 0) {
/* We know only bytes=NNN-[MMM] */
char *s = skip_whitespace(iobuf + sizeof("Range:")-1);
@@ -2358,6 +2390,9 @@ static void handle_incoming_and_exit(const
len_and_sockaddr *fromAddr)
}
#endif
#if ENABLE_FEATURE_HTTPD_GZIP
+#if ENABLE_FEATURE_HTTPD_CGI || ENABLE_FEATURE_HTTPD_PROXY ||
ENABLE_FEATURE_HTTPD_BASIC_AUTH || ENABLE_FEATURE_HTTPD_GZIP
+ else
+#endif
if (STRNCASECMP(iobuf, "Accept-Encoding:") == 0) {
/* Note: we do not support "gzip;q=0"
* method of _disabling_ gzip
@@ -2373,6 +2408,43 @@ static void handle_incoming_and_exit(const
len_and_sockaddr *fromAddr)
//}
}
}
+#endif
+#if ENABLE_FEATURE_HTTPD_CGI
+ else {
+ static HTTP_Header *last;
+ HTTP_Header *cur = xzalloc(sizeof(HTTP_Header));
+ char *after_colon = strchr(iobuf, ':');
+ char *ch = iobuf;
+
+ if (!after_colon)
+ continue;
+
+ *after_colon++ = '\0';
+
+ while (*ch) {
+ if (isalpha(*ch))
+ *ch &= ~0x20;
+ else if (!isdigit(*ch))
+ *ch = '_';
+ ch++;
+ }
+
+ cur->name = xmalloc(sizeof("HTTP_")+strlen(iobuf));
+ memcpy(cur->name, "HTTP_", sizeof("HTTP_")-1);
+ strcpy(cur->name + sizeof("HTTP_")-1, iobuf);
+ cur->value = xstrdup(skip_whitespace(after_colon));
+
+ /* Insert new header into header list */
+ if (!G.hdr_list) {
+ G.hdr_list = cur;
+ cur->next = G.hdr_list;
+ last = cur;
+ } else {
+ cur->next = G.hdr_list;
+ last->next = cur;
+ last = cur;
+ }
+ }
#endif
} /* while extra header reading */
}
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox