mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 07:07:04 +02:00
BUG/MINOR: cache: Fully consume large requests in the cache applet
In the cache applet (in HTX and legacy HTTP), when an cached object is sent to a client, the request must be consumed. It is done at the end, after all the response was copied into the channel's buffer. But only outgoing data at time the applet is called are consumed. Then the applet is closed. If a request with a huge body is sent, an error is triggerred because a SHUTW is catched on an unfinished request. Now, we consume request data as soon as possible and we do it until the end. In fact, we don't try to shutdown the request's channel for write anymore. This patch must be backported to 1.9 after some observation period.
This commit is contained in:
parent
f52170d2f4
commit
adb363135c
47
src/cache.c
47
src/cache.c
@ -1097,39 +1097,22 @@ static void htx_cache_io_handler(struct appctx *appctx)
|
||||
}
|
||||
|
||||
end:
|
||||
if (appctx->st0 == HTX_CACHE_END) {
|
||||
/* eat the whole request */
|
||||
req_htx = htxbuf(&req->buf);
|
||||
htx_reset(req_htx);
|
||||
htx_to_buf(req_htx, &req->buf);
|
||||
co_set_data(req, 0);
|
||||
if (!(res->flags & CF_SHUTR) && appctx->st0 == HTX_CACHE_END) {
|
||||
res->flags |= CF_READ_NULL;
|
||||
si_shutr(si);
|
||||
}
|
||||
|
||||
if ((res->flags & CF_SHUTR) && (si->state == SI_ST_EST))
|
||||
si_shutw(si);
|
||||
|
||||
if (appctx->st0 == HTX_CACHE_END) {
|
||||
if ((req->flags & CF_SHUTW) && (si->state == SI_ST_EST)) {
|
||||
si_shutr(si);
|
||||
res->flags |= CF_READ_NULL;
|
||||
}
|
||||
}
|
||||
out:
|
||||
if (total)
|
||||
channel_add_input(res, total);
|
||||
|
||||
/* we have left the request in the buffer for the case where we
|
||||
* process a POST, and this automatically re-enables activity on
|
||||
* read. It's better to indicate that we want to stop reading when
|
||||
* we're sending, so that we know there's at most one direction
|
||||
* deciding to wake the applet up. It saves it from looping when
|
||||
* emitting large blocks into small TCP windows.
|
||||
*/
|
||||
htx_to_buf(res_htx, &res->buf);
|
||||
if (!channel_is_empty(res))
|
||||
si_stop_get(si);
|
||||
|
||||
/* eat the whole request */
|
||||
if (co_data(req)) {
|
||||
req_htx = htx_from_buf(&req->buf);
|
||||
co_htx_skip(req, req_htx, co_data(req));
|
||||
htx_to_buf(req_htx, &req->buf);
|
||||
}
|
||||
return;
|
||||
|
||||
error:
|
||||
@ -1266,17 +1249,17 @@ static void http_cache_io_handler(struct appctx *appctx)
|
||||
}
|
||||
}
|
||||
|
||||
if (appctx->st0 == HTTP_CACHE_FWD) {
|
||||
/* eat the whole request */
|
||||
co_skip(si_oc(si), co_data(si_oc(si))); // NOTE: when disabled does not repport the correct status code
|
||||
if (appctx->st0 == HTTP_CACHE_FWD)
|
||||
appctx->st0 = HTTP_CACHE_END;
|
||||
|
||||
if (!(res->flags & CF_SHUTR) && appctx->st0 == HTTP_CACHE_END) {
|
||||
res->flags |= CF_READ_NULL;
|
||||
si_shutr(si);
|
||||
}
|
||||
|
||||
if ((res->flags & CF_SHUTR) && (si->state == SI_ST_EST))
|
||||
si_shutw(si);
|
||||
out:
|
||||
;
|
||||
/* eat the whole request */
|
||||
if (co_data(si_oc(si)))
|
||||
co_skip(si_oc(si), co_data(si_oc(si)));
|
||||
}
|
||||
|
||||
static int parse_cache_rule(struct proxy *proxy, const char *name, struct act_rule *rule, char **err)
|
||||
|
Loading…
Reference in New Issue
Block a user