You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

71 lines
2.6 KiB

  1. commit c0968f59b723dfa9effa63ac28b59642b11c6b8b
  2. Author: Richard Russo <russor@whatsapp.com>
  3. Date: Wed Jul 31 11:45:56 2019 -0700
  4. BUG/MAJOR: http/sample: use a static buffer for raw -> htx conversion
  5. Multiple calls to smp_fetch_fhdr use the header context to keep track of
  6. header parsing position; however, when using header sampling on a raw
  7. connection, the raw buffer is converted into an HTX structure each time, and
  8. this was done in the trash areas; so the block reference would be invalid on
  9. subsequent calls.
  10. This patch must be backported to 2.0 and 1.9.
  11. (cherry picked from commit 458eafb36df88932a02d1ce7ca31832abf11b8b3)
  12. Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
  13. diff --git a/src/http_fetch.c b/src/http_fetch.c
  14. index 67ea2094..e372a122 100644
  15. --- a/src/http_fetch.c
  16. +++ b/src/http_fetch.c
  17. @@ -46,10 +46,40 @@
  18. /* this struct is used between calls to smp_fetch_hdr() or smp_fetch_cookie() */
  19. static THREAD_LOCAL struct hdr_ctx static_hdr_ctx;
  20. static THREAD_LOCAL struct http_hdr_ctx static_http_hdr_ctx;
  21. +/* this is used to convert raw connection buffers to htx */
  22. +static THREAD_LOCAL struct buffer static_raw_htx_chunk;
  23. +static THREAD_LOCAL char *static_raw_htx_buf;
  24. #define SMP_REQ_CHN(smp) (smp->strm ? &smp->strm->req : NULL)
  25. #define SMP_RES_CHN(smp) (smp->strm ? &smp->strm->res : NULL)
  26. +/* This function returns the static htx chunk, where raw connections get
  27. + * converted to HTX as needed for samplxsing.
  28. + */
  29. +struct buffer *get_raw_htx_chunk(void)
  30. +{
  31. + chunk_reset(&static_raw_htx_chunk);
  32. + return &static_raw_htx_chunk;
  33. +}
  34. +
  35. +static int alloc_raw_htx_chunk_per_thread()
  36. +{
  37. + static_raw_htx_buf = malloc(global.tune.bufsize);
  38. + if (!static_raw_htx_buf)
  39. + return 0;
  40. + chunk_init(&static_raw_htx_chunk, static_raw_htx_buf, global.tune.bufsize);
  41. + return 1;
  42. +}
  43. +
  44. +static void free_raw_htx_chunk_per_thread()
  45. +{
  46. + free(static_raw_htx_buf);
  47. + static_raw_htx_buf = NULL;
  48. +}
  49. +
  50. +REGISTER_PER_THREAD_ALLOC(alloc_raw_htx_chunk_per_thread);
  51. +REGISTER_PER_THREAD_FREE(free_raw_htx_chunk_per_thread);
  52. +
  53. /*
  54. * Returns the data from Authorization header. Function may be called more
  55. * than once so data is stored in txn->auth_data. When no header is found
  56. @@ -265,7 +295,7 @@ struct htx *smp_prefetch_htx(struct sample *smp, struct channel *chn, int vol)
  57. else if (h1m.flags & H1_MF_CLEN)
  58. flags |= HTX_SL_F_CLEN;
  59. - htx = htx_from_buf(get_trash_chunk());
  60. + htx = htx_from_buf(get_raw_htx_chunk());
  61. sl = htx_add_stline(htx, HTX_BLK_REQ_SL, flags, h1sl.rq.m, h1sl.rq.u, h1sl.rq.v);
  62. if (!sl || !htx_add_all_headers(htx, hdrs))
  63. return NULL;