MEDIUM: stream-int: replace occurrences of si->appctx with si_appctx()

We're about to remove si->appctx, so first let's replace all occurrences
of its usage with a dynamic extract from si->end. A lot of code was changed
by search-n-replace, but the behaviour was intentionally not altered.

The code surrounding calls to stream_int_register_handler() was slightly
changed since we can only use si->end *after* the registration.
This commit is contained in:
Willy Tarreau 2013-12-01 09:15:12 +01:00
parent 57cd3e46b9
commit 7b4b499fde
4 changed files with 643 additions and 581 deletions

View File

@ -107,11 +107,20 @@ static inline void si_attach_applet(struct stream_interface *si, struct si_apple
si->end = &si->appctx.obj_type; si->end = &si->appctx.obj_type;
} }
/* returns a pointer to the appctx being run in the SI or NULL if none */
static inline struct appctx *si_appctx(struct stream_interface *si)
{
return objt_appctx(si->end);
}
/* returns a pointer to the applet being run in the SI or NULL if none */ /* returns a pointer to the applet being run in the SI or NULL if none */
static inline const struct si_applet *si_applet(struct stream_interface *si) static inline const struct si_applet *si_applet(struct stream_interface *si)
{ {
if (objt_appctx(si->end)) const struct appctx *appctx;
return si->appctx.applet;
appctx = si_appctx(si);
if (appctx)
return appctx->applet;
return NULL; return NULL;
} }

File diff suppressed because it is too large Load Diff

View File

@ -184,10 +184,11 @@ static int peer_prepare_datamsg(struct stksess *ts, struct peer_session *ps, cha
static void peer_session_release(struct stream_interface *si) static void peer_session_release(struct stream_interface *si)
{ {
struct session *s = session_from_task(si->owner); struct session *s = session_from_task(si->owner);
struct peer_session *ps = (struct peer_session *)si->appctx.ctx.peers.ptr; struct appctx *appctx = objt_appctx(si->end);
struct peer_session *ps = (struct peer_session *)appctx->ctx.peers.ptr;
/* si->appctx.ctx.peers.ptr is not a peer session */ /* appctx->ctx.peers.ptr is not a peer session */
if (si->appctx.st0 < PEER_SESSION_SENDSUCCESS) if (appctx->st0 < PEER_SESSION_SENDSUCCESS)
return; return;
/* peer session identified */ /* peer session identified */
@ -218,26 +219,27 @@ static void peer_io_handler(struct stream_interface *si)
{ {
struct session *s = session_from_task(si->owner); struct session *s = session_from_task(si->owner);
struct peers *curpeers = (struct peers *)s->fe->parent; struct peers *curpeers = (struct peers *)s->fe->parent;
struct appctx *appctx = objt_appctx(si->end);
int reql = 0; int reql = 0;
int repl = 0; int repl = 0;
while (1) { while (1) {
switchstate: switchstate:
switch(si->appctx.st0) { switch(appctx->st0) {
case PEER_SESSION_ACCEPT: case PEER_SESSION_ACCEPT:
si->appctx.ctx.peers.ptr = NULL; appctx->ctx.peers.ptr = NULL;
si->appctx.st0 = PEER_SESSION_GETVERSION; appctx->st0 = PEER_SESSION_GETVERSION;
/* fall through */ /* fall through */
case PEER_SESSION_GETVERSION: case PEER_SESSION_GETVERSION:
reql = bo_getline(si->ob, trash.str, trash.size); reql = bo_getline(si->ob, trash.str, trash.size);
if (reql <= 0) { /* closed or EOL not found */ if (reql <= 0) { /* closed or EOL not found */
if (reql == 0) if (reql == 0)
goto out; goto out;
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
if (trash.str[reql-1] != '\n') { if (trash.str[reql-1] != '\n') {
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
else if (reql > 1 && (trash.str[reql-2] == '\r')) else if (reql > 1 && (trash.str[reql-2] == '\r'))
@ -249,26 +251,26 @@ switchstate:
/* test version */ /* test version */
if (strcmp(PEER_SESSION_PROTO_NAME " 1.0", trash.str) != 0) { if (strcmp(PEER_SESSION_PROTO_NAME " 1.0", trash.str) != 0) {
si->appctx.st0 = PEER_SESSION_EXIT; appctx->st0 = PEER_SESSION_EXIT;
si->appctx.st1 = PEER_SESSION_ERRVERSION; appctx->st1 = PEER_SESSION_ERRVERSION;
/* test protocol */ /* test protocol */
if (strncmp(PEER_SESSION_PROTO_NAME " ", trash.str, strlen(PEER_SESSION_PROTO_NAME)+1) != 0) if (strncmp(PEER_SESSION_PROTO_NAME " ", trash.str, strlen(PEER_SESSION_PROTO_NAME)+1) != 0)
si->appctx.st1 = PEER_SESSION_ERRPROTO; appctx->st1 = PEER_SESSION_ERRPROTO;
goto switchstate; goto switchstate;
} }
si->appctx.st0 = PEER_SESSION_GETHOST; appctx->st0 = PEER_SESSION_GETHOST;
/* fall through */ /* fall through */
case PEER_SESSION_GETHOST: case PEER_SESSION_GETHOST:
reql = bo_getline(si->ob, trash.str, trash.size); reql = bo_getline(si->ob, trash.str, trash.size);
if (reql <= 0) { /* closed or EOL not found */ if (reql <= 0) { /* closed or EOL not found */
if (reql == 0) if (reql == 0)
goto out; goto out;
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
if (trash.str[reql-1] != '\n') { if (trash.str[reql-1] != '\n') {
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
else if (reql > 1 && (trash.str[reql-2] == '\r')) else if (reql > 1 && (trash.str[reql-2] == '\r'))
@ -280,12 +282,12 @@ switchstate:
/* test hostname match */ /* test hostname match */
if (strcmp(localpeer, trash.str) != 0) { if (strcmp(localpeer, trash.str) != 0) {
si->appctx.st0 = PEER_SESSION_EXIT; appctx->st0 = PEER_SESSION_EXIT;
si->appctx.st1 = PEER_SESSION_ERRHOST; appctx->st1 = PEER_SESSION_ERRHOST;
goto switchstate; goto switchstate;
} }
si->appctx.st0 = PEER_SESSION_GETPEER; appctx->st0 = PEER_SESSION_GETPEER;
/* fall through */ /* fall through */
case PEER_SESSION_GETPEER: { case PEER_SESSION_GETPEER: {
struct peer *curpeer; struct peer *curpeer;
@ -294,12 +296,12 @@ switchstate:
if (reql <= 0) { /* closed or EOL not found */ if (reql <= 0) { /* closed or EOL not found */
if (reql == 0) if (reql == 0)
goto out; goto out;
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
if (trash.str[reql-1] != '\n') { if (trash.str[reql-1] != '\n') {
/* Incomplete line, we quit */ /* Incomplete line, we quit */
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
else if (reql > 1 && (trash.str[reql-2] == '\r')) else if (reql > 1 && (trash.str[reql-2] == '\r'))
@ -312,8 +314,8 @@ switchstate:
/* parse line "<peer name> <pid>" */ /* parse line "<peer name> <pid>" */
p = strchr(trash.str, ' '); p = strchr(trash.str, ' ');
if (!p) { if (!p) {
si->appctx.st0 = PEER_SESSION_EXIT; appctx->st0 = PEER_SESSION_EXIT;
si->appctx.st1 = PEER_SESSION_ERRPROTO; appctx->st1 = PEER_SESSION_ERRPROTO;
goto switchstate; goto switchstate;
} }
*p = 0; *p = 0;
@ -326,17 +328,17 @@ switchstate:
/* if unknown peer */ /* if unknown peer */
if (!curpeer) { if (!curpeer) {
si->appctx.st0 = PEER_SESSION_EXIT; appctx->st0 = PEER_SESSION_EXIT;
si->appctx.st1 = PEER_SESSION_ERRPEER; appctx->st1 = PEER_SESSION_ERRPEER;
goto switchstate; goto switchstate;
} }
si->appctx.ctx.peers.ptr = curpeer; appctx->ctx.peers.ptr = curpeer;
si->appctx.st0 = PEER_SESSION_GETTABLE; appctx->st0 = PEER_SESSION_GETTABLE;
/* fall through */ /* fall through */
} }
case PEER_SESSION_GETTABLE: { case PEER_SESSION_GETTABLE: {
struct peer *curpeer = (struct peer *)si->appctx.ctx.peers.ptr; struct peer *curpeer = (struct peer *)appctx->ctx.peers.ptr;
struct shared_table *st; struct shared_table *st;
struct peer_session *ps = NULL; struct peer_session *ps = NULL;
unsigned long key_type; unsigned long key_type;
@ -347,16 +349,16 @@ switchstate:
if (reql <= 0) { /* closed or EOL not found */ if (reql <= 0) { /* closed or EOL not found */
if (reql == 0) if (reql == 0)
goto out; goto out;
si->appctx.ctx.peers.ptr = NULL; appctx->ctx.peers.ptr = NULL;
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
/* Re init si->appctx.ctx.peers.ptr to null, to handle correctly a release case */ /* Re init appctx->ctx.peers.ptr to null, to handle correctly a release case */
si->appctx.ctx.peers.ptr = NULL; appctx->ctx.peers.ptr = NULL;
if (trash.str[reql-1] != '\n') { if (trash.str[reql-1] != '\n') {
/* Incomplete line, we quit */ /* Incomplete line, we quit */
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
else if (reql > 1 && (trash.str[reql-2] == '\r')) else if (reql > 1 && (trash.str[reql-2] == '\r'))
@ -369,8 +371,8 @@ switchstate:
/* Parse line "<table name> <type> <size>" */ /* Parse line "<table name> <type> <size>" */
p = strchr(trash.str, ' '); p = strchr(trash.str, ' ');
if (!p) { if (!p) {
si->appctx.st0 = PEER_SESSION_EXIT; appctx->st0 = PEER_SESSION_EXIT;
si->appctx.st1 = PEER_SESSION_ERRPROTO; appctx->st1 = PEER_SESSION_ERRPROTO;
goto switchstate; goto switchstate;
} }
*p = 0; *p = 0;
@ -378,9 +380,9 @@ switchstate:
p = strchr(p+1, ' '); p = strchr(p+1, ' ');
if (!p) { if (!p) {
si->appctx.ctx.peers.ptr = NULL; appctx->ctx.peers.ptr = NULL;
si->appctx.st0 = PEER_SESSION_EXIT; appctx->st0 = PEER_SESSION_EXIT;
si->appctx.st1 = PEER_SESSION_ERRPROTO; appctx->st1 = PEER_SESSION_ERRPROTO;
goto switchstate; goto switchstate;
} }
@ -395,15 +397,15 @@ switchstate:
if (key_size != st->table->key_size && if (key_size != st->table->key_size &&
(key_type != STKTABLE_TYPE_STRING || (key_type != STKTABLE_TYPE_STRING ||
1 + 4 + 4 + key_size - 1 >= trash.size)) { 1 + 4 + 4 + key_size - 1 >= trash.size)) {
si->appctx.st0 = PEER_SESSION_EXIT; appctx->st0 = PEER_SESSION_EXIT;
si->appctx.st1 = PEER_SESSION_ERRSIZE; appctx->st1 = PEER_SESSION_ERRSIZE;
goto switchstate; goto switchstate;
} }
/* If key type mismatches */ /* If key type mismatches */
if (key_type != st->table->type) { if (key_type != st->table->type) {
si->appctx.st0 = PEER_SESSION_EXIT; appctx->st0 = PEER_SESSION_EXIT;
si->appctx.st1 = PEER_SESSION_ERRTYPE; appctx->st1 = PEER_SESSION_ERRTYPE;
goto switchstate; goto switchstate;
} }
@ -414,8 +416,8 @@ switchstate:
if (ps->session && ps->session != s) { if (ps->session && ps->session != s) {
if (ps->peer->local) { if (ps->peer->local) {
/* Local connection, reply a retry */ /* Local connection, reply a retry */
si->appctx.st0 = PEER_SESSION_EXIT; appctx->st0 = PEER_SESSION_EXIT;
si->appctx.st1 = PEER_SESSION_TRYAGAIN; appctx->st1 = PEER_SESSION_TRYAGAIN;
goto switchstate; goto switchstate;
} }
peer_session_forceshutdown(ps->session); peer_session_forceshutdown(ps->session);
@ -430,31 +432,31 @@ switchstate:
/* If table not found */ /* If table not found */
if (!st){ if (!st){
si->appctx.st0 = PEER_SESSION_EXIT; appctx->st0 = PEER_SESSION_EXIT;
si->appctx.st1 = PEER_SESSION_ERRTABLE; appctx->st1 = PEER_SESSION_ERRTABLE;
goto switchstate; goto switchstate;
} }
/* If no peer session for current peer */ /* If no peer session for current peer */
if (!ps) { if (!ps) {
si->appctx.st0 = PEER_SESSION_EXIT; appctx->st0 = PEER_SESSION_EXIT;
si->appctx.st1 = PEER_SESSION_ERRPEER; appctx->st1 = PEER_SESSION_ERRPEER;
goto switchstate; goto switchstate;
} }
si->appctx.ctx.peers.ptr = ps; appctx->ctx.peers.ptr = ps;
si->appctx.st0 = PEER_SESSION_SENDSUCCESS; appctx->st0 = PEER_SESSION_SENDSUCCESS;
/* fall through */ /* fall through */
} }
case PEER_SESSION_SENDSUCCESS:{ case PEER_SESSION_SENDSUCCESS:{
struct peer_session *ps = (struct peer_session *)si->appctx.ctx.peers.ptr; struct peer_session *ps = (struct peer_session *)appctx->ctx.peers.ptr;
repl = snprintf(trash.str, trash.size, "%d\n", PEER_SESSION_SUCCESSCODE); repl = snprintf(trash.str, trash.size, "%d\n", PEER_SESSION_SUCCESSCODE);
repl = bi_putblk(si->ib, trash.str, repl); repl = bi_putblk(si->ib, trash.str, repl);
if (repl <= 0) { if (repl <= 0) {
if (repl == -1) if (repl == -1)
goto out; goto out;
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
@ -493,11 +495,11 @@ switchstate:
ps->table->flags |= SHTABLE_F_RESYNC_ASSIGN; ps->table->flags |= SHTABLE_F_RESYNC_ASSIGN;
} }
/* switch to waiting message state */ /* switch to waiting message state */
si->appctx.st0 = PEER_SESSION_WAITMSG; appctx->st0 = PEER_SESSION_WAITMSG;
goto switchstate; goto switchstate;
} }
case PEER_SESSION_CONNECT: { case PEER_SESSION_CONNECT: {
struct peer_session *ps = (struct peer_session *)si->appctx.ctx.peers.ptr; struct peer_session *ps = (struct peer_session *)appctx->ctx.peers.ptr;
/* Send headers */ /* Send headers */
repl = snprintf(trash.str, trash.size, repl = snprintf(trash.str, trash.size,
@ -510,7 +512,7 @@ switchstate:
(int)ps->table->table->key_size); (int)ps->table->table->key_size);
if (repl >= trash.size) { if (repl >= trash.size) {
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
@ -518,16 +520,16 @@ switchstate:
if (repl <= 0) { if (repl <= 0) {
if (repl == -1) if (repl == -1)
goto out; goto out;
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
/* switch to the waiting statuscode state */ /* switch to the waiting statuscode state */
si->appctx.st0 = PEER_SESSION_GETSTATUS; appctx->st0 = PEER_SESSION_GETSTATUS;
/* fall through */ /* fall through */
} }
case PEER_SESSION_GETSTATUS: { case PEER_SESSION_GETSTATUS: {
struct peer_session *ps = (struct peer_session *)si->appctx.ctx.peers.ptr; struct peer_session *ps = (struct peer_session *)appctx->ctx.peers.ptr;
if (si->ib->flags & CF_WRITE_PARTIAL) if (si->ib->flags & CF_WRITE_PARTIAL)
ps->statuscode = PEER_SESSION_CONNECTEDCODE; ps->statuscode = PEER_SESSION_CONNECTEDCODE;
@ -536,12 +538,12 @@ switchstate:
if (reql <= 0) { /* closed or EOL not found */ if (reql <= 0) { /* closed or EOL not found */
if (reql == 0) if (reql == 0)
goto out; goto out;
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
if (trash.str[reql-1] != '\n') { if (trash.str[reql-1] != '\n') {
/* Incomplete line, we quit */ /* Incomplete line, we quit */
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
else if (reql > 1 && (trash.str[reql-2] == '\r')) else if (reql > 1 && (trash.str[reql-2] == '\r'))
@ -591,14 +593,14 @@ switchstate:
} }
else { else {
/* Status code is not success, abort */ /* Status code is not success, abort */
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
si->appctx.st0 = PEER_SESSION_WAITMSG; appctx->st0 = PEER_SESSION_WAITMSG;
/* fall through */ /* fall through */
} }
case PEER_SESSION_WAITMSG: { case PEER_SESSION_WAITMSG: {
struct peer_session *ps = (struct peer_session *)si->appctx.ctx.peers.ptr; struct peer_session *ps = (struct peer_session *)appctx->ctx.peers.ptr;
struct stksess *ts, *newts = NULL; struct stksess *ts, *newts = NULL;
char c; char c;
int totl = 0; int totl = 0;
@ -771,7 +773,7 @@ switchstate:
if (stopping) { if (stopping) {
/* Close session, push resync no more needed */ /* Close session, push resync no more needed */
ps->flags |= PEER_F_TEACH_COMPLETE; ps->flags |= PEER_F_TEACH_COMPLETE;
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
@ -813,7 +815,7 @@ switchstate:
} }
else { else {
/* Unknown message */ /* Unknown message */
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
@ -834,7 +836,7 @@ incomplete:
if (reql < 0) { if (reql < 0) {
/* there was an error */ /* there was an error */
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
@ -848,7 +850,7 @@ incomplete:
/* no more write possible */ /* no more write possible */
if (repl == -1) if (repl == -1)
goto out; goto out;
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
ps->confirm--; ps->confirm--;
@ -865,7 +867,7 @@ incomplete:
/* no more write possible */ /* no more write possible */
if (repl == -1) if (repl == -1)
goto out; goto out;
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
ps->table->flags |= SHTABLE_F_RESYNC_PROCESS; ps->table->flags |= SHTABLE_F_RESYNC_PROCESS;
@ -884,7 +886,7 @@ incomplete:
/* no more write possible */ /* no more write possible */
if (repl == -1) if (repl == -1)
goto out; goto out;
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
ps->lastack = ps->pushack; ps->lastack = ps->pushack;
@ -920,7 +922,7 @@ incomplete:
/* no more write possible */ /* no more write possible */
if (repl == -1) if (repl == -1)
goto out; goto out;
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
ps->lastpush = ps->pushed = ts->upd.key; ps->lastpush = ps->pushed = ts->upd.key;
@ -954,7 +956,7 @@ incomplete:
/* no more write possible */ /* no more write possible */
if (repl == -1) if (repl == -1)
goto out; goto out;
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
ps->lastpush = ps->pushed = ts->upd.key; ps->lastpush = ps->pushed = ts->upd.key;
@ -970,7 +972,7 @@ incomplete:
/* no more write possible */ /* no more write possible */
if (repl == -1) if (repl == -1)
goto out; goto out;
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
@ -1012,7 +1014,7 @@ incomplete:
/* no more write possible */ /* no more write possible */
if (repl == -1) if (repl == -1)
goto out; goto out;
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
goto switchstate; goto switchstate;
} }
ps->lastpush = ps->pushed = ts->upd.key; ps->lastpush = ps->pushed = ts->upd.key;
@ -1024,11 +1026,11 @@ incomplete:
goto out; goto out;
} }
case PEER_SESSION_EXIT: case PEER_SESSION_EXIT:
repl = snprintf(trash.str, trash.size, "%d\n", si->appctx.st1); repl = snprintf(trash.str, trash.size, "%d\n", appctx->st1);
if (bi_putblk(si->ib, trash.str, repl) == -1) if (bi_putblk(si->ib, trash.str, repl) == -1)
goto out; goto out;
si->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
/* fall through */ /* fall through */
case PEER_SESSION_END: { case PEER_SESSION_END: {
si_shutw(si); si_shutw(si);
@ -1060,19 +1062,28 @@ static struct si_applet peer_applet = {
*/ */
static void peer_session_forceshutdown(struct session * session) static void peer_session_forceshutdown(struct session * session)
{ {
struct stream_interface *oldsi; struct stream_interface *oldsi = NULL;
struct appctx *appctx = NULL;
int i;
if (si_applet(&session->si[0]) == &peer_applet) { for (i = 0; i <= 1; i++) {
oldsi = &session->si[0]; appctx = objt_appctx(session->si[i].end);
} if (!appctx)
else { continue;
oldsi = &session->si[1]; if (appctx->applet != &peer_applet)
continue;
oldsi = &session->si[i];
break;
} }
if (!appctx)
return;
/* call release to reinit resync states if needed */ /* call release to reinit resync states if needed */
peer_session_release(oldsi); peer_session_release(oldsi);
oldsi->appctx.st0 = PEER_SESSION_END; appctx->st0 = PEER_SESSION_END;
oldsi->appctx.ctx.peers.ptr = NULL; appctx->ctx.peers.ptr = NULL;
task_wakeup(session->task, TASK_WOKEN_MSG); task_wakeup(session->task, TASK_WOKEN_MSG);
} }
@ -1083,10 +1094,13 @@ static void peer_session_forceshutdown(struct session * session)
*/ */
int peer_accept(struct session *s) int peer_accept(struct session *s)
{ {
stream_int_register_handler(&s->si[1], &peer_applet); struct appctx *appctx;
s->target = &peer_applet.obj_type; // for logging only
s->si[1].appctx.ctx.peers.ptr = s; s->target = &peer_applet.obj_type;
s->si[1].appctx.st0 = PEER_SESSION_ACCEPT; stream_int_register_handler(&s->si[1], objt_applet(s->target));
appctx = si_appctx(&s->si[1]);
appctx->st0 = PEER_SESSION_ACCEPT;
appctx->ctx.peers.ptr = s;
tv_zero(&s->logs.tv_request); tv_zero(&s->logs.tv_request);
s->logs.t_queue = 0; s->logs.t_queue = 0;
@ -1113,6 +1127,7 @@ static struct session *peer_session_create(struct peer *peer, struct peer_sessio
{ {
struct listener *l = LIST_NEXT(&peer->peers->peers_fe->conf.listeners, struct listener *, by_fe); struct listener *l = LIST_NEXT(&peer->peers->peers_fe->conf.listeners, struct listener *, by_fe);
struct proxy *p = (struct proxy *)l->frontend; /* attached frontend */ struct proxy *p = (struct proxy *)l->frontend; /* attached frontend */
struct appctx *appctx;
struct session *s; struct session *s;
struct http_txn *txn; struct http_txn *txn;
struct task *t; struct task *t;
@ -1161,8 +1176,9 @@ static struct session *peer_session_create(struct peer *peer, struct peer_sessio
s->si[0].flags |= SI_FL_INDEP_STR; s->si[0].flags |= SI_FL_INDEP_STR;
stream_int_register_handler(&s->si[0], &peer_applet); stream_int_register_handler(&s->si[0], &peer_applet);
s->si[0].appctx.st0 = PEER_SESSION_CONNECT; appctx = si_appctx(&s->si[0]);
s->si[0].appctx.ctx.peers.ptr = (void *)ps; appctx->st0 = PEER_SESSION_CONNECT;
appctx->ctx.peers.ptr = (void *)ps;
si_reset(&s->si[1], t); si_reset(&s->si[1], t);

View File

@ -2795,7 +2795,8 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit)
* and program a response message if something was unexpected. It cannot fail * and program a response message if something was unexpected. It cannot fail
* and always relies on the stats applet to complete the job. It does not touch * and always relies on the stats applet to complete the job. It does not touch
* analysers nor counters, which are left to the caller. It does not touch * analysers nor counters, which are left to the caller. It does not touch
* s->target which is supposed to already point to the stats applet. * s->target which is supposed to already point to the stats applet. The caller
* is expected to have already assigned an appctx to the session.
*/ */
int http_handle_stats(struct session *s, struct channel *req) int http_handle_stats(struct session *s, struct channel *req)
{ {
@ -2805,17 +2806,20 @@ int http_handle_stats(struct session *s, struct channel *req)
struct http_msg *msg = &txn->req; struct http_msg *msg = &txn->req;
struct uri_auth *uri_auth = s->be->uri_auth; struct uri_auth *uri_auth = s->be->uri_auth;
const char *uri, *h, *lookup; const char *uri, *h, *lookup;
struct appctx *appctx;
memset(&si->appctx.ctx.stats, 0, sizeof(si->appctx.ctx.stats)); appctx = si_appctx(si);
si->appctx.ctx.stats.st_code = STAT_STATUS_INIT; memset(&appctx->ctx.stats, 0, sizeof(appctx->ctx.stats));
si->appctx.ctx.stats.flags |= STAT_FMT_HTML; /* assume HTML mode by default */ appctx->st1 = appctx->st2 = 0;
appctx->ctx.stats.st_code = STAT_STATUS_INIT;
appctx->ctx.stats.flags |= STAT_FMT_HTML; /* assume HTML mode by default */
uri = msg->chn->buf->p + msg->sl.rq.u; uri = msg->chn->buf->p + msg->sl.rq.u;
lookup = uri + uri_auth->uri_len; lookup = uri + uri_auth->uri_len;
for (h = lookup; h <= uri + msg->sl.rq.u_l - 3; h++) { for (h = lookup; h <= uri + msg->sl.rq.u_l - 3; h++) {
if (memcmp(h, ";up", 3) == 0) { if (memcmp(h, ";up", 3) == 0) {
si->appctx.ctx.stats.flags |= STAT_HIDE_DOWN; appctx->ctx.stats.flags |= STAT_HIDE_DOWN;
break; break;
} }
} }
@ -2823,7 +2827,7 @@ int http_handle_stats(struct session *s, struct channel *req)
if (uri_auth->refresh) { if (uri_auth->refresh) {
for (h = lookup; h <= uri + msg->sl.rq.u_l - 10; h++) { for (h = lookup; h <= uri + msg->sl.rq.u_l - 10; h++) {
if (memcmp(h, ";norefresh", 10) == 0) { if (memcmp(h, ";norefresh", 10) == 0) {
si->appctx.ctx.stats.flags |= STAT_NO_REFRESH; appctx->ctx.stats.flags |= STAT_NO_REFRESH;
break; break;
} }
} }
@ -2831,7 +2835,7 @@ int http_handle_stats(struct session *s, struct channel *req)
for (h = lookup; h <= uri + msg->sl.rq.u_l - 4; h++) { for (h = lookup; h <= uri + msg->sl.rq.u_l - 4; h++) {
if (memcmp(h, ";csv", 4) == 0) { if (memcmp(h, ";csv", 4) == 0) {
si->appctx.ctx.stats.flags &= ~STAT_FMT_HTML; appctx->ctx.stats.flags &= ~STAT_FMT_HTML;
break; break;
} }
} }
@ -2840,10 +2844,10 @@ int http_handle_stats(struct session *s, struct channel *req)
if (memcmp(h, ";st=", 4) == 0) { if (memcmp(h, ";st=", 4) == 0) {
int i; int i;
h += 4; h += 4;
si->appctx.ctx.stats.st_code = STAT_STATUS_UNKN; appctx->ctx.stats.st_code = STAT_STATUS_UNKN;
for (i = STAT_STATUS_INIT + 1; i < STAT_STATUS_SIZE; i++) { for (i = STAT_STATUS_INIT + 1; i < STAT_STATUS_SIZE; i++) {
if (strncmp(stat_status_codes[i], h, 4) == 0) { if (strncmp(stat_status_codes[i], h, 4) == 0) {
si->appctx.ctx.stats.st_code = i; appctx->ctx.stats.st_code = i;
break; break;
} }
} }
@ -2851,8 +2855,8 @@ int http_handle_stats(struct session *s, struct channel *req)
} }
} }
si->appctx.ctx.stats.scope_str = 0; appctx->ctx.stats.scope_str = 0;
si->appctx.ctx.stats.scope_len = 0; appctx->ctx.stats.scope_len = 0;
for (h = lookup; h <= uri + msg->sl.rq.u_l - 8; h++) { for (h = lookup; h <= uri + msg->sl.rq.u_l - 8; h++) {
if (memcmp(h, STAT_SCOPE_INPUT_NAME "=", strlen(STAT_SCOPE_INPUT_NAME) + 1) == 0) { if (memcmp(h, STAT_SCOPE_INPUT_NAME "=", strlen(STAT_SCOPE_INPUT_NAME) + 1) == 0) {
int itx = 0; int itx = 0;
@ -2862,7 +2866,7 @@ int http_handle_stats(struct session *s, struct channel *req)
h += strlen(STAT_SCOPE_INPUT_NAME) + 1; h += strlen(STAT_SCOPE_INPUT_NAME) + 1;
h2 = h; h2 = h;
si->appctx.ctx.stats.scope_str = h2 - msg->chn->buf->p; appctx->ctx.stats.scope_str = h2 - msg->chn->buf->p;
while (*h != ';' && *h != '\0' && *h != '&' && *h != ' ' && *h != '\n') { while (*h != ';' && *h != '\0' && *h != '&' && *h != ' ' && *h != '\n') {
itx++; itx++;
h++; h++;
@ -2870,16 +2874,16 @@ int http_handle_stats(struct session *s, struct channel *req)
if (itx > STAT_SCOPE_TXT_MAXLEN) if (itx > STAT_SCOPE_TXT_MAXLEN)
itx = STAT_SCOPE_TXT_MAXLEN; itx = STAT_SCOPE_TXT_MAXLEN;
si->appctx.ctx.stats.scope_len = itx; appctx->ctx.stats.scope_len = itx;
/* scope_txt = search query, si->appctx.ctx.stats.scope_len is always <= STAT_SCOPE_TXT_MAXLEN */ /* scope_txt = search query, appctx->ctx.stats.scope_len is always <= STAT_SCOPE_TXT_MAXLEN */
memcpy(scope_txt, h2, itx); memcpy(scope_txt, h2, itx);
scope_txt[itx] = '\0'; scope_txt[itx] = '\0';
err = invalid_char(scope_txt); err = invalid_char(scope_txt);
if (err) { if (err) {
/* bad char in search text => clear scope */ /* bad char in search text => clear scope */
si->appctx.ctx.stats.scope_str = 0; appctx->ctx.stats.scope_str = 0;
si->appctx.ctx.stats.scope_len = 0; appctx->ctx.stats.scope_len = 0;
} }
break; break;
} }
@ -2898,14 +2902,14 @@ int http_handle_stats(struct session *s, struct channel *req)
if (ret) { if (ret) {
/* no rule, or the rule matches */ /* no rule, or the rule matches */
s->rep->prod->appctx.ctx.stats.flags |= STAT_ADMIN; appctx->ctx.stats.flags |= STAT_ADMIN;
break; break;
} }
} }
/* Was the status page requested with a POST ? */ /* Was the status page requested with a POST ? */
if (unlikely(txn->meth == HTTP_METH_POST && txn->req.body_len > 0)) { if (unlikely(txn->meth == HTTP_METH_POST && txn->req.body_len > 0)) {
if (si->appctx.ctx.stats.flags & STAT_ADMIN) { if (appctx->ctx.stats.flags & STAT_ADMIN) {
if (msg->msg_state < HTTP_MSG_100_SENT) { if (msg->msg_state < HTTP_MSG_100_SENT) {
/* If we have HTTP/1.1 and Expect: 100-continue, then we must /* If we have HTTP/1.1 and Expect: 100-continue, then we must
* send an HTTP/1.1 100 Continue intermediate response. * send an HTTP/1.1 100 Continue intermediate response.
@ -2922,21 +2926,19 @@ int http_handle_stats(struct session *s, struct channel *req)
msg->msg_state = HTTP_MSG_100_SENT; msg->msg_state = HTTP_MSG_100_SENT;
s->logs.tv_request = now; /* update the request timer to reflect full request */ s->logs.tv_request = now; /* update the request timer to reflect full request */
} }
s->rep->prod->appctx.st0 = STAT_HTTP_POST; appctx->st0 = STAT_HTTP_POST;
} }
else { else {
si->appctx.ctx.stats.st_code = STAT_STATUS_DENY; appctx->ctx.stats.st_code = STAT_STATUS_DENY;
s->rep->prod->appctx.st0 = STAT_HTTP_LAST; appctx->st0 = STAT_HTTP_LAST;
} }
} }
else { else {
/* So it was another method (GET/HEAD) */ /* So it was another method (GET/HEAD) */
s->rep->prod->appctx.st0 = STAT_HTTP_HEAD; appctx->st0 = STAT_HTTP_HEAD;
} }
s->task->nice = -32; /* small boost for HTTP statistics */ s->task->nice = -32; /* small boost for HTTP statistics */
stream_int_register_handler(s->rep->prod, &http_stats_applet);
s->rep->prod->appctx.st1 = s->rep->prod->appctx.st2 = 0;
return 1; return 1;
} }
@ -3459,6 +3461,8 @@ int http_process_req_common(struct session *s, struct channel *req, int an_bit,
if (!http_req_last_rule) { if (!http_req_last_rule) {
if (stats_check_uri(s->rep->prod, txn, px)) { if (stats_check_uri(s->rep->prod, txn, px)) {
s->target = &http_stats_applet.obj_type; s->target = &http_stats_applet.obj_type;
stream_int_register_handler(s->rep->prod, objt_applet(s->target));
/* parse the whole stats request and extract the relevant information */ /* parse the whole stats request and extract the relevant information */
http_handle_stats(s, req); http_handle_stats(s, req);
http_req_last_rule = http_req_get_intercept_rule(px, &px->uri_auth->http_req_rules, s, txn); http_req_last_rule = http_req_get_intercept_rule(px, &px->uri_auth->http_req_rules, s, txn);