aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOmar Polo <op@omarpolo.com>2024-08-24 10:35:56 +0000
committerOmar Polo <op@omarpolo.com>2024-08-24 12:43:19 +0200
commit66000479ed4eff21b9958a12bed34911f7544366 (patch)
treea7206ae2f5f17dbcbcd04df5397590daf4f507e0
parent7e444bb814858183a5761f50037028c1f12416c7 (diff)
regress/fcgi: dump and check all the parameters
-rw-r--r--regress/fcgi-test.c95
-rw-r--r--regress/lib.sh27
-rw-r--r--regress/tests.sh17
3 files changed, 124 insertions, 15 deletions
diff --git a/regress/fcgi-test.c b/regress/fcgi-test.c
index 8f2f9ec..ed6ec4e 100644
--- a/regress/fcgi-test.c
+++ b/regress/fcgi-test.c
@@ -43,6 +43,10 @@
#define SUM(a, b) (((a) << 8) + (b))
+#ifndef nitems
+#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
+#endif
+
struct fcgi_header {
uint8_t version;
uint8_t type;
@@ -63,6 +67,11 @@ struct fcgi_end_req_body {
unsigned char reserved[3];
};
+struct param {
+ char name[32];
+ char value[128];
+};
+
static int
prepare_header(struct fcgi_header *h, int type, int id, size_t size,
size_t padding)
@@ -156,12 +165,65 @@ assert_record(int fd, int type)
consume(fd, hdr.padding);
}
+static int
+parse_len(int sock)
+{
+ unsigned char c, x[3];
+
+ must_read(sock, &c, 1);
+ if (c >> 7 == 0)
+ return (c);
+
+ must_read(sock, &x, sizeof(x));
+ return (((c & 0x7F) << 24) | (x[0] << 16) | (x[1] << 8) | x[2]);
+}
+
+static void
+parse_params(int sock, struct param *param, struct fcgi_header *hdr)
+{
+ int tot;
+ int nlen, vlen;
+
+ tot = SUM(hdr->content_len1, hdr->content_len0);
+ tot -= sizeof(*hdr);
+
+ nlen = parse_len(sock);
+ vlen = parse_len(sock);
+
+ if (nlen + vlen != tot)
+ errx(1, "unexpected length, name=%d val=%d exp=%d",
+ nlen, vlen, tot);
+
+ if ((size_t)nlen > sizeof(param->name) - 1 ||
+ (size_t)vlen > sizeof(param->value) - 1)
+ errx(1, "parameter name or value too long");
+
+ memset(param, 0, sizeof(*param));
+ must_read(sock, param->name, nlen);
+ must_read(sock, param->value, vlen);
+
+ if (!strcmp(param->name, "SERVER_NAME"))
+ strlcpy(param->value, "<redacted>", sizeof(param->value));
+
+ consume(sock, hdr->padding);
+}
+
+static int
+param_cmp(const void *a, const void *b)
+{
+ const struct param *x = a, *y = b;
+
+ return (strcmp(x->name, y->name));
+}
+
int
main(int argc, char **argv)
{
struct fcgi_header hdr;
struct fcgi_end_req_body end;
struct sockaddr_un sun;
+ struct param params[64];
+ size_t i, nparam;
const char *path;
const char *msg;
size_t len;
@@ -201,37 +263,58 @@ main(int argc, char **argv)
assert_record(s, FCGI_BEGIN_REQUEST);
/* read params */
+ nparam = 0;
for (;;) {
read_header(s, &hdr);
- consume(s, SUM(hdr.content_len1, hdr.content_len0));
- consume(s, hdr.padding);
-
if (hdr.type != FCGI_PARAMS)
errx(1, "got %d; expecting PARAMS", hdr.type);
if (hdr.content_len0 == 0 &&
hdr.content_len1 == 0 &&
- hdr.padding == 0)
+ hdr.padding == 0) {
+ consume(s, SUM(hdr.content_len1, hdr.content_len0));
+ consume(s, hdr.padding);
break;
+ }
+
+ if (nparam == nitems(params))
+ errx(1, "too many parameters");
+
+ parse_params(s, &params[nparam++], &hdr);
}
assert_record(s, FCGI_STDIN);
- msg = "20 text/gemini\r\n# hello from fastcgi!\n";
+ msg = "20 text/gemini\r\n";
len = strlen(msg);
prepare_header(&hdr, FCGI_STDOUT, 1, len, 0);
must_write(s, &hdr, sizeof(hdr));
must_write(s, msg, len);
- msg = "some more content in the page...\n";
+ msg = "Here's the parameters I've got:\n";
len = strlen(msg);
prepare_header(&hdr, FCGI_STDOUT, 1, len, 0);
must_write(s, &hdr, sizeof(hdr));
must_write(s, msg, len);
+ qsort(params, nparam, sizeof(params[0]), param_cmp);
+ for (i = 0; i < nparam; ++i) {
+ char line[256];
+ int r;
+
+ r = snprintf(line, sizeof(line), "* %s=%s\n",
+ params[i].name, params[i].value);
+ if (r < 0 || (size_t)r >= sizeof(line))
+ errx(1, "line too short");
+
+ prepare_header(&hdr, FCGI_STDOUT, 1, r, 0);
+ must_write(s, &hdr, sizeof(hdr));
+ must_write(s, line, r);
+ }
+
prepare_header(&hdr, FCGI_END_REQUEST, 1, sizeof(end), 0);
write(s, &hdr, sizeof(hdr));
memset(&end, 0, sizeof(end));
diff --git a/regress/lib.sh b/regress/lib.sh
index d5e9609..9abfa1e 100644
--- a/regress/lib.sh
+++ b/regress/lib.sh
@@ -9,6 +9,31 @@ current_test=
server_name=
gghost=
+fcgi_content() {
+ remote_host=::1
+ if [ "$HAVE_IPV6" != yes ]; then
+ remote_host=127.0.0.1
+ fi
+
+ cat <<EOF
+Here's the parameters I've got:
+* AUTH_TYPE=
+* GATEWAY_INTERFACE=CGI/1.1
+* GEMINI_URL_PATH=${fcgi_path_info##/}
+* PATH_INFO=$fcgi_path_info
+* PATH_TRANSLATED=$fcgi_path
+* QUERY_STRING=
+* REMOTE_ADDR=$remote_host
+* REMOTE_HOST=$remote_host
+* REQUEST_METHOD=GET
+* SCRIPT_NAME=
+* SERVER_NAME=<redacted>
+* SERVER_PORT=$port
+* SERVER_PROTOCOL=GEMINI
+* SERVER_SOFTWARE=$($gmid -V | awk '{print $2 "/" $3}')
+EOF
+}
+
run_test() {
ggflags=
host="$REGRESS_HOST"
@@ -16,6 +41,8 @@ run_test() {
proxy_port=10966
proxy=
config_common="log syslog off"
+ fcgi_path_info=/
+ fcgi_path="$PWD/testdata/"
hdr=
body=
dont_check_server_alive=no
diff --git a/regress/tests.sh b/regress/tests.sh
index b5fa93e..b2fe511 100644
--- a/regress/tests.sh
+++ b/regress/tests.sh
@@ -306,12 +306,10 @@ test_fastcgi() {
setup_simple_test 'prefork 1' 'fastcgi socket "'$PWD'/fcgi.sock"'
- msg=$(printf "# hello from fastcgi!\nsome more content in the page...")
-
i=0
while [ $i -lt 10 ]; do
fetch /
- check_reply "20 text/gemini" "$msg"
+ check_reply "20 text/gemini" "$(fcgi_content)"
if [ $? -ne 0 ]; then
kill $fcgi_pid
return 1
@@ -327,15 +325,16 @@ test_fastcgi() {
test_fastcgi_inside_location() {
./fcgi-test fcgi.sock &
fcgi_pid=$!
+ fcgi_path_info="/foo"
+ fcgi_path="$PWD/testdata/foo"
setup_simple_test 'prefork 1' 'fastcgi socket "'$PWD'/fcgi.sock"
location "/dir/*" {
fastcgi off
}'
- msg=$(printf "# hello from fastcgi!\nsome more content in the page...")
fetch /foo
- if ! check_reply "20 text/gemini" "$msg"; then
+ if ! check_reply "20 text/gemini" "$(fcgi_content)"; then
kill $fcgi_pid
return 1
fi
@@ -353,6 +352,8 @@ test_fastcgi_inside_location() {
test_fastcgi_location_match() {
./fcgi-test fcgi.sock &
fcgi_pid=$!
+ fcgi_path_info="/foo"
+ fcgi_path="$PWD/testdata/foo"
setup_simple_test 'prefork 1' '
location "/dir/*" {
@@ -362,9 +363,8 @@ test_fastcgi_location_match() {
fastcgi socket "'$PWD'/fcgi.sock"
}'
- msg=$(printf "# hello from fastcgi!\nsome more content in the page...")
fetch /foo
- if ! check_reply "20 text/gemini" "$msg"; then
+ if ! check_reply "20 text/gemini" "$(fcgi_content)"; then
kill $fcgi_pid
return 1
fi
@@ -387,9 +387,8 @@ test_fastcgi_deprecated_syntax() {
# backward compatibility works.
setup_simple_test 'prefork 1' 'fastcgi "'$PWD'/fcgi.sock"'
- msg=$(printf "# hello from fastcgi!\nsome more content in the page...")
fetch /
- check_reply "20 text/gemini" "$msg"
+ check_reply "20 text/gemini" "$(fcgi_content)"
if [ $? -ne 0 ]; then
kill $fcgi_pid
return 1