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 <open...@ledeuns.net>
> To: Hiltjo Posthuma <hil...@codemadness.org>
> 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 -0000      1.246
> +++ parse.y   25 Oct 2020 09:20:53 -0000
> @@ -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(&strip, "%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 -0000      1.251
> +++ relay.c   25 Oct 2020 09:20:53 -0000
> @@ -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 -0000       1.79
> +++ relay_http.c      25 Oct 2020 09:20:53 -0000
> @@ -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 @@ 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)
> -             return (-1);
> -     else if (kv->kv_value != NULL && kv->kv_option == KEY_OPTION_NONE) {
> -             query = desc->http_query == NULL ? "" : desc->http_query;
> -             if (fnmatch(kv->kv_value, query, FNM_CASEFOLD) == FNM_NOMATCH)
> +     else if (kv->kv_option != KEY_OPTION_STRIP) {
> +             if (kv->kv_key == NULL)
> +                     return (0);
> +             else if (fnmatch(kv->kv_key, desc->http_path, 0) == FNM_NOMATCH)
>                       return (-1);
> +             else if (kv->kv_value != NULL && kv->kv_option == 
> KEY_OPTION_NONE) {
> +                     query = desc->http_query == NULL ? "" : 
> desc->http_query;
> +                     if (fnmatch(kv->kv_value, query, FNM_CASEFOLD) == 
> FNM_NOMATCH)
> +                             return (-1);
> +             }
>       }
>  
>       relay_match(actions, kv, match, NULL);
> @@ -1554,7 +1557,7 @@ relay_apply_actions(struct ctl_relay_eve
>       struct kv               *host = NULL;
>       const char              *value;
>       struct kv               *kv, *match, *kp, *mp, kvcopy, matchcopy, key;
> -     int                      addkv, ret;
> +     int                      addkv, ret, nstrip;
>       char                     buf[IBUF_READ_SIZE], *ptr;
>       char                    *msg = NULL;
>       const char              *meth = NULL;
> @@ -1655,6 +1658,15 @@ relay_apply_actions(struct ctl_relay_eve
>               case KEY_OPTION_LOG:
>                       /* perform this later */
>                       break;
> +             case KEY_OPTION_STRIP:
> +                     nstrip = strtonum(kv->kv_value, 0, INT_MAX, NULL);
> +                     if (kv->kv_type == KEY_TYPE_PATH) {
> +                             if (kv_setkey(match,
> +                                 server_root_strip(match->kv_key,
> +                                 nstrip)) == -1)
> +                                     goto fail;
> +                     }
> +                     break;
>               default:
>                       fatalx("%s: invalid action", __func__);
>                       /* NOTREACHED */
> @@ -1932,3 +1944,19 @@ relay_match(struct kvlist *actions, stru
>               TAILQ_INSERT_TAIL(actions, kv, kv_match_entry);
>       }
>  }
> +
> +char *
> +server_root_strip(char *path, int n)
> +{
> +     char *p;
> +
> +     /* Strip strip leading directories. Leading '/' is ignored. */
> +     for (; n > 0 && *path != '\0'; n--)
> +             if ((p = strchr(++path, '/')) == NULL)
> +                     path = strchr(path, '\0');
> +             else
> +                     path = p;
> +
> +     return (path);
> +}
> +
> Index: relayd.conf.5
> ===================================================================
> RCS file: /cvs/src/usr.sbin/relayd/relayd.conf.5,v
> retrieving revision 1.201
> diff -u -p -r1.201 relayd.conf.5
> --- relayd.conf.5     22 Oct 2020 08:00:24 -0000      1.201
> +++ relayd.conf.5     25 Oct 2020 09:20:53 -0000
> @@ -1287,6 +1287,15 @@ for example:
>  block path "/index.html"
>  block path "/cgi-bin/t.cgi" value "foo=bar*"
>  .Ed
> +.It Ic path  strip Ar number
> +Strip
> +.Ar number
> +path components from the beginning of the path of the requested URL
> +when using the
> +.Ic http
> +protocol.
> +This type is only available with the direction
> +.Ic request .
>  .It Ic query Ar option Oo Ar key Oo Ic value Ar value Oc Oc
>  Look up the entity as a query variable in the URL when using the
>  .Ic http
> Index: relayd.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/relayd/relayd.h,v
> retrieving revision 1.262
> diff -u -p -r1.262 relayd.h
> --- relayd.h  14 Sep 2020 11:30:25 -0000      1.262
> +++ relayd.h  25 Oct 2020 09:20:53 -0000
> @@ -292,7 +292,8 @@ enum key_option {
>       KEY_OPTION_SET,
>       KEY_OPTION_REMOVE,
>       KEY_OPTION_HASH,
> -     KEY_OPTION_LOG
> +     KEY_OPTION_LOG,
> +     KEY_OPTION_STRIP
>  };
>  
>  enum key_type {
> 

Reply via email to