diff --git a/src/proto_htx.c b/src/proto_htx.c index 236bfd04d..9fa820653 100644 --- a/src/proto_htx.c +++ b/src/proto_htx.c @@ -4887,8 +4887,8 @@ static int htx_handle_stats(struct stream *s, struct channel *req) h += strlen(STAT_SCOPE_INPUT_NAME) + 1; h2 = h; - appctx->ctx.stats.scope_str = h2 - s->txn->uri; - while (h <= end) { + appctx->ctx.stats.scope_str = h2 - HTX_SL_REQ_UPTR(sl); + while (h < end) { if (*h == ';' || *h == '&' || *h == ' ') break; itx++; diff --git a/src/stats.c b/src/stats.c index ebd95d3f0..a7c12e120 100644 --- a/src/stats.c +++ b/src/stats.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -257,6 +258,23 @@ static int stats_putchk(struct channel *chn, struct htx *htx, struct buffer *chk return 1; } +static const char *stats_scope_ptr(struct appctx *appctx, struct stream_interface *si) +{ + const char *p; + + if (IS_HTX_STRM(si_strm(si))) { + struct channel *req = si_oc(si); + struct htx *htx = htxbuf(&req->buf); + struct ist uri = htx_sl_req_uri(http_find_stline(htx)); + + p = uri.ptr; + } + else + p = co_head(si_oc(si)); + + return p + appctx->ctx.stats.scope_str; +} + /* * http_stats_io_handler() * -> stats_dump_stat_to_buffer() // same as above, but used for CSV or HTML @@ -1912,8 +1930,10 @@ static void stats_dump_html_px_hdr(struct stream_interface *si, struct proxy *px /* scope_txt = search pattern + search query, appctx->ctx.stats.scope_len is always <= STAT_SCOPE_TXT_MAXLEN */ scope_txt[0] = 0; if (appctx->ctx.stats.scope_len) { + const char *scope_ptr = stats_scope_ptr(appctx, si); + strcpy(scope_txt, STAT_SCOPE_PATTERN); - memcpy(scope_txt + strlen(STAT_SCOPE_PATTERN), co_head(si_oc(si)) + appctx->ctx.stats.scope_str, appctx->ctx.stats.scope_len); + memcpy(scope_txt + strlen(STAT_SCOPE_PATTERN), scope_ptr, appctx->ctx.stats.scope_len); scope_txt[strlen(STAT_SCOPE_PATTERN) + appctx->ctx.stats.scope_len] = 0; } @@ -2075,9 +2095,12 @@ int stats_dump_proxy_to_buffer(struct stream_interface *si, struct htx *htx, /* if the user has requested a limited output and the proxy * name does not match, skip it. */ - if (appctx->ctx.stats.scope_len && - strnistr(px->id, strlen(px->id), co_head(si_oc(si)) + appctx->ctx.stats.scope_str, appctx->ctx.stats.scope_len) == NULL) - return 1; + if (appctx->ctx.stats.scope_len) { + const char *scope_ptr = stats_scope_ptr(appctx, si); + + if (strnistr(px->id, strlen(px->id), scope_ptr, appctx->ctx.stats.scope_len) == NULL) + return 1; + } if ((appctx->ctx.stats.flags & STAT_BOUND) && (appctx->ctx.stats.iid != -1) && @@ -2347,6 +2370,7 @@ static void stats_dump_html_info(struct stream_interface *si, struct uri_auth *u struct appctx *appctx = __objt_appctx(si->end); unsigned int up = (now.tv_sec - start_date.tv_sec); char scope_txt[STAT_SCOPE_TXT_MAXLEN + sizeof STAT_SCOPE_PATTERN]; + const char *scope_ptr = stats_scope_ptr(appctx, si); /* WARNING! this has to fit the first packet too. * We are around 3.5 kB, add adding entries will @@ -2405,7 +2429,7 @@ static void stats_dump_html_info(struct stream_interface *si, struct uri_auth *u ); /* scope_txt = search query, appctx->ctx.stats.scope_len is always <= STAT_SCOPE_TXT_MAXLEN */ - memcpy(scope_txt, co_head(si_oc(si)) + appctx->ctx.stats.scope_str, appctx->ctx.stats.scope_len); + memcpy(scope_txt, scope_ptr, appctx->ctx.stats.scope_len); scope_txt[appctx->ctx.stats.scope_len] = '\0'; chunk_appendf(&trash, @@ -2417,7 +2441,7 @@ static void stats_dump_html_info(struct stream_interface *si, struct uri_auth *u scope_txt[0] = 0; if (appctx->ctx.stats.scope_len) { strcpy(scope_txt, STAT_SCOPE_PATTERN); - memcpy(scope_txt + strlen(STAT_SCOPE_PATTERN), co_head(si_oc(si)) + appctx->ctx.stats.scope_str, appctx->ctx.stats.scope_len); + memcpy(scope_txt + strlen(STAT_SCOPE_PATTERN), scope_ptr, appctx->ctx.stats.scope_len); scope_txt[strlen(STAT_SCOPE_PATTERN) + appctx->ctx.stats.scope_len] = 0; } @@ -2719,7 +2743,13 @@ static int stats_process_http_post(struct stream_interface *si) struct htx_blk *blk; size_t count = co_data(&s->req); - /* Remove the headers */ + /* we need more data */ + if (htx->extra || htx->data > count) { + appctx->ctx.stats.st_code = STAT_STATUS_NONE; + return 0; + } + + /* Skip the headers */ blk = htx_get_head_blk(htx); while (count && blk) { enum htx_blk_type type = htx_get_blk_type(blk); @@ -2731,25 +2761,18 @@ static int stats_process_http_post(struct stream_interface *si) } count -= sz; - co_set_data(&s->req, co_data(&s->req) - sz); - blk = htx_remove_blk(htx, blk); + blk = htx_get_next_blk(htx, blk); if (type == HTX_BLK_EOH) break; } /* too large request */ - if (htx->data + htx->extra > b_size(temp)) { + if (count > b_size(temp)) { appctx->ctx.stats.st_code = STAT_STATUS_EXCD; goto out; } - /* we need more data */ - if (htx->extra || htx->data > count) { - appctx->ctx.stats.st_code = STAT_STATUS_NONE; - return 0; - } - while (count && blk) { enum htx_blk_type type = htx_get_blk_type(blk); uint32_t sz = htx_get_blksz(blk); @@ -2766,8 +2789,7 @@ static int stats_process_http_post(struct stream_interface *si) } count -= sz; - co_set_data(&s->req, co_data(&s->req) - sz); - blk = htx_remove_blk(htx, blk); + blk = htx_get_next_blk(htx, blk); } } else { @@ -3135,8 +3157,10 @@ static int stats_send_htx_redirect(struct stream_interface *si, struct htx *htx) /* scope_txt = search pattern + search query, appctx->ctx.stats.scope_len is always <= STAT_SCOPE_TXT_MAXLEN */ scope_txt[0] = 0; if (appctx->ctx.stats.scope_len) { + const char *scope_ptr = stats_scope_ptr(appctx, si); + strcpy(scope_txt, STAT_SCOPE_PATTERN); - memcpy(scope_txt + strlen(STAT_SCOPE_PATTERN), co_head(si_oc(si)) + appctx->ctx.stats.scope_str, appctx->ctx.stats.scope_len); + memcpy(scope_txt + strlen(STAT_SCOPE_PATTERN), scope_ptr, appctx->ctx.stats.scope_len); scope_txt[strlen(STAT_SCOPE_PATTERN) + appctx->ctx.stats.scope_len] = 0; }