Re: Port httpd(8) 'strip' directive to relayd(8)

2021-01-07 Thread Hiltjo Posthuma
On Thu, Jan 07, 2021 at 04:56:14PM +0100, Denis Fondras wrote:
> Le Thu, Jan 07, 2021 at 12:03:54PM +0100, Hiltjo Posthuma a écrit :
> > Hi Denis,
> > 
> > I like this feature. For example it would be useful for using relayd as a
> > reverse-proxy to forward it to an internal network running a httpd with some
> > service. Then the path can be stripped without having to touch this service
> > configuration.
> > 
> > Like: https://example.com/myservice/ -> http://192.168.0.2/ .
> > 
> > I've noticed a small thing while testing the patch. When the path is "/" and
> > "strip 1" is used it becomes "", the request becomes: "GET HTTP/1.0". Maybe
> > this should be instead: "/". The same thing happens with a "strip number"
> > higher than the amount of sub paths.
> > 
> > It could be worked-around by prefiltering with a match rule, but maybe it is
> > more obvious to make the root "/" ? The way the function 
> > server_root_strip() is
> > used by OpenBSD httpd is that it first does a filesystem path check/open(2).
> > 
> > 
> 

Hi Denis,

Awesome, tested the patch below and it looks good to me!

> Thank you for testing.
> 
> Here is an update:
> 
> Index: parse.y
> ===
> RCS file: /cvs/src/usr.sbin/relayd/parse.y,v
> retrieving revision 1.250
> diff -u -p -r1.250 parse.y
> --- parse.y   29 Dec 2020 19:48:06 -  1.250
> +++ parse.y   7 Jan 2021 15:08:28 -
> @@ -175,7 +175,7 @@ typedef struct {
>  %token   LOOKUP METHOD MODE NAT NO DESTINATION NODELAY NOTHING ON PARENT 
> PATH
>  %token   PFTAG PORT PREFORK PRIORITY PROTO QUERYSTR REAL REDIRECT RELAY 
> REMOVE
>  %token   REQUEST RESPONSE RETRY QUICK RETURN ROUNDROBIN ROUTE SACK 
> SCRIPT SEND
> -%token   SESSION SOCKET SPLICE SSL STICKYADDR STYLE TABLE TAG TAGGED TCP
> +%token   SESSION SOCKET SPLICE SSL STICKYADDR STRIP STYLE TABLE TAG 
> TAGGED TCP
>  %token   TIMEOUT TLS TO ROUTER RTLABEL TRANSPARENT URL WITH TTL RTABLE
>  %token   MATCH PARAMS RANDOM LEASTSTATES SRCHASH KEY CERTIFICATE 
> PASSWORD ECDHE
>  %token   EDH TICKETS CONNECTION CONNECTIONS CONTEXT ERRORS STATE CHANGES 
> CHECKS
> @@ -1549,6 +1549,20 @@ ruleopts   : METHOD STRING 
> {
>   rule->rule_kv[keytype].kv_option = $2;
>   rule->rule_kv[keytype].kv_type = keytype;
>   }
> + | PATH STRIP NUMBER {
> + char*strip = NULL;
> +
> + if ($3 < 0 || $3 > INT_MAX) {
> + yyerror("invalid strip number");
> + YYERROR;
> + }
> + if (asprintf(, "%lld", $3) <= 0)
> + fatal("can't parse strip");
> + keytype = KEY_TYPE_PATH;
> + rule->rule_kv[keytype].kv_option = KEY_OPTION_STRIP;
> + rule->rule_kv[keytype].kv_value = strip;
> + rule->rule_kv[keytype].kv_type = keytype;
> + }
>   | QUERYSTR key_option STRING value  {
>   switch ($2) {
>   case KEY_OPTION_APPEND:
> @@ -2481,6 +2495,7 @@ lookup(char *s)
>   { "ssl",SSL },
>   { "state",  STATE },
>   { "sticky-address", STICKYADDR },
> + { "strip",  STRIP },
>   { "style",  STYLE },
>   { "table",  TABLE },
>   { "tag",TAG },
> Index: relay.c
> ===
> RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
> retrieving revision 1.251
> diff -u -p -r1.251 relay.c
> --- relay.c   14 May 2020 17:27:38 -  1.251
> +++ relay.c   7 Jan 2021 15:08:28 -
> @@ -214,6 +214,9 @@ relay_ruledebug(struct relay_rule *rule)
>   case KEY_OPTION_LOG:
>   fprintf(stderr, "log ");
>   break;
> + case KEY_OPTION_STRIP:
> + fprintf(stderr, "strip ");
> + break;
>   case KEY_OPTION_NONE:
>   break;
>   }
> @@ -227,13 +230,15 @@ relay_ruledebug(struct relay_rule *rule)
>   break;
>   }
>  
> + int kvv = (kv->kv_option == KEY_OPTION_STRIP ||
> +  kv->kv_value == NULL);
>   fprintf(stderr, "%s%s%s%s%s%s ",
>   kv->kv_key == NULL ? "" : "\"",
>   kv->kv_key == NULL ? "" : kv->kv_key,
>   kv->kv_key == NULL ? "" : "\"",
> - kv->kv_value == NULL ? "" : " value \"",
> + kvv ? "" : " value \"",
>   kv->kv_value == NULL ? "" : kv->kv_value,
> - kv->kv_value == NULL ? "" : "\"");
> +   

Re: Port httpd(8) 'strip' directive to relayd(8)

2021-01-07 Thread Denis Fondras
Le Thu, Jan 07, 2021 at 12:03:54PM +0100, Hiltjo Posthuma a écrit :
> Hi Denis,
> 
> I like this feature. For example it would be useful for using relayd as a
> reverse-proxy to forward it to an internal network running a httpd with some
> service. Then the path can be stripped without having to touch this service
> configuration.
> 
> Like: https://example.com/myservice/ -> http://192.168.0.2/ .
> 
> I've noticed a small thing while testing the patch. When the path is "/" and
> "strip 1" is used it becomes "", the request becomes: "GET HTTP/1.0". Maybe
> this should be instead: "/". The same thing happens with a "strip number"
> higher than the amount of sub paths.
> 
> It could be worked-around by prefiltering with a match rule, but maybe it is
> more obvious to make the root "/" ? The way the function server_root_strip() 
> is
> used by OpenBSD httpd is that it first does a filesystem path check/open(2).
> 
> 

Thank you for testing.

Here is an update:

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/relayd/parse.y,v
retrieving revision 1.250
diff -u -p -r1.250 parse.y
--- parse.y 29 Dec 2020 19:48:06 -  1.250
+++ parse.y 7 Jan 2021 15:08:28 -
@@ -175,7 +175,7 @@ typedef struct {
 %token LOOKUP METHOD MODE NAT NO DESTINATION NODELAY NOTHING ON PARENT PATH
 %token PFTAG PORT PREFORK PRIORITY PROTO QUERYSTR REAL REDIRECT RELAY REMOVE
 %token REQUEST RESPONSE RETRY QUICK RETURN ROUNDROBIN ROUTE SACK SCRIPT SEND
-%token SESSION SOCKET SPLICE SSL STICKYADDR STYLE TABLE TAG TAGGED TCP
+%token SESSION SOCKET SPLICE SSL STICKYADDR STRIP STYLE TABLE TAG TAGGED TCP
 %token TIMEOUT TLS TO ROUTER RTLABEL TRANSPARENT URL WITH TTL RTABLE
 %token MATCH PARAMS RANDOM LEASTSTATES SRCHASH KEY CERTIFICATE PASSWORD ECDHE
 %token EDH TICKETS CONNECTION CONNECTIONS CONTEXT ERRORS STATE CHANGES CHECKS
@@ -1549,6 +1549,20 @@ ruleopts : METHOD STRING 
{
rule->rule_kv[keytype].kv_option = $2;
rule->rule_kv[keytype].kv_type = keytype;
}
+   | PATH STRIP NUMBER {
+   char*strip = NULL;
+
+   if ($3 < 0 || $3 > INT_MAX) {
+   yyerror("invalid strip number");
+   YYERROR;
+   }
+   if (asprintf(, "%lld", $3) <= 0)
+   fatal("can't parse strip");
+   keytype = KEY_TYPE_PATH;
+   rule->rule_kv[keytype].kv_option = KEY_OPTION_STRIP;
+   rule->rule_kv[keytype].kv_value = strip;
+   rule->rule_kv[keytype].kv_type = keytype;
+   }
| QUERYSTR key_option STRING value  {
switch ($2) {
case KEY_OPTION_APPEND:
@@ -2481,6 +2495,7 @@ lookup(char *s)
{ "ssl",SSL },
{ "state",  STATE },
{ "sticky-address", STICKYADDR },
+   { "strip",  STRIP },
{ "style",  STYLE },
{ "table",  TABLE },
{ "tag",TAG },
Index: relay.c
===
RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
retrieving revision 1.251
diff -u -p -r1.251 relay.c
--- relay.c 14 May 2020 17:27:38 -  1.251
+++ relay.c 7 Jan 2021 15:08:28 -
@@ -214,6 +214,9 @@ relay_ruledebug(struct relay_rule *rule)
case KEY_OPTION_LOG:
fprintf(stderr, "log ");
break;
+   case KEY_OPTION_STRIP:
+   fprintf(stderr, "strip ");
+   break;
case KEY_OPTION_NONE:
break;
}
@@ -227,13 +230,15 @@ relay_ruledebug(struct relay_rule *rule)
break;
}
 
+   int kvv = (kv->kv_option == KEY_OPTION_STRIP ||
+kv->kv_value == NULL);
fprintf(stderr, "%s%s%s%s%s%s ",
kv->kv_key == NULL ? "" : "\"",
kv->kv_key == NULL ? "" : kv->kv_key,
kv->kv_key == NULL ? "" : "\"",
-   kv->kv_value == NULL ? "" : " value \"",
+   kvv ? "" : " value \"",
kv->kv_value == NULL ? "" : kv->kv_value,
-   kv->kv_value == NULL ? "" : "\"");
+   kvv ? "" : "\"");
}
 
if (rule->rule_tablename[0])
Index: relay_http.c
===
RCS file: /cvs/src/usr.sbin/relayd/relay_http.c,v
retrieving revision 1.79
diff -u -p -r1.79 relay_http.c
--- relay_http.c4 Sep 2020 13:09:14 

Re: Port httpd(8) 'strip' directive to relayd(8)

2021-01-07 Thread Hiltjo Posthuma
On Sun, Jan 03, 2021 at 11:40:42AM +0100, Denis Fondras wrote:
> Le Fri, Dec 11, 2020 at 10:53:56AM +, Olivier Cherrier a écrit :
> > 
> > Hello tech@,
> > 
> > Is there any interest for this feature to be commited?
> > I find it very useful. Thank you Denis!
> > 
> 
> Here is an up to date diff, looking for OKs.
> 

Hi Denis,

I like this feature. For example it would be useful for using relayd as a
reverse-proxy to forward it to an internal network running a httpd with some
service. Then the path can be stripped without having to touch this service
configuration.

Like: https://example.com/myservice/ -> http://192.168.0.2/ .

I've noticed a small thing while testing the patch. When the path is "/" and
"strip 1" is used it becomes "", the request becomes: "GET HTTP/1.0". Maybe
this should be instead: "/". The same thing happens with a "strip number"
higher than the amount of sub paths.

It could be worked-around by prefiltering with a match rule, but maybe it is
more obvious to make the root "/" ? The way the function server_root_strip() is
used by OpenBSD httpd is that it first does a filesystem path check/open(2).


My test config:

Command:
printf 'GET / HTTP/1.0\r\nConnection: Close\r\nHost: 127.0.0.1\r\n\r\n' 
| \
nc -v 127.0.0.1 80


relayd.conf:

table  { 127.0.0.1 }
table  { 127.0.0.1 }

http protocol "t" {
tcp { nodelay }

return error

match tag "notag"
match path strip 1 tag "ok"

block tagged "notag"
}

relay "r" {
listen on "127.0.0.1" port 80
protocol "t"
forward to  port 8080
}


Netcat (fake server):
nc -k -v -l 127.0.0.1 8080


The incoming request is then:

Connection received on localhost 45510
GET  HTTP/1.0
Connection: Close
Host: 127.0.0.1


I made no changes to the diff below.

> Index: parse.y
> ===
> RCS file: /cvs/src/usr.sbin/relayd/parse.y,v
> retrieving revision 1.250
> diff -u -p -r1.250 parse.y
> --- parse.y   29 Dec 2020 19:48:06 -  1.250
> +++ parse.y   3 Jan 2021 10:38:26 -
> @@ -175,7 +175,7 @@ typedef struct {
>  %token   LOOKUP METHOD MODE NAT NO DESTINATION NODELAY NOTHING ON PARENT 
> PATH
>  %token   PFTAG PORT PREFORK PRIORITY PROTO QUERYSTR REAL REDIRECT RELAY 
> REMOVE
>  %token   REQUEST RESPONSE RETRY QUICK RETURN ROUNDROBIN ROUTE SACK 
> SCRIPT SEND
> -%token   SESSION SOCKET SPLICE SSL STICKYADDR STYLE TABLE TAG TAGGED TCP
> +%token   SESSION SOCKET SPLICE SSL STICKYADDR STRIP STYLE TABLE TAG 
> TAGGED TCP
>  %token   TIMEOUT TLS TO ROUTER RTLABEL TRANSPARENT URL WITH TTL RTABLE
>  %token   MATCH PARAMS RANDOM LEASTSTATES SRCHASH KEY CERTIFICATE 
> PASSWORD ECDHE
>  %token   EDH TICKETS CONNECTION CONNECTIONS CONTEXT ERRORS STATE CHANGES 
> CHECKS
> @@ -1549,6 +1549,20 @@ ruleopts   : METHOD STRING 
> {
>   rule->rule_kv[keytype].kv_option = $2;
>   rule->rule_kv[keytype].kv_type = keytype;
>   }
> + | PATH STRIP NUMBER {
> + char*strip = NULL;
> +
> + if ($3 < 0 || $3 > INT_MAX) {
> + yyerror("invalid strip number");
> + YYERROR;
> + }
> + if (asprintf(, "%lld", $3) <= 0)
> + fatal("can't parse strip");
> + keytype = KEY_TYPE_PATH;
> + rule->rule_kv[keytype].kv_option = KEY_OPTION_STRIP;
> + rule->rule_kv[keytype].kv_value = strip;
> + rule->rule_kv[keytype].kv_type = keytype;
> + }
>   | QUERYSTR key_option STRING value  {
>   switch ($2) {
>   case KEY_OPTION_APPEND:
> @@ -2481,6 +2495,7 @@ lookup(char *s)
>   { "ssl",SSL },
>   { "state",  STATE },
>   { "sticky-address", STICKYADDR },
> + { "strip",  STRIP },
>   { "style",  STYLE },
>   { "table",  TABLE },
>   { "tag",TAG },
> Index: relay.c
> ===
> RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
> retrieving revision 1.251
> diff -u -p -r1.251 relay.c
> --- relay.c   14 May 2020 17:27:38 -  1.251
> +++ relay.c   3 Jan 2021 10:38:27 -
> @@ -214,6 +214,9 @@ relay_ruledebug(struct relay_rule *rule)
>   case KEY_OPTION_LOG:
>   fprintf(stderr, "log ");
>   break;
> + case KEY_OPTION_STRIP:
> + fprintf(stderr, "strip ");
> + break;
>   case KEY_OPTION_NONE:
>   break;
>   }

Re: Port httpd(8) 'strip' directive to relayd(8)

2021-01-04 Thread Mischa
By no means an official OK, but would love to see this in relayd!

Mischa

> On 3 Jan 2021, at 11:40, Denis Fondras  wrote:
> 
> Le Fri, Dec 11, 2020 at 10:53:56AM +, Olivier Cherrier a écrit :
>> 
>>  Hello tech@,
>> 
>> Is there any interest for this feature to be commited?
>> I find it very useful. Thank you Denis!
>> 
> 
> Here is an up to date diff, looking for OKs.
> 
> Index: parse.y
> ===
> RCS file: /cvs/src/usr.sbin/relayd/parse.y,v
> retrieving revision 1.250
> diff -u -p -r1.250 parse.y
> --- parse.y   29 Dec 2020 19:48:06 -  1.250
> +++ parse.y   3 Jan 2021 10:38:26 -
> @@ -175,7 +175,7 @@ typedef struct {
> %tokenLOOKUP METHOD MODE NAT NO DESTINATION NODELAY NOTHING ON PARENT 
> PATH
> %tokenPFTAG PORT PREFORK PRIORITY PROTO QUERYSTR REAL REDIRECT RELAY 
> REMOVE
> %tokenREQUEST RESPONSE RETRY QUICK RETURN ROUNDROBIN ROUTE SACK 
> SCRIPT SEND
> -%token   SESSION SOCKET SPLICE SSL STICKYADDR STYLE TABLE TAG TAGGED TCP
> +%token   SESSION SOCKET SPLICE SSL STICKYADDR STRIP STYLE TABLE TAG 
> TAGGED TCP
> %tokenTIMEOUT TLS TO ROUTER RTLABEL TRANSPARENT URL WITH TTL RTABLE
> %tokenMATCH PARAMS RANDOM LEASTSTATES SRCHASH KEY CERTIFICATE 
> PASSWORD ECDHE
> %tokenEDH TICKETS CONNECTION CONNECTIONS CONTEXT ERRORS STATE CHANGES 
> CHECKS
> @@ -1549,6 +1549,20 @@ ruleopts   : METHOD STRING 
> {
>   rule->rule_kv[keytype].kv_option = $2;
>   rule->rule_kv[keytype].kv_type = keytype;
>   }
> + | PATH STRIP NUMBER {
> + char*strip = NULL;
> +
> + if ($3 < 0 || $3 > INT_MAX) {
> + yyerror("invalid strip number");
> + YYERROR;
> + }
> + if (asprintf(, "%lld", $3) <= 0)
> + fatal("can't parse strip");
> + keytype = KEY_TYPE_PATH;
> + rule->rule_kv[keytype].kv_option = KEY_OPTION_STRIP;
> + rule->rule_kv[keytype].kv_value = strip;
> + rule->rule_kv[keytype].kv_type = keytype;
> + }
>   | QUERYSTR key_option STRING value  {
>   switch ($2) {
>   case KEY_OPTION_APPEND:
> @@ -2481,6 +2495,7 @@ lookup(char *s)
>   { "ssl",SSL },
>   { "state",  STATE },
>   { "sticky-address", STICKYADDR },
> + { "strip",  STRIP },
>   { "style",  STYLE },
>   { "table",  TABLE },
>   { "tag",TAG },
> Index: relay.c
> ===
> RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
> retrieving revision 1.251
> diff -u -p -r1.251 relay.c
> --- relay.c   14 May 2020 17:27:38 -  1.251
> +++ relay.c   3 Jan 2021 10:38:27 -
> @@ -214,6 +214,9 @@ relay_ruledebug(struct relay_rule *rule)
>   case KEY_OPTION_LOG:
>   fprintf(stderr, "log ");
>   break;
> + case KEY_OPTION_STRIP:
> + fprintf(stderr, "strip ");
> + break;
>   case KEY_OPTION_NONE:
>   break;
>   }
> @@ -227,13 +230,15 @@ relay_ruledebug(struct relay_rule *rule)
>   break;
>   }
> 
> + int kvv = (kv->kv_option == KEY_OPTION_STRIP ||
> +  kv->kv_value == NULL);
>   fprintf(stderr, "%s%s%s%s%s%s ",
>   kv->kv_key == NULL ? "" : "\"",
>   kv->kv_key == NULL ? "" : kv->kv_key,
>   kv->kv_key == NULL ? "" : "\"",
> - kv->kv_value == NULL ? "" : " value \"",
> + kvv ? "" : " value \"",
>   kv->kv_value == NULL ? "" : kv->kv_value,
> - kv->kv_value == NULL ? "" : "\"");
> + kvv ? "" : "\"");
>   }
> 
>   if (rule->rule_tablename[0])
> Index: relay_http.c
> ===
> RCS file: /cvs/src/usr.sbin/relayd/relay_http.c,v
> retrieving revision 1.79
> diff -u -p -r1.79 relay_http.c
> --- relay_http.c  4 Sep 2020 13:09:14 -   1.79
> +++ relay_http.c  3 Jan 2021 10:38:27 -
> @@ -77,6 +77,7 @@ int  relay_match_actions(struct ctl_rel
>   struct relay_rule *, struct kvlist *, struct kvlist *,
>   struct relay_table **);
> void   relay_httpdesc_free(struct http_descriptor *);
> +char *server_root_strip(char *, int);
> 
> static struct relayd  *env = NULL;
> 
> @@ -1421,14 +1422,16 @@ 

Re: Port httpd(8) 'strip' directive to relayd(8)

2021-01-03 Thread Denis Fondras
Le Fri, Dec 11, 2020 at 10:53:56AM +, Olivier Cherrier a écrit :
> 
>   Hello tech@,
> 
> Is there any interest for this feature to be commited?
> I find it very useful. Thank you Denis!
> 

Here is an up to date diff, looking for OKs.

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/relayd/parse.y,v
retrieving revision 1.250
diff -u -p -r1.250 parse.y
--- parse.y 29 Dec 2020 19:48:06 -  1.250
+++ parse.y 3 Jan 2021 10:38:26 -
@@ -175,7 +175,7 @@ typedef struct {
 %token LOOKUP METHOD MODE NAT NO DESTINATION NODELAY NOTHING ON PARENT PATH
 %token PFTAG PORT PREFORK PRIORITY PROTO QUERYSTR REAL REDIRECT RELAY REMOVE
 %token REQUEST RESPONSE RETRY QUICK RETURN ROUNDROBIN ROUTE SACK SCRIPT SEND
-%token SESSION SOCKET SPLICE SSL STICKYADDR STYLE TABLE TAG TAGGED TCP
+%token SESSION SOCKET SPLICE SSL STICKYADDR STRIP STYLE TABLE TAG TAGGED TCP
 %token TIMEOUT TLS TO ROUTER RTLABEL TRANSPARENT URL WITH TTL RTABLE
 %token MATCH PARAMS RANDOM LEASTSTATES SRCHASH KEY CERTIFICATE PASSWORD ECDHE
 %token EDH TICKETS CONNECTION CONNECTIONS CONTEXT ERRORS STATE CHANGES CHECKS
@@ -1549,6 +1549,20 @@ ruleopts : METHOD STRING 
{
rule->rule_kv[keytype].kv_option = $2;
rule->rule_kv[keytype].kv_type = keytype;
}
+   | PATH STRIP NUMBER {
+   char*strip = NULL;
+
+   if ($3 < 0 || $3 > INT_MAX) {
+   yyerror("invalid strip number");
+   YYERROR;
+   }
+   if (asprintf(, "%lld", $3) <= 0)
+   fatal("can't parse strip");
+   keytype = KEY_TYPE_PATH;
+   rule->rule_kv[keytype].kv_option = KEY_OPTION_STRIP;
+   rule->rule_kv[keytype].kv_value = strip;
+   rule->rule_kv[keytype].kv_type = keytype;
+   }
| QUERYSTR key_option STRING value  {
switch ($2) {
case KEY_OPTION_APPEND:
@@ -2481,6 +2495,7 @@ lookup(char *s)
{ "ssl",SSL },
{ "state",  STATE },
{ "sticky-address", STICKYADDR },
+   { "strip",  STRIP },
{ "style",  STYLE },
{ "table",  TABLE },
{ "tag",TAG },
Index: relay.c
===
RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
retrieving revision 1.251
diff -u -p -r1.251 relay.c
--- relay.c 14 May 2020 17:27:38 -  1.251
+++ relay.c 3 Jan 2021 10:38:27 -
@@ -214,6 +214,9 @@ relay_ruledebug(struct relay_rule *rule)
case KEY_OPTION_LOG:
fprintf(stderr, "log ");
break;
+   case KEY_OPTION_STRIP:
+   fprintf(stderr, "strip ");
+   break;
case KEY_OPTION_NONE:
break;
}
@@ -227,13 +230,15 @@ relay_ruledebug(struct relay_rule *rule)
break;
}
 
+   int kvv = (kv->kv_option == KEY_OPTION_STRIP ||
+kv->kv_value == NULL);
fprintf(stderr, "%s%s%s%s%s%s ",
kv->kv_key == NULL ? "" : "\"",
kv->kv_key == NULL ? "" : kv->kv_key,
kv->kv_key == NULL ? "" : "\"",
-   kv->kv_value == NULL ? "" : " value \"",
+   kvv ? "" : " value \"",
kv->kv_value == NULL ? "" : kv->kv_value,
-   kv->kv_value == NULL ? "" : "\"");
+   kvv ? "" : "\"");
}
 
if (rule->rule_tablename[0])
Index: relay_http.c
===
RCS file: /cvs/src/usr.sbin/relayd/relay_http.c,v
retrieving revision 1.79
diff -u -p -r1.79 relay_http.c
--- relay_http.c4 Sep 2020 13:09:14 -   1.79
+++ relay_http.c3 Jan 2021 10:38:27 -
@@ -77,6 +77,7 @@ intrelay_match_actions(struct ctl_rel
struct relay_rule *, struct kvlist *, struct kvlist *,
struct relay_table **);
 voidrelay_httpdesc_free(struct http_descriptor *);
+char *  server_root_strip(char *, int);
 
 static struct relayd   *env = NULL;
 
@@ -1421,14 +1422,16 @@ relay_httppath_test(struct ctl_relay_eve
 
if (cre->dir == RELAY_DIR_RESPONSE || kv->kv_type != KEY_TYPE_PATH)
return (0);
-   else if (kv->kv_key == NULL)
-   return (0);
-   else if (fnmatch(kv->kv_key, desc->http_path, 0) == FNM_NOMATCH)
-   

Re: Port httpd(8) 'strip' directive to relayd(8)

2020-12-11 Thread Olivier Cherrier


Hello tech@,

Is there any interest for this feature to be commited?
I find it very useful. Thank you Denis!

-- 
Olivier Cherrier
Phone: +352691570680
mailto:o...@symacx.com

On Sun, Oct 25, 2020 at 11:28:10AM +0100, open...@ledeuns.net wrote:
> Date: Sun, 25 Oct 2020 11:28:10 +0100
> From: Denis Fondras 
> To: Hiltjo Posthuma 
> Cc: tech@openbsd.org
> Subject: Re: Port httpd(8) 'strip' directive to relayd(8)
> 
> Previous one had a typo... :/
> 
> On Sat, Oct 24, 2020 at 08:01:36PM +0200, Hiltjo Posthuma wrote:
> > Thanks for working on this.  I haven't tested the patch yet except 
> > compiling,
> > but this feature would be very nice to have imho.
> > 
> > I find the current "path replace" syntax confusing and it doesn't work for 
> > this
> > use-case.
> > 
> > Some comments below:
> > 
> 
> Thank you for the comments Hiltjo.
> 
> Here is an updated diff :
> 
> Index: parse.y
> ===
> RCS file: /cvs/src/usr.sbin/relayd/parse.y,v
> retrieving revision 1.246
> diff -u -p -r1.246 parse.y
> --- parse.y   14 Sep 2020 11:30:25 -  1.246
> +++ parse.y   25 Oct 2020 09:20:53 -
> @@ -175,8 +175,8 @@ typedef struct {
>  %token   LOOKUP METHOD MODE NAT NO DESTINATION NODELAY NOTHING ON PARENT 
> PATH
>  %token   PFTAG PORT PREFORK PRIORITY PROTO QUERYSTR REAL REDIRECT RELAY 
> REMOVE
>  %token   REQUEST RESPONSE RETRY QUICK RETURN ROUNDROBIN ROUTE SACK 
> SCRIPT SEND
> -%token   SESSION SNMP SOCKET SPLICE SSL STICKYADDR STYLE TABLE TAG 
> TAGGED TCP
> -%token   TIMEOUT TLS TO ROUTER RTLABEL TRANSPARENT TRAP URL WITH TTL 
> RTABLE
> +%token   SESSION SNMP SOCKET SPLICE SSL STICKYADDR STRIP STYLE TABLE TAG 
> TAGGED
> +%token   TCP TIMEOUT TLS TO ROUTER RTLABEL TRANSPARENT TRAP URL WITH TTL 
> RTABLE
>  %token   MATCH PARAMS RANDOM LEASTSTATES SRCHASH KEY CERTIFICATE 
> PASSWORD ECDHE
>  %token   EDH TICKETS CONNECTION CONNECTIONS CONTEXT ERRORS STATE CHANGES 
> CHECKS
>  %token   WEBSOCKETS
> @@ -1569,6 +1569,20 @@ ruleopts   : METHOD STRING 
> {
>   rule->rule_kv[keytype].kv_option = $2;
>   rule->rule_kv[keytype].kv_type = keytype;
>   }
> + | PATH STRIP NUMBER {
> + char*strip = NULL;
> +
> + if ($3 < 0 || $3 > INT_MAX) {
> + yyerror("invalid strip number");
> + YYERROR;
> + }
> + if (asprintf(, "%lld", $3) <= 0)
> + fatal("can't parse strip");
> + keytype = KEY_TYPE_PATH;
> + rule->rule_kv[keytype].kv_option = KEY_OPTION_STRIP;
> + rule->rule_kv[keytype].kv_value = strip;
> + rule->rule_kv[keytype].kv_type = keytype;
> + }
>   | QUERYSTR key_option STRING value  {
>   switch ($2) {
>   case KEY_OPTION_APPEND:
> @@ -2506,6 +2520,7 @@ lookup(char *s)
>   { "ssl",SSL },
>   { "state",  STATE },
>   { "sticky-address", STICKYADDR },
> + { "strip",  STRIP },
>   { "style",  STYLE },
>   { "table",  TABLE },
>   { "tag",TAG },
> Index: relay.c
> ===
> RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
> retrieving revision 1.251
> diff -u -p -r1.251 relay.c
> --- relay.c   14 May 2020 17:27:38 -  1.251
> +++ relay.c   25 Oct 2020 09:20:53 -
> @@ -214,6 +214,9 @@ relay_ruledebug(struct relay_rule *rule)
>   case KEY_OPTION_LOG:
>   fprintf(stderr, "log ");
>   break;
> + case KEY_OPTION_STRIP:
> + fprintf(stderr, "strip ");
> + break;
>   case KEY_OPTION_NONE:
>   break;
>   }
> @@ -227,13 +230,15 @@ relay_ruledebug(struct relay_rule *rule)
>   break;
>   }
>  
> + int kvv = (kv->kv_option == KEY_OPTION_STRIP ||
> +  kv->kv_value == NULL);
>   fprintf(stderr, "

Re: Port httpd(8) 'strip' directive to relayd(8)

2020-10-25 Thread Denis Fondras
Previous one had a typo... :/

On Sat, Oct 24, 2020 at 08:01:36PM +0200, Hiltjo Posthuma wrote:
> Thanks for working on this.  I haven't tested the patch yet except compiling,
> but this feature would be very nice to have imho.
> 
> I find the current "path replace" syntax confusing and it doesn't work for 
> this
> use-case.
> 
> Some comments below:
> 

Thank you for the comments Hiltjo.

Here is an updated diff :

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/relayd/parse.y,v
retrieving revision 1.246
diff -u -p -r1.246 parse.y
--- parse.y 14 Sep 2020 11:30:25 -  1.246
+++ parse.y 25 Oct 2020 09:20:53 -
@@ -175,8 +175,8 @@ typedef struct {
 %token LOOKUP METHOD MODE NAT NO DESTINATION NODELAY NOTHING ON PARENT PATH
 %token PFTAG PORT PREFORK PRIORITY PROTO QUERYSTR REAL REDIRECT RELAY REMOVE
 %token REQUEST RESPONSE RETRY QUICK RETURN ROUNDROBIN ROUTE SACK SCRIPT SEND
-%token SESSION SNMP SOCKET SPLICE SSL STICKYADDR STYLE TABLE TAG TAGGED TCP
-%token TIMEOUT TLS TO ROUTER RTLABEL TRANSPARENT TRAP URL WITH TTL RTABLE
+%token SESSION SNMP SOCKET SPLICE SSL STICKYADDR STRIP STYLE TABLE TAG TAGGED
+%token TCP TIMEOUT TLS TO ROUTER RTLABEL TRANSPARENT TRAP URL WITH TTL RTABLE
 %token MATCH PARAMS RANDOM LEASTSTATES SRCHASH KEY CERTIFICATE PASSWORD ECDHE
 %token EDH TICKETS CONNECTION CONNECTIONS CONTEXT ERRORS STATE CHANGES CHECKS
 %token WEBSOCKETS
@@ -1569,6 +1569,20 @@ ruleopts : METHOD STRING 
{
rule->rule_kv[keytype].kv_option = $2;
rule->rule_kv[keytype].kv_type = keytype;
}
+   | PATH STRIP NUMBER {
+   char*strip = NULL;
+
+   if ($3 < 0 || $3 > INT_MAX) {
+   yyerror("invalid strip number");
+   YYERROR;
+   }
+   if (asprintf(, "%lld", $3) <= 0)
+   fatal("can't parse strip");
+   keytype = KEY_TYPE_PATH;
+   rule->rule_kv[keytype].kv_option = KEY_OPTION_STRIP;
+   rule->rule_kv[keytype].kv_value = strip;
+   rule->rule_kv[keytype].kv_type = keytype;
+   }
| QUERYSTR key_option STRING value  {
switch ($2) {
case KEY_OPTION_APPEND:
@@ -2506,6 +2520,7 @@ lookup(char *s)
{ "ssl",SSL },
{ "state",  STATE },
{ "sticky-address", STICKYADDR },
+   { "strip",  STRIP },
{ "style",  STYLE },
{ "table",  TABLE },
{ "tag",TAG },
Index: relay.c
===
RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
retrieving revision 1.251
diff -u -p -r1.251 relay.c
--- relay.c 14 May 2020 17:27:38 -  1.251
+++ relay.c 25 Oct 2020 09:20:53 -
@@ -214,6 +214,9 @@ relay_ruledebug(struct relay_rule *rule)
case KEY_OPTION_LOG:
fprintf(stderr, "log ");
break;
+   case KEY_OPTION_STRIP:
+   fprintf(stderr, "strip ");
+   break;
case KEY_OPTION_NONE:
break;
}
@@ -227,13 +230,15 @@ relay_ruledebug(struct relay_rule *rule)
break;
}
 
+   int kvv = (kv->kv_option == KEY_OPTION_STRIP ||
+kv->kv_value == NULL);
fprintf(stderr, "%s%s%s%s%s%s ",
kv->kv_key == NULL ? "" : "\"",
kv->kv_key == NULL ? "" : kv->kv_key,
kv->kv_key == NULL ? "" : "\"",
-   kv->kv_value == NULL ? "" : " value \"",
+   kvv ? "" : " value \"",
kv->kv_value == NULL ? "" : kv->kv_value,
-   kv->kv_value == NULL ? "" : "\"");
+   kvv ? "" : "\"");
}
 
if (rule->rule_tablename[0])
Index: relay_http.c
===
RCS file: /cvs/src/usr.sbin/relayd/relay_http.c,v
retrieving revision 1.79
diff -u -p -r1.79 relay_http.c
--- relay_http.c4 Sep 2020 13:09:14 -   1.79
+++ relay_http.c25 Oct 2020 09:20:53 -
@@ -77,6 +77,7 @@ intrelay_match_actions(struct ctl_rel
struct relay_rule *, struct kvlist *, struct kvlist *,
struct relay_table **);
 voidrelay_httpdesc_free(struct http_descriptor *);
+char *  server_root_strip(char *, int);
 
 static struct relayd   *env = NULL;
 
@@ -1421,14 +1422,16 @@ 

Re: Port httpd(8) 'strip' directive to relayd(8)

2020-10-25 Thread Denis Fondras
On Sat, Oct 24, 2020 at 08:01:36PM +0200, Hiltjo Posthuma wrote:
> Thanks for working on this.  I haven't tested the patch yet except compiling,
> but this feature would be very nice to have imho.
> 
> I find the current "path replace" syntax confusing and it doesn't work for 
> this
> use-case.
> 
> Some comments below:
> 

Thank you for the comments Hiltjo.

Here is an updated diff :

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/relayd/parse.y,v
retrieving revision 1.246
diff -u -p -r1.246 parse.y
--- parse.y 14 Sep 2020 11:30:25 -  1.246
+++ parse.y 25 Oct 2020 09:20:53 -
@@ -175,8 +175,8 @@ typedef struct {
 %token LOOKUP METHOD MODE NAT NO DESTINATION NODELAY NOTHING ON PARENT PATH
 %token PFTAG PORT PREFORK PRIORITY PROTO QUERYSTR REAL REDIRECT RELAY REMOVE
 %token REQUEST RESPONSE RETRY QUICK RETURN ROUNDROBIN ROUTE SACK SCRIPT SEND
-%token SESSION SNMP SOCKET SPLICE SSL STICKYADDR STYLE TABLE TAG TAGGED TCP
-%token TIMEOUT TLS TO ROUTER RTLABEL TRANSPARENT TRAP URL WITH TTL RTABLE
+%token SESSION SNMP SOCKET SPLICE SSL STICKYADDR STRIP STYLE TABLE TAG TAGGED
+%token TCP TIMEOUT TLS TO ROUTER RTLABEL TRANSPARENT TRAP URL WITH TTL RTABLE
 %token MATCH PARAMS RANDOM LEASTSTATES SRCHASH KEY CERTIFICATE PASSWORD ECDHE
 %token EDH TICKETS CONNECTION CONNECTIONS CONTEXT ERRORS STATE CHANGES CHECKS
 %token WEBSOCKETS
@@ -1569,6 +1569,20 @@ ruleopts : METHOD STRING 
{
rule->rule_kv[keytype].kv_option = $2;
rule->rule_kv[keytype].kv_type = keytype;
}
+   | PATH STRIP NUMBER {
+   char*strip = NULL;
+
+   if ($3 < 0 || $3 > INT_MAX) {
+   yyerror("invalid strip number");
+   YYERROR;
+   }
+   if (asprintf(, "%lld", $3) <= 1)
+   fatal("can't parse strip");
+   keytype = KEY_TYPE_PATH;
+   rule->rule_kv[keytype].kv_option = KEY_OPTION_STRIP;
+   rule->rule_kv[keytype].kv_value = strip;
+   rule->rule_kv[keytype].kv_type = keytype;
+   }
| QUERYSTR key_option STRING value  {
switch ($2) {
case KEY_OPTION_APPEND:
@@ -2506,6 +2520,7 @@ lookup(char *s)
{ "ssl",SSL },
{ "state",  STATE },
{ "sticky-address", STICKYADDR },
+   { "strip",  STRIP },
{ "style",  STYLE },
{ "table",  TABLE },
{ "tag",TAG },
Index: relay.c
===
RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
retrieving revision 1.251
diff -u -p -r1.251 relay.c
--- relay.c 14 May 2020 17:27:38 -  1.251
+++ relay.c 25 Oct 2020 09:20:53 -
@@ -214,6 +214,9 @@ relay_ruledebug(struct relay_rule *rule)
case KEY_OPTION_LOG:
fprintf(stderr, "log ");
break;
+   case KEY_OPTION_STRIP:
+   fprintf(stderr, "strip ");
+   break;
case KEY_OPTION_NONE:
break;
}
@@ -227,13 +230,15 @@ relay_ruledebug(struct relay_rule *rule)
break;
}
 
+   int kvv = (kv->kv_option == KEY_OPTION_STRIP ||
+kv->kv_value == NULL);
fprintf(stderr, "%s%s%s%s%s%s ",
kv->kv_key == NULL ? "" : "\"",
kv->kv_key == NULL ? "" : kv->kv_key,
kv->kv_key == NULL ? "" : "\"",
-   kv->kv_value == NULL ? "" : " value \"",
+   kvv ? "" : " value \"",
kv->kv_value == NULL ? "" : kv->kv_value,
-   kv->kv_value == NULL ? "" : "\"");
+   kvv ? "" : "\"");
}
 
if (rule->rule_tablename[0])
Index: relay_http.c
===
RCS file: /cvs/src/usr.sbin/relayd/relay_http.c,v
retrieving revision 1.79
diff -u -p -r1.79 relay_http.c
--- relay_http.c4 Sep 2020 13:09:14 -   1.79
+++ relay_http.c25 Oct 2020 09:20:53 -
@@ -77,6 +77,7 @@ intrelay_match_actions(struct ctl_rel
struct relay_rule *, struct kvlist *, struct kvlist *,
struct relay_table **);
 voidrelay_httpdesc_free(struct http_descriptor *);
+char *  server_root_strip(char *, int);
 
 static struct relayd   *env = NULL;
 
@@ -1421,14 +1422,16 @@ relay_httppath_test(struct 

Re: Port httpd(8) 'strip' directive to relayd(8)

2020-10-24 Thread Hiltjo Posthuma
On Sat, Oct 24, 2020 at 05:04:20PM +0200, Denis Fondras wrote:
> The 'strip' directive from httpd(8) is useful when forwarding to another 
> server.
> 
> This diff adds the feature to relayd(8).
> 
> With :
> 
>   match request path "/server/*" tag psonoserver
>   match request tagged psonoserver path strip 1
>   match request tagged psonoserver forward to 
> 
> 
> https://psono.pw/server/info/ is forwarded as /info
> 
> Comments ? OK ?
> 

Hi Dennis,

Thanks for working on this.  I haven't tested the patch yet except compiling,
but this feature would be very nice to have imho.

I find the current "path replace" syntax confusing and it doesn't work for this
use-case.

Some comments below:

> Index: parse.y
> ===
> RCS file: /cvs/src/usr.sbin/relayd/parse.y,v
> retrieving revision 1.246
> diff -u -p -r1.246 parse.y
> --- parse.y   14 Sep 2020 11:30:25 -  1.246
> +++ parse.y   24 Oct 2020 14:52:36 -
> @@ -175,8 +175,8 @@ typedef struct {
>  %token   LOOKUP METHOD MODE NAT NO DESTINATION NODELAY NOTHING ON PARENT 
> PATH
>  %token   PFTAG PORT PREFORK PRIORITY PROTO QUERYSTR REAL REDIRECT RELAY 
> REMOVE
>  %token   REQUEST RESPONSE RETRY QUICK RETURN ROUNDROBIN ROUTE SACK 
> SCRIPT SEND
> -%token   SESSION SNMP SOCKET SPLICE SSL STICKYADDR STYLE TABLE TAG 
> TAGGED TCP
> -%token   TIMEOUT TLS TO ROUTER RTLABEL TRANSPARENT TRAP URL WITH TTL 
> RTABLE
> +%token   SESSION SNMP SOCKET SPLICE SSL STICKYADDR STRIP STYLE TABLE TAG 
> TAGGED
> +%token   TCP TIMEOUT TLS TO ROUTER RTLABEL TRANSPARENT TRAP URL WITH TTL 
> RTABLE
>  %token   MATCH PARAMS RANDOM LEASTSTATES SRCHASH KEY CERTIFICATE 
> PASSWORD ECDHE
>  %token   EDH TICKETS CONNECTION CONNECTIONS CONTEXT ERRORS STATE CHANGES 
> CHECKS
>  %token   WEBSOCKETS
> @@ -1569,6 +1569,23 @@ ruleopts   : METHOD STRING 
> {
>   rule->rule_kv[keytype].kv_option = $2;
>   rule->rule_kv[keytype].kv_type = keytype;
>   }
> + | PATH STRIP NUMBER {
> + char*strip = NULL;
> +
> + if ($3 < 0 || $3 > INT_MAX) {
> + yyerror("invalid strip number");
> + YYERROR;
> + }
> + if ((strip = calloc(11, sizeof(char))) == NULL) {
> + yyerror("calloc() failed");
> + YYERROR;
> + }

I think this could be a fatal("calloc"); call, like similar sections in this
file, because it is not a syntax error (YYERROR;).

> + sprintf(strip, "%lld", $3);

The calloc and sprintf could probably be rewritten to a single asprintf() call.

> + keytype = KEY_TYPE_PATH;
> + rule->rule_kv[keytype].kv_option = KEY_OPTION_STRIP;
> + rule->rule_kv[keytype].kv_value = strip;
> + rule->rule_kv[keytype].kv_type = keytype;
> + }
>   | QUERYSTR key_option STRING value  {
>   switch ($2) {
>   case KEY_OPTION_APPEND:
> @@ -2506,6 +2523,7 @@ lookup(char *s)
>   { "ssl",SSL },
>   { "state",  STATE },
>   { "sticky-address", STICKYADDR },
> + { "strip",  STRIP },
>   { "style",  STYLE },
>   { "table",  TABLE },
>   { "tag",TAG },
> Index: relay.c
> ===
> RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
> retrieving revision 1.251
> diff -u -p -r1.251 relay.c
> --- relay.c   14 May 2020 17:27:38 -  1.251
> +++ relay.c   24 Oct 2020 14:52:36 -
> @@ -214,6 +214,9 @@ relay_ruledebug(struct relay_rule *rule)
>   case KEY_OPTION_LOG:
>   fprintf(stderr, "log ");
>   break;
> + case KEY_OPTION_STRIP:
> + fprintf(stderr, "strip ");
> + break;
>   case KEY_OPTION_NONE:
>   break;
>   }
> @@ -227,13 +230,15 @@ relay_ruledebug(struct relay_rule *rule)
>   break;
>   }
>  
> + int kvv = (kv->kv_option == KEY_OPTION_STRIP ||
> +  kv->kv_value == NULL);
>   fprintf(stderr, "%s%s%s%s%s%s ",
>   kv->kv_key == NULL ? "" : "\"",
>   kv->kv_key == NULL ? "" : kv->kv_key,
>   kv->kv_key == NULL ? "" : "\"",
> - kv->kv_value == NULL ? "" : " value \"",
> + kvv ? "" : " value \"",
>   kv->kv_value == NULL ? "" : kv->kv_value,
> - kv->kv_value ==