]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: pattern: retrieve the sample type in the sample, not in the keyword description
authorWilly Tarreau <w@1wt.eu>
Mon, 23 Apr 2012 20:38:26 +0000 (22:38 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 8 May 2012 18:57:16 +0000 (20:57 +0200)
We need the pattern fetchers and converters to correctly set the output type
so that they can be used by ACL fetchers. By using the sample type instead of
the keyword type, we also open the possibility to create some multi-type
pattern fetch methods later (eg: "src" being v4/v6). Right now the type in
the keyword is used to validate the configuration.

src/pattern.c
src/proto_http.c
src/proto_tcp.c

index f851331f5263fb61a5ca49521915ca79d93cadd3..9787eccd06c667fe9bb85c135f085adff6971131 100644 (file)
@@ -118,6 +118,8 @@ static struct chunk *get_trash_chunk(void)
 
 /******************************************************************/
 /*          Pattern casts functions                               */
+/*   Note: these functions do *NOT* set the output type on the    */
+/*   sample, the caller is responsible for doing this on return.  */
 /******************************************************************/
 
 static int c_ip2int(struct sample *smp)
@@ -466,6 +468,10 @@ out_error:
  * pattern is not found or when format conversion failed.
  *  If <p> is not null, function returns results in structure pointed by <p>.
  *  If <p> is null, functions returns a pointer on a static pattern structure.
+ *
+ * Note: the fetch functions are required to properly set the return type. The
+ * conversion functions must do so too. However the cast functions do not need
+ * to since they're made to cast mutiple types according to what is required.
  */
 struct sample *pattern_process(struct proxy *px, struct session *l4, void *l7, int dir,
                                struct pattern_expr *expr, struct sample *p)
@@ -479,23 +485,21 @@ struct sample *pattern_process(struct proxy *px, struct session *l4, void *l7, i
        if (!expr->fetch->process(px, l4, l7, dir, expr->arg_p, p))
                return NULL;
 
-       p->type = expr->fetch->out_type;
-
        list_for_each_entry(conv_expr, &expr->conv_exprs, list) {
                if (!pattern_casts[p->type][conv_expr->conv->in_type](p))
                        return NULL;
 
+               /* force the output type after a cast */
                p->type = conv_expr->conv->in_type;
                if (!conv_expr->conv->process(conv_expr->arg_p, p))
                        return NULL;
-
-               p->type = conv_expr->conv->out_type;
        }
        return p;
 }
 
 /*****************************************************************/
 /*    Pattern format convert functions                           */
+/*    These functions set the data type on return.               */
 /*****************************************************************/
 
 static int pattern_conv_str2lower(const struct arg *arg_p, struct sample *smp)
@@ -509,6 +513,7 @@ static int pattern_conv_str2lower(const struct arg *arg_p, struct sample *smp)
                if ((smp->data.str.str[i] >= 'A') && (smp->data.str.str[i] <= 'Z'))
                        smp->data.str.str[i] += 'a' - 'A';
        }
+       smp->type = SMP_T_STR;
        return 1;
 }
 
@@ -523,6 +528,7 @@ static int pattern_conv_str2upper(const struct arg *arg_p, struct sample *smp)
                if ((smp->data.str.str[i] >= 'a') && (smp->data.str.str[i] <= 'z'))
                        smp->data.str.str[i] += 'A' - 'a';
        }
+       smp->type = SMP_T_STR;
        return 1;
 }
 
@@ -530,6 +536,7 @@ static int pattern_conv_str2upper(const struct arg *arg_p, struct sample *smp)
 static int pattern_conv_ipmask(const struct arg *arg_p, struct sample *smp)
 {
        smp->data.ipv4.s_addr &= arg_p->data.ipv4.s_addr;
+       smp->type = SMP_T_IPV4;
        return 1;
 }
 
index 4d504b09da41f67dae63afb64744c170b290a1c8..933351ac85e042b3c6bc5f172c23a02531fa230f 100644 (file)
@@ -8352,6 +8352,7 @@ pattern_fetch_hdr(struct proxy *px, struct session *l4, void *l7, int dir,
 {
        struct http_txn *txn = l7;
 
+       smp->type = SMP_T_CSTR;
        return http_get_hdr(&txn->req, arg_p->data.str.str, arg_p->data.str.len, &txn->hdr_idx,
                            -1, NULL, &smp->data.str.str, &smp->data.str.len);
 }
@@ -8455,6 +8456,7 @@ pattern_fetch_url_param(struct proxy *px, struct session *l4, void *l7, int dir,
                                  &url_param_value, &url_param_value_l))
                return 0;
 
+       smp->type = SMP_T_CSTR;
        smp->data.str.str = url_param_value;
        smp->data.str.len = url_param_value_l;
        return 1;
@@ -8508,6 +8510,7 @@ pattern_fetch_cookie(struct proxy *px, struct session *l4, void *l7, int dir,
                                  arg_p->data.str.str, arg_p->data.str.len, 1,
                                  &cookie_value, &cookie_value_l);
        if (found) {
+               smp->type = SMP_T_CSTR;
                smp->data.str.str = cookie_value;
                smp->data.str.len = cookie_value_l;
        }
@@ -8530,6 +8533,7 @@ pattern_fetch_set_cookie(struct proxy *px, struct session *l4, void *l7, int dir
                                  arg_p->data.str.str, arg_p->data.str.len, 1,
                                  &cookie_value, &cookie_value_l);
        if (found) {
+               smp->type = SMP_T_CSTR;
                smp->data.str.str = cookie_value;
                smp->data.str.len = cookie_value_l;
        }
index 6b2101a2480bca470b294658fd4e60dc3e9b0dd5..bd46de29c0d05f470a2405578ef790769614e983 100644 (file)
@@ -1281,6 +1281,7 @@ pattern_fetch_src(struct proxy *px, struct session *l4, void *l7, int dir,
        if (l4->si[0].addr.from.ss_family != AF_INET )
                return 0;
 
+       smp->type = SMP_T_IPV4;
        smp->data.ipv4.s_addr = ((struct sockaddr_in *)&l4->si[0].addr.from)->sin_addr.s_addr;
        return 1;
 }
@@ -1293,6 +1294,7 @@ pattern_fetch_src6(struct proxy *px, struct session *l4, void *l7, int dir,
        if (l4->si[0].addr.from.ss_family != AF_INET6)
                return 0;
 
+       smp->type = SMP_T_IPV6;
        memcpy(smp->data.ipv6.s6_addr, ((struct sockaddr_in6 *)&l4->si[0].addr.from)->sin6_addr.s6_addr, sizeof(smp->data.ipv6.s6_addr));
        return 1;
 }
@@ -1346,6 +1348,7 @@ pattern_fetch_dst(struct proxy *px, struct session *l4, void *l7, int dir,
        if (l4->si[0].addr.to.ss_family != AF_INET)
                return 0;
 
+       smp->type = SMP_T_IPV4;
        smp->data.ipv4.s_addr = ((struct sockaddr_in *)&l4->si[0].addr.to)->sin_addr.s_addr;
        return 1;
 }
@@ -1360,6 +1363,7 @@ pattern_fetch_dst6(struct proxy *px, struct session *l4, void *l7, int dir,
        if (l4->si[0].addr.to.ss_family != AF_INET6)
                return 0;
 
+       smp->type = SMP_T_IPV6;
        memcpy(smp->data.ipv6.s6_addr, ((struct sockaddr_in6 *)&l4->si[0].addr.to)->sin6_addr.s6_addr, sizeof(smp->data.ipv6.s6_addr));
        return 1;
 }
@@ -1383,6 +1387,7 @@ static int
 pattern_fetch_dport(struct proxy *px, struct session *l4, void *l7, int dir,
                     const struct arg *arg, struct sample *smp)
 {
+       smp->type = SMP_T_UINT;
        stream_sock_get_to_addr(&l4->si[0]);
 
        if (!(smp->data.uint = get_host_port(&l4->si[0].addr.to)))
@@ -1435,6 +1440,7 @@ pattern_fetch_payloadlv(struct proxy *px, struct session *l4, void *l7, int dir,
                return 0;
 
        /* init chunk as read only */
+       smp->type = SMP_T_CBIN;
        chunk_initlen(&smp->data.str, b->p + buf_offset, 0, buf_size);
 
        return 1;
@@ -1460,6 +1466,7 @@ pattern_fetch_payload(struct proxy *px, struct session *l4, void *l7, int dir,
                return 0;
 
        /* init chunk as read only */
+       smp->type = SMP_T_CBIN;
        chunk_initlen(&smp->data.str, b->p + buf_offset, 0, buf_size);
 
        return 1;
@@ -1486,6 +1493,7 @@ pattern_fetch_rdp_cookie(struct proxy *px, struct session *l4, void *l7, int dir
 
        expr.args = args;
 
+       /* type set by acl_fetch_rdp_cookie */
        ret = acl_fetch_rdp_cookie(px, l4, NULL, ACL_DIR_REQ, &expr, smp);
        if (ret == 0 || (smp->flags & SMP_F_MAY_CHANGE) || smp->data.str.len == 0)
                return 0;