summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authormrg <mrg@NetBSD.org>2012-07-19 09:53:06 +0000
committermrg <mrg@NetBSD.org>2012-07-19 09:53:06 +0000
commit8f190ec9879f6eb5c1d8bcf17e1f45fe59814690 (patch)
treeda27038b453debda15f49d3cc28ce7e3ac963aee /libexec
parent9224e862bdf1ca0cfc2f20860ea63ce287c3001c (diff)
when generating URIs escape various characters as specified in RFC 3986.
this makes, among other things, files/dirs with "?" work with dir indexing.
Diffstat (limited to 'libexec')
-rw-r--r--libexec/httpd/CHANGES3
-rw-r--r--libexec/httpd/bozohttpd.c92
-rw-r--r--libexec/httpd/bozohttpd.h3
-rw-r--r--libexec/httpd/dir-index-bozo.c10
4 files changed, 88 insertions, 20 deletions
diff --git a/libexec/httpd/CHANGES b/libexec/httpd/CHANGES
index 13b5afaf5bd..fc50bb501af 100644
--- a/libexec/httpd/CHANGES
+++ b/libexec/httpd/CHANGES
@@ -1,5 +1,8 @@
$eterna: CHANGES,v 1.78 2011/11/18 01:25:11 mrg Exp $
+changes since bozohttpd 20111118:
+ o properly escape generated URIs
+
changes since bozohttpd 20100920:
o add -P <pidfile> option, from jmmv@netbsd.org
o avoid crashes with http basic auth, from pooka@netbsd.org
diff --git a/libexec/httpd/bozohttpd.c b/libexec/httpd/bozohttpd.c
index df5871d0a7b..39b29c1609d 100644
--- a/libexec/httpd/bozohttpd.c
+++ b/libexec/httpd/bozohttpd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: bozohttpd.c,v 1.31 2012/02/20 09:26:56 elric Exp $ */
+/* $NetBSD: bozohttpd.c,v 1.32 2012/07/19 09:53:06 mrg Exp $ */
/* $eterna: bozohttpd.c,v 1.178 2011/11/18 09:21:15 mrg Exp $ */
@@ -847,6 +847,67 @@ parse_http_date(const char *val, time_t *timestamp)
}
/*
+ * given an url, encode it ala rfc 3986. ie, escape ? and friends.
+ * note that this function returns a static buffer, and thus needs
+ * to be updated for any sort of parallel processing.
+ */
+char *
+escape_rfc3986(bozohttpd_t *httpd, const char *url)
+{
+ static char *buf;
+ static size_t buflen = 0;
+ size_t len;
+ const char *s;
+ char *d;
+
+ len = strlen(url);
+ if (buflen < len * 3 + 1) {
+ buflen = len * 3 + 1;
+ buf = bozorealloc(httpd, buf, buflen);
+ }
+
+ if (url == NULL) {
+ buf[0] = 0;
+ return buf;
+ }
+
+ for (s = url, d = buf; *s;) {
+ if (*s & 0x80)
+ goto encode_it;
+ switch (*s) {
+ case ':':
+ case '/':
+ case '?':
+ case '#':
+ case '[':
+ case ']':
+ case '@':
+ case '!':
+ case '$':
+ case '&':
+ case '\'':
+ case '(':
+ case ')':
+ case '*':
+ case '+':
+ case ',':
+ case ';':
+ case '=':
+ encode_it:
+ snprintf(d, 4, "%%%2X", *s++);
+ d += 3;
+ len += 3;
+ default:
+ *d++ = *s++;
+ len++;
+ }
+ }
+ buf[len] = 0;
+
+ return buf;
+}
+
+/*
* checks to see if this request has a valid .bzdirect file. returns
* 0 on failure and 1 on success.
*/
@@ -898,10 +959,10 @@ handle_redirect(bozo_httpreq_t *request,
url = urlbuf;
} else
urlbuf = NULL;
+ url = escape_rfc3986(request->hr_httpd, url);
- if (request->hr_query && strlen(request->hr_query)) {
+ if (request->hr_query && strlen(request->hr_query))
query = 1;
- }
if (request->hr_serverport && strcmp(request->hr_serverport, "80") != 0)
snprintf(portbuf, sizeof(portbuf), ":%s",
@@ -918,9 +979,9 @@ handle_redirect(bozo_httpreq_t *request,
if (absolute == 0)
bozo_printf(httpd, "%s%s", httpd->virthostname, portbuf);
if (query) {
- bozo_printf(httpd, "%s?%s\r\n", url, request->hr_query);
+ bozo_printf(httpd, "%s?%s\r\n", url, request->hr_query);
} else {
- bozo_printf(httpd, "%s\r\n", url);
+ bozo_printf(httpd, "%s\r\n", url);
}
}
bozo_printf(httpd, "\r\n");
@@ -930,16 +991,17 @@ handle_redirect(bozo_httpreq_t *request,
bozo_printf(httpd, "<body><h1>Document Moved</h1>\n");
bozo_printf(httpd, "This document had moved <a href=\"http://");
if (query) {
- if (absolute)
- bozo_printf(httpd, "%s?%s", url, request->hr_query);
- else
- bozo_printf(httpd, "%s%s%s?%s", httpd->virthostname, portbuf, url,
- request->hr_query);
- } else {
- if (absolute)
- bozo_printf(httpd, "%s", url);
- else
- bozo_printf(httpd, "%s%s%s", httpd->virthostname, portbuf, url);
+ if (absolute)
+ bozo_printf(httpd, "%s?%s", url, request->hr_query);
+ else
+ bozo_printf(httpd, "%s%s%s?%s", httpd->virthostname,
+ portbuf, url, request->hr_query);
+ } else {
+ if (absolute)
+ bozo_printf(httpd, "%s", url);
+ else
+ bozo_printf(httpd, "%s%s%s", httpd->virthostname,
+ portbuf, url);
}
bozo_printf(httpd, "\">here</a>\n");
bozo_printf(httpd, "</body></html>\n");
diff --git a/libexec/httpd/bozohttpd.h b/libexec/httpd/bozohttpd.h
index bad55a512b1..904a44fd54b 100644
--- a/libexec/httpd/bozohttpd.h
+++ b/libexec/httpd/bozohttpd.h
@@ -1,4 +1,4 @@
-/* $NetBSD: bozohttpd.h,v 1.22 2012/03/14 23:47:19 joerg Exp $ */
+/* $NetBSD: bozohttpd.h,v 1.23 2012/07/19 09:53:06 mrg Exp $ */
/* $eterna: bozohttpd.h,v 1.39 2011/11/18 09:21:15 mrg Exp $ */
@@ -186,6 +186,7 @@ int bozo_http_error(bozohttpd_t *, int, bozo_httpreq_t *, const char *);
int bozo_check_special_files(bozo_httpreq_t *, const char *);
char *bozo_http_date(char *, size_t);
void bozo_print_header(bozo_httpreq_t *, struct stat *, const char *, const char *);
+char *escape_rfc3986(bozohttpd_t *httpd, const char *url);
char *bozodgetln(bozohttpd_t *, int, ssize_t *, ssize_t (*)(bozohttpd_t *, int, void *, size_t));
char *bozostrnsep(char **, const char *, ssize_t *);
diff --git a/libexec/httpd/dir-index-bozo.c b/libexec/httpd/dir-index-bozo.c
index 466c8d0dd47..2b2aaa71e40 100644
--- a/libexec/httpd/dir-index-bozo.c
+++ b/libexec/httpd/dir-index-bozo.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dir-index-bozo.c,v 1.14 2012/02/29 23:38:46 joerg Exp $ */
+/* $NetBSD: dir-index-bozo.c,v 1.15 2012/07/19 09:53:06 mrg Exp $ */
/* $eterna: dir-index-bozo.c,v 1.20 2011/11/18 09:21:15 mrg Exp $ */
@@ -127,6 +127,7 @@ bozo_dir_index(bozo_httpreq_t *request, const char *dirname, int isindex)
j--; de++) {
int nostat = 0;
char *name = (*de)->d_name;
+ char *urlname;
if (strcmp(name, ".") == 0 ||
(strcmp(name, "..") != 0 &&
@@ -139,18 +140,19 @@ bozo_dir_index(bozo_httpreq_t *request, const char *dirname, int isindex)
l = 0;
+ urlname = escape_rfc3986(httpd, name);
if (strcmp(name, "..") == 0) {
bozo_printf(httpd, "<a href=\"../\">");
l += bozo_printf(httpd, "Parent Directory");
} else if (S_ISDIR(sb.st_mode)) {
- bozo_printf(httpd, "<a href=\"%s/\">", name);
+ bozo_printf(httpd, "<a href=\"%s/\">", urlname);
l += bozo_printf(httpd, "%s/", name);
} else if (strchr(name, ':') != NULL) {
/* RFC 3986 4.2 */
- bozo_printf(httpd, "<a href=\"./%s\">", name);
+ bozo_printf(httpd, "<a href=\"./%s\">", urlname);
l += bozo_printf(httpd, "%s", name);
} else {
- bozo_printf(httpd, "<a href=\"%s\">", name);
+ bozo_printf(httpd, "<a href=\"%s\">", urlname);
l += bozo_printf(httpd, "%s", name);
}
bozo_printf(httpd, "</a>");