Module Name: src
Committed By: mrg
Date: Thu Jul 19 09:53:06 UTC 2012
Modified Files:
src/libexec/httpd: CHANGES bozohttpd.c bozohttpd.h dir-index-bozo.c
Log Message:
when generating URIs escape various characters as specified in RFC 3986.
this makes, among other things, files/dirs with "?" work with dir indexing.
To generate a diff of this commit:
cvs rdiff -u -r1.11 -r1.12 src/libexec/httpd/CHANGES
cvs rdiff -u -r1.31 -r1.32 src/libexec/httpd/bozohttpd.c
cvs rdiff -u -r1.22 -r1.23 src/libexec/httpd/bozohttpd.h
cvs rdiff -u -r1.14 -r1.15 src/libexec/httpd/dir-index-bozo.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/libexec/httpd/CHANGES
diff -u src/libexec/httpd/CHANGES:1.11 src/libexec/httpd/CHANGES:1.12
--- src/libexec/httpd/CHANGES:1.11 Fri Nov 18 09:51:31 2011
+++ src/libexec/httpd/CHANGES Thu Jul 19 09:53:06 2012
@@ -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 [email protected]
o avoid crashes with http basic auth, from [email protected]
Index: src/libexec/httpd/bozohttpd.c
diff -u src/libexec/httpd/bozohttpd.c:1.31 src/libexec/httpd/bozohttpd.c:1.32
--- src/libexec/httpd/bozohttpd.c:1.31 Mon Feb 20 09:26:56 2012
+++ src/libexec/httpd/bozohttpd.c Thu Jul 19 09:53:06 2012
@@ -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
}
/*
+ * 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");
Index: src/libexec/httpd/bozohttpd.h
diff -u src/libexec/httpd/bozohttpd.h:1.22 src/libexec/httpd/bozohttpd.h:1.23
--- src/libexec/httpd/bozohttpd.h:1.22 Wed Mar 14 23:47:19 2012
+++ src/libexec/httpd/bozohttpd.h Thu Jul 19 09:53:06 2012
@@ -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,
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 *);
Index: src/libexec/httpd/dir-index-bozo.c
diff -u src/libexec/httpd/dir-index-bozo.c:1.14 src/libexec/httpd/dir-index-bozo.c:1.15
--- src/libexec/httpd/dir-index-bozo.c:1.14 Wed Feb 29 23:38:46 2012
+++ src/libexec/httpd/dir-index-bozo.c Thu Jul 19 09:53:06 2012
@@ -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,
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,
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>");