commit c0968f59b723dfa9effa63ac28b59642b11c6b8b Author: Richard Russo Date: Wed Jul 31 11:45:56 2019 -0700 BUG/MAJOR: http/sample: use a static buffer for raw -> htx conversion 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. (cherry picked from commit 458eafb36df88932a02d1ce7ca31832abf11b8b3) Signed-off-by: Christopher Faulet diff --git a/src/http_fetch.c b/src/http_fetch.c index 67ea2094..e372a122 100644 --- a/src/http_fetch.c +++ b/src/http_fetch.c @@ -46,10 +46,40 @@ /* this struct is used between calls to smp_fetch_hdr() or smp_fetch_cookie() */ static THREAD_LOCAL struct hdr_ctx static_hdr_ctx; 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 @@ -265,7 +295,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;