mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 15:17:01 +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.
|
int (*init)(struct appctx *); /* callback to init resources, may be NULL.
|
||||||
expect 0 if ok, -1 if an error occurs. */
|
expect 0 if ok, -1 if an error occurs. */
|
||||||
void (*fct)(struct appctx *); /* internal I/O handler, may never be NULL */
|
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 (*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 stconn *sc, struct buffer *buf, size_t count, unsigned int flags); /* Called from the upper layet to put 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 */
|
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 */
|
void (*release)(struct appctx *); /* callback to release resources, may be NULL */
|
||||||
unsigned int timeout; /* execution timeout. */
|
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_on_early_error(struct appctx *appctx);
|
||||||
void appctx_free(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_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);
|
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);
|
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)
|
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;
|
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)
|
size_t appctx_rcv_buf(struct stconn *sc, struct buffer *buf, size_t count, unsigned int flags)
|
||||||
{
|
{
|
||||||
struct appctx *appctx = __sc_appctx(sc);
|
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;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_HTX_SC(sc)) {
|
ret = appctx->applet->rcv_buf(appctx, buf, count, flags);
|
||||||
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:
|
|
||||||
if (ret)
|
if (ret)
|
||||||
applet_fl_clr(appctx, APPCTX_FL_OUTBLK_FULL);
|
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;
|
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)
|
size_t appctx_snd_buf(struct stconn *sc, struct buffer *buf, size_t count, unsigned int flags)
|
||||||
{
|
{
|
||||||
struct appctx *appctx = __sc_appctx(sc);
|
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)
|
if (!count)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
if (IS_HTX_SC(sc)) {
|
ret = appctx->applet->snd_buf(appctx, buf, count, flags);
|
||||||
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:
|
|
||||||
if (ret < count) {
|
if (ret < count) {
|
||||||
applet_fl_set(appctx, APPCTX_FL_INBLK_FULL);
|
applet_fl_set(appctx, APPCTX_FL_INBLK_FULL);
|
||||||
appctx_wakeup(appctx);
|
appctx_wakeup(appctx);
|
||||||
|
@ -3159,8 +3159,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,
|
.rcv_buf = appctx_htx_rcv_buf,
|
||||||
.snd_buf = appctx_snd_buf,
|
.snd_buf = appctx_htx_snd_buf,
|
||||||
.fastfwd = http_cache_fastfwd,
|
.fastfwd = http_cache_fastfwd,
|
||||||
.release = http_cache_applet_release,
|
.release = http_cache_applet_release,
|
||||||
};
|
};
|
||||||
|
@ -5539,8 +5539,8 @@ struct applet http_stats_applet = {
|
|||||||
.obj_type = OBJ_TYPE_APPLET,
|
.obj_type = OBJ_TYPE_APPLET,
|
||||||
.name = "<STATS>", /* used for logging */
|
.name = "<STATS>", /* used for logging */
|
||||||
.fct = http_stats_io_handler,
|
.fct = http_stats_io_handler,
|
||||||
.rcv_buf = appctx_rcv_buf,
|
.rcv_buf = appctx_htx_rcv_buf,
|
||||||
.snd_buf = appctx_snd_buf,
|
.snd_buf = appctx_htx_snd_buf,
|
||||||
.fastfwd = http_stats_fastfwd,
|
.fastfwd = http_stats_fastfwd,
|
||||||
.release = NULL,
|
.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.
|
* SE_FL_RCV_MORE on the SC if more space is needed.
|
||||||
*/
|
*/
|
||||||
max = channel_recv_max(ic);
|
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)) {
|
if (sc_ep_test(sc, SE_FL_WANT_ROOM)) {
|
||||||
/* SE_FL_WANT_ROOM must not be reported if the channel's
|
/* SE_FL_WANT_ROOM must not be reported if the channel's
|
||||||
* buffer is empty.
|
* buffer is empty.
|
||||||
@ -2120,7 +2120,6 @@ int sc_applet_sync_recv(struct stconn *sc)
|
|||||||
*/
|
*/
|
||||||
int sc_applet_send(struct stconn *sc)
|
int sc_applet_send(struct stconn *sc)
|
||||||
{
|
{
|
||||||
struct appctx *appctx = __sc_appctx(sc);
|
|
||||||
struct stconn *sco = sc_opposite(sc);
|
struct stconn *sco = sc_opposite(sc);
|
||||||
struct channel *oc = sc_oc(sc);
|
struct channel *oc = sc_oc(sc);
|
||||||
size_t ret;
|
size_t ret;
|
||||||
@ -2146,7 +2145,7 @@ int sc_applet_send(struct stconn *sc)
|
|||||||
BUG_ON(sc_ep_have_ff_data(sc));
|
BUG_ON(sc_ep_have_ff_data(sc));
|
||||||
|
|
||||||
if (co_data(oc)) {
|
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) {
|
if (ret > 0) {
|
||||||
did_send = 1;
|
did_send = 1;
|
||||||
c_rew(oc, ret);
|
c_rew(oc, ret);
|
||||||
|
Loading…
Reference in New Issue
Block a user