* we'll never have any HTTP message there; this includes null strm or chn.
* The HTX message if ready
*/
-struct htx *smp_prefetch_htx(struct sample *smp, struct channel *chn, int vol)
+struct htx *smp_prefetch_htx(struct sample *smp, struct channel *chn, struct check *check, int vol)
{
struct stream *s = smp->strm;
struct http_txn *txn = NULL;
/* Note: it is possible that <s> is NULL when called before stream
* initialization (eg: tcp-request connection), so this function is the
* one responsible for guarding against this case for all HTTP users.
+ *
+ * In the health check context, the stream and the channel must be NULL
+ * and <check> must be set. In this case, only the input buffer,
+ * corresponding to the response, is considered. It is the caller
+ * responsibility to provide <check>.
*/
- if (!s || !chn)
+ BUG_ON(check && (s || chn));
+ if (!s || !chn) {
+ if (check) {
+ htx = htxbuf(&check->bi);
+
+ /* Analyse not yet started */
+ if (htx_is_empty(htx) || htx->first == -1)
+ return NULL;
+
+ sl = http_get_stline(htx);
+ if (vol && !sl) {
+ /* The start-line was already forwarded, it is too late to fetch anything */
+ return NULL;
+ }
+ goto end;
+ }
+
return NULL;
+ }
if (!s->txn) {
if (unlikely(!http_alloc_txn(s)))
}
/* everything's OK */
+ end:
smp->data.u.sint = 1;
return htx;
}
static int smp_fetch_meth(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 0);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 0);
struct http_txn *txn;
int meth;
static int smp_fetch_rqver(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct htx_sl *sl;
char *ptr;
int len;
static int smp_fetch_stver(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_RES_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct htx_sl *sl;
char *ptr;
int len;
static int smp_fetch_stcode(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_RES_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct htx_sl *sl;
char *ptr;
int len;
static int smp_fetch_hdrs(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct buffer *temp;
int32_t pos;
static int smp_fetch_hdrs_bin(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct buffer *temp;
char *p, *end;
int32_t pos;
static int smp_fetch_body(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct buffer *temp;
int32_t pos;
static int smp_fetch_body_len(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
int32_t pos;
unsigned long long len = 0;
static int smp_fetch_body_size(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
int32_t pos;
unsigned long long len = 0;
static int smp_fetch_url(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct htx_sl *sl;
if (!htx)
static int smp_fetch_url_ip(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct htx_sl *sl;
struct sockaddr_storage addr;
static int smp_fetch_url_port(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct htx_sl *sl;
struct sockaddr_storage addr;
{
/* possible keywords: req.fhdr, res.fhdr */
struct channel *chn = ((kw[2] == 'q') ? SMP_REQ_CHN(smp) : SMP_RES_CHN(smp));
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct http_hdr_ctx *ctx = smp->ctx.a[0];
struct ist name;
int occ = 0;
{
/* possible keywords: req.fhdr_cnt, res.fhdr_cnt */
struct channel *chn = ((kw[2] == 'q') ? SMP_REQ_CHN(smp) : SMP_RES_CHN(smp));
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct http_hdr_ctx ctx;
struct ist name;
int cnt;
{
/* possible keywords: req.hdr_names, res.hdr_names */
struct channel *chn = ((kw[2] == 'q') ? SMP_REQ_CHN(smp) : SMP_RES_CHN(smp));
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct buffer *temp;
char del = ',';
{
/* possible keywords: req.hdr / hdr, res.hdr / shdr */
struct channel *chn = ((kw[0] == 'h' || kw[2] == 'q') ? SMP_REQ_CHN(smp) : SMP_RES_CHN(smp));
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct http_hdr_ctx *ctx = smp->ctx.a[0];
struct ist name;
int occ = 0;
{
/* possible keywords: req.hdr_cnt / hdr_cnt, res.hdr_cnt / shdr_cnt */
struct channel *chn = ((kw[0] == 'h' || kw[2] == 'q') ? SMP_REQ_CHN(smp) : SMP_RES_CHN(smp));
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct http_hdr_ctx ctx;
struct ist name;
int cnt;
static int smp_fetch_path(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct htx_sl *sl;
struct ist path;
static int smp_fetch_base(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct htx_sl *sl;
struct buffer *temp;
struct http_hdr_ctx ctx;
static int smp_fetch_base32(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct htx_sl *sl;
struct http_hdr_ctx ctx;
struct ist path;
static int smp_fetch_query(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct htx_sl *sl;
char *ptr, *end;
static int smp_fetch_proto_http(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 0);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 0);
if (!htx)
return 0;
static int smp_fetch_http_auth_type(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct http_txn *txn;
if (!htx)
static int smp_fetch_http_auth_user(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct http_txn *txn;
if (!htx)
static int smp_fetch_http_auth_pass(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct http_txn *txn;
if (!htx)
static int smp_fetch_http_auth(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
if (!args || args->type != ARGT_USR)
return 0;
static int smp_fetch_http_auth_grp(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
if (!args || args->type != ARGT_USR)
return 0;
{
/* possible keywords: req.cookie / cookie / cook, res.cookie / scook / set-cookie */
struct channel *chn = ((kw[0] == 'c' || kw[2] == 'q') ? SMP_REQ_CHN(smp) : SMP_RES_CHN(smp));
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct http_hdr_ctx *ctx = smp->ctx.a[2];
struct ist hdr;
int occ = 0;
{
/* possible keywords: req.cook_cnt / cook_cnt, res.cook_cnt / scook_cnt */
struct channel *chn = ((kw[0] == 'c' || kw[2] == 'q') ? SMP_REQ_CHN(smp) : SMP_RES_CHN(smp));
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct http_hdr_ctx ctx;
struct ist hdr;
char *val_beg, *val_end;
delim = *args[1].data.str.area;
if (!smp->ctx.a[0]) { // first call, find the query string
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct htx_sl *sl;
if (!htx)
}
if (!smp->ctx.a[0]) { // first call, find the query string
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct buffer *temp;
int32_t pos;
static int smp_fetch_url32(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct channel *chn = SMP_REQ_CHN(smp);
- struct htx *htx = smp_prefetch_htx(smp, chn, 1);
+ struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1);
struct http_hdr_ctx ctx;
struct htx_sl *sl;
struct ist path;
return 0;
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
- htx = smp_prefetch_htx(smp, chn, 0);
+ htx = smp_prefetch_htx(smp, chn, NULL, 0);
if (!htx)
return 0;
return 0;
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
- htx = smp_prefetch_htx(smp, chn, 0);
+ htx = smp_prefetch_htx(smp, chn, NULL, 0);
if (!htx)
return 0;
return 0;
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
- htx = smp_prefetch_htx(smp, chn, 0);
+ htx = smp_prefetch_htx(smp, chn, NULL, 0);
if (!htx)
return 0;
return 0;
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
- htx = smp_prefetch_htx(smp, chn, 0);
+ htx = smp_prefetch_htx(smp, chn, NULL, 0);
if (!htx)
return 0;
return 0;
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
- htx = smp_prefetch_htx(smp, chn, 0);
+ htx = smp_prefetch_htx(smp, chn, NULL, 0);
if (!htx)
return 0;
return 0;
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
- htx = smp_prefetch_htx(smp, chn, 0);
+ htx = smp_prefetch_htx(smp, chn, NULL, 0);
if (!htx)
return 0;
return 0;
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
- htx = smp_prefetch_htx(smp, chn, 0);
+ htx = smp_prefetch_htx(smp, chn, NULL, 0);
if (!htx)
return 0;
return 0;
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
- htx = smp_prefetch_htx(smp, chn, 0);
+ htx = smp_prefetch_htx(smp, chn, NULL, 0);
if (!htx)
return 0;
return 0;
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
- htx = smp_prefetch_htx(smp, chn, 0);
+ htx = smp_prefetch_htx(smp, chn, NULL, 0);
if (!htx)
return 0;
return 0;
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
- htx = smp_prefetch_htx(smp, chn, 0);
+ htx = smp_prefetch_htx(smp, chn, NULL, 0);
if (!htx)
return 0;
return 0;
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
- htx = smp_prefetch_htx(smp, chn, 0);
+ htx = smp_prefetch_htx(smp, chn, NULL, 0);
if (!htx)
return 0;
return 0;
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
- htx = smp_prefetch_htx(smp, chn, 0);
+ htx = smp_prefetch_htx(smp, chn, NULL, 0);
if (!htx)
return 0;
return 0;
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
- htx = smp_prefetch_htx(smp, chn, 0);
+ htx = smp_prefetch_htx(smp, chn, NULL, 0);
if (!htx)
return 0;