mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-22 20:32:12 +00:00
BUG/MEDIUM: proto_htx: Introduce the state ENDING during forwarding
This state is used in the legacy HTTP when everything was received from an endpoint but a filter doesn't forward all the data. It is used to not report a client or a server abort, depending on channels flags. The same must be done on HTX streams. Otherwise, the message may be truncated. For instance, it may happen with the filter trace with the random forwarding enabled on the response channel. This patch must be backported to 1.9.
This commit is contained in:
parent
36a7702b03
commit
d20fdb0454
@ -1221,8 +1221,6 @@ int htx_request_forward_body(struct stream *s, struct channel *req, int an_bit)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto return_bad_req;
|
goto return_bad_req;
|
||||||
c_adv(req, ret);
|
c_adv(req, ret);
|
||||||
if (htx->data != co_data(req) || htx->extra)
|
|
||||||
goto missing_data_or_waiting;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c_adv(req, htx->data - co_data(req));
|
c_adv(req, htx->data - co_data(req));
|
||||||
@ -1235,12 +1233,17 @@ int htx_request_forward_body(struct stream *s, struct channel *req, int an_bit)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Check if the end-of-message is reached and if so, switch the message
|
/* Check if the end-of-message is reached and if so, switch the message
|
||||||
* in HTTP_MSG_DONE state.
|
* in HTTP_MSG_ENDING state. Then if all data was marked to be
|
||||||
|
* forwarded, set the state to HTTP_MSG_DONE.
|
||||||
*/
|
*/
|
||||||
if (htx_get_tail_type(htx) != HTX_BLK_EOM)
|
if (htx_get_tail_type(htx) != HTX_BLK_EOM)
|
||||||
goto missing_data_or_waiting;
|
goto missing_data_or_waiting;
|
||||||
|
|
||||||
|
msg->msg_state = HTTP_MSG_ENDING;
|
||||||
|
if (htx->data != co_data(req))
|
||||||
|
goto missing_data_or_waiting;
|
||||||
msg->msg_state = HTTP_MSG_DONE;
|
msg->msg_state = HTTP_MSG_DONE;
|
||||||
req->to_forward = 0;
|
req->to_forward = 0;
|
||||||
|
|
||||||
@ -1295,7 +1298,7 @@ int htx_request_forward_body(struct stream *s, struct channel *req, int an_bit)
|
|||||||
|
|
||||||
missing_data_or_waiting:
|
missing_data_or_waiting:
|
||||||
/* stop waiting for data if the input is closed before the end */
|
/* stop waiting for data if the input is closed before the end */
|
||||||
if (msg->msg_state < HTTP_MSG_DONE && req->flags & CF_SHUTR)
|
if (msg->msg_state < HTTP_MSG_ENDING && req->flags & CF_SHUTR)
|
||||||
goto return_cli_abort;
|
goto return_cli_abort;
|
||||||
|
|
||||||
waiting:
|
waiting:
|
||||||
@ -2220,8 +2223,6 @@ int htx_response_forward_body(struct stream *s, struct channel *res, int an_bit)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto return_bad_res;
|
goto return_bad_res;
|
||||||
c_adv(res, ret);
|
c_adv(res, ret);
|
||||||
if (htx->data != co_data(res) || htx->extra)
|
|
||||||
goto missing_data_or_waiting;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c_adv(res, htx->data - co_data(res));
|
c_adv(res, htx->data - co_data(res));
|
||||||
@ -2236,11 +2237,15 @@ int htx_response_forward_body(struct stream *s, struct channel *res, int an_bit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the end-of-message is reached and if so, switch the message
|
/* Check if the end-of-message is reached and if so, switch the message
|
||||||
* in HTTP_MSG_DONE state.
|
* in HTTP_MSG_ENDING state. Then if all data was marked to be
|
||||||
|
* forwarded, set the state to HTTP_MSG_DONE.
|
||||||
*/
|
*/
|
||||||
if (htx_get_tail_type(htx) != HTX_BLK_EOM)
|
if (htx_get_tail_type(htx) != HTX_BLK_EOM)
|
||||||
goto missing_data_or_waiting;
|
goto missing_data_or_waiting;
|
||||||
|
|
||||||
|
msg->msg_state = HTTP_MSG_ENDING;
|
||||||
|
if (htx->data != co_data(res))
|
||||||
|
goto missing_data_or_waiting;
|
||||||
msg->msg_state = HTTP_MSG_DONE;
|
msg->msg_state = HTTP_MSG_DONE;
|
||||||
res->to_forward = 0;
|
res->to_forward = 0;
|
||||||
|
|
||||||
@ -2284,7 +2289,7 @@ int htx_response_forward_body(struct stream *s, struct channel *res, int an_bit)
|
|||||||
* so we don't want to count this as a server abort. Otherwise it's a
|
* so we don't want to count this as a server abort. Otherwise it's a
|
||||||
* server abort.
|
* server abort.
|
||||||
*/
|
*/
|
||||||
if (msg->msg_state < HTTP_MSG_DONE && res->flags & CF_SHUTR) {
|
if (msg->msg_state < HTTP_MSG_ENDING && res->flags & CF_SHUTR) {
|
||||||
if ((s->req.flags & (CF_SHUTR|CF_SHUTW)) == (CF_SHUTR|CF_SHUTW))
|
if ((s->req.flags & (CF_SHUTR|CF_SHUTW)) == (CF_SHUTR|CF_SHUTW))
|
||||||
goto return_cli_abort;
|
goto return_cli_abort;
|
||||||
/* If we have some pending data, we continue the processing */
|
/* If we have some pending data, we continue the processing */
|
||||||
|
Loading…
Reference in New Issue
Block a user