MINOR: sample: add the host_only and port_only converters

Add 2 converters that can manipulate the value of an Host header.
host_only will return the host without any port, and port_only will
return the port.
This commit is contained in:
William Lallemand 2022-08-26 16:21:28 +02:00
parent 1ef2460934
commit dd754cba16
2 changed files with 75 additions and 0 deletions

View File

@ -17052,6 +17052,16 @@ hmac(<algorithm>,<key>)
Please note that this converter is only available when HAProxy has been Please note that this converter is only available when HAProxy has been
compiled with USE_OPENSSL. compiled with USE_OPENSSL.
host_only
Converts a string which contains a Host header value and removes its port.
The input must respect the format of the host header value
(rfc9110#section-7.2). It will support that kind of input: hostname,
hostname:80, 127.0.0.1, 127.0.0.1:80, [::1], [::1]:80.
This converter also sets the string in lowercase.
See also: "port_only" converter which will return the port.
http_date([<offset],[<unit>]) http_date([<offset],[<unit>])
Converts an integer supposed to contain a date since epoch to a string Converts an integer supposed to contain a date since epoch to a string
representing this date in a format suitable for use in HTTP header fields. If representing this date in a format suitable for use in HTTP header fields. If
@ -17494,6 +17504,17 @@ or(<value>)
This prefix is followed by a name. The separator is a '.'. The name may only This prefix is followed by a name. The separator is a '.'. The name may only
contain characters 'a-z', 'A-Z', '0-9', '.' and '_'. contain characters 'a-z', 'A-Z', '0-9', '.' and '_'.
port_only
Converts a string which contains a Host header value into an integer by
returning its port.
The input must respect the format of the host header value
(rfc9110#section-7.2). It will support that kind of input: hostname,
hostname:80, 127.0.0.1, 127.0.0.1:80, [::1], [::1]:80.
If no port were provided in the input, it will return 0.
See also: "host_only" converter which will return the host.
protobuf(<field_number>,[<field_type>]) protobuf(<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 protocol buffer message with <field_number> as field sample representation of a protocol buffer message with <field_number> as field

View File

@ -3266,6 +3266,58 @@ static int sample_conv_strcmp(const struct arg *arg_p, struct sample *smp, void
smp->data.type = SMP_T_SINT; smp->data.type = SMP_T_SINT;
return 1; return 1;
} }
/*
* This converter can takes a Host header value as defined by rfc9110#section-7.2
* Host = uri-host [ ":" port ] ;
* It returns the uri-host value in lowecase with the port stripped.
*/
static int sample_conv_host_only(const struct arg *arg_p, struct sample *smp, void *private)
{
/* Working cases: hostname00, hostname00:80, 127.0.0.1, 127.0.0.1:80, [::1], [::1]:80 */
char *beg = smp->data.u.str.area;
char *end = smp->data.u.str.area + smp->data.u.str.data - 1;
char *p;
for (p = end; p >= beg; p--) {
if (*p == ':' || *p == ']')
break;
}
if (p >= beg && *p == ':')
smp->data.u.str.data = p - beg;
/* if no port part was found, the hostname is the whole string */
smp->data.type = SMP_T_STR;
return sample_conv_str2lower(arg_p, smp, NULL);
}
/*
* This converter can takes a Host header value as defined by rfc9110#section-7.2
* Host = uri-host [ ":" port ] ;
* It returns the port value as a int.
*/
static int sample_conv_port_only(const struct arg *arg_p, struct sample *smp, void *private)
{
/* Working cases: hostname00, hostname00:80, 127.0.0.1, 127.0.0.1:80, [::1], [::1]:80 */
char *beg = smp->data.u.str.area;
char *end = smp->data.u.str.area + smp->data.u.str.data - 1;
char *p;
for (p = end; p >= beg; p--) {
if (*p == ':' || *p == ']')
break;
}
smp->data.type = SMP_T_SINT;
if (p >= beg && *p == ':' && ++p <= end) {
smp->data.u.sint = strl2ui(p, smp->data.u.str.data + smp->data.u.str.area - p);
} else {
smp->data.u.sint = 0;
}
return 1;
}
/* Takes a boolean as input. Returns the first argument if that boolean is true and /* Takes a boolean as input. Returns the first argument if that boolean is true and
* the second argument otherwise. * the second argument otherwise.
@ -4350,6 +4402,8 @@ static struct sample_conv_kw_list sample_conv_kws = {ILH, {
{ "regsub", sample_conv_regsub, ARG3(2,REG,STR,STR), sample_conv_regsub_check, SMP_T_STR, SMP_T_STR }, { "regsub", sample_conv_regsub, ARG3(2,REG,STR,STR), sample_conv_regsub_check, SMP_T_STR, SMP_T_STR },
{ "sha1", sample_conv_sha1, 0, NULL, SMP_T_BIN, SMP_T_BIN }, { "sha1", sample_conv_sha1, 0, NULL, SMP_T_BIN, SMP_T_BIN },
{ "strcmp", sample_conv_strcmp, ARG1(1,STR), smp_check_strcmp, SMP_T_STR, SMP_T_SINT }, { "strcmp", sample_conv_strcmp, ARG1(1,STR), smp_check_strcmp, SMP_T_STR, SMP_T_SINT },
{ "host_only", sample_conv_host_only, 0, NULL, SMP_T_STR, SMP_T_STR },
{ "port_only", sample_conv_port_only, 0, NULL, SMP_T_STR, SMP_T_SINT },
/* gRPC converters. */ /* gRPC converters. */
{ "ungrpc", sample_conv_ungrpc, ARG2(1,PBUF_FNUM,STR), sample_conv_protobuf_check, SMP_T_BIN, SMP_T_BIN }, { "ungrpc", sample_conv_ungrpc, ARG2(1,PBUF_FNUM,STR), sample_conv_protobuf_check, SMP_T_BIN, SMP_T_BIN },