MAJOR: cache: Update HTTP cache applet to handle its own buffers

Just like the HTTP stats applet, the cache applet was refactored to use its
own buffers. Changes are pretty similar.
This commit is contained in:
Christopher Faulet 2024-01-23 08:40:48 +01:00
parent 6d5dd23dbc
commit 863417292b

View File

@ -1485,8 +1485,7 @@ static unsigned int htx_cache_dump_blk(struct appctx *appctx, struct htx *htx, e
unsigned int max, total; unsigned int max, total;
uint32_t blksz; uint32_t blksz;
max = htx_get_max_blksz(htx, max = htx_free_data_space(htx);
channel_htx_recv_max(sc_ic(appctx_sc(appctx)), htx));
if (!max) if (!max)
return 0; return 0;
blksz = ((type == HTX_BLK_HDR || type == HTX_BLK_TLR) blksz = ((type == HTX_BLK_HDR || type == HTX_BLK_TLR)
@ -1529,8 +1528,7 @@ static unsigned int htx_cache_dump_data_blk(struct appctx *appctx, struct htx *h
unsigned int max, total, rem_data, data_len; unsigned int max, total, rem_data, data_len;
uint32_t blksz; uint32_t blksz;
max = htx_get_max_blksz(htx, max = htx_free_data_space(htx);
channel_htx_recv_max(sc_ic(appctx_sc(appctx)), htx));
if (!max) if (!max)
return 0; return 0;
@ -1785,28 +1783,27 @@ static void http_cache_io_handler(struct appctx *appctx)
struct cache_appctx *ctx = appctx->svcctx; struct cache_appctx *ctx = appctx->svcctx;
struct cache_entry *cache_ptr = ctx->entry; struct cache_entry *cache_ptr = ctx->entry;
struct shared_block *first = block_ptr(cache_ptr); struct shared_block *first = block_ptr(cache_ptr);
struct stconn *sc = appctx_sc(appctx); struct htx *res_htx = NULL;
struct channel *req = sc_oc(sc);
struct channel *res = sc_ic(sc);
struct htx *req_htx, *res_htx;
struct buffer *errmsg; struct buffer *errmsg;
unsigned int len; unsigned int len;
size_t ret, total = 0; size_t ret;
if (unlikely(se_fl_test(appctx->sedesc, (SE_FL_EOS|SE_FL_ERROR|SE_FL_SHR|SE_FL_SHW)))) if (applet_fl_test(appctx, APPCTX_FL_OUTBLK_ALLOC|APPCTX_FL_OUTBLK_FULL))
goto exit; goto exit;
applet_have_more_data(appctx);
if (!appctx_get_buf(appctx, &appctx->outbuf)) {
appctx->flags |= APPCTX_FL_OUTBLK_ALLOC;
goto exit;
}
if (unlikely(applet_fl_test(appctx, APPCTX_FL_EOS|APPCTX_FL_ERROR|APPCTX_FL_SHUTDOWN)))
goto exit;
res_htx = htx_from_buf(&appctx->outbuf);
len = first->len - sizeof(*cache_ptr) - ctx->sent; len = first->len - sizeof(*cache_ptr) - ctx->sent;
res_htx = htx_from_buf(&res->buf); res_htx = htx_from_buf(&appctx->outbuf);
total = res_htx->data;
/* Check if the input buffer is available. */
if (!b_size(&res->buf)) {
sc_need_room(sc, 0);
goto out;
}
if (appctx->st0 == HTX_CACHE_INIT) { if (appctx->st0 == HTX_CACHE_INIT) {
ctx->next = block_ptr(cache_ptr); ctx->next = block_ptr(cache_ptr);
@ -1817,6 +1814,8 @@ static void http_cache_io_handler(struct appctx *appctx)
} }
if (appctx->st0 == HTX_CACHE_HEADER) { if (appctx->st0 == HTX_CACHE_HEADER) {
struct ist meth;
/* Headers must be dump at once. Otherwise it is an error */ /* Headers must be dump at once. Otherwise it is an error */
ret = htx_cache_dump_msg(appctx, res_htx, len, HTX_BLK_EOH); ret = htx_cache_dump_msg(appctx, res_htx, len, HTX_BLK_EOH);
if (!ret || (htx_get_tail_type(res_htx) != HTX_BLK_EOH) || if (!ret || (htx_get_tail_type(res_htx) != HTX_BLK_EOH) ||
@ -1834,7 +1833,8 @@ static void http_cache_io_handler(struct appctx *appctx)
/* Skip response body for HEAD requests or in case of "304 Not /* Skip response body for HEAD requests or in case of "304 Not
* Modified" response. */ * Modified" response. */
if (__sc_strm(sc)->txn->meth == HTTP_METH_HEAD || ctx->send_notmodified) meth = htx_sl_req_meth(http_get_stline(htxbuf(&appctx->inbuf)));
if (find_http_meth(istptr(meth), istlen(meth)) == HTTP_METH_HEAD || ctx->send_notmodified)
appctx->st0 = HTX_CACHE_EOM; appctx->st0 = HTX_CACHE_EOM;
else { else {
len = first->len - sizeof(*cache_ptr) - ctx->sent; len = first->len - sizeof(*cache_ptr) - ctx->sent;
@ -1846,7 +1846,7 @@ static void http_cache_io_handler(struct appctx *appctx)
if (len) { if (len) {
ret = htx_cache_dump_msg(appctx, res_htx, len, HTX_BLK_UNUSED); ret = htx_cache_dump_msg(appctx, res_htx, len, HTX_BLK_UNUSED);
if (ret < len) { if (ret < len) {
sc_need_room(sc, channel_htx_recv_max(res, res_htx) + 1); appctx->flags |= APPCTX_FL_OUTBLK_FULL;
goto out; goto out;
} }
} }
@ -1857,41 +1857,35 @@ static void http_cache_io_handler(struct appctx *appctx)
if (appctx->st0 == HTX_CACHE_EOM) { if (appctx->st0 == HTX_CACHE_EOM) {
/* no more data are expected. */ /* no more data are expected. */
res_htx->flags |= HTX_FL_EOM; res_htx->flags |= HTX_FL_EOM;
se_fl_set(appctx->sedesc, SE_FL_EOI); applet_set_eoi(appctx);
appctx->st0 = HTX_CACHE_END; appctx->st0 = HTX_CACHE_END;
} }
end: end:
if (appctx->st0 == HTX_CACHE_END) { if (appctx->st0 == HTX_CACHE_END) {
applet_have_no_more_data(appctx); applet_set_eos(appctx);
se_fl_set(appctx->sedesc, SE_FL_EOS);
} }
out: out:
total = res_htx->data - total; if (res_htx)
if (total) htx_to_buf(res_htx, &appctx->outbuf);
channel_add_input(res, total);
htx_to_buf(res_htx, &res->buf);
exit: exit:
/* eat the whole request */ /* eat the whole request */
if (co_data(req)) { b_reset(&appctx->inbuf);
req_htx = htx_from_buf(&req->buf); applet_fl_clr(appctx, APPCTX_FL_INBLK_FULL);
co_htx_skip(req, req_htx, co_data(req));
htx_to_buf(req_htx, &req->buf);
}
return; return;
error: error:
/* Sent and HTTP error 500 */ /* Sent and HTTP error 500 */
b_reset(&res->buf); b_reset(&appctx->outbuf);
errmsg = &http_err_chunks[HTTP_ERR_500]; errmsg = &http_err_chunks[HTTP_ERR_500];
res->buf.data = b_data(errmsg); appctx->outbuf.data = b_data(errmsg);
memcpy(res->buf.area, b_head(errmsg), b_data(errmsg)); memcpy(appctx->outbuf.area, b_head(errmsg), b_data(errmsg));
res_htx = htx_from_buf(&res->buf); res_htx = htx_from_buf(&appctx->outbuf);
total = 0; applet_set_eos(appctx);
se_fl_set(appctx->sedesc, SE_FL_ERROR); applet_set_error(appctx);
appctx->st0 = HTX_CACHE_END; appctx->st0 = HTX_CACHE_END;
goto end; goto end;
} }
@ -3164,6 +3158,8 @@ struct applet http_cache_applet = {
.obj_type = OBJ_TYPE_APPLET, .obj_type = OBJ_TYPE_APPLET,
.name = "<CACHE>", /* used for logging */ .name = "<CACHE>", /* used for logging */
.fct = http_cache_io_handler, .fct = http_cache_io_handler,
.rcv_buf = appctx_rcv_buf,
.snd_buf = appctx_snd_buf,
.release = http_cache_applet_release, .release = http_cache_applet_release,
}; };