NetBSD Problem Report #58880
From www@netbsd.org Fri Dec 6 03:48:17 2024
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
client-signature RSA-PSS (2048 bits) client-digest SHA256)
(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id AFFA21A9238
for <gnats-bugs@gnats.NetBSD.org>; Fri, 6 Dec 2024 03:48:17 +0000 (UTC)
Message-Id: <20241206034816.595851A923B@mollari.NetBSD.org>
Date: Fri, 6 Dec 2024 03:48:16 +0000 (UTC)
From: campbell+netbsd@mumble.net
Reply-To: campbell+netbsd@mumble.net
To: gnats-bugs@NetBSD.org
Subject: bozohttpd(8): set custom header field in responses
X-Send-Pr-Version: www-1.0
>Number: 58880
>Category: bin
>Synopsis: bozohttpd(8): set custom header field in responses
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: mrg
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Dec 06 03:50:00 +0000 2024
>Last-Modified: Mon Dec 16 12:30:01 +0000 2024
>Originator: Taylor R Campbell
>Release: 10
>Organization:
The-NetBSD-Foundation: max-age=31556956
>Environment:
>Description:
How do I set a custom header field in bozohttpd responses, such as `Strict-Transport-Security: max-age=31556956'?
With Apache I would do:
Header set Strict-Transport-Security "max-age=31556956"
This is for serving any response, not just scripts, so while I can easily add the header field manually in a script that's not enough here.
>How-To-Repeat:
try to implement RFC 6797 or anything else that requires setting a header field on content, like X-Frame-Options or things like that
>Fix:
Yes, please!
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: bin-bug-people->mrg
Responsible-Changed-By: riastradh@NetBSD.org
Responsible-Changed-When: Fri, 06 Dec 2024 04:04:33 +0000
Responsible-Changed-Why:
exec bozohelpd
From: Sunil Nimmagadda <sunil@nimmagadda.net>
To: campbell+netbsd@mumble.net
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org, gnats-bugs@netbsd.org
Subject: Re: bin/58880: bozohttpd(8): set custom header field in responses
Date: Fri, 13 Dec 2024 13:03:05 +0530
campbell+netbsd@mumble.net writes:
>>Number: 58880
>>Category: bin
>>Synopsis: bozohttpd(8): set custom header field in responses
>>Confidential: no
>>Severity: serious
>>Priority: medium
>>Responsible: bin-bug-people
>>State: open
>>Class: sw-bug
>>Submitter-Id: net
>>Arrival-Date: Fri Dec 06 03:50:00 +0000 2024
>>Originator: Taylor R Campbell
>>Release: 10
>>Organization:
> The-NetBSD-Foundation: max-age=31556956
>>Environment:
>>Description:
> How do I set a custom header field in bozohttpd responses, such as `Strict-Transport-Security: max-age=31556956'?
>
> With Apache I would do:
>
> Header set Strict-Transport-Security "max-age=31556956"
>
> This is for serving any response, not just scripts, so while I can easily add the header field manually in a script that's not enough here.
>>How-To-Repeat:
> try to implement RFC 6797 or anything else that requires setting a header field on content, like X-Frame-Options or things like that
>>Fix:
> Yes, please!
This diff allows custom headers to be specified in a .bzcustomheaders file at
the root of the server. The lines from it are included verbatim as
headers in all of the responses...
diff --git a/libexec/httpd/bozohttpd.8 b/libexec/httpd/bozohttpd.8
index 196fcb52acc7..b37cfb50de6c 100644
--- a/libexec/httpd/bozohttpd.8
+++ b/libexec/httpd/bozohttpd.8
@@ -640,6 +640,11 @@ with a backslash
.Pq Ql \e
The right hand side of the colon is always used verbatim, no escape sequences
are interpreted.
+.Ss CUSTOM RESPONSE HEADERS
+If a
+.Pa .bzcustomheaders
+file is found at the root of the server, it is expected to contain
+custom headers to be included verbatim in all of the responses.
.Sh EXAMPLES
To configure set of virtual hosts, one would use an
.Xr inetd.conf 5
diff --git a/libexec/httpd/bozohttpd.c b/libexec/httpd/bozohttpd.c
index 656bdf073af3..cbdc5a6b96b0 100644
--- a/libexec/httpd/bozohttpd.c
+++ b/libexec/httpd/bozohttpd.c
@@ -181,6 +181,7 @@ struct {
{ ABSREDIRECT_FILE, "rejected absredirect request" },
{ REMAP_FILE, "rejected remap request" },
{ AUTH_FILE, "rejected authfile request" },
+ { CUSTOMHEADERS_FILE, "rejected customheaders request" },
{ NULL, NULL },
};
@@ -1974,12 +1975,17 @@ bozo_print_header(bozo_httpreq_t *request,
off_t len;
char date[40];
bozoheaders_t *hdr;
+ bozocustomheaders_t *chdr;
SIMPLEQ_FOREACH(hdr, &request->hr_replheaders, h_next) {
bozo_printf(httpd, "%s: %s\r\n", hdr->h_header,
hdr->h_value);
}
+ SIMPLEQ_FOREACH(chdr, &httpd->customheaders, h_next) {
+ bozo_printf(httpd, "%s\r\n", chdr->h_header);
+ }
+
bozo_printf(httpd, "Date: %s\r\n", bozo_http_date(date, sizeof(date)));
bozo_printf(httpd, "Server: %s\r\n", httpd->server_software);
bozo_printf(httpd, "Accept-Ranges: bytes\r\n");
@@ -2524,6 +2530,8 @@ bozo_init_httpd(bozohttpd_t *httpd)
#ifndef NO_LUA_SUPPORT
SIMPLEQ_INIT(&httpd->lua_states);
#endif
+
+ SIMPLEQ_INIT(&httpd->customheaders);
return 1;
}
@@ -2562,6 +2570,34 @@ bozo_set_defaults(bozohttpd_t *httpd, bozoprefs_t *prefs)
return bozo_init_httpd(httpd) && bozo_init_prefs(httpd, prefs);
}
+static void
+bozo_setup_customheaders(bozohttpd_t *httpd)
+{
+ struct bozocustomheaders *hdr;
+ FILE *fp;
+ char *fn, *line = NULL;
+ size_t linecap = 0;
+ ssize_t linelen;
+
+ bozoasprintf(httpd, &fn, "%s/%s", httpd->slashdir, CUSTOMHEADERS_FILE);
+ fp = fopen(fn, "r");
+ if (fp == NULL) {
+ free(fn);
+ return;
+ }
+
+ bozowarn(httpd, "reading %s", fn);
+ free(fn);
+ while ((linelen = getline(&line, &linecap, fp)) > 0) {
+ line[strcspn(line, "\n")] = '\0';
+ hdr = bozomalloc(httpd, sizeof *hdr);
+ hdr->h_header = bozostrdup(httpd, NULL, line);
+ SIMPLEQ_INSERT_TAIL(&httpd->customheaders, hdr, h_next);
+ }
+ free(line);
+ fclose(fp);
+}
+
/* set the virtual host name, port and root */
int
bozo_setup(bozohttpd_t *httpd, bozoprefs_t *prefs, const char *vhost,
@@ -2674,6 +2710,7 @@ bozo_setup(bozohttpd_t *httpd, bozoprefs_t *prefs, const char *vhost,
*/
bozo_ssl_init(httpd);
bozo_daemon_init(httpd);
+ bozo_setup_customheaders(httpd);
username = bozo_get_pref(prefs, "username");
if (username != NULL) {
diff --git a/libexec/httpd/bozohttpd.h b/libexec/httpd/bozohttpd.h
index cdfec757793e..811b891215da 100644
--- a/libexec/httpd/bozohttpd.h
+++ b/libexec/httpd/bozohttpd.h
@@ -64,6 +64,12 @@ typedef struct bozoheaders {
} bozoheaders_t;
SIMPLEQ_HEAD(qheaders, bozoheaders);
+typedef struct bozocustomheaders {
+ const char *h_header;
+ SIMPLEQ_ENTRY(bozocustomheaders) h_next;
+} bozocustomheaders_t;
+SIMPLEQ_HEAD(cheaders, bozocustomheaders);
+
#ifndef NO_LUA_SUPPORT
typedef struct lua_handler {
const char *name;
@@ -144,6 +150,7 @@ typedef struct bozohttpd_t {
ssize_t getln_buflen; /* length of allocated space */
char *errorbuf; /* no dynamic allocation allowed */
bozo_consts_t consts; /* various constants */
+ struct cheaders customheaders; /* Headers read from .bzcustomheaders */
} bozohttpd_t;
/* bozo_httpreq_t */
@@ -280,6 +287,9 @@ void debug__(bozohttpd_t *, int, const char *, ...) BOZO_PRINTFLIKE(3, 4);
#ifndef AUTH_FILE
#define AUTH_FILE ".htpasswd"
#endif
+#ifndef CUSTOMHEADERS_FILE
+#define CUSTOMHEADERS_FILE ".bzcustomheaders"
+#endif
/* be sure to always return this error up */
int bozo_http_error(bozohttpd_t *, int, bozo_httpreq_t *, const char *);
From: Martin Husemann <martin@duskware.de>
To: gnats-bugs@netbsd.org
Cc: mrg@netbsd.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org,
campbell+netbsd@mumble.net
Subject: Re: bin/58880: bozohttpd(8): set custom header field in responses
Date: Fri, 13 Dec 2024 09:30:57 +0100
Just a tangential node:
- if we always want to send all headers verbatim, it would be simpler to
create a single malloc() for the whole header file and make sure it has
no empty lines in it when reading, then just write it out in one
call. Gets rid of the simpleque and the iterations.
- if we consider doing value replacements later (not sure if that could
be usefull and what values to offer in that context) it would be easier
if we would parse the file into header and value pairs, unwrap continuation
lines and have them in a struct with header/value pointer on the simpleque.
Do other servers offer some kind of right-hand-side (value) string
substitutions for this?
Martin
From: Sunil Nimmagadda <sunil@nimmagadda.net>
To: Martin Husemann <martin@duskware.de>
Cc: gnats-bugs@netbsd.org, mrg@netbsd.org, gnats-admin@netbsd.org,
netbsd-bugs@netbsd.org, campbell+netbsd@mumble.net
Subject: Re: bin/58880: bozohttpd(8): set custom header field in responses
Date: Fri, 13 Dec 2024 18:26:25 +0530
Martin Husemann <martin@duskware.de> writes:
> Just a tangential node:
>
> - if we always want to send all headers verbatim, it would be simpler to
> create a single malloc() for the whole header file and make sure it has
> no empty lines in it when reading, then just write it out in one
> call. Gets rid of the simpleque and the iterations.
It's a nice idea except that the line delimiter mismatch ("\n" vs "\r\n")
between the file and HTTP headers will require fragmenting it anyway.
>
> - if we consider doing value replacements later (not sure if that could
> be usefull and what values to offer in that context) it would be easier
> if we would parse the file into header and value pairs, unwrap continuation
> lines and have them in a struct with header/value pointer on the simpleque.
>
> Do other servers offer some kind of right-hand-side (value) string
> substitutions for this?
Checked nginx[0], apache[1] and they do allow value substitutions.
On Jan 3, 2016, elric introduced the concept of reply headers[2] but I
couldn't see any code populating them. If we intend to support value
substitutions, I guess it's a good idea to tokenize the custom headers
from .bzcustomheaders file and use hr_replheaders.
[0] http://nginx.org/en/docs/http/ngx_http_headers_module.html
[1] https://httpd.apache.org/docs/2.4/mod/mod_headers.html
[2] http://cvsweb.netbsd.org/bsdweb.cgi/src/libexec/httpd/bozohttpd.c.diff?r1=1.77;r2=1.78
From: Taylor R Campbell <riastradh@NetBSD.org>
To: Sunil Nimmagadda <sunil@nimmagadda.net>
Cc: gnats-admin@netbsd.org,
netbsd-bugs@netbsd.org, gnats-bugs@netbsd.org
Subject: Re: bin/58880: bozohttpd(8): set custom header field in responses
Date: Fri, 13 Dec 2024 14:57:03 +0000
> Date: Fri, 13 Dec 2024 13:03:05 +0530
> From: Sunil Nimmagadda <sunil@nimmagadda.net>
>=20
> This diff allows custom headers to be specified in a .bzcustomheaders fil=
e at
> the root of the server. The lines from it are included verbatim as
> headers in all of the responses...
Awesome! Can I interest you in writing some automatic tests for this
too, including the edge cases martin@ mentioned?
From: matthew green <mrg@eterna23.net>
To: Sunil Nimmagadda <sunil@nimmagadda.net>
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org,
gnats-bugs@netbsd.org, campbell+netbsd@mumble.net
Subject: re: bin/58880: bozohttpd(8): set custom header field in responses
Date: Sat, 14 Dec 2024 05:40:45 +1100
thanks for the patch, i'll have a look soon.
.mrg.
From: Sunil Nimmagadda <sunil@nimmagadda.net>
To: "Taylor R Campbell via gnats" <gnats-admin@NetBSD.org>
Cc: mrg@netbsd.org, netbsd-bugs@netbsd.org, campbell+netbsd@mumble.net,
gnats-bugs@netbsd.org
Subject: Re: bin/58880: bozohttpd(8): set custom header field in responses
Date: Mon, 16 Dec 2024 17:58:59 +0530
--=-=-=
Content-Type: text/plain
"Taylor R Campbell via gnats" <gnats-admin@NetBSD.org> writes:
> The following reply was made to PR bin/58880; it has been noted by GNATS.
>
> From: Taylor R Campbell <riastradh@NetBSD.org>
> To: Sunil Nimmagadda <sunil@nimmagadda.net>
> Cc: gnats-admin@netbsd.org,
> netbsd-bugs@netbsd.org, gnats-bugs@netbsd.org
> Subject: Re: bin/58880: bozohttpd(8): set custom header field in responses
> Date: Fri, 13 Dec 2024 14:57:03 +0000
>
> > Date: Fri, 13 Dec 2024 13:03:05 +0530
> > From: Sunil Nimmagadda <sunil@nimmagadda.net>
> >=20
> > This diff allows custom headers to be specified in a .bzcustomheaders fil=
> e at
> > the root of the server. The lines from it are included verbatim as
> > headers in all of the responses...
>
> Awesome! Can I interest you in writing some automatic tests for this
> too, including the edge cases martin@ mentioned?
Sure, updated diff with atf test case. For now, this diff only supports
static text and no variable substitutions...
--=-=-=
Content-Type: text/x-patch
Content-Disposition: inline;
filename=0001-Implement-custom-headers-for-httpd.patch
Content-Description: Custom headers for bozohttpd
>From 7f8f1ab04076f7a276fd3fec892450880ac388e1 Mon Sep 17 00:00:00 2001
From: Sunil Nimmagadda <sunil@nimmagadda.net>
Date: Sat, 14 Dec 2024 09:00:05 +0530
Subject: [PATCH] Implement custom headers for httpd.
---
libexec/httpd/bozohttpd.8 | 5 ++
libexec/httpd/bozohttpd.c | 36 ++++++++++++++
libexec/httpd/bozohttpd.h | 10 ++++
tests/libexec/httpd/.bzcustomheaders | 2 +
tests/libexec/httpd/Makefile | 6 +++
tests/libexec/httpd/custom_headers.awk | 51 ++++++++++++++++++++
tests/libexec/httpd/index.html | 4 ++
tests/libexec/httpd/t_custom_headers.sh | 62 +++++++++++++++++++++++++
8 files changed, 176 insertions(+)
create mode 100644 tests/libexec/httpd/.bzcustomheaders
create mode 100644 tests/libexec/httpd/Makefile
create mode 100644 tests/libexec/httpd/custom_headers.awk
create mode 100644 tests/libexec/httpd/index.html
create mode 100644 tests/libexec/httpd/t_custom_headers.sh
diff --git a/libexec/httpd/bozohttpd.8 b/libexec/httpd/bozohttpd.8
index 196fcb52acc7..b37cfb50de6c 100644
--- a/libexec/httpd/bozohttpd.8
+++ b/libexec/httpd/bozohttpd.8
@@ -640,6 +640,11 @@ with a backslash
.Pq Ql \e
The right hand side of the colon is always used verbatim, no escape sequences
are interpreted.
+.Ss CUSTOM RESPONSE HEADERS
+If a
+.Pa .bzcustomheaders
+file is found at the root of the server, it is expected to contain
+custom headers to be included verbatim in all of the responses.
.Sh EXAMPLES
To configure set of virtual hosts, one would use an
.Xr inetd.conf 5
diff --git a/libexec/httpd/bozohttpd.c b/libexec/httpd/bozohttpd.c
index 656bdf073af3..a488f8b4fa5f 100644
--- a/libexec/httpd/bozohttpd.c
+++ b/libexec/httpd/bozohttpd.c
@@ -181,6 +181,7 @@ struct {
{ ABSREDIRECT_FILE, "rejected absredirect request" },
{ REMAP_FILE, "rejected remap request" },
{ AUTH_FILE, "rejected authfile request" },
+ { CUSTOMHEADERS_FILE, "rejected customheaders request" },
{ NULL, NULL },
};
@@ -1974,12 +1975,17 @@ bozo_print_header(bozo_httpreq_t *request,
off_t len;
char date[40];
bozoheaders_t *hdr;
+ bozocustomheaders_t *chdr;
SIMPLEQ_FOREACH(hdr, &request->hr_replheaders, h_next) {
bozo_printf(httpd, "%s: %s\r\n", hdr->h_header,
hdr->h_value);
}
+ SIMPLEQ_FOREACH(chdr, &httpd->customheaders, h_next) {
+ bozo_printf(httpd, "%s\r\n", chdr->h_header);
+ }
+
bozo_printf(httpd, "Date: %s\r\n", bozo_http_date(date, sizeof(date)));
bozo_printf(httpd, "Server: %s\r\n", httpd->server_software);
bozo_printf(httpd, "Accept-Ranges: bytes\r\n");
@@ -2524,6 +2530,8 @@ bozo_init_httpd(bozohttpd_t *httpd)
#ifndef NO_LUA_SUPPORT
SIMPLEQ_INIT(&httpd->lua_states);
#endif
+
+ SIMPLEQ_INIT(&httpd->customheaders);
return 1;
}
@@ -2562,6 +2570,33 @@ bozo_set_defaults(bozohttpd_t *httpd, bozoprefs_t *prefs)
return bozo_init_httpd(httpd) && bozo_init_prefs(httpd, prefs);
}
+static void
+bozo_setup_customheaders(bozohttpd_t *httpd)
+{
+ struct bozocustomheaders *hdr;
+ FILE *fp;
+ char *fn, *line = NULL;
+ size_t linecap = 0;
+ ssize_t linelen;
+
+ bozoasprintf(httpd, &fn, "%s/%s", httpd->slashdir, CUSTOMHEADERS_FILE);
+ fp = fopen(fn, "r");
+ if (fp == NULL) {
+ free(fn);
+ return;
+ }
+
+ free(fn);
+ while ((linelen = getline(&line, &linecap, fp)) > 0) {
+ line[strcspn(line, "\n")] = '\0';
+ hdr = bozomalloc(httpd, sizeof *hdr);
+ hdr->h_header = bozostrdup(httpd, NULL, line);
+ SIMPLEQ_INSERT_TAIL(&httpd->customheaders, hdr, h_next);
+ }
+ free(line);
+ fclose(fp);
+}
+
/* set the virtual host name, port and root */
int
bozo_setup(bozohttpd_t *httpd, bozoprefs_t *prefs, const char *vhost,
@@ -2674,6 +2709,7 @@ bozo_setup(bozohttpd_t *httpd, bozoprefs_t *prefs, const char *vhost,
*/
bozo_ssl_init(httpd);
bozo_daemon_init(httpd);
+ bozo_setup_customheaders(httpd);
username = bozo_get_pref(prefs, "username");
if (username != NULL) {
diff --git a/libexec/httpd/bozohttpd.h b/libexec/httpd/bozohttpd.h
index cdfec757793e..811b891215da 100644
--- a/libexec/httpd/bozohttpd.h
+++ b/libexec/httpd/bozohttpd.h
@@ -64,6 +64,12 @@ typedef struct bozoheaders {
} bozoheaders_t;
SIMPLEQ_HEAD(qheaders, bozoheaders);
+typedef struct bozocustomheaders {
+ const char *h_header;
+ SIMPLEQ_ENTRY(bozocustomheaders) h_next;
+} bozocustomheaders_t;
+SIMPLEQ_HEAD(cheaders, bozocustomheaders);
+
#ifndef NO_LUA_SUPPORT
typedef struct lua_handler {
const char *name;
@@ -144,6 +150,7 @@ typedef struct bozohttpd_t {
ssize_t getln_buflen; /* length of allocated space */
char *errorbuf; /* no dynamic allocation allowed */
bozo_consts_t consts; /* various constants */
+ struct cheaders customheaders; /* Headers read from .bzcustomheaders */
} bozohttpd_t;
/* bozo_httpreq_t */
@@ -280,6 +287,9 @@ void debug__(bozohttpd_t *, int, const char *, ...) BOZO_PRINTFLIKE(3, 4);
#ifndef AUTH_FILE
#define AUTH_FILE ".htpasswd"
#endif
+#ifndef CUSTOMHEADERS_FILE
+#define CUSTOMHEADERS_FILE ".bzcustomheaders"
+#endif
/* be sure to always return this error up */
int bozo_http_error(bozohttpd_t *, int, bozo_httpreq_t *, const char *);
diff --git a/tests/libexec/httpd/.bzcustomheaders b/tests/libexec/httpd/.bzcustomheaders
new file mode 100644
index 000000000000..3e2ca829597f
--- /dev/null
+++ b/tests/libexec/httpd/.bzcustomheaders
@@ -0,0 +1,2 @@
+Strict-Transport-Security: max-age=31536000
+Content-Security-Policy: default-src https:
diff --git a/tests/libexec/httpd/Makefile b/tests/libexec/httpd/Makefile
new file mode 100644
index 000000000000..936f616997c2
--- /dev/null
+++ b/tests/libexec/httpd/Makefile
@@ -0,0 +1,6 @@
+.include <bsd.own.mk>
+
+TESTSDIR= ${TESTSBASE}/libexec/httpd
+TESTS_SH= t_custom_headers
+
+.include <bsd.test.mk>
diff --git a/tests/libexec/httpd/custom_headers.awk b/tests/libexec/httpd/custom_headers.awk
new file mode 100644
index 000000000000..a7e00cb1847b
--- /dev/null
+++ b/tests/libexec/httpd/custom_headers.awk
@@ -0,0 +1,51 @@
+# Copyright (c) 2024 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Sunil Nimmagadda.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+BEGIN {
+ in_headers = 1
+ while (getline <".bzcustomheaders" > 0) {
+ custom_headers[$0] = 0
+ }
+}
+
+/^$/ { in_headers = 0 }
+
+{
+ if (in_headers && $0 in custom_headers) {
+ custom_headers[$0] += 1
+ }
+}
+
+END {
+ for (h in custom_headers) {
+ if (custom_headers[h] == 0) {
+ printf("\'%s\' header not found\n", h)
+ exit 1
+ }
+ }
+}
diff --git a/tests/libexec/httpd/index.html b/tests/libexec/httpd/index.html
new file mode 100644
index 000000000000..b0941bbd5809
--- /dev/null
+++ b/tests/libexec/httpd/index.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<html lang="en">
+<head><title>hello world!</title></head>
+</html>
diff --git a/tests/libexec/httpd/t_custom_headers.sh b/tests/libexec/httpd/t_custom_headers.sh
new file mode 100644
index 000000000000..666af720accc
--- /dev/null
+++ b/tests/libexec/httpd/t_custom_headers.sh
@@ -0,0 +1,62 @@
+# Copyright (c) 2024 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Sunil Nimmagadda.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+atf_test_case custom_headers cleanup
+custom_headers_head()
+{
+ atf_set "descr" "Check for custom HTTP headers"
+}
+
+HTTPD_PID=./.__httpd.pid
+custom_headers_body()
+{
+ # start httpd in daemon mode
+ atf_check -s exit:0 \
+ /usr/libexec/httpd -P $HTTPD_PID -I 8080 -b .
+
+ atf_check -s exit:0 \
+ printf "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n" | \
+ nc 127.0.0.1 8080 | \
+ tr -d '\r' | \
+ awk -f $(atf_get_srcdir)/custom_headers.awk
+}
+
+custom_headers_cleanup()
+{
+ if [ -f "$HTTPD_PID" ]; then
+ echo kill -9 "$(cat $HTTPD_PID)"
+ kill -9 "$(cat $HTTPD_PID)"
+ echo '# wait for httpd to exit'
+ sleep 1
+ fi
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case custom_headers
+}
--
2.47.0
--=-=-=--
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2024
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.