Le Fri, Dec 11, 2020 at 10:53:56AM +0000, 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 -0000      1.250
+++ parse.y     3 Jan 2021 10:38:26 -0000
@@ -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(&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:
@@ -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 -0000      1.251
+++ relay.c     3 Jan 2021 10:38:27 -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        3 Jan 2021 10:38:27 -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.202
diff -u -p -r1.202 relayd.conf.5
--- relayd.conf.5       30 Oct 2020 09:47:35 -0000      1.202
+++ relayd.conf.5       3 Jan 2021 10:38:27 -0000
@@ -1289,6 +1289,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    3 Jan 2021 10:38:27 -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