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