Re: patch: adding httpd implicit file extensions
On 2/27/21 3:10 AM, Stuart Henderson wrote: I might be missing something but doesn't this do the same? location not found match "/(.*)" { request rewrite "/%1.html" } Nope, you're not missing anything, I wasn't aware you could do this. This *does* actually solve my problem, although it should be location not found match "/(.+)" (with `.+` instead of `.*`) in order for it to work properly with `index.html`. I guess my patch is pretty unnecessary :) On 2/27/21 3:10 AM, Stuart Henderson wrote: Custom error pages sound useful indeed. My patch for that is actually quite small (including a slight tweak to the default font). It hardcodes the error file path to `/.html` (e.g. /var/www/htdocs/404.html) and if that file exists, it uses that file's contents instead of a hardcoded error string. It's not very configurable, but it gets the job done: Index: server_http.c === RCS file: /cvs/src/usr.sbin/httpd/server_http.c,v retrieving revision 1.143 diff -u -p -u -p -r1.143 server_http.c --- server_http.c 5 Jan 2021 19:56:11 - 1.143 +++ server_http.c 27 Feb 2021 23:31:13 - @@ -848,6 +848,8 @@ server_abort_http(struct client *clt, un char buf[IBUF_READ_SIZE]; char*escapedmsg = NULL; int bodylen; + char err_path[PATH_MAX]; + FILE*f; if (code == 0) { server_close(clt, "dropped"); @@ -925,14 +927,25 @@ server_abort_http(struct client *clt, un /* A CSS stylesheet allows minimal customization by the user */ style = "body { background-color: white; color: black; font-family: " - "'Comic Sans MS', 'Chalkboard SE', 'Comic Neue', sans-serif; }\n" + "sans-serif; }\n" "hr { border: 0; border-bottom: 1px dashed; }\n" "@media (prefers-color-scheme: dark) {\n" "body { background-color: #1E1F21; color: #EEEFF1; }\n" "a { color: #BAD7FF; }\n}"; + /* Check for error document HTML file */ + bodylen = 0; + if (snprintf(err_path, sizeof(err_path), "%s/%d.html", srv_conf->root, + code) != -1 && (f = fopen(err_path, "r")) != NULL) { + fseek(f, 0, SEEK_END); + bodylen = ftell(f); + fseek(f, 0, SEEK_SET); + body = calloc(bodylen + 1, sizeof(char)); + bodylen = body ? fread(body, sizeof(char), bodylen, f) : 0; + } + /* Generate simple HTML error document */ - if ((bodylen = asprintf(, + if (bodylen == 0 && (bodylen = asprintf(, "\n" "\n" "\n"
Re: patch: adding httpd implicit file extensions
On 2021/02/26 15:38, Bruce Hill wrote: > Hello, this is my first time contributing to openbsd and this mailing > list, so please excuse any newbie blunders. I recently switched my > personal website to use httpd with statically generated HTML files, but > was unhappy to find that my HTML files could only be accessed by exact > filename, including the ".html" at the end. My site previously ran on > Apache with rewrite rules to ensure that "example.com/foo" would serve > the file "/foo.html" (when "/foo" didn't exist). I wanted to keep my > original URLs working and I aesthetically prefer URLs without ".html" > suffixes, so I looked around for different options with httpd. The best > option I could find was to create symbolic links from "/foo" to > "/foo.html" and set the default media type to text/html, but this > solution was cumbersome (I had to maintain all the symbolic links) and > had undesirable side effects (all extensionless files were treated as > text/html instead of text/plain). > > I decided instead to look into modifying httpd to support implicit file > extensions. My basic idea was to add a configurable setting called > `implicit extension`. When a file is not found and the file doesn't > already have the implicit extension, then httpd will look for the same > filename but with the implicit extension added at the end, and reroute > to that file if it exists. This neatly solves my problem by adding > `implicit extension ".html"` to the top of my /etc/httpd.conf file, and > `implicit extension ".php"` to the section of my website that uses PHP > scripts. For simplicity (and because my website doesn't use both HTML > and PHP in the same subdomain), I opted to only support a single > implicit extension per config block, though in the future, supporting > globs as implicit extensions might also be nice(e.g. `implicit extension > ".{html,php}"`). I might be missing something but doesn't this do the same? location not found match "/(.*)" { request rewrite "/%1.html" } > I've been running the code on my personal website for a while now > without any issues. If this patch is accepted, I also have a separate > small patch that displays custom HTTP error pages if you have a > /[] file (e.g. /404 or /404.html), which > works well in conjunction with this patch. Custom error pages sound useful indeed. > I'm happy to take any feedback or criticism on both the idea and my > implementation patch below. Hopefully other people find this useful as > well! > > - Bruce Hill > > > Index: config.c > === > RCS file: /cvs/src/usr.sbin/httpd/config.c,v > retrieving revision 1.61 > diff -u -p -u -p -r1.61 config.c > --- config.c 21 Sep 2020 09:42:07 - 1.61 > +++ config.c 26 Feb 2021 23:30:18 - > @@ -568,6 +568,13 @@ config_getserver_config(struct httpd *en > >default_type, sizeof(struct media_type)); > } > + f = SRVFLAG_IMPLICIT_EXT; > + if ((srv_conf->flags & f) == 0) { > + srv_conf->flags |= parent->flags & f; > + memcpy(_conf->implicit_extension, > + >implicit_extension, > sizeof(parent->implicit_extension)); > + } > + > f = SRVFLAG_PATH_REWRITE|SRVFLAG_NO_PATH_REWRITE; > if ((srv_conf->flags & f) == 0) { > srv_conf->flags |= parent->flags & f; > Index: httpd.h > === > RCS file: /cvs/src/usr.sbin/httpd/httpd.h,v > retrieving revision 1.153 > diff -u -p -u -p -r1.153 httpd.h > --- httpd.h 29 Oct 2020 12:30:52 - 1.153 > +++ httpd.h 26 Feb 2021 23:30:19 - > @@ -57,6 +57,7 @@ > #define HTTPD_REALM_MAX 255 > #define HTTPD_LOCATION_MAX 255 > #define HTTPD_DEFAULT_TYPE { "bin", "application", "octet-stream", NULL } > +#define HTTPD_IMPLICIT_EXT "" > #define HTTPD_LOGVIS VIS_NL|VIS_TAB|VIS_CSTYLE > #define HTTPD_TLS_CERT "/etc/ssl/server.crt" > #define HTTPD_TLS_KEY"/etc/ssl/private/server.key" > @@ -391,6 +392,7 @@ SPLAY_HEAD(client_tree, client); > #define SRVFLAG_DEFAULT_TYPE 0x0080 > #define SRVFLAG_PATH_REWRITE 0x0100 > #define SRVFLAG_NO_PATH_REWRITE 0x0200 > +#define SRVFLAG_IMPLICIT_EXT 0x0400 > #define SRVFLAG_LOCATION_FOUND 0x4000 > #define SRVFLAG_LOCATION_NOT_FOUND 0x8000 > @@ -399,8 +401,8 @@ SPLAY_HEAD(client_tree, client); > "\05ROOT\06LOCATION\07FCGI\10NO_FCGI\11LOG\12NO_LOG"\ > "\14SYSLOG\15NO_SYSLOG\16TLS\17ACCESS_LOG\20ERROR_LOG" \ > "\21AUTH\22NO_AUTH\23BLOCK\24NO_BLOCK\25LOCATION_MATCH" \ > - "\26SERVER_MATCH\27SERVER_HSTS\30DEFAULT_TYPE\31PATH\32NO_PATH" \ > - "\37LOCATION_FOUND\40LOCATION_NOT_FOUND" > +
Re: patch: adding httpd implicit file extensions
On 2021-02-27 00:38, Bruce Hill wrote: > Hello, this is my first time contributing to openbsd and this mailing > list, so please excuse any newbie blunders. I recently switched my > personal website to use httpd with statically generated HTML files, but > was unhappy to find that my HTML files could only be accessed by exact > filename, including the ".html" at the end. My site previously ran on > Apache with rewrite rules to ensure that "example.com/foo" would serve > the file "/foo.html" (when "/foo" didn't exist). I wanted to keep my > original URLs working and I aesthetically prefer URLs without ".html" > suffixes, so I looked around for different options with httpd. The best > option I could find was to create symbolic links from "/foo" to > "/foo.html" and set the default media type to text/html, but this > solution was cumbersome (I had to maintain all the symbolic links) and > had undesirable side effects (all extensionless files were treated as > text/html instead of text/plain). > Hello, wouldn't the following serve for what you want? location not found match "^/scripts/(.*)$" { request rewrite "/scripts/%1.php" } location not found match "^/(.*)$" { request rewrite "/%1.html" }
patch: adding httpd implicit file extensions
Hello, this is my first time contributing to openbsd and this mailing list, so please excuse any newbie blunders. I recently switched my personal website to use httpd with statically generated HTML files, but was unhappy to find that my HTML files could only be accessed by exact filename, including the ".html" at the end. My site previously ran on Apache with rewrite rules to ensure that "example.com/foo" would serve the file "/foo.html" (when "/foo" didn't exist). I wanted to keep my original URLs working and I aesthetically prefer URLs without ".html" suffixes, so I looked around for different options with httpd. The best option I could find was to create symbolic links from "/foo" to "/foo.html" and set the default media type to text/html, but this solution was cumbersome (I had to maintain all the symbolic links) and had undesirable side effects (all extensionless files were treated as text/html instead of text/plain). I decided instead to look into modifying httpd to support implicit file extensions. My basic idea was to add a configurable setting called `implicit extension`. When a file is not found and the file doesn't already have the implicit extension, then httpd will look for the same filename but with the implicit extension added at the end, and reroute to that file if it exists. This neatly solves my problem by adding `implicit extension ".html"` to the top of my /etc/httpd.conf file, and `implicit extension ".php"` to the section of my website that uses PHP scripts. For simplicity (and because my website doesn't use both HTML and PHP in the same subdomain), I opted to only support a single implicit extension per config block, though in the future, supporting globs as implicit extensions might also be nice(e.g. `implicit extension ".{html,php}"`). I've been running the code on my personal website for a while now without any issues. If this patch is accepted, I also have a separate small patch that displays custom HTTP error pages if you have a /[] file (e.g. /404 or /404.html), which works well in conjunction with this patch. I'm happy to take any feedback or criticism on both the idea and my implementation patch below. Hopefully other people find this useful as well! - Bruce Hill Index: config.c === RCS file: /cvs/src/usr.sbin/httpd/config.c,v retrieving revision 1.61 diff -u -p -u -p -r1.61 config.c --- config.c21 Sep 2020 09:42:07 - 1.61 +++ config.c26 Feb 2021 23:30:18 - @@ -568,6 +568,13 @@ config_getserver_config(struct httpd *en >default_type, sizeof(struct media_type)); } + f = SRVFLAG_IMPLICIT_EXT; + if ((srv_conf->flags & f) == 0) { + srv_conf->flags |= parent->flags & f; + memcpy(_conf->implicit_extension, + >implicit_extension, sizeof(parent->implicit_extension)); + } + f = SRVFLAG_PATH_REWRITE|SRVFLAG_NO_PATH_REWRITE; if ((srv_conf->flags & f) == 0) { srv_conf->flags |= parent->flags & f; Index: httpd.h === RCS file: /cvs/src/usr.sbin/httpd/httpd.h,v retrieving revision 1.153 diff -u -p -u -p -r1.153 httpd.h --- httpd.h 29 Oct 2020 12:30:52 - 1.153 +++ httpd.h 26 Feb 2021 23:30:19 - @@ -57,6 +57,7 @@ #define HTTPD_REALM_MAX255 #define HTTPD_LOCATION_MAX 255 #define HTTPD_DEFAULT_TYPE { "bin", "application", "octet-stream", NULL } +#define HTTPD_IMPLICIT_EXT "" #define HTTPD_LOGVIS VIS_NL|VIS_TAB|VIS_CSTYLE #define HTTPD_TLS_CERT "/etc/ssl/server.crt" #define HTTPD_TLS_KEY "/etc/ssl/private/server.key" @@ -391,6 +392,7 @@ SPLAY_HEAD(client_tree, client); #define SRVFLAG_DEFAULT_TYPE 0x0080 #define SRVFLAG_PATH_REWRITE 0x0100 #define SRVFLAG_NO_PATH_REWRITE0x0200 +#define SRVFLAG_IMPLICIT_EXT 0x0400 #define SRVFLAG_LOCATION_FOUND 0x4000 #define SRVFLAG_LOCATION_NOT_FOUND 0x8000 @@ -399,8 +401,8 @@ SPLAY_HEAD(client_tree, client); "\05ROOT\06LOCATION\07FCGI\10NO_FCGI\11LOG\12NO_LOG" \ "\14SYSLOG\15NO_SYSLOG\16TLS\17ACCESS_LOG\20ERROR_LOG"\ "\21AUTH\22NO_AUTH\23BLOCK\24NO_BLOCK\25LOCATION_MATCH" \ - "\26SERVER_MATCH\27SERVER_HSTS\30DEFAULT_TYPE\31PATH\32NO_PATH" \ - "\37LOCATION_FOUND\40LOCATION_NOT_FOUND" + "\26SERVER_MATCH\27SERVER_HSTS\30DEFAULT_TYPE\31PATH\32NO_PATH" \ + "\33IMPLICIT_EXTENSION\37LOCATION_FOUND\40LOCATION_NOT_FOUND" #define TCPFLAG_NODELAY 0x01 #define TCPFLAG_NNODELAY 0x02 @@ -481,6 +483,7 @@ struct server_config { char accesslog[PATH_MAX]; char errorlog[PATH_MAX]; struct media_typedefault_type; + char