]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MAJOR: http/sample: use a static buffer for raw -> htx conversion
authorRichard Russo <russor@whatsapp.com>
Wed, 31 Jul 2019 18:45:56 +0000 (11:45 -0700)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 1 Aug 2019 09:35:29 +0000 (11:35 +0200)
Multiple calls to smp_fetch_fhdr use the header context to keep track of
header parsing position; however, when using header sampling on a raw
connection, the raw buffer is converted into an HTX structure each time, and
this was done in the trash areas; so the block reference would be invalid on
subsequent calls.

This patch must be backported to 2.0 and 1.9.

src/http_fetch.c

index df1ca3318bcbfbf83496a83d9078912097fe2552..922e25cc1adaff4e1b11fc34285b5f03121450d4 100644 (file)
 
 /* this struct is used between calls to smp_fetch_hdr() or smp_fetch_cookie() */
 static THREAD_LOCAL struct http_hdr_ctx static_http_hdr_ctx;
+/* this is used to convert raw connection buffers to htx */
+static THREAD_LOCAL struct buffer static_raw_htx_chunk;
+static THREAD_LOCAL char *static_raw_htx_buf;
 
 #define SMP_REQ_CHN(smp) (smp->strm ? &smp->strm->req : NULL)
 #define SMP_RES_CHN(smp) (smp->strm ? &smp->strm->res : NULL)
 
+/* This function returns the static htx chunk, where raw connections get
+ * converted to HTX as needed for samplxsing.
+ */
+struct buffer *get_raw_htx_chunk(void)
+{
+       chunk_reset(&static_raw_htx_chunk);
+       return &static_raw_htx_chunk;
+}
+
+static int alloc_raw_htx_chunk_per_thread()
+{
+       static_raw_htx_buf = malloc(global.tune.bufsize);
+       if (!static_raw_htx_buf)
+               return 0;
+       chunk_init(&static_raw_htx_chunk, static_raw_htx_buf, global.tune.bufsize);
+       return 1;
+}
+
+static void free_raw_htx_chunk_per_thread()
+{
+       free(static_raw_htx_buf);
+       static_raw_htx_buf = NULL;
+}
+
+REGISTER_PER_THREAD_ALLOC(alloc_raw_htx_chunk_per_thread);
+REGISTER_PER_THREAD_FREE(free_raw_htx_chunk_per_thread);
+
 /*
  * Returns the data from Authorization header. Function may be called more
  * than once so data is stored in txn->auth_data. When no header is found
@@ -234,7 +264,7 @@ struct htx *smp_prefetch_htx(struct sample *smp, struct channel *chn, int vol)
                else if (h1m.flags & H1_MF_CLEN)
                        flags |= HTX_SL_F_CLEN;
 
-               htx = htx_from_buf(get_trash_chunk());
+               htx = htx_from_buf(get_raw_htx_chunk());
                sl = htx_add_stline(htx, HTX_BLK_REQ_SL, flags, h1sl.rq.m, h1sl.rq.u, h1sl.rq.v);
                if (!sl || !htx_add_all_headers(htx, hdrs))
                        return NULL;