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 j...@netbsd.org
 	o  avoid crashes with http basic auth, from po...@netbsd.org

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>");

Reply via email to