diff options
| author | mrg <mrg@NetBSD.org> | 2012-07-19 09:53:06 +0000 |
|---|---|---|
| committer | mrg <mrg@NetBSD.org> | 2012-07-19 09:53:06 +0000 |
| commit | 8f190ec9879f6eb5c1d8bcf17e1f45fe59814690 (patch) | |
| tree | da27038b453debda15f49d3cc28ce7e3ac963aee /libexec | |
| parent | 9224e862bdf1ca0cfc2f20860ea63ce287c3001c (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/CHANGES | 3 | ||||
| -rw-r--r-- | libexec/httpd/bozohttpd.c | 92 | ||||
| -rw-r--r-- | libexec/httpd/bozohttpd.h | 3 | ||||
| -rw-r--r-- | libexec/httpd/dir-index-bozo.c | 10 |
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>"); |
