MEDIUM: acl: use temp_pattern to store any string-type information

Now strings and data blocks are stored in the temp_pattern's chunk
and matched against this one.

The rdp_cookie currently makes extensive use of acl_fetch_rdp_cookie()
and will be a good candidate for the initial rework so that ACLs use
the patterns framework and not the other way around.
diff --git a/src/acl.c b/src/acl.c
index c23e5c3..9a20cc2 100644
--- a/src/acl.c
+++ b/src/acl.c
@@ -423,8 +423,8 @@
 			name_len = (data[7] << 8) + data[8];
 
 			if (name_type == 0) { /* hostname */
-				test->ptr = data + 9;
-				test->len = name_len;
+				temp_pattern.data.str.str = data + 9;
+				temp_pattern.data.str.len = name_len;
 				test->flags = ACL_TEST_F_VOLATILE;
 				//fprintf(stderr, "found SNI : <");
 				//write(2, test->ptr, test->len);
@@ -513,8 +513,8 @@
 	}
 
 	/* data points to cookie value */
-	test->ptr = (char *)data;
-	test->len = 0;
+	temp_pattern.data.str.str = (char *)data;
+	temp_pattern.data.str.len = 0;
 
 	while (bleft > 0 && *data != '\r') {
 		data++;
@@ -527,7 +527,7 @@
 	if (data[0] != '\r' || data[1] != '\n')
 		goto not_cookie;
 
-	test->len = (char *)data - test->ptr;
+	temp_pattern.data.str.len = (char *)data - temp_pattern.data.str.str;
 	test->flags = ACL_TEST_F_VOLATILE;
 	return 1;
 
@@ -545,8 +545,8 @@
 
 	ret = acl_fetch_rdp_cookie(px, l4, l7, dir, expr, test);
 
-	test->ptr = NULL;
-	test->len = 0;
+	temp_pattern.data.str.str = NULL;
+	temp_pattern.data.str.len = 0;
 
 	if (test->flags & ACL_TEST_F_MAY_CHANGE)
 		return 0;
@@ -587,12 +587,12 @@
 {
 	int icase;
 
-	if (pattern->len != test->len)
+	if (pattern->len != temp_pattern.data.str.len)
 		return ACL_PAT_FAIL;
 
 	icase = pattern->flags & ACL_PAT_F_IGNORE_CASE;
-	if ((icase && strncasecmp(pattern->ptr.str, test->ptr, test->len) == 0) ||
-	    (!icase && strncmp(pattern->ptr.str, test->ptr, test->len) == 0))
+	if ((icase && strncasecmp(pattern->ptr.str, temp_pattern.data.str.str, temp_pattern.data.str.len) == 0) ||
+	    (!icase && strncmp(pattern->ptr.str, temp_pattern.data.str.str, temp_pattern.data.str.len) == 0))
 		return ACL_PAT_PASS;
 	return ACL_PAT_FAIL;
 }
@@ -607,12 +607,12 @@
 	char prev;
 
 	/* we may have to force a trailing zero on the test pattern */
-	prev = test->ptr[test->len];
+	prev = temp_pattern.data.str.str[temp_pattern.data.str.len];
 	if (prev)
-		test->ptr[test->len] = '\0';
-	node = ebst_lookup(&expr->pattern_tree, test->ptr);
+		temp_pattern.data.str.str[temp_pattern.data.str.len] = '\0';
+	node = ebst_lookup(&expr->pattern_tree, temp_pattern.data.str.str);
 	if (prev)
-		test->ptr[test->len] = prev;
+		temp_pattern.data.str.str[temp_pattern.data.str.len] = prev;
 	return node;
 }
 
@@ -629,28 +629,28 @@
 	if (unlikely(test->flags & ACL_TEST_F_READ_ONLY)) {
 		char *new_str;
 
-		new_str = calloc(1, test->len + 1);
+		new_str = calloc(1, temp_pattern.data.str.len + 1);
 		if (!new_str)
 			return ACL_PAT_FAIL;
 
-		memcpy(new_str, test->ptr, test->len);
-		new_str[test->len] = 0;
+		memcpy(new_str, temp_pattern.data.str.str, temp_pattern.data.str.len);
+		new_str[temp_pattern.data.str.len] = 0;
 		if (test->flags & ACL_TEST_F_MUST_FREE)
-			free(test->ptr);
-		test->ptr = new_str;
+			free(temp_pattern.data.str.str);
+		temp_pattern.data.str.str = new_str;
 		test->flags |= ACL_TEST_F_MUST_FREE;
 		test->flags &= ~ACL_TEST_F_READ_ONLY;
 	}
 
-	old_char = test->ptr[test->len];
-	test->ptr[test->len] = 0;
+	old_char = temp_pattern.data.str.str[temp_pattern.data.str.len];
+	temp_pattern.data.str.str[temp_pattern.data.str.len] = 0;
 
-	if (regexec(pattern->ptr.reg, test->ptr, 0, NULL, 0) == 0)
+	if (regexec(pattern->ptr.reg, temp_pattern.data.str.str, 0, NULL, 0) == 0)
 		ret = ACL_PAT_PASS;
 	else
 		ret = ACL_PAT_FAIL;
 
-	test->ptr[test->len] = old_char;
+	temp_pattern.data.str.str[temp_pattern.data.str.len] = old_char;
 	return ret;
 }
 
@@ -659,12 +659,12 @@
 {
 	int icase;
 
-	if (pattern->len > test->len)
+	if (pattern->len > temp_pattern.data.str.len)
 		return ACL_PAT_FAIL;
 
 	icase = pattern->flags & ACL_PAT_F_IGNORE_CASE;
-	if ((icase && strncasecmp(pattern->ptr.str, test->ptr, pattern->len) != 0) ||
-	    (!icase && strncmp(pattern->ptr.str, test->ptr, pattern->len) != 0))
+	if ((icase && strncasecmp(pattern->ptr.str, temp_pattern.data.str.str, pattern->len) != 0) ||
+	    (!icase && strncmp(pattern->ptr.str, temp_pattern.data.str.str, pattern->len) != 0))
 		return ACL_PAT_FAIL;
 	return ACL_PAT_PASS;
 }
@@ -674,11 +674,11 @@
 {
 	int icase;
 
-	if (pattern->len > test->len)
+	if (pattern->len > temp_pattern.data.str.len)
 		return ACL_PAT_FAIL;
 	icase = pattern->flags & ACL_PAT_F_IGNORE_CASE;
-	if ((icase && strncasecmp(pattern->ptr.str, test->ptr + test->len - pattern->len, pattern->len) != 0) ||
-	    (!icase && strncmp(pattern->ptr.str, test->ptr + test->len - pattern->len, pattern->len) != 0))
+	if ((icase && strncasecmp(pattern->ptr.str, temp_pattern.data.str.str + temp_pattern.data.str.len - pattern->len, pattern->len) != 0) ||
+	    (!icase && strncmp(pattern->ptr.str, temp_pattern.data.str.str + temp_pattern.data.str.len - pattern->len, pattern->len) != 0))
 		return ACL_PAT_FAIL;
 	return ACL_PAT_PASS;
 }
@@ -692,20 +692,20 @@
 	char *end;
 	char *c;
 
-	if (pattern->len > test->len)
+	if (pattern->len > temp_pattern.data.str.len)
 		return ACL_PAT_FAIL;
 
-	end = test->ptr + test->len - pattern->len;
+	end = temp_pattern.data.str.str + temp_pattern.data.str.len - pattern->len;
 	icase = pattern->flags & ACL_PAT_F_IGNORE_CASE;
 	if (icase) {
-		for (c = test->ptr; c <= end; c++) {
+		for (c = temp_pattern.data.str.str; c <= end; c++) {
 			if (tolower(*c) != tolower(*pattern->ptr.str))
 				continue;
 			if (strncasecmp(pattern->ptr.str, c, pattern->len) == 0)
 				return ACL_PAT_PASS;
 		}
 	} else {
-		for (c = test->ptr; c <= end; c++) {
+		for (c = temp_pattern.data.str.str; c <= end; c++) {
 			if (*c != *pattern->ptr.str)
 				continue;
 			if (strncmp(pattern->ptr.str, c, pattern->len) == 0)
@@ -761,13 +761,13 @@
 	while (pl > 0 && is_delimiter(ps[pl - 1], delimiters))
 		pl--;
 
-	if (pl > test->len)
+	if (pl > temp_pattern.data.str.len)
 		return ACL_PAT_FAIL;
 
 	may_match = 1;
 	icase = pattern->flags & ACL_PAT_F_IGNORE_CASE;
-	end = test->ptr + test->len - pl;
-	for (c = test->ptr; c <= end; c++) {
+	end = temp_pattern.data.str.str + temp_pattern.data.str.len - pl;
+	for (c = temp_pattern.data.str.str; c <= end; c++) {
 		if (is_delimiter(*c, delimiters)) {
 			may_match = 1;
 			continue;
@@ -822,8 +822,8 @@
 /* Checks that the length of the pattern in <test> is included between min and max */
 int acl_match_len(struct acl_test *test, struct acl_pattern *pattern)
 {
-	if ((!pattern->val.range.min_set || pattern->val.range.min <= test->len) &&
-	    (!pattern->val.range.max_set || test->len <= pattern->val.range.max))
+	if ((!pattern->val.range.min_set || pattern->val.range.min <= temp_pattern.data.str.len) &&
+	    (!pattern->val.range.max_set || temp_pattern.data.str.len <= pattern->val.range.max))
 		return ACL_PAT_PASS;
 	return ACL_PAT_FAIL;
 }
@@ -1851,8 +1851,8 @@
 
 				/* now we may have some cleanup to do */
 				if (test.flags & ACL_TEST_F_MUST_FREE) {
-					free(test.ptr);
-					test.len = 0;
+					free(temp_pattern.data.str.str);
+					temp_pattern.data.str.len = 0;
 				}
 
 				/* we're ORing these terms, so a single PASS is enough */
diff --git a/src/backend.c b/src/backend.c
index 0f3bccd..5e88f62 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -413,7 +413,9 @@
 	expr.arg_len = px->hh_len;
 
 	ret = acl_fetch_rdp_cookie(px, s, NULL, ACL_DIR_REQ, &expr, &test);
-	if (ret == 0 || (test.flags & ACL_TEST_F_MAY_CHANGE) || test.len == 0)
+	len = temp_pattern.data.str.len;
+
+	if (ret == 0 || (test.flags & ACL_TEST_F_MAY_CHANGE) || len == 0)
 		return NULL;
 
 	/* note: we won't hash if there's only one server left */
@@ -423,8 +425,7 @@
 	/* Found a the hh_name in the headers.
 	 * we will compute the hash based on this value ctx.val.
 	 */
-	len = test.len;
-	p = (char *)test.ptr;
+	p = temp_pattern.data.str.str;
 	while (len) {
 		hash = *p + (hash << 6) + (hash << 16) - hash;
 		len--;
@@ -1112,14 +1113,14 @@
 	expr.arg_len = s->be->rdp_cookie_len;
 
 	ret = acl_fetch_rdp_cookie(px, s, NULL, ACL_DIR_REQ, &expr, &test);
-	if (ret == 0 || (test.flags & ACL_TEST_F_MAY_CHANGE) || test.len == 0)
+	if (ret == 0 || (test.flags & ACL_TEST_F_MAY_CHANGE) || temp_pattern.data.str.len == 0)
 		goto no_cookie;
 
 	memset(&addr, 0, sizeof(addr));
 	addr.sin_family = AF_INET;
 
-	/* Considering an rdp cookie detected using acl, test.ptr ended with <cr><lf> and should return */
-	addr.sin_addr.s_addr = strtoul(test.ptr, &p, 10);
+	/* Considering an rdp cookie detected using acl, str ended with <cr><lf> and should return */
+	addr.sin_addr.s_addr = strtoul(temp_pattern.data.str.str, &p, 10);
 	if (*p != '.')
 		goto no_cookie;
 	p++;
diff --git a/src/proto_http.c b/src/proto_http.c
index b60048e..10a4bdd 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -7866,8 +7866,8 @@
 	if (len <= 0)
 		return 0;
 
-	test->ptr = ptr;
-	test->len = len;
+	temp_pattern.data.str.str = ptr;
+	temp_pattern.data.str.len = len;
 
 	test->flags = ACL_TEST_F_READ_ONLY | ACL_TEST_F_VOL_1ST;
 	return 1;
@@ -7894,8 +7894,8 @@
 	if (len <= 0)
 		return 0;
 
-	test->ptr = ptr;
-	test->len = len;
+	temp_pattern.data.str.str = ptr;
+	temp_pattern.data.str.len = len;
 
 	test->flags = ACL_TEST_F_READ_ONLY | ACL_TEST_F_VOL_1ST;
 	return 1;
@@ -7941,8 +7941,8 @@
 		/* ensure the indexes are not affected */
 		return 0;
 
-	test->len = txn->req.sl.rq.u_l;
-	test->ptr = txn->req.sol + txn->req.sl.rq.u;
+	temp_pattern.data.str.len = txn->req.sl.rq.u_l;
+	temp_pattern.data.str.str = txn->req.sol + txn->req.sl.rq.u;
 
 	/* we do not need to set READ_ONLY because the data is in a buffer */
 	test->flags = ACL_TEST_F_VOL_1ST;
@@ -8031,8 +8031,9 @@
 	if (http_find_header2(expr->arg.str, expr->arg_len, sol, idx, ctx)) {
 		test->flags |= ACL_TEST_F_FETCH_MORE;
 		test->flags |= ACL_TEST_F_VOL_HDR;
-		test->len = ctx->vlen;
-		test->ptr = (char *)ctx->line + ctx->val;
+		temp_pattern.data.str.str = (char *)ctx->line + ctx->val;
+		temp_pattern.data.str.len = ctx->vlen;
+
 		return 1;
 	}
 
@@ -8292,12 +8293,12 @@
 		return 0;
 
 	/* OK, we got the '/' ! */
-	test->ptr = ptr;
+	temp_pattern.data.str.str = ptr;
 
 	while (ptr < end && *ptr != '?')
 		ptr++;
 
-	test->len = ptr - test->ptr;
+	temp_pattern.data.str.len = ptr - temp_pattern.data.str.str;
 
 	/* we do not need to set READ_ONLY because the data is in a buffer */
 	test->flags = ACL_TEST_F_VOL_1ST;
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 207fec0..ea3692c 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -1580,11 +1580,10 @@
 	expr.arg_len = arg_p[0].data.str.len;
 
 	ret = acl_fetch_rdp_cookie(px, l4, NULL, ACL_DIR_REQ, &expr, &test);
-	if (ret == 0 || (test.flags & ACL_TEST_F_MAY_CHANGE) || test.len == 0)
+	if (ret == 0 || (test.flags & ACL_TEST_F_MAY_CHANGE) || temp_pattern.data.str.len == 0)
 		return 0;
 
-	/* init chunk as read only */
-	chunk_initlen(&data->str, test.ptr, 0, test.len);
+	data->str = temp_pattern.data.str;
 	return 1;
 }