BUG/MEDIUM: http: Switch the HTTP response in tunnel mode as earlier as possible

When the body length is undefined (no Content-Length or Transfer-Encoding
headers), The reponse remains in ending mode, waiting the request is done. So,
most of time this is not a problem because the resquest is done before the
response. But when a client sends data to a server that replies without waiting
all the data, it is really not desirable to wait the end of the request to
finish the response.

This bug was introduced when the tunneling of the request and the reponse was
refactored, in commit 4be980391 ("MINOR: http: Switch requests/responses in
TUNNEL mode only by checking txn flag").

This patch should be backported in 1.8 and 1.7.
This commit is contained in:
Christopher Faulet 2018-02-02 15:54:15 +01:00 committed by Willy Tarreau
parent 4ac77a98cd
commit fd04fcf5ed

View File

@ -4636,16 +4636,8 @@ int http_sync_res_state(struct stream *s)
* let's enforce it now that we're not expecting any new
* data to come. The caller knows the stream is complete
* once both states are CLOSED.
*
* However, there is an exception if the response length
* is undefined. In this case, we switch in TUNNEL mode.
*/
if (!(txn->rsp.flags & HTTP_MSGF_XFER_LEN)) {
channel_auto_read(chn);
txn->rsp.msg_state = HTTP_MSG_TUNNEL;
chn->flags |= CF_NEVER_WAIT;
}
else if (!(chn->flags & (CF_SHUTW|CF_SHUTW_NOW))) {
if (!(chn->flags & (CF_SHUTW|CF_SHUTW_NOW))) {
channel_shutr_now(chn);
channel_shutw_now(chn);
}
@ -6243,6 +6235,8 @@ http_msg_forward_body(struct stream *s, struct http_msg *msg)
/* The server still sending data that should be filtered */
if (!(chn->flags & CF_SHUTR) && HAS_DATA_FILTERS(s, chn))
goto missing_data_or_waiting;
msg->msg_state = HTTP_MSG_TUNNEL;
goto ending;
}
msg->msg_state = HTTP_MSG_ENDING;
@ -6264,6 +6258,7 @@ http_msg_forward_body(struct stream *s, struct http_msg *msg)
/* default_ret */ 1,
/* on_error */ goto error,
/* on_wait */ goto waiting);
if (msg->msg_state == HTTP_MSG_ENDING)
msg->msg_state = HTTP_MSG_DONE;
return 1;