OpenBSD's httpd refuses to serve an index file and returns a nasty "500 Internal Server Error" when the URL that's being requested does not contain a file name and there's a rewrite rule for the path in httpd.conf. Here's an excerpt from my httpd.conf that demonstrates the issue:
location match "/~(.*)" { request rewrite "/users/%1" } Example URL: https://example.org/~joe/ This doesn't work properly because the pointer http_path_alias is assigned in server_response() whenever a rewrite rule is processed, but is subsequently checked for NULL in server_file_access() in an attempt to detect an infinite recursive loop. I've attached a patch for your consideration. It makes a lot of sense to me to simply use a counter. This even improves readability. Let me know what you think, thanks! Sincerely, Erik
Index: usr.sbin/httpd/server_file.c =================================================================== RCS file: /cvs/src/usr.sbin/httpd/server_file.c,v retrieving revision 1.75 diff -u -r1.75 server_file.c --- usr.sbin/httpd/server_file.c 15 Aug 2022 09:40:14 -0000 1.75 +++ usr.sbin/httpd/server_file.c 2 Jun 2023 04:36:02 -0000 @@ -38,7 +38,7 @@ #define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) int server_file_access(struct httpd *, struct client *, - char *, size_t); + char *, size_t, int); int server_file_request(struct httpd *, struct client *, char *, struct timespec *); int server_partial_file_request(struct httpd *, struct client *, @@ -52,7 +52,7 @@ int server_file_access(struct httpd *env, struct client *clt, - char *path, size_t len) + char *path, size_t len, int attempts) { struct http_descriptor *desc = clt->clt_descreq; struct server_config *srv_conf = clt->clt_srv_conf; @@ -72,7 +72,7 @@ goto fail; } - if (desc->http_path_alias != NULL) { + if (attempts > 0) { /* Recursion - the index "file" is a directory? */ errno = EINVAL; goto fail; @@ -111,7 +111,7 @@ goto fail; } - ret = server_file_access(env, clt, path, len); + ret = server_file_access(env, clt, path, len, attempts + 1); if (ret == 404) { /* * Index file not found; fail if auto-indexing is @@ -179,7 +179,7 @@ } /* Returns HTTP status code on error */ - if ((ret = server_file_access(env, clt, path, sizeof(path))) > 0) { + if ((ret = server_file_access(env, clt, path, sizeof(path), 0)) > 0) { errstr = desc->http_path_alias != NULL ? desc->http_path_alias : desc->http_path; goto abort;