diff --git a/doc/configuration.txt b/doc/configuration.txt index b5b22c9b7..fd3e38de6 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -467,6 +467,7 @@ The following keywords are supported in the "global" section : - tune.bufsize - tune.chksize - tune.comp.maxlevel + - tune.http.cookielen - tune.http.maxhdr - tune.maxaccept - tune.maxpollevents @@ -792,6 +793,16 @@ tune.comp.maxlevel Each session using compression initializes the compression algorithm with this value. The default value is 1. +tune.http.cookielen + Sets the maximum length of captured cookies. This is the maximum value that + the "capture cookie xxx len yyy" will be allowed to take, and any upper value + will automatically be truncated to this one. It is important not to set too + high a value because all cookie captures still allocate this size whatever + their configured value (they share a same pool). This value is per request + per response, so the memory allocated is twice this value per connection. + When not specified, the limit is set to 63 characters. It is recommended not + to change this value. + tune.http.maxhdr Sets the maximum number of headers in a request. When a request comes with a number of headers greater than this value (including the first line), it is @@ -1736,9 +1747,9 @@ capture cookie len The capture is performed in the frontend only because it is necessary that the log format does not change for a given frontend depending on the backends. This may change in the future. Note that there can be only one - "capture cookie" statement in a frontend. The maximum capture length is - configured in the sources by default to 64 characters. It is not possible to - specify a capture in a "defaults" section. + "capture cookie" statement in a frontend. The maximum capture length is set + by the global "tune.http.cookielen" setting and defaults to 63 characters. It + is not possible to specify a capture in a "defaults" section. Example: capture cookie ASPSESSION len 32 diff --git a/include/types/global.h b/include/types/global.h index 081cf5453..bfc1a351b 100644 --- a/include/types/global.h +++ b/include/types/global.h @@ -112,6 +112,7 @@ struct global { int chksize; /* check buffer size in bytes, defaults to BUFSIZE */ int pipesize; /* pipe size in bytes, system defaults if zero */ int max_http_hdr; /* max number of HTTP headers, use MAX_HTTP_HDR if zero */ + int cookie_len; /* max length of cookie captures */ #ifdef USE_OPENSSL int sslcachesize; /* SSL cache size in session, defaults to 20000 */ unsigned int ssllifetime; /* SSL session lifetime in seconds */ diff --git a/src/cfgparse.c b/src/cfgparse.c index d173e65fa..72719dc2a 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -673,6 +673,14 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm) } global.tune.pipesize = atol(args[1]); } + else if (!strcmp(args[0], "tune.http.cookielen")) { + if (*(args[1]) == 0) { + Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]); + err_code |= ERR_ALERT | ERR_FATAL; + goto out; + } + global.tune.cookie_len = atol(args[1]) + 1; + } else if (!strcmp(args[0], "tune.http.maxhdr")) { if (*(args[1]) == 0) { Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]); @@ -2495,12 +2503,6 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) curproxy->capture_name = strdup(args[2]); curproxy->capture_namelen = strlen(curproxy->capture_name); curproxy->capture_len = atol(args[4]); - if (curproxy->capture_len >= CAPTURE_LEN) { - Warning("parsing [%s:%d] : truncating capture length to %d bytes.\n", - file, linenum, CAPTURE_LEN - 1); - err_code |= ERR_WARN; - curproxy->capture_len = CAPTURE_LEN - 1; - } curproxy->to_log |= LW_COOKIE; } else if (!strcmp(args[1], "request") && !strcmp(args[2], "header")) { @@ -5951,6 +5953,14 @@ int check_config_validity() /* will be needed further to delay some tasks */ tv_update_date(0,1); + if (!global.tune.max_http_hdr) + global.tune.max_http_hdr = MAX_HTTP_HDR; + + if (!global.tune.cookie_len) + global.tune.cookie_len = CAPTURE_LEN; + + pool2_capture = create_pool("capture", global.tune.cookie_len, MEM_F_SHARED); + /* first, we will invert the proxy list order */ curproxy = NULL; while (proxy) { @@ -6438,6 +6448,14 @@ out_uri_auth_compat: memcpy(curproxy->check_req, sslv3_client_hello_pkt, curproxy->check_len); } + /* ensure that cookie capture length is not too large */ + if (curproxy->capture_len >= global.tune.cookie_len) { + Warning("config : truncating capture length to %d bytes for %s '%s'.\n", + global.tune.cookie_len - 1, proxy_type_str(curproxy), curproxy->id); + err_code |= ERR_WARN; + curproxy->capture_len = global.tune.cookie_len - 1; + } + /* The small pools required for the capture lists */ if (curproxy->nb_req_cap) { if (curproxy->mode == PR_MODE_HTTP) { @@ -7142,9 +7160,6 @@ out_uri_auth_compat: } } - if (!global.tune.max_http_hdr) - global.tune.max_http_hdr = MAX_HTTP_HDR; - pool2_hdr_idx = create_pool("hdr_idx", global.tune.max_http_hdr * sizeof(struct hdr_idx_elem), MEM_F_SHARED); diff --git a/src/proto_http.c b/src/proto_http.c index e5b0fb613..b82d45319 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -269,7 +269,6 @@ void init_proto_http() /* memory allocations */ pool2_requri = create_pool("requri", REQURI_LEN, MEM_F_SHARED); - pool2_capture = create_pool("capture", CAPTURE_LEN, MEM_F_SHARED); pool2_uniqueid = create_pool("uniqueid", UNIQUEID_LEN, MEM_F_SHARED); } @@ -862,7 +861,7 @@ extern const char sess_term_cond[8]; extern const char sess_fin_state[8]; extern const char *monthname[12]; struct pool_head *pool2_requri; -struct pool_head *pool2_capture; +struct pool_head *pool2_capture = NULL; struct pool_head *pool2_uniqueid; /*