mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 07:37:02 +02:00
MINOR: converter: adding support for url_enc
add base support for url encode following RFC3986, supporting `query` type only. - add test checking url_enc/url_dec/url_enc - update documentation - leave the door open for future changes this should resolve github issue #941 Signed-off-by: William Dauchy <wdauchy@gmail.com>
This commit is contained in:
parent
421ed3952d
commit
888b0ae8cf
@ -16240,6 +16240,12 @@ url_dec([<in_form>])
|
|||||||
space (' '). Otherwise this will only happen after a question mark indicating
|
space (' '). Otherwise this will only happen after a question mark indicating
|
||||||
a query string ('?').
|
a query string ('?').
|
||||||
|
|
||||||
|
url_enc([<enc_type>])
|
||||||
|
Takes a string provided as input and returns the encoded version as output.
|
||||||
|
The input and the output are of type string. By default the type of encoding
|
||||||
|
is meant for `query` type. There is no other type supported for now but the
|
||||||
|
optional argument is here for future changes.
|
||||||
|
|
||||||
ungrpc(<field_number>,[<field_type>])
|
ungrpc(<field_number>,[<field_type>])
|
||||||
This extracts the protocol buffers message field in raw mode of an input binary
|
This extracts the protocol buffers message field in raw mode of an input binary
|
||||||
sample representation of a gRPC message with <field_number> as field number
|
sample representation of a gRPC message with <field_number> as field number
|
||||||
|
43
reg-tests/converter/url_enc.vtc
Normal file
43
reg-tests/converter/url_enc.vtc
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
varnishtest "url_enc converter test"
|
||||||
|
|
||||||
|
#REQUIRE_VERSION=2.4
|
||||||
|
|
||||||
|
feature ignore_unknown_macro
|
||||||
|
|
||||||
|
server s1 {
|
||||||
|
rxreq
|
||||||
|
txresp
|
||||||
|
} -repeat 2 -start
|
||||||
|
|
||||||
|
haproxy h1 -conf {
|
||||||
|
defaults
|
||||||
|
mode http
|
||||||
|
timeout connect 1s
|
||||||
|
timeout client 1s
|
||||||
|
timeout server 1s
|
||||||
|
|
||||||
|
frontend fe
|
||||||
|
bind "fd@${fe}"
|
||||||
|
|
||||||
|
http-request set-var(txn.url0) "str(foo=bar+42 42 )"
|
||||||
|
http-request set-var(txn.url1) "var(txn.url0),url_enc"
|
||||||
|
http-request set-var(txn.url2) "var(txn.url1),url_dec"
|
||||||
|
http-request set-var(txn.url3) "var(txn.url2),url_enc(query)"
|
||||||
|
http-response set-header url_enc0 "%[var(txn.url1)]"
|
||||||
|
http-response set-header url_dec "%[var(txn.url2)]"
|
||||||
|
http-response set-header url_enc1 "%[var(txn.url3)]"
|
||||||
|
|
||||||
|
default_backend be
|
||||||
|
|
||||||
|
backend be
|
||||||
|
server s1 ${s1_addr}:${s1_port}
|
||||||
|
} -start
|
||||||
|
|
||||||
|
client c1 -connect ${h1_fe_sock} {
|
||||||
|
txreq -url "/"
|
||||||
|
rxresp
|
||||||
|
expect resp.http.url_enc0 == "foo%3Dbar%2B42%2042%20"
|
||||||
|
expect resp.http.url_dec == "foo=bar+42 42 "
|
||||||
|
expect resp.http.url_enc1 == "foo%3Dbar%2B42%2042%20"
|
||||||
|
expect resp.status == 200
|
||||||
|
} -run
|
@ -268,6 +268,82 @@ static int sample_conv_url_dec(const struct arg *args, struct sample *smp, void
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* url-encode types and encode maps */
|
||||||
|
enum encode_type {
|
||||||
|
ENC_QUERY = 0,
|
||||||
|
};
|
||||||
|
long query_encode_map[(256 / 8) / sizeof(long)];
|
||||||
|
|
||||||
|
/* Check url-encode type */
|
||||||
|
static int sample_conv_url_enc_check(struct arg *arg, struct sample_conv *conv,
|
||||||
|
const char *file, int line, char **err)
|
||||||
|
{
|
||||||
|
enum encode_type enc_type;
|
||||||
|
|
||||||
|
if (strcmp(arg->data.str.area, "") == 0)
|
||||||
|
enc_type = ENC_QUERY;
|
||||||
|
else if (strcmp(arg->data.str.area, "query") == 0)
|
||||||
|
enc_type = ENC_QUERY;
|
||||||
|
else {
|
||||||
|
memprintf(err, "Unexpected encode type. "
|
||||||
|
"Allowed value is 'query'");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk_destroy(&arg->data.str);
|
||||||
|
arg->type = ARGT_SINT;
|
||||||
|
arg->data.sint = enc_type;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initializes some url encode data at boot */
|
||||||
|
static void sample_conf_url_enc_init()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
memset(query_encode_map, 0, sizeof(query_encode_map));
|
||||||
|
/* use rfc3986 to determine list of characters to keep unchanged for
|
||||||
|
* query string */
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
if (!((i >= 'a' && i <= 'z') || (i >= 'A' && i <= 'Z')
|
||||||
|
|| (i >= '0' && i <= '9') ||
|
||||||
|
i == '-' || i == '.' || i == '_' || i == '~'))
|
||||||
|
ha_bit_set(i, query_encode_map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INITCALL0(STG_PREPARE, sample_conf_url_enc_init);
|
||||||
|
|
||||||
|
/* This fetch url-encode any input string. Only support query string for now */
|
||||||
|
static int sample_conv_url_enc(const struct arg *args, struct sample *smp, void
|
||||||
|
*private)
|
||||||
|
{
|
||||||
|
enum encode_type enc_type;
|
||||||
|
struct buffer *trash = get_trash_chunk();
|
||||||
|
long *encode_map;
|
||||||
|
char *ret;
|
||||||
|
|
||||||
|
enc_type = ENC_QUERY;
|
||||||
|
if (args)
|
||||||
|
enc_type = args->data.sint;
|
||||||
|
|
||||||
|
/* Add final \0 required by encode_string() */
|
||||||
|
smp->data.u.str.area[smp->data.u.str.data] = '\0';
|
||||||
|
|
||||||
|
if (enc_type == ENC_QUERY)
|
||||||
|
encode_map = query_encode_map;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ret = encode_string(trash->area, trash->area + trash->size, '%',
|
||||||
|
encode_map, smp->data.u.str.area);
|
||||||
|
if (ret == NULL || *ret != '\0')
|
||||||
|
return 0;
|
||||||
|
trash->data = ret - trash->area;
|
||||||
|
smp->data.u.str = *trash;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int smp_conv_req_capture(const struct arg *args, struct sample *smp, void *private)
|
static int smp_conv_req_capture(const struct arg *args, struct sample *smp, void *private)
|
||||||
{
|
{
|
||||||
struct proxy *fe;
|
struct proxy *fe;
|
||||||
@ -369,6 +445,7 @@ static struct sample_conv_kw_list sample_conv_kws = {ILH, {
|
|||||||
{ "capture-req", smp_conv_req_capture, ARG1(1,SINT), NULL, SMP_T_STR, SMP_T_STR},
|
{ "capture-req", smp_conv_req_capture, ARG1(1,SINT), NULL, SMP_T_STR, SMP_T_STR},
|
||||||
{ "capture-res", smp_conv_res_capture, ARG1(1,SINT), NULL, SMP_T_STR, SMP_T_STR},
|
{ "capture-res", smp_conv_res_capture, ARG1(1,SINT), NULL, SMP_T_STR, SMP_T_STR},
|
||||||
{ "url_dec", sample_conv_url_dec, ARG1(0,SINT), NULL, SMP_T_STR, SMP_T_STR},
|
{ "url_dec", sample_conv_url_dec, ARG1(0,SINT), NULL, SMP_T_STR, SMP_T_STR},
|
||||||
|
{ "url_enc", sample_conv_url_enc, ARG1(1,STR), sample_conv_url_enc_check, SMP_T_STR, SMP_T_STR},
|
||||||
{ NULL, NULL, 0, 0, 0 },
|
{ NULL, NULL, 0, 0, 0 },
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user