Module Name:    src
Committed By:   elric
Date:           Sat Jan  2 18:40:13 UTC 2016

Modified Files:
        src/libexec/httpd: bozohttpd.c bozohttpd.h

Log Message:
Add the concept of ``reply headers'', that is a SIMPLEQ of headers that
will be included in the HTTP reply.  We define this as we are about to
add an authentication method that may need to have a conversation with
the client.


To generate a diff of this commit:
cvs rdiff -u -r1.77 -r1.78 src/libexec/httpd/bozohttpd.c
cvs rdiff -u -r1.43 -r1.44 src/libexec/httpd/bozohttpd.h

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/bozohttpd.c
diff -u src/libexec/httpd/bozohttpd.c:1.77 src/libexec/httpd/bozohttpd.c:1.78
--- src/libexec/httpd/bozohttpd.c:1.77	Thu Dec 31 04:58:43 2015
+++ src/libexec/httpd/bozohttpd.c	Sat Jan  2 18:40:13 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: bozohttpd.c,v 1.77 2015/12/31 04:58:43 mrg Exp $	*/
+/*	$NetBSD: bozohttpd.c,v 1.78 2016/01/02 18:40:13 elric Exp $	*/
 
 /*	$eterna: bozohttpd.c,v 1.178 2011/11/18 09:21:15 mrg Exp $	*/
 
@@ -347,6 +347,13 @@ bozo_clean_request(bozo_httpreq_t *reque
 		free(ohdr);
 		ohdr = hdr;
 	}
+	for (hdr = SIMPLEQ_FIRST(&request->hr_replheaders); hdr;
+	    hdr = SIMPLEQ_NEXT(hdr, h_next)) {
+		free(hdr->h_value);
+		free(hdr->h_header);
+		free(ohdr);
+		ohdr = hdr;
+	}
 	free(ohdr);
 
 	free(request);
@@ -363,20 +370,33 @@ alarmer(int sig)
 }
 
 /*
+ * a list of header quirks: currently, a list of headers that
+ * can't be folded into a single line.
+ */
+const char *header_quirks[] = { "WWW-Authenticate", NULL };
+
+/*
  * add or merge this header (val: str) into the requests list
  */
 static bozoheaders_t *
-addmerge_header(bozo_httpreq_t *request, char *val,
-		char *str, ssize_t len)
+addmerge_header(bozo_httpreq_t *request, struct qheaders *headers,
+		const char *val, const char *str, ssize_t len)
 {
 	struct	bozohttpd_t *httpd = request->hr_httpd;
-	struct	bozoheaders *hdr;
+	struct bozoheaders	 *hdr = NULL;
+	const char		**quirk;
 
 	USE_ARG(len);
-	/* do we exist already? */
-	SIMPLEQ_FOREACH(hdr, &request->hr_headers, h_next) {
-		if (strcasecmp(val, hdr->h_header) == 0)
+	for (quirk = header_quirks; *quirk; quirk++)
+		if (strcasecmp(*quirk, val) == 0)
 			break;
+
+	if (*quirk == NULL) {
+		/* do we exist already? */
+		SIMPLEQ_FOREACH(hdr, headers, h_next) {
+			if (strcasecmp(val, hdr->h_header) == 0)
+				break;
+		}
 	}
 
 	if (hdr) {
@@ -396,13 +416,30 @@ addmerge_header(bozo_httpreq_t *request,
 		else
 			hdr->h_value = bozostrdup(httpd, request, " ");
 
-		SIMPLEQ_INSERT_TAIL(&request->hr_headers, hdr, h_next);
+		SIMPLEQ_INSERT_TAIL(headers, hdr, h_next);
 		request->hr_nheaders++;
 	}
 
 	return hdr;
 }
 
+bozoheaders_t *
+addmerge_reqheader(bozo_httpreq_t *request, const char *val, const char *str,
+		   ssize_t len)
+{
+
+	return addmerge_header(request, &request->hr_headers, val, str, len);
+}
+
+bozoheaders_t *
+addmerge_replheader(bozo_httpreq_t *request, const char *val, const char *str,
+		    ssize_t len)
+{
+
+	return addmerge_header(request, &request->hr_replheaders,
+	    val, str, len);
+}
+
 /*
  * as the prototype string is not constant (eg, "HTTP/1.1" is equivalent
  * to "HTTP/001.01"), we MUST parse this.
@@ -538,6 +575,7 @@ bozo_read_request(bozohttpd_t *httpd)
 	request->hr_virthostname = NULL;
 	request->hr_file = NULL;
 	request->hr_oldfile = NULL;
+	SIMPLEQ_INIT(&request->hr_replheaders);
 	bozo_auth_init(request);
 
 	slen = sizeof(ss);
@@ -673,7 +711,7 @@ bozo_read_request(bozohttpd_t *httpd)
 			if (bozo_auth_check_headers(request, val, str, len))
 				goto next_header;
 
-			hdr = addmerge_header(request, val, str, len);
+			hdr = addmerge_reqheader(request, val, str, len);
 
 			if (strcasecmp(hdr->h_header, "content-type") == 0)
 				request->hr_content_type = hdr->h_value;
@@ -1680,6 +1718,12 @@ bozo_print_header(bozo_httpreq_t *reques
 	bozohttpd_t *httpd = request->hr_httpd;
 	off_t len;
 	char	date[40];
+	bozoheaders_t *hdr;
+
+	SIMPLEQ_FOREACH(hdr, &request->hr_replheaders, h_next) {
+		bozo_printf(httpd, "%s: %s\r\n", hdr->h_header,
+				hdr->h_value);
+	}
 
 	bozo_printf(httpd, "Date: %s\r\n", bozo_http_date(date, sizeof(date)));
 	bozo_printf(httpd, "Server: %s\r\n", httpd->server_software);
@@ -1901,6 +1945,7 @@ bozo_http_error(bozohttpd_t *httpd, int 
 	const char *proto = (request && request->hr_proto) ?
 				request->hr_proto : httpd->consts.http_11;
 	int	size;
+	bozoheaders_t *hdr;
 
 	debug((httpd, DEBUG_FAT, "bozo_http_error %d: %s", code, msg));
 	if (header == NULL || reason == NULL) {
@@ -1963,8 +2008,14 @@ bozo_http_error(bozohttpd_t *httpd, int 
 		size = 0;
 
 	bozo_printf(httpd, "%s %s\r\n", proto, header);
-	if (request)
+
+	if (request) {
 		bozo_auth_check_401(request, code);
+		SIMPLEQ_FOREACH(hdr, &request->hr_replheaders, h_next) {
+			bozo_printf(httpd, "%s: %s\r\n", hdr->h_header,
+					hdr->h_value);
+		}
+	}
 
 	bozo_printf(httpd, "Content-Type: text/html\r\n");
 	bozo_printf(httpd, "Content-Length: %d\r\n", size);

Index: src/libexec/httpd/bozohttpd.h
diff -u src/libexec/httpd/bozohttpd.h:1.43 src/libexec/httpd/bozohttpd.h:1.44
--- src/libexec/httpd/bozohttpd.h:1.43	Tue Dec 29 04:21:46 2015
+++ src/libexec/httpd/bozohttpd.h	Sat Jan  2 18:40:13 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: bozohttpd.h,v 1.43 2015/12/29 04:21:46 mrg Exp $	*/
+/*	$NetBSD: bozohttpd.h,v 1.44 2016/01/02 18:40:13 elric Exp $	*/
 
 /*	$eterna: bozohttpd.h,v 1.39 2011/11/18 09:21:15 mrg Exp $	*/
 
@@ -54,6 +54,7 @@ typedef struct bozoheaders {
 	/*const*/ char *h_value;	/* this gets free()'ed etc at times */
 	SIMPLEQ_ENTRY(bozoheaders)	h_next;
 } bozoheaders_t;
+SIMPLEQ_HEAD(qheaders, bozoheaders);
 
 #ifndef NO_LUA_SUPPORT
 typedef struct lua_handler {
@@ -172,8 +173,9 @@ typedef struct bozo_httpreq_t {
 	/*const*/ char *hr_authuser;
 	/*const*/ char *hr_authpass;
 #endif
-	SIMPLEQ_HEAD(, bozoheaders)	hr_headers;
-	int	hr_nheaders;
+	struct qheaders		hr_headers;
+	struct qheaders		hr_replheaders;
+	int			hr_nheaders;
 } bozo_httpreq_t;
 
 /* helper to access the "active" host name from a httpd/request pair */
@@ -355,6 +357,10 @@ int bozo_setup(bozohttpd_t *, bozoprefs_
 bozo_httpreq_t *bozo_read_request(bozohttpd_t *);
 void bozo_process_request(bozo_httpreq_t *);
 void bozo_clean_request(bozo_httpreq_t *);
+bozoheaders_t *addmerge_reqheader(bozo_httpreq_t *, const char *,
+				  const char *, ssize_t);
+bozoheaders_t *addmerge_replheader(bozo_httpreq_t *, const char *,
+				   const char *, ssize_t);
 
 /* variables */
 int bozo_set_pref(bozohttpd_t *, bozoprefs_t *, const char *, const char *);

Reply via email to