0003-BUG-MEDIUM-http-Switch-the-HTTP-response-in-tunnel-mode-as-earlier-as-possible.patch 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. From 8a5949f2d74c3a3a6c6da25449992c312b183ef3 Mon Sep 17 00:00:00 2001
  2. From: Christopher Faulet <cfaulet@haproxy.com>
  3. Date: Fri, 2 Feb 2018 15:54:15 +0100
  4. Subject: [PATCH] BUG/MEDIUM: http: Switch the HTTP response in tunnel mode as
  5. earlier as possible
  6. When the body length is undefined (no Content-Length or Transfer-Encoding
  7. headers), The reponse remains in ending mode, waiting the request is done. So,
  8. most of time this is not a problem because the resquest is done before the
  9. response. But when a client sends data to a server that replies without waiting
  10. all the data, it is really not desirable to wait the end of the request to
  11. finish the response.
  12. This bug was introduced when the tunneling of the request and the reponse was
  13. refactored, in commit 4be980391 ("MINOR: http: Switch requests/responses in
  14. TUNNEL mode only by checking txn flag").
  15. This patch should be backported in 1.8 and 1.7.
  16. (cherry picked from commit fd04fcf5edb0a24cd29ce8f4d4dc2aa3a0e2e82c)
  17. Signed-off-by: Willy Tarreau <w@1wt.eu>
  18. ---
  19. src/proto_http.c | 15 +++++----------
  20. 1 file changed, 5 insertions(+), 10 deletions(-)
  21. diff --git a/src/proto_http.c b/src/proto_http.c
  22. index 64bd410..29880ea 100644
  23. --- a/src/proto_http.c
  24. +++ b/src/proto_http.c
  25. @@ -4634,16 +4634,8 @@ int http_sync_res_state(struct stream *s)
  26. * let's enforce it now that we're not expecting any new
  27. * data to come. The caller knows the stream is complete
  28. * once both states are CLOSED.
  29. - *
  30. - * However, there is an exception if the response length
  31. - * is undefined. In this case, we switch in TUNNEL mode.
  32. */
  33. - if (!(txn->rsp.flags & HTTP_MSGF_XFER_LEN)) {
  34. - channel_auto_read(chn);
  35. - txn->rsp.msg_state = HTTP_MSG_TUNNEL;
  36. - chn->flags |= CF_NEVER_WAIT;
  37. - }
  38. - else if (!(chn->flags & (CF_SHUTW|CF_SHUTW_NOW))) {
  39. + if (!(chn->flags & (CF_SHUTW|CF_SHUTW_NOW))) {
  40. channel_shutr_now(chn);
  41. channel_shutw_now(chn);
  42. }
  43. @@ -6241,6 +6233,8 @@ http_msg_forward_body(struct stream *s, struct http_msg *msg)
  44. /* The server still sending data that should be filtered */
  45. if (!(chn->flags & CF_SHUTR) && HAS_DATA_FILTERS(s, chn))
  46. goto missing_data_or_waiting;
  47. + msg->msg_state = HTTP_MSG_TUNNEL;
  48. + goto ending;
  49. }
  50. msg->msg_state = HTTP_MSG_ENDING;
  51. @@ -6262,7 +6256,8 @@ http_msg_forward_body(struct stream *s, struct http_msg *msg)
  52. /* default_ret */ 1,
  53. /* on_error */ goto error,
  54. /* on_wait */ goto waiting);
  55. - msg->msg_state = HTTP_MSG_DONE;
  56. + if (msg->msg_state == HTTP_MSG_ENDING)
  57. + msg->msg_state = HTTP_MSG_DONE;
  58. return 1;
  59. missing_data_or_waiting:
  60. --
  61. 1.7.10.4