Commit 78c82e5e authored by Martin Blix Grydeland's avatar Martin Blix Grydeland

Add field operator

parent 66c12d8f
......@@ -6,6 +6,9 @@ server s1 {
} -start
varnish v1 -vcl+backend {
sub vcl_deliver {
set resp.http.x-test = "123 321";
}
} -start
logexpect l1 -v v1
......@@ -162,3 +165,10 @@ logexpect l1 -d 1 -g vxid -q "RespStatus == 200 or RespStatus == 503 and RespSta
expect * = ReqEnd
expect * = End
} -run
# Test field
logexpect l1 -d 1 -g vxid -q "RespHeader[2] == 123" {
expect 0 * Begin req
expect * = ReqEnd
expect * = End
} -run
......@@ -73,8 +73,7 @@ vslq_test_rec(const struct vex *vex, const struct VSLC_ptr *rec)
const struct vex_rhs *rhs;
long long lhs_int;
double lhs_float;
const char *lhs_string;
size_t lhs_stringlen;
const char *b, *e;
char *p;
int i;
......@@ -83,8 +82,26 @@ vslq_test_rec(const struct vex *vex, const struct VSLC_ptr *rec)
rhs = vex->rhs;
AN(rhs);
lhs_string = VSL_CDATA(rec->ptr);
lhs_stringlen = VSL_LEN(rec->ptr) - 1;
b = VSL_CDATA(rec->ptr);
e = b + VSL_LEN(rec->ptr) - 1;
/* Field */
if (vex->lhs->field > 0) {
for (e = b, i = 0; *e && i < vex->lhs->field; i++) {
b = e;
/* Skip ws */
while (*b && isspace(*b))
b++;
e = b;
/* Skip non-ws */
while (*e && !isspace(*e))
e++;
}
assert(b <= e);
if (*b == '\0' || i < vex->lhs->field)
/* Missing field - no match */
return (0);
}
/* Prepare */
switch (vex->tok) {
......@@ -95,15 +112,18 @@ vslq_test_rec(const struct vex *vex, const struct VSLC_ptr *rec)
case T_LEQ: /* <= */
case T_GEQ: /* >= */
/* Numerical comparison */
if (*b == '\0')
/* Empty string doesn't match */
return (0);
switch (rhs->type) {
case VEX_INT:
lhs_int = strtoll(lhs_string, &p, 0);
lhs_int = strtoll(b, &p, 0);
if (*p == '\0' || isspace(*p))
break;
/* Can't parse - no match */
return (0);
case VEX_FLOAT:
lhs_float = strtod(lhs_string, &p);
lhs_float = strtod(b, &p);
if (*p == '\0' || isspace(*p))
break;
/* Can't parse - no match */
......@@ -130,27 +150,25 @@ vslq_test_rec(const struct vex *vex, const struct VSLC_ptr *rec)
VSLQ_TEST_NUMOP(rhs->type, lhs, >=, rhs->val);
case T_SEQ: /* eq */
assert(rhs->type == VEX_STRING);
if (lhs_stringlen == rhs->val_stringlen &&
!strncmp(lhs_string, rhs->val_string, lhs_stringlen))
if (e - b == rhs->val_stringlen &&
!strncmp(b, rhs->val_string, e - b))
return (1);
return (0);
case T_SNEQ: /* ne */
assert(rhs->type == VEX_STRING);
if (lhs_stringlen != rhs->val_stringlen ||
strncmp(lhs_string, rhs->val_string, lhs_stringlen))
if (e - b != rhs->val_stringlen ||
strncmp(b, rhs->val_string, e - b))
return (1);
return (0);
case '~': /* ~ */
assert(rhs->type == VEX_REGEX && rhs->val_regex != NULL);
i = VRE_exec(rhs->val_regex, lhs_string, lhs_stringlen, 0, 0,
NULL, 0, NULL);
i = VRE_exec(rhs->val_regex, b, e - b, 0, 0, NULL, 0, NULL);
if (i != VRE_ERROR_NOMATCH)
return (1);
return (0);
case T_NOMATCH: /* !~ */
assert(rhs->type == VEX_REGEX && rhs->val_regex != NULL);
i = VRE_exec(rhs->val_regex, lhs_string, lhs_stringlen, 0, 0,
NULL, 0, NULL);
i = VRE_exec(rhs->val_regex, b, e - b, 0, 0, NULL, 0, NULL);
if (i == VRE_ERROR_NOMATCH)
return (1);
return (0);
......
......@@ -50,6 +50,7 @@ static void vxp_expr_or(struct vxp *vxp, struct vex **pvex);
static void
vxp_expr_lhs(struct vxp *vxp, struct vex_lhs **plhs)
{
char *p;
/* XXX: Tag wildcards */
AN(plhs);
......@@ -75,7 +76,27 @@ vxp_expr_lhs(struct vxp *vxp, struct vex_lhs **plhs)
}
vxp_NextToken(vxp);
/* XXX: Lhs limiting operators ([], {}) */
if (vxp->t->tok == '[') {
/* LHS field [] */
vxp_NextToken(vxp);
if (vxp->t->tok != VAL) {
VSB_printf(vxp->sb, "Expected integer got '%.*s' ",
PF(vxp->t));
vxp_ErrWhere(vxp, vxp->t, -1);
return;
}
(*plhs)->field = (int)strtol(vxp->t->dec, &p, 0);
if (*p || (*plhs)->field <= 0) {
VSB_printf(vxp->sb, "Expected positive integer");
vxp_ErrWhere(vxp, vxp->t, -1);
return;
}
vxp_NextToken(vxp);
ExpectErr(vxp, ']');
vxp_NextToken(vxp);
}
/* XXX: LHS Level {} */
}
static void
......@@ -460,6 +481,8 @@ vex_print(const struct vex *vex, int indent)
if (vex->lhs != NULL) {
CHECK_OBJ_NOTNULL(vex->lhs, VEX_LHS_MAGIC);
fprintf(stderr, " tag=%s", VSL_tags[vex->lhs->tag]);
if (vex->lhs->field >= 0)
fprintf(stderr, "[%d]", vex->lhs->field);
}
if (vex->rhs != NULL) {
fprintf(stderr, " ");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment