Hello list,
the httpd applet's proxy feature has glitches. The promise is, quote
P:/url:[http://]hostname[:port]/new/path
# When /urlXXXXXX is requested, reverse proxy
# it to http://hostname[:port]/new/pathXXXXXX
urlcopy is not a true copy anymore when it is fdprint'ed to proxy_fd,
this is because percent_decode_in_place() is called after the copy
is created.
Not fixing this breaks reverse proxying all URIs containing percent
encoded spaces, e.g. - because a decoded URI will be printed out
to proxy_fd instead of the original.
The fix keeps the logic in place to canonicalize the uri first, before
reverse proxying (one could argue that the uri should be proxied
completely unaltered, except for the prefix rewrite), but percent
(re-)encodes the (canonicalized) string before it is used.
Please find attached patch that is tried and tested to work.
Regards,
Jim
______________________________________________________
Firemail.de Freemail - 10 GB für Mails und Daten
POP3 und IMAP kostenfrei
http://www.firemail.de/
diff -ur busybox-1.28.4/networking/httpd.c busybox.patched/networking/httpd.c
--- busybox-1.28.4/networking/httpd.c 2018-04-01 13:03:43.000000000 +0200
+++ busybox.patched/networking/httpd.c 2018-06-25 15:21:39.087341186 +0200
@@ -921,6 +921,36 @@
fclose(f);
}
+static char *percent_encode(const char *s)
+{
+ char tb[256] = {0};
+ char *out = xmalloc(strlen(s) * 3 + 1);
+ char *p = out;
+ int i;
+
+ // non rfc3986, since it does encode '/'
+ for (i = 0; i < 256; i++) {
+ tb[i] = isalnum(i)
+ || i == '~'
+ || i == '-'
+ || i == '.'
+ || i == '_'
+ || i == '/'
+ ? i : 0;
+ }
+
+ for (; *s; s++) {
+ if (tb[(char)*s])
+ sprintf(p, "%c", tb[(char)*s]);
+ else
+ sprintf(p, "%%%02X", *s);
+ while (*++p);
+ }
+ *p = '\0';
+
+ return out;
+}
+
#if ENABLE_FEATURE_HTTPD_ENCODE_URL_STR
/*
* Given a string, html-encode special characters.
@@ -2405,10 +2435,11 @@
send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);
if (connect(proxy_fd, &lsa->u.sa, lsa->len) < 0)
send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);
+ tptr = percent_encode(urlcopy + strlen(proxy_entry->url_from));
fdprintf(proxy_fd, "%s %s%s%s%s HTTP/%c.%c\r\n",
prequest, /* GET or POST */
proxy_entry->url_to, /* url part 1 */
- urlcopy + strlen(proxy_entry->url_from), /* url part 2 */
+ tptr, /* url part 2 */
(g_query ? "?" : ""), /* "?" (maybe) */
(g_query ? g_query : ""), /* query string (maybe) */
http_major_version, http_minor_version);
@@ -2416,6 +2447,7 @@
header_ptr[1] = '\n';
header_ptr += 2;
write(proxy_fd, header_buf, header_ptr - header_buf);
+ free(tptr);
free(header_buf); /* on the order of 8k, free it */
cgi_io_loop_and_exit(proxy_fd, proxy_fd, length);
}
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox