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.
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 8f8900b..fce5698 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -17052,6 +17052,16 @@
Please note that this converter is only available when HAProxy has been
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>])
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
@@ -17494,6 +17504,17 @@
This prefix is followed by a name. The separator is a '.'. The name may only
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>])
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
diff --git a/src/sample.c b/src/sample.c
index 50ae76b..852cd04 100644
--- a/src/sample.c
+++ b/src/sample.c
@@ -3266,6 +3266,58 @@
smp->data.type = SMP_T_SINT;
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
* the second argument otherwise.
@@ -4350,6 +4402,8 @@
{ "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 },
{ "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. */
{ "ungrpc", sample_conv_ungrpc, ARG2(1,PBUF_FNUM,STR), sample_conv_protobuf_check, SMP_T_BIN, SMP_T_BIN },