]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: http: allow the cookie capture size to be changed
authorWilly Tarreau <w@1wt.eu>
Wed, 21 Nov 2012 23:17:38 +0000 (00:17 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 21 Nov 2012 23:44:27 +0000 (00:44 +0100)
Some users need more than 64 characters to log large cookies. The limit
was set to 63 characters (and not 64 as previously documented). Now it
is possible to change this using the global "tune.http.cookielen" setting
if required.

doc/configuration.txt
include/types/global.h
src/cfgparse.c
src/proto_http.c

index b5b22c9b749435dc201f657cd26bdfb2f7e6eef2..fd3e38de69c48690eab15986f8e72069a041b2d7 100644 (file)
@@ -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 <number>
   Each session using compression initializes the compression algorithm with
   this value. The default value is 1.
 
+tune.http.cookielen <number>
+  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 <number>
   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 <name> len <length>
   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
index 081cf545314599fb05a51d0b2b74fa1d36b74a3e..bfc1a351be99d6fddf8eba03bb2b1ec8aa88f0c4 100644 (file)
@@ -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 */
index d173e65fa0eb659eb1072aae8bfe1fd3f5ff708c..72719dc2ab70c2f3a8b981e5ff3fe55e907b1de6 100644 (file)
@@ -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);
index e5b0fb613e370bdada6689c33e11d5b8a3ba3d04..b82d45319b0a78fb0bab6a75d2a15502b29debb3 100644 (file)
@@ -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;
 
 /*