mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-01 11:01:46 +00:00
[MEDIUM] http: wait for some flush of the response buffer before a new request
If we accept a new request and that request produces an immediate response (error, redirect, ...), then we may fail to send it in case of pipelined requests if the response buffer is full. To avoid this, we check the availability of at least maxrewrite bytes in the response buffer before accepting a new pipelined request.
This commit is contained in:
parent
ea65e68cc8
commit
065e8338e8
@ -2145,7 +2145,8 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit)
|
||||
* data later, which is much more complicated.
|
||||
*/
|
||||
if (req->l && msg->msg_state < HTTP_MSG_ERROR) {
|
||||
if (unlikely((req->flags & BF_FULL) ||
|
||||
if ((txn->flags & TX_NOT_FIRST) &&
|
||||
unlikely((req->flags & BF_FULL) ||
|
||||
req->r < req->lr ||
|
||||
req->r > req->data + req->size - global.tune.maxrewrite)) {
|
||||
if (req->send_max) {
|
||||
@ -2158,6 +2159,24 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit)
|
||||
http_buffer_heavy_realign(req, msg);
|
||||
}
|
||||
|
||||
/* Note that we have the same problem with the response ; we
|
||||
* may want to send a redirect, error or anything which requires
|
||||
* some spare space. So we'll ensure that we have at least
|
||||
* maxrewrite bytes available in the response buffer before
|
||||
* processing that one. This will only affect pipelined
|
||||
* keep-alive requests.
|
||||
*/
|
||||
if ((txn->flags & TX_NOT_FIRST) &&
|
||||
unlikely((s->rep->flags & BF_FULL) ||
|
||||
s->rep->r < s->rep->lr ||
|
||||
s->rep->r > s->rep->data + s->rep->size - global.tune.maxrewrite)) {
|
||||
if (s->rep->send_max) {
|
||||
/* don't let a connection request be initiated */
|
||||
buffer_dont_connect(req);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (likely(req->lr < req->r))
|
||||
http_msg_analyzer(req, msg, &txn->hdr_idx);
|
||||
}
|
||||
@ -3404,9 +3423,17 @@ void http_end_txn_clean_session(struct session *s)
|
||||
/* if the request buffer is not empty, it means we're
|
||||
* about to process another request, so send pending
|
||||
* data with MSG_MORE to merge TCP packets when possible.
|
||||
* Just don't do this if the buffer is close to be full,
|
||||
* because the request will wait for it to flush a little
|
||||
* bit before proceeding.
|
||||
*/
|
||||
if (s->req->l > s->req->send_max)
|
||||
s->rep->flags |= BF_EXPECT_MORE;
|
||||
if (s->req->l > s->req->send_max) {
|
||||
if (s->rep->send_max &&
|
||||
!(s->rep->flags & BF_FULL) &&
|
||||
s->rep->lr <= s->rep->r &&
|
||||
s->rep->r <= s->rep->data + s->rep->size - global.tune.maxrewrite)
|
||||
s->rep->flags |= BF_EXPECT_MORE;
|
||||
}
|
||||
|
||||
/* we're removing the analysers, we MUST re-enable events detection */
|
||||
buffer_auto_read(s->req);
|
||||
|
Loading…
Reference in New Issue
Block a user