Pinging this patch. On Tue, 10 Oct 2017 21:31:20 -0700 Ori Bernstein <o...@eigenstate.org> wrote:
> My website generator is a little stupid at times. It generates > files with .html suffixes, but urls without them. > > I worked around this with some redirects, but it never felt > quite right doing an extra round trip. Therefore, I added > internal redirects, processing the rewrite before responding to > an http request. > > This introduces new syntax to the config file, allowing you to > do: > > location match "^(/foo/bar/[%w]+)$" { > rewrite-to "/baz/%1.html" > } > > Because we don't know what the paths should be relative > to, all paths rewritten must be absolute. > > It seems like someone else may find it useful[1], so > I'm submitting it. I've been running a slightly older > version of this on https://myrlang.org for the last > day or two, and it's been uneventful. The difference > is that the syntax used to piggy back off the "block" > action => 'block internal return 302 "path"'. > > This doesn't currently support chained rewrites. I think > that it wouldn't be hard to add if it's needed. > > Ok? > > [1] https://github.com/reyk/httpd/issues/27 > ========================================== > > > diff --git usr.sbin/httpd/config.c usr.sbin/httpd/config.c > index 3c31c3d4cd3..7d2982af7b9 100644 > --- usr.sbin/httpd/config.c > +++ usr.sbin/httpd/config.c > @@ -448,7 +448,7 @@ config_getserver_config(struct httpd *env, struct server > *srv, > sizeof(srv_conf->errorlog)); > } > > - f = SRVFLAG_BLOCK|SRVFLAG_NO_BLOCK; > + f = SRVFLAG_BLOCK|SRVFLAG_NO_BLOCK|SRVFLAG_REWRITE; > if ((srv_conf->flags & f) == 0) { > free(srv_conf->return_uri); > srv_conf->flags |= parent->flags & f; > diff --git usr.sbin/httpd/httpd.conf.5 usr.sbin/httpd/httpd.conf.5 > index a3c97629de3..3a00a750537 100644 > --- usr.sbin/httpd/httpd.conf.5 > +++ usr.sbin/httpd/httpd.conf.5 > @@ -454,6 +454,14 @@ instead of the log files. > Disable any previous > .Ic block > in a location. > +.It Ic rewrite-to Ar path > +The current request path is rewritten to > +.Ar path . > +using the same macro expansions as > +.Cm block return > +rules. After macros are substituted, the resulting paths must be > +absolute, beginning with a slash. Rewriting is not done > +recursively. > .It Ic root Ar option > Configure the document root and options for the request path. > Valid options are: > diff --git usr.sbin/httpd/httpd.h usr.sbin/httpd/httpd.h > index 05cbb8e3550..477115ec92d 100644 > --- usr.sbin/httpd/httpd.h > +++ usr.sbin/httpd/httpd.h > @@ -394,6 +394,7 @@ SPLAY_HEAD(client_tree, client); > #define SRVFLAG_SERVER_MATCH 0x00200000 > #define SRVFLAG_SERVER_HSTS 0x00400000 > #define SRVFLAG_DEFAULT_TYPE 0x00800000 > +#define SRVFLAG_REWRITE 0x01000000 > > #define SRVFLAG_BITS \ > "\10\01INDEX\02NO_INDEX\03AUTO_INDEX\04NO_AUTO_INDEX" \ > diff --git usr.sbin/httpd/parse.y usr.sbin/httpd/parse.y > index fcf1938c42d..4072ee5b532 100644 > --- usr.sbin/httpd/parse.y > +++ usr.sbin/httpd/parse.y > @@ -134,7 +134,7 @@ typedef struct { > %token LISTEN LOCATION LOG LOGDIR MATCH MAXIMUM NO NODELAY OCSP ON > PORT PREFORK > %token PROTOCOLS REQUESTS ROOT SACK SERVER SOCKET STRIP STYLE SYSLOG > TCP TICKET > %token TIMEOUT TLS TYPE TYPES HSTS MAXAGE SUBDOMAINS DEFAULT PRELOAD > REQUEST > -%token ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN PASS > +%token ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN REWRITE PASS > %token <v.string> STRING > %token <v.number> NUMBER > %type <v.port> port > @@ -986,6 +986,11 @@ filter : block RETURN NUMBER optstring { > srv_conf->return_uri_len = strlen($4) + 1; > } > } > + | REWRITE STRING { > + srv_conf->flags |= SRVFLAG_REWRITE; > + srv_conf->return_uri = $2; > + srv_conf->return_uri_len = strlen($2) + 1; > + } > | block DROP { > /* No return code, silently drop the connection */ > srv_conf->return_code = 0; > @@ -1255,6 +1260,7 @@ lookup(char *s) > { "request", REQUEST }, > { "requests", REQUESTS }, > { "return", RETURN }, > + { "rewrite-to", REWRITE }, > { "root", ROOT }, > { "sack", SACK }, > { "server", SERVER }, > diff --git usr.sbin/httpd/server_http.c usr.sbin/httpd/server_http.c > index e64de0d2f9c..c9ea4771037 100644 > --- usr.sbin/httpd/server_http.c > +++ usr.sbin/httpd/server_http.c > @@ -1162,10 +1162,34 @@ server_expand_http(struct client *clt, const char > *val, char *buf, > return (buf); > } > > +static int > +server_set_path(struct http_descriptor *desc, char *input) > +{ > + char path[PATH_MAX]; > + > + if (input == NULL || url_decode(input) == NULL) > + return -1; > + if (canonicalize_path(input, path, sizeof(path)) == NULL) > + return (-1); > + free(desc->http_path); > + if ((desc->http_path = strdup(path)) == NULL) > + return(-1); > + return (0); > +} > + > +static int > +server_rewrite(struct client *clt, struct http_descriptor *desc, char *input) > +{ > + char path[PATH_MAX]; > + > + if (server_expand_http(clt, input, path, sizeof(path)) == NULL) > + return -1; > + return (server_set_path(desc, path)); > +} > + > int > server_response(struct httpd *httpd, struct client *clt) > { > - char path[PATH_MAX]; > char hostname[HOST_NAME_MAX+1]; > struct http_descriptor *desc = clt->clt_descreq; > struct http_descriptor *resp = clt->clt_descresp; > @@ -1178,12 +1202,7 @@ server_response(struct httpd *httpd, struct client > *clt) > const char *errstr = NULL; > > /* Canonicalize the request path */ > - if (desc->http_path == NULL || > - url_decode(desc->http_path) == NULL || > - canonicalize_path(desc->http_path, path, sizeof(path)) == NULL) > - goto fail; > - free(desc->http_path); > - if ((desc->http_path = strdup(path)) == NULL) > + if (server_set_path(desc, desc->http_path) == -1) > goto fail; > > key.kv_key = "Host"; > @@ -1284,6 +1303,10 @@ server_response(struct httpd *httpd, struct client > *clt) > /* Now search for the location */ > srv_conf = server_getlocation(clt, desc->http_path); > > + /* If we have an internal redirection, rewrite the URL */ > + if (srv_conf->flags & SRVFLAG_REWRITE) > + if (server_rewrite(clt, desc, srv_conf->return_uri) == -1) > + goto fail; > if (srv_conf->flags & SRVFLAG_BLOCK) { > server_abort_http(clt, srv_conf->return_code, > srv_conf->return_uri); > -- Ori Bernstein <o...@eigenstate.org>