diff --git a/doc/configuration.txt b/doc/configuration.txt index fdb0ddc65..1d9e3a54d 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -1504,6 +1504,7 @@ clitimeout (deprecated) X X X - compression X X X X contimeout (deprecated) X - X X cookie X - X X +declare capture - X X - default-server X - X X default_backend X X X - description - X X X @@ -2619,6 +2620,22 @@ cookie [ rewrite | insert | prefix ] [ indirect ] [ nocache ] and "ignore-persist". +declare capture [ request | response ] len + Declares a capture slot. + May be used in sections : defaults | frontend | listen | backend + no | yes | yes | no + Arguments: + is the length allowed for the capture. + + This declaration is only available in the frontend or listen section, but the + reserved slot can be used in the backends. The "request" keyword allocates a + capture slot for use in the request, and "response" allocates a capture slot + for use in the response. + + See also: "capture-req", "capture-res" (sample converters), + "http-request capture" and "http-response capture". + + default-server [param*] Change default options for a server in a backend May be used in sections : defaults | frontend | listen | backend diff --git a/src/proxy.c b/src/proxy.c index b6d870b1e..90d131356 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -337,6 +338,106 @@ static int proxy_parse_max_ka_queue(char **args, int section, struct proxy *prox return retval; } +/* This function parses a "declare" statement in a proxy section. It returns -1 + * if there is any error, 1 for warning, otherwise 0. If it does not return zero, + * it will write an error or warning message into a preallocated buffer returned + * at . The function must be called with pointing to the first command + * line word, with pointing to the proxy being parsed, and to the + * default proxy or NULL. + */ +static int proxy_parse_declare(char **args, int section, struct proxy *curpx, + struct proxy *defpx, const char *file, int line, + char **err) +{ + /* Capture keyword wannot be declared in a default proxy. */ + if (curpx == defpx) { + memprintf(err, "'%s' not avalaible in default section", args[0]); + return -1; + } + + /* Capture keywork is only avalaible in frontend. */ + if (!(curpx->cap & PR_CAP_FE)) { + memprintf(err, "'%s' only avalaible in frontend or listen section", args[0]); + return -1; + } + + /* Check mandatory second keyword. */ + if (!args[1] || !*args[1]) { + memprintf(err, "'%s' needs a second keyword that specify the type of declaration ('capture')", args[0]); + return -1; + } + + /* Actually, declare is only avalaible for declaring capture + * slot, but in the future it can declare maps or variables. + * So, this section permits to check and switch acording with + * the second keyword. + */ + if (strcmp(args[1], "capture") == 0) { + char *error = NULL; + long len; + struct cap_hdr *hdr; + + /* Check the next keyword. */ + if (!args[2] || !*args[2] || + (strcmp(args[2], "response") != 0 && + strcmp(args[2], "request") != 0)) { + memprintf(err, "'%s %s' requires a direction ('request' or 'response')", args[0], args[1]); + return -1; + } + + /* Check the 'len' keyword. */ + if (!args[3] || !*args[3] || strcmp(args[3], "len") != 0) { + memprintf(err, "'%s %s' requires a capture length ('len')", args[0], args[1]); + return -1; + } + + /* Check the length value. */ + if (!args[4] || !*args[4]) { + memprintf(err, "'%s %s': 'len' requires a numeric value that represents the " + "capture length", + args[0], args[1]); + return -1; + } + + /* convert the length value. */ + len = strtol(args[4], &error, 10); + if (*error != '\0') { + memprintf(err, "'%s %s': cannot parse the length '%s'.", + args[0], args[1], args[3]); + return -1; + } + + /* check length. */ + if (len <= 0) { + memprintf(err, "length must be > 0"); + return -1; + } + + /* register the capture. */ + hdr = calloc(sizeof(struct cap_hdr), 1); + hdr->name = NULL; /* not a header capture */ + hdr->namelen = 0; + hdr->len = len; + hdr->pool = create_pool("caphdr", hdr->len + 1, MEM_F_SHARED); + + if (strcmp(args[2], "request") == 0) { + hdr->next = curpx->req_cap; + hdr->index = curpx->nb_req_cap++; + curpx->req_cap = hdr; + } + if (strcmp(args[2], "response") == 0) { + hdr->next = curpx->rsp_cap; + hdr->index = curpx->nb_rsp_cap++; + curpx->rsp_cap = hdr; + } + return 0; + } + else { + memprintf(err, "unknown declaration type '%s' (supports 'capture')", args[1]); + return -1; + } +} + /* This function inserts proxy into the tree of known proxies. The proxy's * name is used as the storing key so it must already have been initialized. */ @@ -1093,6 +1194,7 @@ static struct cfg_kw_list cfg_kws = {ILH, { { CFG_LISTEN, "srvtimeout", proxy_parse_timeout }, { CFG_LISTEN, "rate-limit", proxy_parse_rate_limit }, { CFG_LISTEN, "max-keep-alive-queue", proxy_parse_max_ka_queue }, + { CFG_LISTEN, "declare", proxy_parse_declare }, { 0, NULL, NULL }, }};