mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 07:07:04 +02:00
MEDIUM: applet: Simplify a bit API to exchange data with applets
Default .rcv_buf and .snd_buf functions that applets can use are now specialized to manipulate raw buffers or HTX buffers. Thus a TCP applet should use appctx_raw_rcv_buf() and appctx_raw_snd_buf() while HTTP applet should use appctx_htx_rcv_buf() and appctx_htx_snd_buf(). Note that the appctx is now directly passed to these functions instead of the SC.
This commit is contained in:
parent
868205943c
commit
ee53d8421f
@ -61,8 +61,8 @@ struct applet {
|
||||
int (*init)(struct appctx *); /* callback to init resources, may be NULL.
|
||||
expect 0 if ok, -1 if an error occurs. */
|
||||
void (*fct)(struct appctx *); /* internal I/O handler, may never be NULL */
|
||||
size_t (*rcv_buf)(struct stconn *sc, struct buffer *buf, size_t count, unsigned int flags); /* called from the upper layer to get data */
|
||||
size_t (*snd_buf)(struct stconn *sc, struct buffer *buf, size_t count, unsigned int flags); /* Called from the upper layet to put data */
|
||||
size_t (*rcv_buf)(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags); /* called from the upper layer to get data */
|
||||
size_t (*snd_buf)(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags); /* Called from the upper layet to put data */
|
||||
size_t (*fastfwd)(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags); /* Callback to fast-forward data */
|
||||
void (*release)(struct appctx *); /* callback to release resources, may be NULL */
|
||||
unsigned int timeout; /* execution timeout. */
|
||||
|
@ -49,8 +49,14 @@ int appctx_finalize_startup(struct appctx *appctx, struct proxy *px, struct buff
|
||||
void appctx_free_on_early_error(struct appctx *appctx);
|
||||
void appctx_free(struct appctx *appctx);
|
||||
|
||||
size_t appctx_htx_rcv_buf(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags);
|
||||
size_t appctx_raw_rcv_buf(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags);
|
||||
size_t appctx_rcv_buf(struct stconn *sc, struct buffer *buf, size_t count, unsigned int flags);
|
||||
|
||||
size_t appctx_htx_snd_buf(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags);
|
||||
size_t appctx_raw_snd_buf(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags);
|
||||
size_t appctx_snd_buf(struct stconn *sc, struct buffer *buf, size_t count, unsigned int flags);
|
||||
|
||||
int appctx_fastfwd(struct stconn *sc, unsigned int count, unsigned int flags);
|
||||
|
||||
static inline struct appctx *appctx_new_here(struct applet *applet, struct sedesc *sedesc)
|
||||
|
132
src/applet.c
132
src/applet.c
@ -452,6 +452,45 @@ int appctx_buf_available(void *arg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t appctx_htx_rcv_buf(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags)
|
||||
{
|
||||
struct htx *appctx_htx = htx_from_buf(&appctx->outbuf);
|
||||
struct htx *buf_htx = NULL;
|
||||
size_t ret = 0;
|
||||
|
||||
if (htx_is_empty(appctx_htx)) {
|
||||
htx_to_buf(appctx_htx, &appctx->outbuf);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = appctx_htx->data;
|
||||
buf_htx = htx_from_buf(buf);
|
||||
if (htx_is_empty(buf_htx) && htx_used_space(appctx_htx) <= count) {
|
||||
htx_to_buf(buf_htx, buf);
|
||||
htx_to_buf(appctx_htx, &appctx->outbuf);
|
||||
b_xfer(buf, &appctx->outbuf, b_data(&appctx->outbuf));
|
||||
goto out;
|
||||
}
|
||||
|
||||
htx_xfer_blks(buf_htx, appctx_htx, count, HTX_BLK_UNUSED);
|
||||
buf_htx->flags |= (appctx_htx->flags & (HTX_FL_PARSING_ERROR|HTX_FL_PROCESSING_ERROR));
|
||||
if (htx_is_empty(appctx_htx)) {
|
||||
buf_htx->flags |= (appctx_htx->flags & HTX_FL_EOM);
|
||||
}
|
||||
buf_htx->extra = (appctx_htx->extra ? (appctx_htx->data + appctx_htx->extra) : 0);
|
||||
htx_to_buf(buf_htx, buf);
|
||||
htx_to_buf(appctx_htx, &appctx->inbuf);
|
||||
ret -= appctx_htx->data;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t appctx_raw_rcv_buf(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags)
|
||||
{
|
||||
return b_xfer(buf, &appctx->outbuf, MAX(count, b_data(&appctx->outbuf)));
|
||||
}
|
||||
|
||||
size_t appctx_rcv_buf(struct stconn *sc, struct buffer *buf, size_t count, unsigned int flags)
|
||||
{
|
||||
struct appctx *appctx = __sc_appctx(sc);
|
||||
@ -471,38 +510,7 @@ size_t appctx_rcv_buf(struct stconn *sc, struct buffer *buf, size_t count, unsig
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (IS_HTX_SC(sc)) {
|
||||
struct htx *appctx_htx = htx_from_buf(&appctx->outbuf);
|
||||
struct htx *buf_htx = NULL;
|
||||
|
||||
if (htx_is_empty(appctx_htx)) {
|
||||
htx_to_buf(appctx_htx, &appctx->outbuf);
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = appctx_htx->data;
|
||||
buf_htx = htx_from_buf(buf);
|
||||
if (htx_is_empty(buf_htx) && htx_used_space(appctx_htx) <= count) {
|
||||
htx_to_buf(buf_htx, buf);
|
||||
htx_to_buf(appctx_htx, &appctx->outbuf);
|
||||
b_xfer(buf, &appctx->outbuf, b_data(&appctx->outbuf));
|
||||
goto done;
|
||||
}
|
||||
|
||||
htx_xfer_blks(buf_htx, appctx_htx, count, HTX_BLK_UNUSED);
|
||||
buf_htx->flags |= (appctx_htx->flags & (HTX_FL_PARSING_ERROR|HTX_FL_PROCESSING_ERROR));
|
||||
if (htx_is_empty(appctx_htx)) {
|
||||
buf_htx->flags |= (appctx_htx->flags & HTX_FL_EOM);
|
||||
}
|
||||
buf_htx->extra = (appctx_htx->extra ? (appctx_htx->data + appctx_htx->extra) : 0);
|
||||
htx_to_buf(buf_htx, buf);
|
||||
htx_to_buf(appctx_htx, &appctx->inbuf);
|
||||
ret -= appctx_htx->data;
|
||||
}
|
||||
else
|
||||
ret = b_xfer(buf, &appctx->outbuf, MAX(count, b_data(&appctx->outbuf)));
|
||||
|
||||
done:
|
||||
ret = appctx->applet->rcv_buf(appctx, buf, count, flags);
|
||||
if (ret)
|
||||
applet_fl_clr(appctx, APPCTX_FL_OUTBLK_FULL);
|
||||
|
||||
@ -531,6 +539,39 @@ size_t appctx_rcv_buf(struct stconn *sc, struct buffer *buf, size_t count, unsig
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t appctx_htx_snd_buf(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags)
|
||||
{
|
||||
struct htx *appctx_htx = htx_from_buf(&appctx->inbuf);
|
||||
struct htx *buf_htx = htx_from_buf(buf);
|
||||
size_t ret = 0;
|
||||
|
||||
ret = buf_htx->data;
|
||||
if (htx_is_empty(appctx_htx) && buf_htx->data == count) {
|
||||
htx_to_buf(appctx_htx, &appctx->inbuf);
|
||||
htx_to_buf(buf_htx, buf);
|
||||
b_xfer(&appctx->inbuf, buf, b_data(buf));
|
||||
goto end;
|
||||
}
|
||||
|
||||
htx_xfer_blks(appctx_htx, buf_htx, count, HTX_BLK_UNUSED);
|
||||
if (htx_is_empty(buf_htx)) {
|
||||
appctx_htx->flags |= (buf_htx->flags & HTX_FL_EOM);
|
||||
}
|
||||
|
||||
appctx_htx->extra = (buf_htx->extra ? (buf_htx->data + buf_htx->extra) : 0);
|
||||
htx_to_buf(appctx_htx, &appctx->outbuf);
|
||||
htx_to_buf(buf_htx, buf);
|
||||
ret -= buf_htx->data;
|
||||
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t appctx_raw_snd_buf(struct appctx *appctx, struct buffer *buf, size_t count, unsigned flags)
|
||||
{
|
||||
return b_xfer(&appctx->inbuf, buf, MIN(b_room(&appctx->inbuf), count));
|
||||
}
|
||||
|
||||
size_t appctx_snd_buf(struct stconn *sc, struct buffer *buf, size_t count, unsigned int flags)
|
||||
{
|
||||
struct appctx *appctx = __sc_appctx(sc);
|
||||
@ -553,32 +594,7 @@ size_t appctx_snd_buf(struct stconn *sc, struct buffer *buf, size_t count, unsig
|
||||
if (!count)
|
||||
goto end;
|
||||
|
||||
if (IS_HTX_SC(sc)) {
|
||||
struct htx *appctx_htx = htx_from_buf(&appctx->inbuf);
|
||||
struct htx *buf_htx = htx_from_buf(buf);
|
||||
|
||||
ret = buf_htx->data;
|
||||
if (htx_is_empty(appctx_htx) && buf_htx->data == count) {
|
||||
htx_to_buf(appctx_htx, &appctx->inbuf);
|
||||
htx_to_buf(buf_htx, buf);
|
||||
b_xfer(&appctx->inbuf, buf, b_data(buf));
|
||||
goto done;
|
||||
}
|
||||
|
||||
htx_xfer_blks(appctx_htx, buf_htx, count, HTX_BLK_UNUSED);
|
||||
if (htx_is_empty(buf_htx)) {
|
||||
appctx_htx->flags |= (buf_htx->flags & HTX_FL_EOM);
|
||||
}
|
||||
|
||||
appctx_htx->extra = (buf_htx->extra ? (buf_htx->data + buf_htx->extra) : 0);
|
||||
htx_to_buf(appctx_htx, &appctx->outbuf);
|
||||
htx_to_buf(buf_htx, buf);
|
||||
ret -= buf_htx->data;
|
||||
}
|
||||
else
|
||||
ret = b_xfer(&appctx->inbuf, buf, MIN(b_room(&appctx->inbuf), count));
|
||||
|
||||
done:
|
||||
ret = appctx->applet->snd_buf(appctx, buf, count, flags);
|
||||
if (ret < count) {
|
||||
applet_fl_set(appctx, APPCTX_FL_INBLK_FULL);
|
||||
appctx_wakeup(appctx);
|
||||
|
@ -3159,8 +3159,8 @@ struct applet http_cache_applet = {
|
||||
.obj_type = OBJ_TYPE_APPLET,
|
||||
.name = "<CACHE>", /* used for logging */
|
||||
.fct = http_cache_io_handler,
|
||||
.rcv_buf = appctx_rcv_buf,
|
||||
.snd_buf = appctx_snd_buf,
|
||||
.rcv_buf = appctx_htx_rcv_buf,
|
||||
.snd_buf = appctx_htx_snd_buf,
|
||||
.fastfwd = http_cache_fastfwd,
|
||||
.release = http_cache_applet_release,
|
||||
};
|
||||
|
@ -5539,8 +5539,8 @@ struct applet http_stats_applet = {
|
||||
.obj_type = OBJ_TYPE_APPLET,
|
||||
.name = "<STATS>", /* used for logging */
|
||||
.fct = http_stats_io_handler,
|
||||
.rcv_buf = appctx_rcv_buf,
|
||||
.snd_buf = appctx_snd_buf,
|
||||
.rcv_buf = appctx_htx_rcv_buf,
|
||||
.snd_buf = appctx_htx_snd_buf,
|
||||
.fastfwd = http_stats_fastfwd,
|
||||
.release = NULL,
|
||||
};
|
||||
|
@ -1968,7 +1968,7 @@ int sc_applet_recv(struct stconn *sc)
|
||||
* SE_FL_RCV_MORE on the SC if more space is needed.
|
||||
*/
|
||||
max = channel_recv_max(ic);
|
||||
ret = appctx->applet->rcv_buf(sc, &ic->buf, max, flags);
|
||||
ret = appctx_rcv_buf(sc, &ic->buf, max, flags);
|
||||
if (sc_ep_test(sc, SE_FL_WANT_ROOM)) {
|
||||
/* SE_FL_WANT_ROOM must not be reported if the channel's
|
||||
* buffer is empty.
|
||||
@ -2120,7 +2120,6 @@ int sc_applet_sync_recv(struct stconn *sc)
|
||||
*/
|
||||
int sc_applet_send(struct stconn *sc)
|
||||
{
|
||||
struct appctx *appctx = __sc_appctx(sc);
|
||||
struct stconn *sco = sc_opposite(sc);
|
||||
struct channel *oc = sc_oc(sc);
|
||||
size_t ret;
|
||||
@ -2146,7 +2145,7 @@ int sc_applet_send(struct stconn *sc)
|
||||
BUG_ON(sc_ep_have_ff_data(sc));
|
||||
|
||||
if (co_data(oc)) {
|
||||
ret = appctx->applet->snd_buf(sc, &oc->buf, co_data(oc), 0);
|
||||
ret = appctx_snd_buf(sc, &oc->buf, co_data(oc), 0);
|
||||
if (ret > 0) {
|
||||
did_send = 1;
|
||||
c_rew(oc, ret);
|
||||
|
Loading…
Reference in New Issue
Block a user