*/
struct proxy *px;
struct session *sess;
- struct stream *strm;
+ struct stream *strm; /* WARNING! MAY BE NULL! (eg: tcp-request connection) */
unsigned int opt; /* fetch options (SMP_OPT_*) */
};
static int
smp_fetch_be_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
+ if (!smp->strm)
+ return 0;
+
smp->flags = SMP_F_VOL_TXN;
smp->data.type = SMP_T_SINT;
smp->data.u.sint = smp->strm->be->uuid;
static int
smp_fetch_srv_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
+ if (!smp->strm)
+ return 0;
+
if (!objt_server(smp->strm->target))
return 0;
smp_fetch_res_comp(const struct arg *args, struct sample *smp, const char *kw,
void *private)
{
- struct http_txn *txn = smp->strm->txn;
+ struct http_txn *txn = smp->strm ? smp->strm->txn : NULL;
smp->data.type = SMP_T_BOOL;
smp->data.u.sint = (txn && (txn->rsp.flags & HTTP_MSGF_COMPRESSING));
smp_fetch_res_comp_algo(const struct arg *args, struct sample *smp,
const char *kw, void *private)
{
- struct http_txn *txn = smp->strm->txn;
+ struct http_txn *txn = smp->strm ? smp->strm->txn : NULL;
struct filter *filter;
struct comp_state *st;
struct hlua_function *fcn = (struct hlua_function *)private;
struct stream *stream = smp->strm;
+ if (!stream)
+ return 0;
+
/* In the execution wrappers linked with a stream, the
* Lua context can be not initialized. This behavior
* permits to save performances because a systematic
/* Wrapper called by HAProxy to execute a sample-fetch. this wrapper
* doesn't allow "yield" functions because the HAProxy engine cannot
- * resume sample-fetches.
+ * resume sample-fetches. This function will be called by the sample
+ * fetch engine to call lua-based fetch operations.
*/
static int hlua_sample_fetch_wrapper(const struct arg *arg_p, struct sample *smp,
const char *kw, void *private)
struct hlua_function *fcn = (struct hlua_function *)private;
struct stream *stream = smp->strm;
+ if (!stream)
+ return 0;
+
/* In the execution wrappers linked with a stream, the
* Lua context can be not initialized. This behavior
* permits to save performances because a systematic
{
struct channel *chn;
+ if (!smp->strm)
+ return 0;
+
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
if (!chn->buf)
return 0;
struct channel *chn;
unsigned char *data;
+ if (!smp->strm)
+ goto not_ssl_hello;
+
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
if (!chn->buf)
goto not_ssl_hello;
struct channel *chn;
unsigned char *data;
+ if (!smp->strm)
+ goto not_ssl_hello;
+
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
if (!chn->buf)
goto not_ssl_hello;
struct channel *chn;
const unsigned char *data;
+ if (!smp->strm)
+ goto not_ssl_hello;
+
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
if (!chn->buf)
goto not_ssl_hello;
{
int version, bleft, msg_len;
const unsigned char *data;
- struct channel *req = &smp->strm->req;
+ struct channel *req;
+
+ if (!smp->strm)
+ return 0;
+ req = &smp->strm->req;
if (!req->buf)
return 0;
struct channel *chn;
unsigned char *data;
+ if (!smp->strm)
+ goto not_ssl_hello;
+
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
if (!chn->buf)
goto not_ssl_hello;
int
smp_fetch_rdp_cookie(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
+ if (!smp->strm)
+ return 0;
+
return fetch_rdp_cookie_name(smp->strm, smp, args ? args->data.str.str : NULL, args ? args->data.str.len : 0);
}
/* by default buf offset == len offset + len size */
/* buf offset could be absolute or relative to len offset + len size if prefixed by + or - */
+ if (!smp->strm)
+ return 0;
+
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
if (!chn->buf)
return 0;
unsigned int buf_size = arg_p[1].data.sint;
struct channel *chn;
+ if (!smp->strm)
+ return 0;
+
chn = ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? &smp->strm->res : &smp->strm->req;
if (!chn->buf)
return 0;
struct http_txn *txn;
struct http_msg *msg;
- /* Note: this function may only be used from places where
- * http_init_txn() has already been done, and implies that <s>,
- * <txn>, and <hdr_idx.v> are properly set. An extra check protects
- * against an eventual mistake in the fetch capability matrix.
+ /* 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.
*/
-
if (!s)
return 0;
+
if (!s->txn) {
if (unlikely(!http_alloc_txn(s)))
return 0; /* not enough memory */
smp_fetch_meth(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
int meth;
- struct http_txn *txn = smp->strm->txn;
+ struct http_txn *txn;
CHECK_HTTP_MESSAGE_FIRST_PERM();
+ txn = smp->strm->txn;
meth = txn->meth;
smp->data.type = SMP_T_METH;
smp->data.u.meth.meth = meth;
static int
smp_fetch_rqver(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct http_txn *txn = smp->strm->txn;
+ struct http_txn *txn;
char *ptr;
int len;
CHECK_HTTP_MESSAGE_FIRST();
+ txn = smp->strm->txn;
len = txn->req.sl.rq.v_l;
ptr = txn->req.chn->buf->p + txn->req.sl.rq.v;
static int
smp_fetch_body(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct http_txn *txn = smp->strm->txn;
struct http_msg *msg;
unsigned long len;
unsigned long block1;
CHECK_HTTP_MESSAGE_FIRST();
if ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_REQ)
- msg = &txn->req;
+ msg = &smp->strm->txn->req;
else
- msg = &txn->rsp;
+ msg = &smp->strm->txn->rsp;
len = http_body_bytes(msg);
body = b_ptr(msg->chn->buf, -http_data_rewind(msg));
static int
smp_fetch_body_len(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct http_txn *txn = smp->strm->txn;
struct http_msg *msg;
CHECK_HTTP_MESSAGE_FIRST();
if ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_REQ)
- msg = &txn->req;
+ msg = &smp->strm->txn->req;
else
- msg = &txn->rsp;
+ msg = &smp->strm->txn->rsp;
smp->data.type = SMP_T_SINT;
smp->data.u.sint = http_body_bytes(msg);
static int
smp_fetch_body_size(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct http_txn *txn = smp->strm->txn;
struct http_msg *msg;
CHECK_HTTP_MESSAGE_FIRST();
if ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_REQ)
- msg = &txn->req;
+ msg = &smp->strm->txn->req;
else
- msg = &txn->rsp;
+ msg = &smp->strm->txn->rsp;
smp->data.type = SMP_T_SINT;
smp->data.u.sint = msg->body_len;
static int
smp_fetch_body_param(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct http_txn *txn = smp->strm->txn;
struct http_msg *msg;
unsigned long len;
unsigned long block1;
CHECK_HTTP_MESSAGE_FIRST();
if ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_REQ)
- msg = &txn->req;
+ msg = &smp->strm->txn->req;
else
- msg = &txn->rsp;
+ msg = &smp->strm->txn->rsp;
len = http_body_bytes(msg);
body = b_ptr(msg->chn->buf, -http_data_rewind(msg));
smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
int back_conn = (kw[4] == 'b') ? 1 : 0;
- struct connection *conn = objt_conn(smp->strm->si[back_conn].end);
+ struct connection *conn = smp->strm ? objt_conn(smp->strm->si[back_conn].end) : NULL;
smp->data.type = SMP_T_BOOL;
smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
int back_conn = (kw[4] == 'b') ? 1 : 0;
struct connection *conn;
- smp->flags = 0;
+ if (!smp->strm)
+ return 0;
+ smp->flags = 0;
conn = objt_conn(smp->strm->si[back_conn].end);
if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
return 0;
struct connection *conn;
int sint;
+ if (!smp->strm)
+ return 0;
+
smp->flags = 0;
conn = objt_conn(smp->strm->si[back_conn].end);
int back_conn = (kw[4] == 'b') ? 1 : 0;
struct connection *conn;
+ if (!smp->strm)
+ return 0;
+
smp->flags = 0;
conn = objt_conn(smp->strm->si[back_conn].end);
{
struct connection *conn;
+ if (!smp->strm)
+ return 0;
+
smp->flags = SMP_F_CONST;
smp->data.type = SMP_T_STR;
{
struct connection *conn;
+ if (!smp->strm)
+ return 0;
+
smp->flags = SMP_F_CONST;
smp->data.type = SMP_T_STR;
int back_conn = (kw[4] == 'b') ? 1 : 0;
struct connection *conn;
+ if (!smp->strm)
+ return 0;
+
smp->flags = 0;
conn = objt_conn(smp->strm->si[back_conn].end);
SSL_SESSION *ssl_sess;
struct connection *conn;
+ if (!smp->strm)
+ return 0;
+
smp->flags = SMP_F_CONST;
smp->data.type = SMP_T_BIN;
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
struct connection *conn;
+ if (!smp->strm)
+ return 0;
+
smp->flags = SMP_F_CONST;
smp->data.type = SMP_T_STR;
int finished_len;
struct chunk *finished_trash;
+ if (!smp->strm)
+ return 0;
+
smp->flags = 0;
conn = objt_conn(smp->strm->si[back_conn].end);
static int
smp_fetch_sc_tracked(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
+ if (!smp->strm)
+ return 0;
+
smp->flags = SMP_F_VOL_TEST;
smp->data.type = SMP_T_BOOL;
smp->data.u.sint = !!smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
static int
smp_fetch_sc_get_gpt0(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct stkctr *stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+ struct stkctr *stkctr;
+ if (!smp->strm)
+ return 0;
+
+ stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
if (!stkctr)
return 0;
static int
smp_fetch_sc_get_gpc0(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct stkctr *stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+ struct stkctr *stkctr;
+
+ if (!smp->strm)
+ return 0;
+ stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
if (!stkctr)
return 0;
static int
smp_fetch_sc_gpc0_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct stkctr *stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+ struct stkctr *stkctr;
+
+ if (!smp->strm)
+ return 0;
+ stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
if (!stkctr)
return 0;
static int
smp_fetch_sc_inc_gpc0(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct stkctr *stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+ struct stkctr *stkctr;
+
+ if (!smp->strm)
+ return 0;
+ stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
if (!stkctr)
return 0;
static int
smp_fetch_sc_clr_gpc0(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct stkctr *stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+ struct stkctr *stkctr;
+ if (!smp->strm)
+ return 0;
+
+ stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
if (!stkctr)
return 0;
static int
smp_fetch_sc_conn_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct stkctr *stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+ struct stkctr *stkctr;
+ if (!smp->strm)
+ return 0;
+
+ stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
if (!stkctr)
return 0;
static int
smp_fetch_sc_conn_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct stkctr *stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+ struct stkctr *stkctr;
+
+ if (!smp->strm)
+ return 0;
+ stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
if (!stkctr)
return 0;
static int
smp_fetch_sc_conn_cur(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct stkctr *stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+ struct stkctr *stkctr;
+
+ if (!smp->strm)
+ return 0;
+ stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
if (!stkctr)
return 0;
static int
smp_fetch_sc_sess_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct stkctr *stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+ struct stkctr *stkctr;
+
+ if (!smp->strm)
+ return 0;
+ stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
if (!stkctr)
return 0;
static int
smp_fetch_sc_sess_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct stkctr *stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+ struct stkctr *stkctr;
+ if (!smp->strm)
+ return 0;
+
+ stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
if (!stkctr)
return 0;
static int
smp_fetch_sc_http_req_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct stkctr *stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+ struct stkctr *stkctr;
+ if (!smp->strm)
+ return 0;
+
+ stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
if (!stkctr)
return 0;
static int
smp_fetch_sc_http_req_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct stkctr *stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+ struct stkctr *stkctr;
+
+ if (!smp->strm)
+ return 0;
+ stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
if (!stkctr)
return 0;
static int
smp_fetch_sc_http_err_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct stkctr *stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+ struct stkctr *stkctr;
+
+ if (!smp->strm)
+ return 0;
+ stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
if (!stkctr)
return 0;
static int
smp_fetch_sc_http_err_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct stkctr *stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+ struct stkctr *stkctr;
+
+ if (!smp->strm)
+ return 0;
+ stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
if (!stkctr)
return 0;
static int
smp_fetch_sc_kbytes_in(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct stkctr *stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+ struct stkctr *stkctr;
+ if (!smp->strm)
+ return 0;
+
+ stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
if (!stkctr)
return 0;
static int
smp_fetch_sc_bytes_in_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct stkctr *stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+ struct stkctr *stkctr;
+ if (!smp->strm)
+ return 0;
+
+ stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
if (!stkctr)
return 0;
static int
smp_fetch_sc_kbytes_out(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct stkctr *stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+ struct stkctr *stkctr;
+
+ if (!smp->strm)
+ return 0;
+ stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
if (!stkctr)
return 0;
static int
smp_fetch_sc_bytes_out_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct stkctr *stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+ struct stkctr *stkctr;
+
+ if (!smp->strm)
+ return 0;
+ stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
if (!stkctr)
return 0;
static int
smp_fetch_sc_trackers(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
- struct stkctr *stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
+ struct stkctr *stkctr;
+
+ if (!smp->strm)
+ return 0;
+ stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw);
if (!stkctr)
return 0;