On Tue, May 29, 2018 at 10:00:22PM +0200, Hiltjo Posthuma wrote:
> On Tue, May 29, 2018 at 06:48:31PM +0200, Reyk Floeter wrote:
> > Hi,
> >
> > it's about time.
> >
> > server "default" {
> > listen on * port 80
> > location match "/de/(.*)" {
> > request rewrite "/ch/%1"
> > }
> > }
> >
> > You can also you the macros as in the "block return" external
> > redirects. So maybe something like:
> >
> > server "default" {
> > listen on * port 80
> > location match "/(.*)" {
> > request rewrite "/$HTTP_HOST/%1"
> > }
> > }
> >
>
> The syntax looks clear in my opinion.
>
> Would it be a good idea in your opinion to have request path rewriting in
> relayd also? For example to rewrite the request path for the (internal)
> application?
>
> For example for the url: "http://somesite.org/gopherproxy" to rewrite the path
> "/gopherproxy" to "/" for the application?
>
> in Nginx my current rule is like:
>
> location /gopherproxy/ {
> rewrite /gopherproxy/(.*) /$1 break;
>
> proxy_pass http://127.0.0.1:6969/;
> proxy_set_header Host $host;
> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
> proxy_pass_header Server;
> }
>
> I have read the man page and relayd source-code, but have not found a way to
> replace part of the pattern in the path (only a fixed string with "set").
>
Well, maybe. relayd is related but a different topic. The filters
are still on my list.
Reyk
> > Tests? OK?
> >
> > Please note that this diff intentionally breaks the "root strip"
> > option because it changes the grammar to "request strip". "root
> > strip" was semantically wrong but we didn't have a better place to put
> > it. An current.html entry can be made for the required grammar change.
> >
> > Reyk
> >
> > Index: usr.sbin/httpd/config.c
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/httpd/config.c,v
> > retrieving revision 1.54
> > diff -u -p -u -p -r1.54 config.c
> > --- usr.sbin/httpd/config.c 19 May 2018 13:56:56 -0000 1.54
> > +++ usr.sbin/httpd/config.c 29 May 2018 16:35:29 -0000
> > @@ -476,6 +476,13 @@ config_getserver_config(struct httpd *en
> > &parent->default_type, sizeof(struct media_type));
> > }
> >
> > + f = SRVFLAG_PATH_REWRITE|SRVFLAG_NO_PATH_REWRITE;
> > + if ((srv_conf->flags & f) == 0) {
> > + srv_conf->flags |= parent->flags & f;
> > + (void)strlcpy(srv_conf->path, parent->path,
> > + sizeof(srv_conf->path));
> > + }
> > +
> > f = SRVFLAG_SERVER_HSTS;
> > srv_conf->flags |= parent->flags & f;
> > srv_conf->hsts_max_age = parent->hsts_max_age;
> > Index: usr.sbin/httpd/httpd.conf.5
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/httpd/httpd.conf.5,v
> > retrieving revision 1.95
> > diff -u -p -u -p -r1.95 httpd.conf.5
> > --- usr.sbin/httpd/httpd.conf.5 23 May 2018 19:02:50 -0000 1.95
> > +++ usr.sbin/httpd/httpd.conf.5 29 May 2018 16:35:29 -0000
> > @@ -198,6 +198,8 @@ argument can be used with return codes i
> > .Sq Location:
> > header for redirection to a specified URI.
> > .Pp
> > +It is possible to rewrite the request to redirect it to a different
> > +external location.
> > The
> > .Ar uri
> > may contain predefined macros that will be expanded at runtime:
> > @@ -396,10 +398,10 @@ the
> > using pattern matching instead of shell globbing rules,
> > see
> > .Xr patterns 7 .
> > -The pattern may contain captures that can be used in the
> > -.Ar uri
> > -of an enclosed
> > +The pattern may contain captures that can be used in an enclosed
> > .Ic block return
> > +or
> > +.Ic request rewrite
> > option.
> > .It Oo Ic no Oc Ic log Op Ar option
> > Set the specified logging options.
> > @@ -458,12 +460,31 @@ instead of the log files.
> > Disable any previous
> > .Ic block
> > in a location.
> > -.It Ic root Ar option
> > -Configure the document root and options for the request path.
> > +.It Ic request Ar option
> > +Configure the options for the request path.
> > Valid options are:
> > .Bl -tag -width Ds
> > -.It Ar directory
> > -Set the document root of the server.
> > +.It Oo Ic no Oc Ic rewrite Ar path
> > +Enable or disable rewriting of the request.
> > +Unlike the redirection with
> > +.Ic block return ,
> > +this will change the request path internally before
> > +.Nm httpd
> > +makes a final decision about the matching location.
> > +The
> > +.Ar path
> > +argument may contain predefined macros that will be expanded at runtime.
> > +See the
> > +.Ic block return
> > +option for the list of supported macros.
> > +.It Ic strip Ar number
> > +Strip
> > +.Ar number
> > +path components from the beginning of the request path before looking
> > +up the stripped-down path at the document root.
> > +.El
> > +.It Ic root Ar directory
> > +Configure the document root of the server.
> > The
> > .Ar directory
> > is a pathname within the
> > @@ -472,12 +493,6 @@ root directory of
> > .Nm httpd .
> > If not specified, it defaults to
> > .Pa /htdocs .
> > -.It Ic strip Ar number
> > -Strip
> > -.Ar number
> > -path components from the beginning of the request path before looking
> > -up the stripped-down path at the document root.
> > -.El
> > .It Ic tcp Ar option
> > Enable or disable the specified TCP/IP options; see
> > .Xr tcp 4
> > @@ -715,6 +730,17 @@ server "example.com" {
> >
> > server "www.example.com" {
> > listen on 10.0.0.1 port 80
> > +}
> > +.Ed
> > +The request can also be rewritten with the
> > +.Ic request rewrite
> > +directive:
> > +.Bd -literal -offset indent
> > +server "example.com" {
> > + listen on * port 80
> > + location match "/old/(.*)" {
> > + request rewrite "/new/%1"
> > + }
> > }
> > .Ed
> > .Sh SEE ALSO
> > Index: usr.sbin/httpd/httpd.h
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/httpd/httpd.h,v
> > retrieving revision 1.137
> > diff -u -p -u -p -r1.137 httpd.h
> > --- usr.sbin/httpd/httpd.h 19 May 2018 13:56:56 -0000 1.137
> > +++ usr.sbin/httpd/httpd.h 29 May 2018 16:35:30 -0000
> > @@ -398,13 +398,15 @@ SPLAY_HEAD(client_tree, client);
> > #define SRVFLAG_SERVER_MATCH 0x00200000
> > #define SRVFLAG_SERVER_HSTS 0x00400000
> > #define SRVFLAG_DEFAULT_TYPE 0x00800000
> > +#define SRVFLAG_PATH_REWRITE 0x01000000
> > +#define SRVFLAG_NO_PATH_REWRITE 0x02000000
> >
> > #define SRVFLAG_BITS
> > \
> > "\10\01INDEX\02NO_INDEX\03AUTO_INDEX\04NO_AUTO_INDEX" \
> > "\05ROOT\06LOCATION\07FCGI\10NO_FCGI\11LOG\12NO_LOG\13SOCKET" \
> > "\14SYSLOG\15NO_SYSLOG\16TLS\17ACCESS_LOG\20ERROR_LOG" \
> > "\21AUTH\22NO_AUTH\23BLOCK\24NO_BLOCK\25LOCATION_MATCH" \
> > - "\26SERVER_MATCH\27SERVER_HSTS\30DEFAULT_TYPE"
> > + "\26SERVER_MATCH\27SERVER_HSTS\30DEFAULT_TYPE\31PATH\32NO_PATH"
> >
> > #define TCPFLAG_NODELAY 0x01
> > #define TCPFLAG_NNODELAY 0x02
> > @@ -470,8 +472,9 @@ struct server_config {
> > uint32_t parent_id;
> > char name[HOST_NAME_MAX+1];
> > char location[HTTPD_LOCATION_MAX];
> > - char index[PATH_MAX];
> > char root[PATH_MAX];
> > + char path[PATH_MAX];
> > + char index[PATH_MAX];
> > char socket[PATH_MAX];
> > char accesslog[PATH_MAX];
> > char errorlog[PATH_MAX];
> > Index: usr.sbin/httpd/parse.y
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/httpd/parse.y,v
> > retrieving revision 1.99
> > diff -u -p -u -p -r1.99 parse.y
> > --- usr.sbin/httpd/parse.y 23 May 2018 19:11:48 -0000 1.99
> > +++ usr.sbin/httpd/parse.y 29 May 2018 16:35:31 -0000
> > @@ -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 PASS REWRITE
> > %token CA CLIENT CRL OPTIONAL
> > %token <v.string> STRING
> > %token <v.number> NUMBER
> > @@ -486,6 +486,7 @@ serveroptsl : LISTEN ON STRING opttls po
> > YYERROR;
> > }
> > }
> > + | request
> > | root
> > | directory
> > | logformat
> > @@ -804,7 +805,33 @@ rootflags : STRING {
> > free($1);
> > srv->srv_conf.flags |= SRVFLAG_ROOT;
> > }
> > - | STRIP NUMBER {
> > + ;
> > +
> > +request : REQUEST requestflags
> > + | REQUEST '{' optnl requestflags_l '}'
> > + ;
> > +
> > +requestflags_l : requestflags optcommanl requestflags_l
> > + | requestflags optnl
> > + ;
> > +
> > +requestflags : REWRITE STRING {
> > + if (strlcpy(srv->srv_conf.path, $2,
> > + sizeof(srv->srv_conf.path)) >=
> > + sizeof(srv->srv_conf.path)) {
> > + yyerror("request path too long");
> > + free($2);
> > + YYERROR;
> > + }
> > + free($2);
> > + srv->srv_conf.flags |= SRVFLAG_PATH_REWRITE;
> > + srv->srv_conf.flags &= ~SRVFLAG_NO_PATH_REWRITE;
> > + }
> > + | NO REWRITE {
> > + srv->srv_conf.flags |= SRVFLAG_NO_PATH_REWRITE;
> > + srv->srv_conf.flags &= ~SRVFLAG_PATH_REWRITE;
> > + }
> > + | STRIP NUMBER {
> > if ($2 < 0 || $2 > INT_MAX) {
> > yyerror("invalid strip number");
> > YYERROR;
> > @@ -1261,6 +1288,7 @@ lookup(char *s)
> > { "request", REQUEST },
> > { "requests", REQUESTS },
> > { "return", RETURN },
> > + { "rewrite", REWRITE },
> > { "root", ROOT },
> > { "sack", SACK },
> > { "server", SERVER },
> > Index: usr.sbin/httpd/server_http.c
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/httpd/server_http.c,v
> > retrieving revision 1.119
> > diff -u -p -u -p -r1.119 server_http.c
> > --- usr.sbin/httpd/server_http.c 6 Apr 2018 13:02:07 -0000 1.119
> > +++ usr.sbin/httpd/server_http.c 29 May 2018 16:35:31 -0000
> > @@ -1180,10 +1180,13 @@ server_response(struct httpd *httpd, str
> > char *hostval;
> > const char *errstr = NULL;
> >
> > - /* Canonicalize the request path */
> > + /* Decode the URL */
> > if (desc->http_path == NULL ||
> > - url_decode(desc->http_path) == NULL ||
> > - canonicalize_path(desc->http_path, path, sizeof(path)) == NULL)
> > + url_decode(desc->http_path) == NULL)
> > + goto fail;
> > +
> > + /* Canonicalize the request path */
> > + if (canonicalize_path(desc->http_path, path, sizeof(path)) == NULL)
> > goto fail;
> > free(desc->http_path);
> > if ((desc->http_path = strdup(path)) == NULL)
> > @@ -1286,6 +1289,28 @@ server_response(struct httpd *httpd, str
> >
> > /* Now search for the location */
> > srv_conf = server_getlocation(clt, desc->http_path);
> > +
> > + /* Optional rewrite */
> > + if (srv_conf->flags & SRVFLAG_PATH_REWRITE) {
> > + if (server_expand_http(clt, srv_conf->path,
> > + path, sizeof(path)) == NULL)
> > + goto fail;
> > +
> > + /* Canonicalize the updated request path */
> > + if (canonicalize_path(path,
> > + path, sizeof(path)) == NULL)
> > + goto fail;
> > +
> > + log_debug("%s: rewrote %s -> %s", __func__,
> > + desc->http_path, path);
> > +
> > + free(desc->http_path);
> > + if ((desc->http_path = strdup(path)) == NULL)
> > + goto fail;
> > +
> > + /* Now search for the updated location */
> > + srv_conf = server_getlocation(clt, desc->http_path);
> > + }
> >
> > if (srv_conf->flags & SRVFLAG_BLOCK) {
> > server_abort_http(clt, srv_conf->return_code,
> >
>
> --
> Kind regards,
> Hiltjo
--