From bfe61381501f1cc87beb4bfcebd33f9af924e0d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= Date: Wed, 6 Mar 2019 14:34:36 +0100 Subject: [PATCH] MINOR: sample: Add a protocol buffers specific converter. This patch adds "protobuf" protocol buffers specific converter wich may used in combination with "ungrpc" as first converter to extract a protocol buffers field value. It is simply implemented reusing protobuf_field_lookup() which is the protocol buffers specific parser already used by "ungrpc" converter which only parse a gRPC header in addition of parsing protocol buffers message. Update the documentation for this new "protobuf" converter. --- doc/configuration.txt | 30 ++++++++++++++++++++++++++++-- src/sample.c | 18 +++++++++++++++--- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/doc/configuration.txt b/doc/configuration.txt index 0d21175b2..a8022fc16 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -13599,6 +13599,19 @@ or() This prefix is followed by a name. The separator is a '.'. The name may only contain characters 'a-z', 'A-Z', '0-9', '.' and '_'. +protobuf(,[]) + This extracts the protocol buffers message field in raw mode of an input binary + sample representation of a protocol buffer message with as field + number (dotted notation) if is not present, or as an integer sample + if this field is present (see also "ungrpc" below). + The list of the authorized types is the following one: "int32", "int64", "uint32", + "uint64", "sint32", "sint64", "bool", "enum" for the "varint" wire type 0 + "fixed64", "sfixed64", "double" for the 64bit wire type 1, "fixed32", "sfixed32", + "float" for the wire type 5. Note that "string" is considered as a length-delimited + type, so it does not require any argument to be extracted. + More information may be found here about the protocol buffers message field types: + https://developers.google.com/protocol-buffers/docs/encoding + regsub(,[,]) Applies a regex-based substitution to the input string. It does the same operation as the well-known "sed" utility with "s///". By @@ -13868,8 +13881,9 @@ url_dec ungrpc(,[]) This extracts the protocol buffers message field in raw mode of an input binary - sample with as field number (dotted notation) if - is not present, or as an integer sample if this field is present. + sample representation of a gRPC message with as field number + (dotted notation) if is not present, or as an integer sample if this + field is present. The list of the authorized types is the following one: "int32", "int64", "uint32", "uint64", "sint32", "sint64", "bool", "enum" for the "varint" wire type 0 "fixed64", "sfixed64", "double" for the 64bit wire type 1, "fixed32", "sfixed32", @@ -13911,6 +13925,18 @@ ungrpc(,[]) req.body,ungrpc(48.59) + As a gRPC message is alway made of a gRPC header followed by protocol buffers + messages, in the previous example the "latitude" of "lo" first PPoint + could be extracted with these equivalent directives: + + req.body,ungrpc(48.59),protobuf(1,int32) + req.body,ungrpc(48),protobuf(59.1,int32) + req.body,ungrpc(48),protobuf(59),protobuf(1,int32) + + Note that the first convert must be "ungrpc", the remaining ones must be + "protobuf" and only the last one may have or not a second argument to + interpret the previous binary sample. + unset-var() Unsets a variable if the input content is defined. The name of the variable diff --git a/src/sample.c b/src/sample.c index e95c57c10..54f7c9b34 100644 --- a/src/sample.c +++ b/src/sample.c @@ -2787,8 +2787,19 @@ static int sample_conv_ungrpc(const struct arg *arg_p, struct sample *smp, void return 0; } -static int sample_conv_ungrpc_check(struct arg *args, struct sample_conv *conv, - const char *file, int line, char **err) +static int sample_conv_protobuf(const struct arg *arg_p, struct sample *smp, void *private) +{ + unsigned char *pos; + size_t left; + + pos = (unsigned char *)smp->data.u.str.area; + left = smp->data.u.str.data; + + return protobuf_field_lookup(arg_p, smp, &pos, &left); +} + +static int sample_conv_protobuf_check(struct arg *args, struct sample_conv *conv, + const char *file, int line, char **err) { if (!args[1].type) { args[1].type = ARGT_SINT; @@ -3197,7 +3208,8 @@ static struct sample_conv_kw_list sample_conv_kws = {ILH, { { "strcmp", sample_conv_strcmp, ARG1(1,STR), smp_check_strcmp, SMP_T_STR, SMP_T_SINT }, /* gRPC converters. */ - { "ungrpc", sample_conv_ungrpc, ARG2(1,PBUF_FNUM,STR), sample_conv_ungrpc_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 }, + { "protobuf", sample_conv_protobuf, ARG2(1,PBUF_FNUM,STR), sample_conv_protobuf_check, SMP_T_BIN, SMP_T_BIN }, { "and", sample_conv_binary_and, ARG1(1,STR), check_operator, SMP_T_SINT, SMP_T_SINT }, { "or", sample_conv_binary_or, ARG1(1,STR), check_operator, SMP_T_SINT, SMP_T_SINT },