From: Christopher Faulet Date: Tue, 14 Apr 2026 16:37:49 +0000 (+0200) Subject: MINOR: stream: Move the HTTP txn in an union X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=594753238c0fe618b661ee14fc5976541a617655;p=thirdparty%2Fhaproxy.git MINOR: stream: Move the HTTP txn in an union The HTTP transaction is moved in an union. For now, it is the only possible transaction that can be allocated. But that will change. Thanks to this commit and the next one, it will be possible to deal with different kind of transactions for a stream. This patch looks quite huge, but it is more or less a renaming of all accesses to "txn" field by "txn.http". --- diff --git a/doc/internals/api/filters.txt b/doc/internals/api/filters.txt index f1d2f341f..f299cc829 100644 --- a/doc/internals/api/filters.txt +++ b/doc/internals/api/filters.txt @@ -738,10 +738,10 @@ For instance : switch (an_bit) { case AN_REQ_WAIT_HTTP: if (/* A test on received headers before any other treatment */) { - msg = ((chn->flags & CF_ISRESP) ? &s->txn->rsp : &s->txn->req); + msg = ((chn->flags & CF_ISRESP) ? &s->txn.http->rsp : &s->txn.http->req); txn->status = 400; msg->msg_state = HTTP_MSG_ERROR; - http_reply_and_close(s, s->txn->status, http_error_message(s)); + http_reply_and_close(s, s->txn.http->status, http_error_message(s)); return -1; /* This is an error ! */ } break; @@ -1161,7 +1161,7 @@ Then, to finish, there are 2 informational callbacks : if we're retrying to send the request to the server after it failed. It could be useful to reset the filter context before receiving the true response. - By checking s->txn->status, it is possible to know why this callback is + By checking s->txn.http->status, it is possible to know why this callback is called. If it's a 1xx, we're called because of an informational message. Otherwise, it is a L7 retry. diff --git a/include/haproxy/filters-t.h b/include/haproxy/filters-t.h index 317c46a9b..f2d804750 100644 --- a/include/haproxy/filters-t.h +++ b/include/haproxy/filters-t.h @@ -143,7 +143,7 @@ struct flt_kw_list { * otherwise. * - http_reset : Called when the HTTP message is reset. It happens * either when a 100-continue response is received. - * that can be detected if s->txn->status is 10X, or + * that can be detected if s->txn.http->status is 10X, or * if we're attempting a L7 retry. * Returns nothing. * - http_reply : Called when, at any time, HAProxy decides to stop diff --git a/include/haproxy/stream-t.h b/include/haproxy/stream-t.h index c8f8719e0..ecd31caae 100644 --- a/include/haproxy/stream-t.h +++ b/include/haproxy/stream-t.h @@ -256,7 +256,9 @@ struct stream { struct server *srv_conn; /* stream already has a slot on a server and is not in queue */ struct pendconn *pend_pos; /* if not NULL, points to the pending position in the pending queue */ - struct http_txn *txn; /* current HTTP transaction being processed. Should become a list. */ + union { + struct http_txn *http; /* current HTTP transaction being processed. Should become a list. */ + } txn; struct task *task; /* the task associated with this stream */ unsigned int pending_events; /* the pending events not yet processed by the stream but handled by process_stream() */ diff --git a/src/backend.c b/src/backend.c index 7a1892f97..19d25aea1 100644 --- a/src/backend.c +++ b/src/backend.c @@ -750,7 +750,7 @@ int assign_server(struct stream *s) case BE_LB_HASH_URI: /* URI hashing */ - if (IS_HTX_STRM(s) && s->txn->req.msg_state >= HTTP_MSG_BODY) { + if (IS_HTX_STRM(s) && s->txn.http->req.msg_state >= HTTP_MSG_BODY) { struct ist uri; uri = htx_sl_req_uri(http_get_stline(htxbuf(&s->req.buf))); @@ -768,20 +768,20 @@ int assign_server(struct stream *s) case BE_LB_HASH_PRM: /* URL Parameter hashing */ - if (IS_HTX_STRM(s) && s->txn->req.msg_state >= HTTP_MSG_BODY) { + if (IS_HTX_STRM(s) && s->txn.http->req.msg_state >= HTTP_MSG_BODY) { struct ist uri; uri = htx_sl_req_uri(http_get_stline(htxbuf(&s->req.buf))); srv = get_server_ph(s->be, uri.ptr, uri.len, prev_srv); - if (!srv && s->txn->meth == HTTP_METH_POST) + if (!srv && s->txn.http->meth == HTTP_METH_POST) srv = get_server_ph_post(s, prev_srv); } break; case BE_LB_HASH_HDR: /* Header Parameter hashing */ - if (IS_HTX_STRM(s) && s->txn->req.msg_state >= HTTP_MSG_BODY) + if (IS_HTX_STRM(s) && s->txn.http->req.msg_state >= HTTP_MSG_BODY) srv = get_server_hh(s, prev_srv); break; @@ -1005,9 +1005,9 @@ int assign_server_and_queue(struct stream *s) */ if (prev_srv != objt_server(s->target)) { - if (s->txn && (s->txn->flags & TX_CK_MASK) == TX_CK_VALID) { - s->txn->flags &= ~TX_CK_MASK; - s->txn->flags |= TX_CK_DOWN; + if (s->txn.http && (s->txn.http->flags & TX_CK_MASK) == TX_CK_VALID) { + s->txn.http->flags &= ~TX_CK_MASK; + s->txn.http->flags |= TX_CK_DOWN; } s->flags |= SF_REDISP; if (prev_srv->counters.shared.tg) @@ -1836,7 +1836,7 @@ int connect_server(struct stream *s) DBG_TRACE_STATE("skip idle connections reuse: websocket stream", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s); } else { - const int not_first_req = s->txn && s->txn->flags & TX_NOT_FIRST; + const int not_first_req = s->txn.http && s->txn.http->flags & TX_NOT_FIRST; struct ist name = IST_NULL; struct sample *name_smp; diff --git a/src/cache.c b/src/cache.c index dfb9f6bf5..58ecd620b 100644 --- a/src/cache.c +++ b/src/cache.c @@ -694,7 +694,7 @@ static int cache_store_post_analyze(struct stream *s, struct filter *filter, struct channel *chn, unsigned an_bit) { - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct http_msg *msg = &txn->rsp; struct cache_st *st = filter->ctx; @@ -1189,7 +1189,7 @@ enum act_return http_action_store_cache(struct act_rule *rule, struct proxy *px, { int effective_maxage = 0; int true_maxage = 0; - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct http_msg *msg = &txn->rsp; struct filter *filter; struct shared_block *first = NULL; @@ -1972,7 +1972,7 @@ enum act_parse_ret parse_cache_store(const char **args, int *orig_arg, struct pr * if it begins with a slash ('/'). */ int sha1_hosturi(struct stream *s) { - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct htx *htx = htxbuf(&s->req.buf); struct htx_sl *sl; struct http_hdr_ctx ctx; @@ -2105,7 +2105,7 @@ enum act_return http_action_req_cache_use(struct act_rule *rule, struct proxy *p struct session *sess, struct stream *s, int flags) { - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct cache_entry *res, *sec_entry = NULL; struct cache_flt_conf *cconf = rule->arg.act.p[0]; struct cache *cache = cconf->c.cache; @@ -2129,7 +2129,7 @@ enum act_return http_action_req_cache_use(struct act_rule *rule, struct proxy *p if (!sha1_hosturi(s)) return ACT_RET_CONT; - if (s->txn->flags & TX_CACHE_IGNORE) + if (s->txn.http->flags & TX_CACHE_IGNORE) return ACT_RET_CONT; if (px == strm_fe(s)) { @@ -2141,13 +2141,14 @@ enum act_return http_action_req_cache_use(struct act_rule *rule, struct proxy *p _HA_ATOMIC_INC(&px->be_counters.shared.tg[tgid - 1]->p.http.cache_lookups); } - cache_tree = get_cache_tree_from_hash(cache, read_u32(s->txn->cache_hash)); + cache_tree = get_cache_tree_from_hash(cache, + read_u32(s->txn.http->cache_hash)); if (!cache_tree) return ACT_RET_CONT; cache_rdlock(cache_tree); - res = get_entry(cache_tree, s->txn->cache_hash, 0); + res = get_entry(cache_tree, s->txn.http->cache_hash, 0); /* We must not use an entry that is not complete but the check will be * performed after we look for a potential secondary entry (in case of * Vary). */ @@ -2176,7 +2177,8 @@ enum act_return http_action_req_cache_use(struct act_rule *rule, struct proxy *p if (!http_request_build_secondary_key(s, res->secondary_key_signature)) { cache_rdlock(cache_tree); sec_entry = get_secondary_entry(cache_tree, res, - s->txn->cache_secondary_hash, 0); + s->txn.http->cache_secondary_hash, + 0); if (sec_entry && sec_entry != res) { /* The wrong row was added to the hot list. */ release_entry(cache_tree, res, 0); @@ -2837,7 +2839,7 @@ static int http_request_prebuild_full_secondary_key(struct stream *s) */ static int http_request_build_secondary_key(struct stream *s, int vary_signature) { - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct htx *htx = htxbuf(&s->req.buf); unsigned int idx; diff --git a/src/debug.c b/src/debug.c index 8c01b757c..ce31711d3 100644 --- a/src/debug.c +++ b/src/debug.c @@ -1401,7 +1401,7 @@ static int debug_parse_cli_stream(char **args, char *payload, struct appctx *app } else if (isteq(name, ist("strm.x"))) { ptr = (!s || !may_access(s)) ? NULL : &s->conn_exp; size = sizeof(s->conn_exp); } else if (isteq(name, ist("txn.f"))) { - ptr = (!s || !may_access(s)) ? NULL : &s->txn->flags; size = sizeof(s->txn->flags); + ptr = (!s || !may_access(s)) ? NULL : &s->txn.http->flags; size = sizeof(s->txn.http->flags); } else if (isteq(name, ist("req.f"))) { ptr = (!s || !may_access(s)) ? NULL : &s->req.flags; size = sizeof(s->req.flags); } else if (isteq(name, ist("res.f"))) { diff --git a/src/fcgi-app.c b/src/fcgi-app.c index dfa9af5a6..eafbe28ab 100644 --- a/src/fcgi-app.c +++ b/src/fcgi-app.c @@ -336,7 +336,7 @@ static int fcgi_flt_http_headers(struct stream *s, struct filter *filter, struct /* Add the header "Content-Length:" if possible */ sl = http_get_stline(htx); - if (s->txn->meth != HTTP_METH_HEAD && sl && + if (s->txn.http->meth != HTTP_METH_HEAD && sl && (msg->flags & (HTTP_MSGF_XFER_LEN|HTTP_MSGF_CNT_LEN|HTTP_MSGF_TE_CHNK)) == HTTP_MSGF_XFER_LEN && (htx->flags & HTX_FL_EOM)) { struct htx_blk * blk; diff --git a/src/filters.c b/src/filters.c index fc6006309..f87a077fb 100644 --- a/src/filters.c +++ b/src/filters.c @@ -814,7 +814,8 @@ flt_http_end(struct stream *s, struct http_msg *msg) unsigned int offset = 0; int ret = 1; - DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s, s->txn, msg); + DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s, + s->txn.http, msg); for (filter = resume_filter_list_start(s, msg->chn); filter; filter = resume_filter_list_next(s, msg->chn, filter)) { unsigned long long flt_off = FLT_OFF(filter, msg->chn); @@ -856,7 +857,8 @@ flt_http_reset(struct stream *s, struct http_msg *msg) { struct filter *filter; - DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s, s->txn, msg); + DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s, + s->txn.http, msg); for (filter = flt_list_start(s, msg->chn); filter; filter = flt_list_next(s, msg->chn, filter)) { if (FLT_OPS(filter)->http_reset) { @@ -879,7 +881,8 @@ flt_http_reply(struct stream *s, short status, const struct buffer *msg) { struct filter *filter; - DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s, s->txn, msg); + DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s, + s->txn.http, msg); list_for_each_entry(filter, &strm_flt(s)->filters, list) { if (FLT_OPS(filter)->http_reply) { struct thread_exec_ctx exec_ctx = EXEC_CTX_MAKE(TH_EX_CTX_FLT, filter->config); @@ -912,7 +915,8 @@ flt_http_payload(struct stream *s, struct http_msg *msg, unsigned int len) strm_flt(s)->flags &= ~STRM_FLT_FL_HOLD_HTTP_HDRS; ret = data = len - out; - DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s, s->txn, msg); + DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s, + s->txn.http, msg); for (filter = flt_list_start(s, msg->chn); filter; filter = flt_list_next(s, msg->chn, filter)) { struct thread_exec_ctx exec_ctx = EXEC_CTX_MAKE(TH_EX_CTX_FLT, filter->config); @@ -1106,8 +1110,9 @@ flt_analyze_http_headers(struct stream *s, struct channel *chn, unsigned int an_ struct filter *filter; int ret = 1; - msg = ((chn->flags & CF_ISRESP) ? &s->txn->rsp : &s->txn->req); - DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s, s->txn, msg); + msg = ((chn->flags & CF_ISRESP) ? &s->txn.http->rsp : &s->txn.http->req); + DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s, + s->txn.http, msg); for (filter = resume_filter_list_start(s, chn); filter; filter = resume_filter_list_next(s, chn, filter)) { @@ -1358,11 +1363,12 @@ handle_analyzer_result(struct stream *s, struct channel *chn, if (IS_HTX_STRM(s)) { http_set_term_flags(s); - if (s->txn->status > 0) - http_reply_and_close(s, s->txn->status, NULL); + if (s->txn.http->status > 0) + http_reply_and_close(s, s->txn.http->status, NULL); else { - s->txn->status = (!(chn->flags & CF_ISRESP)) ? 400 : 502; - http_reply_and_close(s, s->txn->status, http_error_message(s)); + s->txn.http->status = (!(chn->flags & CF_ISRESP)) ? 400 : 502; + http_reply_and_close(s, s->txn.http->status, + http_error_message(s)); } } else { diff --git a/src/flt_http_comp.c b/src/flt_http_comp.c index 6e15cb7e9..50a389c51 100644 --- a/src/flt_http_comp.c +++ b/src/flt_http_comp.c @@ -106,7 +106,7 @@ static void comp_prepare_compress_request(struct comp_state *st, struct stream *s, struct http_msg *msg) { struct htx *htx = htxbuf(&msg->chn->buf); - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct http_hdr_ctx ctx; struct comp_type *comp_type; unsigned int comp_minsize = 0; @@ -261,7 +261,7 @@ static int comp_res_http_post_analyze(struct stream *s, struct filter *filter, struct channel *chn, unsigned an_bit) { - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct http_msg *msg = &txn->rsp; struct comp_state *st = filter->ctx; @@ -648,7 +648,7 @@ static int select_compression_response_header(struct comp_state *st, struct stream *s, struct http_msg *msg) { struct htx *htx = htxbuf(&msg->chn->buf); - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct http_hdr_ctx ctx; struct comp_type *comp_type; unsigned int comp_minsize = 0; @@ -1195,7 +1195,7 @@ static int smp_fetch_res_comp(const struct arg *args, struct sample *smp, const char *kw, void *private) { - struct http_txn *txn = smp->strm ? smp->strm->txn : NULL; + struct http_txn *txn = smp->strm ? smp->strm->txn.http : NULL; smp->data.type = SMP_T_BOOL; smp->data.u.sint = (txn && (txn->rsp.flags & HTTP_MSGF_COMPRESSING)); @@ -1209,7 +1209,7 @@ static int smp_fetch_res_comp_algo(const struct arg *args, struct sample *smp, const char *kw, void *private) { - struct http_txn *txn = smp->strm ? smp->strm->txn : NULL; + struct http_txn *txn = smp->strm ? smp->strm->txn.http : NULL; struct filter *filter; struct comp_state *st; diff --git a/src/hlua.c b/src/hlua.c index 06afdcb04..92a15a97d 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -6615,7 +6615,7 @@ __LJMP static int hlua_http_req_rep_hdr(lua_State *L) if (htxn->dir != SMP_OPT_DIR_REQ || !IS_HTX_STRM(htxn->s)) WILL_LJMP(lua_error(L)); - return MAY_LJMP(hlua_http_rep_hdr(L, &htxn->s->txn->req, 1)); + return MAY_LJMP(hlua_http_rep_hdr(L, &htxn->s->txn.http->req, 1)); } __LJMP static int hlua_http_res_rep_hdr(lua_State *L) @@ -6628,7 +6628,7 @@ __LJMP static int hlua_http_res_rep_hdr(lua_State *L) if (htxn->dir != SMP_OPT_DIR_RES || !IS_HTX_STRM(htxn->s)) WILL_LJMP(lua_error(L)); - return MAY_LJMP(hlua_http_rep_hdr(L, &htxn->s->txn->rsp, 1)); + return MAY_LJMP(hlua_http_rep_hdr(L, &htxn->s->txn.http->rsp, 1)); } __LJMP static int hlua_http_req_rep_val(lua_State *L) @@ -6641,7 +6641,7 @@ __LJMP static int hlua_http_req_rep_val(lua_State *L) if (htxn->dir != SMP_OPT_DIR_REQ || !IS_HTX_STRM(htxn->s)) WILL_LJMP(lua_error(L)); - return MAY_LJMP(hlua_http_rep_hdr(L, &htxn->s->txn->req, 0)); + return MAY_LJMP(hlua_http_rep_hdr(L, &htxn->s->txn.http->req, 0)); } __LJMP static int hlua_http_res_rep_val(lua_State *L) @@ -6654,7 +6654,7 @@ __LJMP static int hlua_http_res_rep_val(lua_State *L) if (htxn->dir != SMP_OPT_DIR_RES || !IS_HTX_STRM(htxn->s)) WILL_LJMP(lua_error(L)); - return MAY_LJMP(hlua_http_rep_hdr(L, &htxn->s->txn->rsp, 0)); + return MAY_LJMP(hlua_http_rep_hdr(L, &htxn->s->txn.http->rsp, 0)); } /* This function deletes all the occurrences of an header. @@ -6683,7 +6683,7 @@ __LJMP static int hlua_http_req_del_hdr(lua_State *L) if (htxn->dir != SMP_OPT_DIR_REQ || !IS_HTX_STRM(htxn->s)) WILL_LJMP(lua_error(L)); - return hlua_http_del_hdr(L, &htxn->s->txn->req); + return hlua_http_del_hdr(L, &htxn->s->txn.http->req); } __LJMP static int hlua_http_res_del_hdr(lua_State *L) @@ -6696,7 +6696,7 @@ __LJMP static int hlua_http_res_del_hdr(lua_State *L) if (htxn->dir != SMP_OPT_DIR_RES || !IS_HTX_STRM(htxn->s)) WILL_LJMP(lua_error(L)); - return hlua_http_del_hdr(L, &htxn->s->txn->rsp); + return hlua_http_del_hdr(L, &htxn->s->txn.http->rsp); } /* This function adds an header. It is a wrapper used by @@ -6725,7 +6725,7 @@ __LJMP static int hlua_http_req_add_hdr(lua_State *L) if (htxn->dir != SMP_OPT_DIR_REQ || !IS_HTX_STRM(htxn->s)) WILL_LJMP(lua_error(L)); - return hlua_http_add_hdr(L, &htxn->s->txn->req); + return hlua_http_add_hdr(L, &htxn->s->txn.http->req); } __LJMP static int hlua_http_res_add_hdr(lua_State *L) @@ -6738,7 +6738,7 @@ __LJMP static int hlua_http_res_add_hdr(lua_State *L) if (htxn->dir != SMP_OPT_DIR_RES || !IS_HTX_STRM(htxn->s)) WILL_LJMP(lua_error(L)); - return hlua_http_add_hdr(L, &htxn->s->txn->rsp); + return hlua_http_add_hdr(L, &htxn->s->txn.http->rsp); } static int hlua_http_req_set_hdr(lua_State *L) @@ -6751,8 +6751,8 @@ static int hlua_http_req_set_hdr(lua_State *L) if (htxn->dir != SMP_OPT_DIR_REQ || !IS_HTX_STRM(htxn->s)) WILL_LJMP(lua_error(L)); - hlua_http_del_hdr(L, &htxn->s->txn->req); - return hlua_http_add_hdr(L, &htxn->s->txn->req); + hlua_http_del_hdr(L, &htxn->s->txn.http->req); + return hlua_http_add_hdr(L, &htxn->s->txn.http->req); } static int hlua_http_res_set_hdr(lua_State *L) @@ -6765,8 +6765,8 @@ static int hlua_http_res_set_hdr(lua_State *L) if (htxn->dir != SMP_OPT_DIR_RES || !IS_HTX_STRM(htxn->s)) WILL_LJMP(lua_error(L)); - hlua_http_del_hdr(L, &htxn->s->txn->rsp); - return hlua_http_add_hdr(L, &htxn->s->txn->rsp); + hlua_http_del_hdr(L, &htxn->s->txn.http->rsp); + return hlua_http_add_hdr(L, &htxn->s->txn.http->rsp); } /* This function set the method. */ @@ -8642,7 +8642,7 @@ __LJMP static int hlua_txn_new(lua_State *L, struct stream *s, struct proxy *p, /* Creates the HTTP-Request object is the current proxy allows http. */ lua_pushstring(L, "http_req"); if (p->mode == PR_MODE_HTTP) { - if (!hlua_http_msg_new(L, &s->txn->req)) + if (!hlua_http_msg_new(L, &s->txn.http->req)) return 0; } else @@ -8652,7 +8652,7 @@ __LJMP static int hlua_txn_new(lua_State *L, struct stream *s, struct proxy *p, /* Creates the HTTP-Response object is the current proxy allows http. */ lua_pushstring(L, "http_res"); if (p->mode == PR_MODE_HTTP) { - if (!hlua_http_msg_new(L, &s->txn->rsp)) + if (!hlua_http_msg_new(L, &s->txn.http->rsp)) return 0; } else @@ -8852,7 +8852,7 @@ __LJMP static int hlua_txn_forward_reply(lua_State *L, struct stream *s) h1m_init_res(&h1m); htx = htx_from_buf(&s->res.buf); channel_htx_truncate(&s->res, htx); - if (s->txn->req.flags & HTTP_MSGF_VER_11) { + if (s->txn.http->req.flags & HTTP_MSGF_VER_11) { flags = (HTX_SL_F_IS_RESP|HTX_SL_F_VER_11); sl = htx_add_stline(htx, HTX_BLK_RES_SL, flags, ist("HTTP/1.1"), ist2(status, status_len), ist2(reason, reason_len)); @@ -8950,7 +8950,7 @@ __LJMP static int hlua_txn_forward_reply(lua_State *L, struct stream *s) htx->flags |= HTX_FL_EOM; /* Now, forward the response and terminate the transaction */ - s->txn->status = code; + s->txn.http->status = code; htx_to_buf(htx, &s->res.buf); if (!http_forward_proxy_resp(s, 1)) goto fail; @@ -9002,7 +9002,7 @@ __LJMP static int hlua_txn_done(lua_State *L) if (lua_gettop(L) == 1 || !lua_istable(L, 2)) { /* No reply or invalid reply */ - s->txn->status = 0; + s->txn.http->status = 0; http_reply_and_close(s, 0, NULL); } else { @@ -11273,7 +11273,7 @@ static int hlua_applet_http_init(struct appctx *ctx) struct task *task; const char *error; - txn = strm->txn; + txn = strm->txn.http; hlua = pool_alloc(pool_head_hlua); if (!hlua) { SEND_ERR(strm->be, "Lua applet http '%s': out of memory.\n", diff --git a/src/http_act.c b/src/http_act.c index f982ce068..afb8bd1d5 100644 --- a/src/http_act.c +++ b/src/http_act.c @@ -127,7 +127,7 @@ static enum act_return http_action_set_req_line(struct act_rule *rule, struct pr if (s->sv_tgcounters) _HA_ATOMIC_INC(&s->sv_tgcounters->failed_rewrites); - if (!(s->txn->req.flags & HTTP_MSGF_SOFT_RW)) { + if (!(s->txn.http->req.flags & HTTP_MSGF_SOFT_RW)) { ret = ACT_RET_ERR; if (!(s->flags & SF_ERR_MASK)) s->flags |= SF_ERR_PRXCOND; @@ -398,7 +398,7 @@ static enum act_return http_action_normalize_uri(struct act_rule *rule, struct p if (s->sv_tgcounters) _HA_ATOMIC_ADD(&s->sv_tgcounters->failed_rewrites, 1); - if (!(s->txn->req.flags & HTTP_MSGF_SOFT_RW)) { + if (!(s->txn.http->req.flags & HTTP_MSGF_SOFT_RW)) { ret = ACT_RET_ERR; if (!(s->flags & SF_ERR_MASK)) s->flags |= SF_ERR_PRXCOND; @@ -575,7 +575,7 @@ static enum act_return http_action_replace_uri(struct act_rule *rule, struct pro if (s->sv_tgcounters) _HA_ATOMIC_INC(&s->sv_tgcounters->failed_rewrites); - if (!(s->txn->req.flags & HTTP_MSGF_SOFT_RW)) { + if (!(s->txn.http->req.flags & HTTP_MSGF_SOFT_RW)) { ret = ACT_RET_ERR; if (!(s->flags & SF_ERR_MASK)) s->flags |= SF_ERR_PRXCOND; @@ -656,7 +656,7 @@ static enum act_return action_http_set_status(struct act_rule *rule, struct prox if (s->sv_tgcounters) _HA_ATOMIC_INC(&s->sv_tgcounters->failed_rewrites); - if (!(s->txn->req.flags & HTTP_MSGF_SOFT_RW)) { + if (!(s->txn.http->req.flags & HTTP_MSGF_SOFT_RW)) { if (!(s->flags & SF_ERR_MASK)) s->flags |= SF_ERR_PRXCOND; return ACT_RET_ERR; @@ -762,8 +762,8 @@ static enum act_return http_req_disable_l7_retry(struct act_rule *rule, struct p /* In theory, the TX_L7_RETRY flags isn't set at this point, but * let's be future-proof and remove it anyway. */ - s->txn->flags &= ~TX_L7_RETRY; - s->txn->flags |= TX_D_L7_RETRY; + s->txn.http->flags &= ~TX_L7_RETRY; + s->txn.http->flags |= TX_D_L7_RETRY; return ACT_RET_CONT; } @@ -1258,12 +1258,12 @@ static enum act_return http_action_auth(struct act_rule *rule, struct proxy *px, auth_realm = px->id; } - if (!(s->txn->flags & TX_USE_PX_CONN)) { - s->txn->status = 401; + if (!(s->txn.http->flags & TX_USE_PX_CONN)) { + s->txn.http->status = 401; hdr = ist("WWW-Authenticate"); } else { - s->txn->status = 407; + s->txn.http->status = 407; hdr = ist("Proxy-Authenticate"); } reply = http_error_message(s); @@ -1361,7 +1361,7 @@ static enum act_return http_action_early_hint(struct act_rule *rule, struct prox struct buffer *value = alloc_trash_chunk(); enum act_return ret = ACT_RET_CONT; - if (!(s->txn->req.flags & HTTP_MSGF_VER_11)) + if (!(s->txn.http->req.flags & HTTP_MSGF_VER_11)) goto leave; if (!value) { @@ -1373,7 +1373,7 @@ static enum act_return http_action_early_hint(struct act_rule *rule, struct prox /* if there is no pending 103 response, start a new response. Otherwise, * continue to add link to a previously started response */ - if (s->txn->status != 103) { + if (s->txn.http->status != 103) { struct htx_sl *sl; unsigned int flags = (HTX_SL_F_IS_RESP|HTX_SL_F_VER_11| HTX_SL_F_XFER_LEN|HTX_SL_F_BODYLESS); @@ -1383,7 +1383,7 @@ static enum act_return http_action_early_hint(struct act_rule *rule, struct prox if (!sl) goto error; sl->info.res.status = 103; - s->txn->status = 103; + s->txn.http->status = 103; } /* Add the HTTP Early Hint HTTP 103 response header */ @@ -1400,7 +1400,7 @@ static enum act_return http_action_early_hint(struct act_rule *rule, struct prox goto error; if (!http_forward_proxy_resp(s, 0)) goto error; - s->txn->status = 0; + s->txn.http->status = 0; } leave: @@ -1412,7 +1412,7 @@ static enum act_return http_action_early_hint(struct act_rule *rule, struct prox * HTTP 103 response from the buffer */ channel_htx_truncate(res, htx); ret = ACT_RET_ERR; - s->txn->status = 0; + s->txn.http->status = 0; goto leave; } @@ -1427,7 +1427,7 @@ static enum act_return http_action_early_hint(struct act_rule *rule, struct prox static enum act_return http_action_set_header(struct act_rule *rule, struct proxy *px, struct session *sess, struct stream *s, int flags) { - struct http_msg *msg = ((rule->from == ACT_F_HTTP_REQ) ? &s->txn->req : &s->txn->rsp); + struct http_msg *msg = ((rule->from == ACT_F_HTTP_REQ) ? &s->txn.http->req : &s->txn.http->rsp); struct htx *htx = htxbuf(&msg->chn->buf); enum act_return ret = ACT_RET_CONT; struct buffer *replace; @@ -1487,7 +1487,7 @@ static enum act_return http_action_set_header(struct act_rule *rule, struct prox static enum act_return http_action_set_headers_bin(struct act_rule *rule, struct proxy *px, struct session *sess, struct stream *s, int flags) { - struct http_msg *msg = ((rule->from == ACT_F_HTTP_REQ) ? &s->txn->req : &s->txn->rsp); + struct http_msg *msg = ((rule->from == ACT_F_HTTP_REQ) ? &s->txn.http->req : &s->txn.http->rsp); struct htx *htx = htxbuf(&msg->chn->buf); struct sample *hdrs_bin; char *p, *end; @@ -1712,7 +1712,7 @@ static enum act_parse_ret parse_http_set_headers_bin(const char **args, int *ori static enum act_return http_action_replace_header(struct act_rule *rule, struct proxy *px, struct session *sess, struct stream *s, int flags) { - struct http_msg *msg = ((rule->from == ACT_F_HTTP_REQ) ? &s->txn->req : &s->txn->rsp); + struct http_msg *msg = ((rule->from == ACT_F_HTTP_REQ) ? &s->txn.http->req : &s->txn.http->rsp); struct htx *htx = htxbuf(&msg->chn->buf); enum act_return ret = ACT_RET_CONT; struct buffer *replace; @@ -1822,7 +1822,7 @@ static enum act_return http_action_del_header(struct act_rule *rule, struct prox struct session *sess, struct stream *s, int flags) { struct http_hdr_ctx ctx; - struct http_msg *msg = ((rule->from == ACT_F_HTTP_REQ) ? &s->txn->req : &s->txn->rsp); + struct http_msg *msg = ((rule->from == ACT_F_HTTP_REQ) ? &s->txn.http->req : &s->txn.http->rsp); struct htx *htx = htxbuf(&msg->chn->buf); enum act_return ret = ACT_RET_CONT; @@ -1920,7 +1920,7 @@ static enum act_return http_action_del_headers_bin(struct act_rule *rule, struct struct session *sess, struct stream *s, int flags) { struct http_hdr_ctx ctx; - struct http_msg *msg = ((rule->from == ACT_F_HTTP_REQ) ? &s->txn->req : &s->txn->rsp); + struct http_msg *msg = ((rule->from == ACT_F_HTTP_REQ) ? &s->txn.http->req : &s->txn.http->rsp); struct htx *htx = htxbuf(&msg->chn->buf); struct sample *hdrs_bin; char *p, *end; @@ -2414,13 +2414,13 @@ static enum act_return http_action_track_sc(struct act_rule *rule, struct proxy * to do it on purpose. */ if (rule->from == ACT_F_HTTP_RES && - http_status_matches(http_err_status_codes, s->txn->status)) { + http_status_matches(http_err_status_codes, s->txn.http->status)) { ptr3 = stktable_data_ptr(t, ts, STKTABLE_DT_HTTP_ERR_CNT); ptr4 = stktable_data_ptr(t, ts, STKTABLE_DT_HTTP_ERR_RATE); } if (rule->from == ACT_F_HTTP_RES && - http_status_matches(http_fail_status_codes, s->txn->status)) { + http_status_matches(http_fail_status_codes, s->txn.http->status)) { ptr5 = stktable_data_ptr(t, ts, STKTABLE_DT_HTTP_FAIL_CNT); ptr6 = stktable_data_ptr(t, ts, STKTABLE_DT_HTTP_FAIL_RATE); } @@ -2577,7 +2577,7 @@ static enum act_parse_ret parse_http_set_timeout(const char **args, static enum act_return http_action_strict_mode(struct act_rule *rule, struct proxy *px, struct session *sess, struct stream *s, int flags) { - struct http_msg *msg = ((rule->from == ACT_F_HTTP_REQ) ? &s->txn->req : &s->txn->rsp); + struct http_msg *msg = ((rule->from == ACT_F_HTTP_REQ) ? &s->txn.http->req : &s->txn.http->rsp); if (rule->action == 0) // strict-mode on msg->flags &= ~HTTP_MSGF_SOFT_RW; @@ -2624,7 +2624,7 @@ static enum act_return http_action_return(struct act_rule *rule, struct proxy *p { struct channel *req = &s->req; - s->txn->status = rule->arg.http_reply->status; + s->txn.http->status = rule->arg.http_reply->status; if (!(s->flags & SF_ERR_MASK)) s->flags |= SF_ERR_LOCAL; diff --git a/src/http_ana.c b/src/http_ana.c index 0751c5005..aea92a9f7 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -92,7 +92,7 @@ int http_wait_for_request(struct stream *s, struct channel *req, int an_bit) * check for monitor-uri, logging and finally headers capture. */ struct session *sess = s->sess; - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct http_msg *msg = &txn->req; struct htx *htx; struct htx_sl *sl; @@ -381,7 +381,7 @@ int http_process_req_common(struct stream *s, struct channel *req, int an_bit, s { struct list *def_rules, *rules; struct session *sess = s->sess; - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct http_msg *msg = &txn->req; struct htx *htx; struct redirect_rule *rule; @@ -666,7 +666,7 @@ int http_process_req_common(struct stream *s, struct channel *req, int an_bit, s int http_process_request(struct stream *s, struct channel *req, int an_bit) { struct session *sess = s->sess; - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct htx *htx; struct connection *cli_conn = objt_conn(strm_sess(s)->origin); @@ -728,7 +728,7 @@ int http_process_request(struct stream *s, struct channel *req, int an_bit) * that parameter. This will be done in another analyser. */ if (!(s->flags & (SF_ASSIGNED|SF_DIRECT)) && - s->txn->meth == HTTP_METH_POST && + s->txn.http->meth == HTTP_METH_POST && (s->be->lbprm.algo & BE_LB_ALGO) == BE_LB_ALGO_PH) { channel_dont_connect(req); req->analysers |= AN_REQ_HTTP_BODY; @@ -796,7 +796,7 @@ int http_process_request(struct stream *s, struct channel *req, int an_bit) */ int http_process_tarpit(struct stream *s, struct channel *req, int an_bit) { - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA, s, txn, &txn->req); /* This connection is being tarpitted. The CLIENT side has @@ -842,9 +842,10 @@ int http_process_tarpit(struct stream *s, struct channel *req, int an_bit) int http_wait_for_request_body(struct stream *s, struct channel *req, int an_bit) { struct session *sess = s->sess; - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; - DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA, s, txn, &s->txn->req); + DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA, s, txn, + &s->txn.http->req); switch (http_wait_for_msg_body(s, req, s->be->timeout.httpreq, 0, 0)) { @@ -931,7 +932,7 @@ int http_wait_for_request_body(struct stream *s, struct channel *req, int an_bit int http_request_forward_body(struct stream *s, struct channel *req, int an_bit) { struct session *sess = s->sess; - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct http_msg *msg = &txn->req; struct htx *htx; short status = 0; @@ -1062,7 +1063,7 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit) s->scb->flags |= SC_FL_NOLINGER; channel_auto_close(req); } - else if (s->txn->meth == HTTP_METH_POST) { + else if (s->txn.http->meth == HTTP_METH_POST) { /* POST requests may require to read extra CRLF sent by broken * browsers and which could cause an RST to be sent upon close * on some systems (eg: Linux). */ @@ -1227,14 +1228,15 @@ static __inline int do_l7_retry(struct stream *s, struct stconn *sc) /* Swap the L7 buffer with the channel buffer */ /* We know we stored the co_data as b_data, so get it there */ - co_data = b_data(&s->txn->l7_buffer); - b_set_data(&s->txn->l7_buffer, b_size(&s->txn->l7_buffer)); + co_data = b_data(&s->txn.http->l7_buffer); + b_set_data(&s->txn.http->l7_buffer, b_size(&s->txn.http->l7_buffer)); - req->buf = s->txn->l7_buffer; - s->txn->l7_buffer = BUF_NULL; + req->buf = s->txn.http->l7_buffer; + s->txn.http->l7_buffer = BUF_NULL; co_set_data(req, co_data); - DBG_TRACE_DEVEL("perform a L7 retry", STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA, s, s->txn); + DBG_TRACE_DEVEL("perform a L7 retry", STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA, s, + s->txn.http); b_reset(&res->buf); co_set_data(res, 0); @@ -1258,7 +1260,7 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit) * logging and finally headers capture. */ struct session *sess = s->sess; - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct http_msg *msg = &txn->rsp; struct htx *htx; struct connection *srv_conn; @@ -1779,7 +1781,7 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit) int http_process_res_common(struct stream *s, struct channel *rep, int an_bit, struct proxy *px) { struct session *sess = s->sess; - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct http_msg *msg = &txn->rsp; struct htx *htx; struct proxy *cur_proxy; @@ -2153,8 +2155,8 @@ int http_process_res_common(struct stream *s, struct channel *rep, int an_bit, s int http_response_forward_body(struct stream *s, struct channel *res, int an_bit) { struct session *sess = s->sess; - struct http_txn *txn = s->txn; - struct http_msg *msg = &s->txn->rsp; + struct http_txn *txn = s->txn.http; + struct http_msg *msg = &s->txn.http->rsp; struct htx *htx; int ret; @@ -2602,7 +2604,7 @@ int http_apply_redirect_rule(struct redirect_rule *rule, struct stream *s, struc if (!sl) goto fail; sl->info.res.status = rule->code; - s->txn->status = rule->code; + s->txn.http->status = rule->code; if (!htx_add_header(htx, ist("Content-length"), ist("0")) || !htx_add_header(htx, ist("Location"), location)) @@ -2701,7 +2703,7 @@ static enum rule_result http_req_restrict_header_names(struct stream *s, struct return rule_ret; block: /* Block the request returning a 403-Forbidden response */ - s->txn->status = 403; + s->txn.http->status = 403; rule_ret = HTTP_RULE_RES_DENY; goto out; } @@ -2804,7 +2806,7 @@ int http_res_set_status(unsigned int status, struct ist reason, struct stream *s if (!http_replace_res_status(htx, ist2(trash.area, trash.data), reason)) return -1; - s->txn->status = status; + s->txn.http->status = status; return 0; } @@ -2821,7 +2823,7 @@ static enum rule_result http_req_get_intercept_rule(struct proxy *px, struct lis struct list *rules, struct stream *s) { struct session *sess = strm_sess(s); - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct act_rule *rule; enum rule_result rule_ret = HTTP_RULE_RES_CONT; int act_opts = 0; @@ -3010,7 +3012,7 @@ static enum rule_result http_res_get_intercept_rule(struct proxy *px, struct lis struct list *rules, struct stream *s, uint8_t final) { struct session *sess = strm_sess(s); - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct act_rule *rule; enum rule_result rule_ret = HTTP_RULE_RES_CONT; int act_opts = 0; @@ -3191,7 +3193,7 @@ int http_eval_after_res_rules(struct stream *s) enum rule_result ret = HTTP_RULE_RES_CONT; /* Eval after-response ruleset only if the reply is not const */ - if (s->txn->flags & TX_CONST_REPLY) + if (s->txn.http->flags & TX_CONST_REPLY) goto end; /* prune the request variables if not already done and swap to the response variables. */ @@ -3224,7 +3226,7 @@ int http_eval_after_res_rules(struct stream *s) static void http_manage_client_side_cookies(struct stream *s, struct channel *req) { struct session *sess = s->sess; - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct htx *htx; struct http_hdr_ctx ctx; char *hdr_beg, *hdr_end, *del_from; @@ -3622,7 +3624,7 @@ static void http_manage_client_side_cookies(struct stream *s, struct channel *re static void http_manage_server_side_cookies(struct stream *s, struct channel *res) { struct session *sess = s->sess; - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct htx *htx; struct http_hdr_ctx ctx; struct server *srv; @@ -3889,11 +3891,11 @@ static void http_manage_server_side_cookies(struct stream *s, struct channel *re /* * Parses the Cache-Control and Pragma request header fields to determine if * the request may be served from the cache and/or if it is cacheable. Updates - * s->txn->flags. + * s->txn.http->flags. */ void http_check_request_for_cacheability(struct stream *s, struct channel *req) { - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct htx *htx; struct http_hdr_ctx ctx = { .blk = NULL }; int pragma_found, cc_found; @@ -3953,11 +3955,11 @@ void http_check_request_for_cacheability(struct stream *s, struct channel *req) } /* - * Check if response is cacheable or not. Updates s->txn->flags. + * Check if response is cacheable or not. Updates s->txn.http->flags. */ void http_check_response_for_cacheability(struct stream *s, struct channel *res) { - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct http_hdr_ctx ctx = { .blk = NULL }; struct htx *htx; int has_freshness_info = 0; @@ -4101,7 +4103,7 @@ static int http_handle_stats(struct stream *s, struct channel *req, struct proxy { struct stats_admin_rule *stats_admin_rule; struct session *sess = s->sess; - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct http_msg *msg = &txn->req; struct uri_auth *uri_auth = px->uri_auth; const char *h, *lookup, *end; @@ -4287,7 +4289,7 @@ enum rule_result http_wait_for_msg_body(struct stream *s, struct channel *chn, unsigned int time, unsigned int bytes, unsigned int large_buffer) { struct session *sess = s->sess; - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct http_msg *msg = ((chn->flags & CF_ISRESP) ? &txn->rsp : &txn->req); struct htx *htx; enum rule_result ret = HTTP_RULE_RES_CONT; @@ -4439,7 +4441,7 @@ void http_perform_server_redirect(struct stream *s, struct stconn *sc) if (!sl) goto fail; sl->info.res.status = 302; - s->txn->status = 302; + s->txn.http->status = 302; if (!htx_add_header(htx, ist("Cache-Control"), ist("no-cache")) || !htx_add_header(htx, ist("Content-length"), ist("0")) || @@ -4484,7 +4486,7 @@ void http_perform_server_redirect(struct stream *s, struct stconn *sc) static void http_end_request(struct stream *s) { struct channel *chn = &s->req; - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; DBG_TRACE_ENTER(STRM_EV_HTTP_ANA, s, txn); @@ -4616,7 +4618,7 @@ static void http_end_request(struct stream *s) static void http_end_response(struct stream *s) { struct channel *chn = &s->res; - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; DBG_TRACE_ENTER(STRM_EV_HTTP_ANA, s, txn); @@ -4724,17 +4726,17 @@ int http_forward_proxy_resp(struct stream *s, int final) size_t data; if (final) { - if (s->txn->server_status == -1) - s->txn->server_status = 0; + if (s->txn.http->server_status == -1) + s->txn.http->server_status = 0; if (!htx_is_empty(htx) && !http_eval_after_res_rules(s)) return 0; - if (s->txn->meth == HTTP_METH_HEAD) + if (s->txn.http->meth == HTTP_METH_HEAD) htx_skip_msg_payload(htx); /* Response from haproxy, override HTTP response version using the request one */ - s->txn->rsp.vsn = s->txn->req.vsn; + s->txn.http->rsp.vsn = s->txn.http->req.vsn; channel_auto_read(req); channel_abort(req); @@ -4768,7 +4770,7 @@ void http_server_error(struct stream *s, struct stconn *sc, int err, if (!(s->flags & SF_FINST_MASK)) s->flags |= finst; - http_reply_and_close(s, s->txn->status, msg); + http_reply_and_close(s, s->txn.http->status, msg); } void http_reply_and_close(struct stream *s, short status, struct http_reply *msg) @@ -4783,14 +4785,15 @@ void http_reply_and_close(struct stream *s, short status, struct http_reply *msg * it is already an internal error. If it was already a "const" * 500 error, just fail. */ - if (s->txn->status == 500) { - if (s->txn->flags & TX_CONST_REPLY) + if (s->txn.http->status == 500) { + if (s->txn.http->flags & TX_CONST_REPLY) goto end; - s->txn->flags |= TX_CONST_REPLY; + s->txn.http->flags |= TX_CONST_REPLY; } - s->txn->status = 500; - s->txn->http_reply = NULL; - return http_reply_and_close(s, s->txn->status, http_error_message(s)); + s->txn.http->status = 500; + s->txn.http->http_reply = NULL; + return http_reply_and_close(s, s->txn.http->status, + http_error_message(s)); } end: @@ -4811,10 +4814,10 @@ end: struct http_reply *http_error_message(struct stream *s) { - const int msgnum = http_get_status_idx(s->txn->status); + const int msgnum = http_get_status_idx(s->txn.http->status); - if (s->txn->http_reply) - return s->txn->http_reply; + if (s->txn.http->http_reply) + return s->txn.http->http_reply; else if (s->be->replies[msgnum]) return s->be->replies[msgnum]; else if (strm_fe(s)->replies[msgnum]) @@ -4851,8 +4854,8 @@ int http_reply_to_htx(struct stream *s, struct htx *htx, struct http_reply *repl } if (reply->type == HTTP_REPLY_ERRMSG && !reply->body.errmsg) { /* get default error message */ - if (reply == s->txn->http_reply) - s->txn->http_reply = NULL; + if (reply == s->txn.http->http_reply) + s->txn.http->http_reply = NULL; reply = http_error_message(s); if (reply->type == HTTP_REPLY_INDIRECT) { if (reply->body.reply) @@ -4950,8 +4953,8 @@ int http_reply_message(struct stream *s, struct http_reply *reply) struct channel *res = &s->res; struct htx *htx = htx_from_buf(&res->buf); - if (s->txn->status == -1) - s->txn->status = reply->status; + if (s->txn.http->status == -1) + s->txn.http->status = reply->status; channel_htx_truncate(res, htx); if (http_reply_to_htx(s, htx, reply) == -1) @@ -4984,45 +4987,45 @@ void http_return_srv_error(struct stream *s, struct stconn *sc) { int err_type = s->conn_err_type; - /* set s->txn->status for http_error_message(s) */ + /* set s->txn.http->status for http_error_message(s) */ if (err_type & STRM_ET_QUEUE_ABRT) { - s->txn->status = -1; + s->txn.http->status = -1; http_server_error(s, sc, SF_ERR_CLICL, SF_FINST_Q, NULL); } else if (err_type & STRM_ET_CONN_ABRT) { - s->txn->status = -1; + s->txn.http->status = -1; http_server_error(s, sc, SF_ERR_CLICL, SF_FINST_C, NULL); } else if (err_type & STRM_ET_QUEUE_TO) { - s->txn->status = 503; + s->txn.http->status = 503; http_server_error(s, sc, SF_ERR_SRVTO, SF_FINST_Q, http_error_message(s)); } else if (err_type & STRM_ET_QUEUE_ERR) { - s->txn->status = 503; + s->txn.http->status = 503; http_server_error(s, sc, SF_ERR_SRVCL, SF_FINST_Q, http_error_message(s)); } else if (err_type & STRM_ET_CONN_TO) { - s->txn->status = 503; + s->txn.http->status = 503; http_server_error(s, sc, SF_ERR_SRVTO, SF_FINST_C, - (s->txn->flags & TX_NOT_FIRST) ? NULL : + (s->txn.http->flags & TX_NOT_FIRST) ? NULL : http_error_message(s)); } else if (err_type & STRM_ET_CONN_ERR) { - s->txn->status = 503; + s->txn.http->status = 503; http_server_error(s, sc, SF_ERR_SRVCL, SF_FINST_C, (s->flags & SF_SRV_REUSED) ? NULL : http_error_message(s)); } else if (err_type & STRM_ET_CONN_RES) { - s->txn->status = 503; + s->txn.http->status = 503; http_server_error(s, sc, SF_ERR_RESOURCE, SF_FINST_C, - (s->txn->flags & TX_NOT_FIRST) ? NULL : + (s->txn.http->flags & TX_NOT_FIRST) ? NULL : http_error_message(s)); } else { /* STRM_ET_CONN_OTHER and others */ - s->txn->status = 500; + s->txn.http->status = 500; http_server_error(s, sc, SF_ERR_INTERNAL, SF_FINST_C, http_error_message(s)); } @@ -5290,7 +5293,7 @@ struct http_txn *http_create_txn(struct stream *s) txn = pool_alloc(pool_head_http_txn); if (!txn) return NULL; - s->txn = txn; + s->txn.http = txn; txn->meth = HTTP_METH_OTHER; txn->flags = ((sc && sc_ep_test(sc, SE_FL_NOT_FIRST)) ? TX_NOT_FIRST : 0); @@ -5326,7 +5329,7 @@ struct http_txn *http_create_txn(struct stream *s) /* to be used at the end of a transaction */ void http_destroy_txn(struct stream *s) { - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; /* these ones will have been dynamically allocated */ pool_free(pool_head_requri, txn->uri); @@ -5345,7 +5348,7 @@ void http_destroy_txn(struct stream *s) b_free(&txn->l7_buffer); pool_free(pool_head_http_txn, txn); - s->txn = NULL; + s->txn.http = NULL; } @@ -5375,12 +5378,12 @@ void http_set_term_flags(struct stream *s) s->flags |= SF_FINST_C; } else { - if (s->txn->rsp.msg_state < HTTP_MSG_DATA) { + if (s->txn.http->rsp.msg_state < HTTP_MSG_DATA) { /* We are still processing the response headers */ s->flags |= SF_FINST_H; } // (res == (done|closing|closed)) & (res->flags & shutw) - else if (s->txn->rsp.msg_state >= HTTP_MSG_DONE && s->txn->rsp.msg_state < HTTP_MSG_TUNNEL && + else if (s->txn.http->rsp.msg_state >= HTTP_MSG_DONE && s->txn.http->rsp.msg_state < HTTP_MSG_TUNNEL && (s->flags & (SF_ERR_CLITO|SF_ERR_CLICL))) { /* A client error was reported and we are * transmitting the last block of data diff --git a/src/http_fetch.c b/src/http_fetch.c index 3169214fa..16f2e5c93 100644 --- a/src/http_fetch.c +++ b/src/http_fetch.c @@ -95,7 +95,7 @@ REGISTER_PER_THREAD_FREE(free_raw_htx_chunk_per_thread); static int get_http_auth(struct sample *smp, struct htx *htx) { struct stream *s = smp->strm; - struct http_txn *txn = s->txn; + struct http_txn *txn = s->txn.http; struct http_hdr_ctx ctx = { .blk = NULL }; struct ist hdr; struct buffer auth_method; @@ -224,9 +224,9 @@ struct htx *smp_prefetch_htx(struct sample *smp, struct channel *chn, struct che return NULL; } - if (!s->txn && !http_create_txn(s)) + if (!s->txn.http && !http_create_txn(s)) return NULL; - txn = s->txn; + txn = s->txn.http; msg = (!(chn->flags & CF_ISRESP) ? &txn->req : &txn->rsp); if (IS_HTX_STRM(s)) { @@ -392,7 +392,7 @@ static int smp_fetch_meth(const struct arg *args, struct sample *smp, const char struct htx *htx = NULL; int meth; - txn = (smp->strm ? smp->strm->txn : NULL); + txn = (smp->strm ? smp->strm->txn.http : NULL); if (!txn) return 0; @@ -425,7 +425,7 @@ static int smp_fetch_rqver(const struct arg *args, struct sample *smp, const cha struct htx *htx = smp_prefetch_htx(smp, chn, NULL, 1); struct buffer *vsn = get_trash_chunk(); - if (!get_msg_version((s && s->txn) ? &s->txn->req : NULL, htx, vsn)) + if (!get_msg_version((s && s->txn.http) ? &s->txn.http->req : NULL, htx, vsn)) return 0; smp->data.type = SMP_T_STR; @@ -441,7 +441,7 @@ static int smp_fetch_stver(const struct arg *args, struct sample *smp, const cha struct htx *htx = smp_prefetch_htx(smp, chn, check, 1); struct buffer *vsn = get_trash_chunk(); - if (!get_msg_version((s && s->txn) ? &s->txn->rsp : NULL, htx, vsn)) + if (!get_msg_version((s && s->txn.http) ? &s->txn.http->rsp : NULL, htx, vsn)) return 0; smp->data.type = SMP_T_STR; @@ -480,7 +480,7 @@ static int smp_fetch_srv_status(const struct arg *args, struct sample *smp, cons struct http_txn *txn; short status; - txn = (smp->strm ? smp->strm->txn : NULL); + txn = (smp->strm ? smp->strm->txn.http : NULL); if (!txn) return 0; @@ -1353,7 +1353,7 @@ static int smp_fetch_http_first_req(const struct arg *args, struct sample *smp, return 0; smp->data.type = SMP_T_BOOL; - smp->data.u.sint = !(smp->strm->txn->flags & TX_NOT_FIRST); + smp->data.u.sint = !(smp->strm->txn.http->flags & TX_NOT_FIRST); return 1; } @@ -1369,7 +1369,7 @@ static int smp_fetch_http_auth_type(const struct arg *args, struct sample *smp, if (!htx) return 0; - txn = smp->strm->txn; + txn = smp->strm->txn.http; if (!get_http_auth(smp, htx)) return 0; @@ -1408,7 +1408,7 @@ static int smp_fetch_http_auth_user(const struct arg *args, struct sample *smp, if (!htx) return 0; - txn = smp->strm->txn; + txn = smp->strm->txn.http; if (!get_http_auth(smp, htx) || txn->auth.method != HTTP_AUTH_BASIC) return 0; @@ -1431,7 +1431,7 @@ static int smp_fetch_http_auth_pass(const struct arg *args, struct sample *smp, if (!htx) return 0; - txn = smp->strm->txn; + txn = smp->strm->txn.http; if (!get_http_auth(smp, htx) || txn->auth.method != HTTP_AUTH_BASIC) return 0; @@ -1471,7 +1471,7 @@ static int smp_fetch_http_auth_bearer(const struct arg *args, struct sample *smp } } else { - txn = smp->strm->txn; + txn = smp->strm->txn.http; if (!get_http_auth(smp, htx) || txn->auth.method != HTTP_AUTH_BEARER) return 0; @@ -1495,12 +1495,12 @@ static int smp_fetch_http_auth(const struct arg *args, struct sample *smp, const if (!htx) return 0; - if (!get_http_auth(smp, htx) || smp->strm->txn->auth.method != HTTP_AUTH_BASIC) + if (!get_http_auth(smp, htx) || smp->strm->txn.http->auth.method != HTTP_AUTH_BASIC) return 0; smp->data.type = SMP_T_BOOL; - smp->data.u.sint = check_user(args->data.usr, smp->strm->txn->auth.user, - smp->strm->txn->auth.pass); + smp->data.u.sint = check_user(args->data.usr, smp->strm->txn.http->auth.user, + smp->strm->txn.http->auth.pass); return 1; } @@ -1515,15 +1515,15 @@ static int smp_fetch_http_auth_grp(const struct arg *args, struct sample *smp, c if (!htx) return 0; - if (!get_http_auth(smp, htx) || smp->strm->txn->auth.method != HTTP_AUTH_BASIC) + if (!get_http_auth(smp, htx) || smp->strm->txn.http->auth.method != HTTP_AUTH_BASIC) return 0; /* if the user does not belong to the userlist or has a wrong password, * report that it unconditionally does not match. Otherwise we return * a string containing the username. */ - if (!check_user(args->data.usr, smp->strm->txn->auth.user, - smp->strm->txn->auth.pass)) + if (!check_user(args->data.usr, smp->strm->txn.http->auth.user, + smp->strm->txn.http->auth.pass)) return 0; /* pat_match_auth() will need the user list */ @@ -1531,8 +1531,8 @@ static int smp_fetch_http_auth_grp(const struct arg *args, struct sample *smp, c smp->data.type = SMP_T_STR; smp->flags = SMP_F_CONST; - smp->data.u.str.area = smp->strm->txn->auth.user; - smp->data.u.str.data = strlen(smp->strm->txn->auth.user); + smp->data.u.str.area = smp->strm->txn.http->auth.user; + smp->data.u.str.data = strlen(smp->strm->txn.http->auth.user); return 1; } @@ -1603,7 +1603,7 @@ static int smp_fetch_capture_req_method(const struct arg *args, struct sample *s if (!smp->strm) return 0; - txn = smp->strm->txn; + txn = smp->strm->txn.http; if (!txn || !txn->uri) return 0; @@ -1634,7 +1634,7 @@ static int smp_fetch_capture_req_uri(const struct arg *args, struct sample *smp, if (!smp->strm) return 0; - txn = smp->strm->txn; + txn = smp->strm->txn.http; if (!txn || !txn->uri) return 0; @@ -1675,7 +1675,7 @@ static int smp_fetch_capture_req_ver(const struct arg *args, struct sample *smp, vsn = get_trash_chunk(); chunk_memcat(vsn, "HTTP/", 5); - if (!get_msg_version((s && s->txn) ? &s->txn->req : NULL, NULL, vsn)) + if (!get_msg_version((s && s->txn.http) ? &s->txn.http->req : NULL, NULL, vsn)) return 0; smp->data.type = SMP_T_STR; @@ -1693,7 +1693,7 @@ static int smp_fetch_capture_res_ver(const struct arg *args, struct sample *smp, vsn = get_trash_chunk(); chunk_memcat(vsn, "HTTP/", 5); - if (!get_msg_version((s && s->txn) ? &s->txn->rsp : NULL, NULL, vsn)) + if (!get_msg_version((s && s->txn.http) ? &s->txn.http->rsp : NULL, NULL, vsn)) return 0; smp->data.type = SMP_T_STR; diff --git a/src/log.c b/src/log.c index 97f06f9ce..be06ad060 100644 --- a/src/log.c +++ b/src/log.c @@ -3959,7 +3959,7 @@ size_t sess_build_logline_orig(struct session *sess, struct stream *s, if (likely(s)) { be = s->be; - txn = s->txn; + txn = s->txn.http; be_conn = sc_conn(s->scb); status = (txn ? txn->status : 0); s_flags = s->flags; @@ -5331,7 +5331,7 @@ void strm_log(struct stream *s, struct log_orig origin) err = (s->flags & SF_REDISP) || ((s->flags & SF_ERR_MASK) > SF_ERR_LOCAL) || (((s->flags & SF_ERR_MASK) == SF_ERR_NONE) && s->conn_retries) || - ((sess->fe->mode == PR_MODE_HTTP) && s->txn && s->txn->status >= 500) || + ((sess->fe->mode == PR_MODE_HTTP) && s->txn.http && s->txn.http->status >= 500) || (origin.flags & LOG_ORIG_FL_ERROR); if (!err && (sess->fe->options2 & PR_O2_NOLOGNORM)) diff --git a/src/proxy.c b/src/proxy.c index c826397bf..1acda4457 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -4164,7 +4164,7 @@ int stream_set_backend(struct stream *s, struct proxy *be) /* If the target backend requires HTTP processing, we have to allocate * the HTTP transaction if we did not have one. */ - if (unlikely(!s->txn && be->http_needed && !http_create_txn(s))) + if (unlikely(!s->txn.http && be->http_needed && !http_create_txn(s))) return 0; } diff --git a/src/sample.c b/src/sample.c index b9a1f0782..80cd93008 100644 --- a/src/sample.c +++ b/src/sample.c @@ -4023,7 +4023,7 @@ static int sample_conv_when(const struct arg *arg_p, struct sample *smp, void *p ((strm->flags & SF_REDISP) || ((strm->flags & SF_ERR_MASK) > SF_ERR_LOCAL) || (((strm->flags & SF_ERR_MASK) == SF_ERR_NONE) && strm->conn_retries) || - ((sess->fe->mode == PR_MODE_HTTP) && strm->txn && strm->txn->status >= 500))) + ((sess->fe->mode == PR_MODE_HTTP) && strm->txn.http && strm->txn.http->status >= 500))) ret = 1; break; diff --git a/src/stconn.c b/src/stconn.c index 6f7f3be60..2941c2d1e 100644 --- a/src/stconn.c +++ b/src/stconn.c @@ -1488,7 +1488,7 @@ int sc_conn_send(struct stconn *sc) if (oc->flags & CF_STREAMER) send_flag |= CO_SFL_STREAMER; - if (s->txn && s->txn->flags & TX_L7_RETRY && !b_data(&s->txn->l7_buffer)) { + if (s->txn.http && s->txn.http->flags & TX_L7_RETRY && !b_data(&s->txn.http->l7_buffer)) { /* If we want to be able to do L7 retries, copy * the data we're about to send, so that we are able * to resend them if needed @@ -1498,23 +1498,24 @@ int sc_conn_send(struct stconn *sc) * disable the l7 retries by setting * l7_conn_retries to 0. */ - if (s->txn->req.msg_state != HTTP_MSG_DONE || b_is_large(&oc->buf)) - s->txn->flags &= ~TX_L7_RETRY; + if (s->txn.http->req.msg_state != HTTP_MSG_DONE || b_is_large(&oc->buf)) + s->txn.http->flags &= ~TX_L7_RETRY; else { if (!(s->be->options2 & PR_O2_USE_SBUF_L7_RETRY) || - !htx_copy_to_small_buffer(&s->txn->l7_buffer, &oc->buf)) { - if (b_alloc(&s->txn->l7_buffer, DB_UNLIKELY) == NULL) - s->txn->flags &= ~TX_L7_RETRY; + !htx_copy_to_small_buffer(&s->txn.http->l7_buffer, &oc->buf)) { + if (b_alloc(&s->txn.http->l7_buffer, DB_UNLIKELY) == NULL) + s->txn.http->flags &= ~TX_L7_RETRY; else { - memcpy(b_orig(&s->txn->l7_buffer), + memcpy(b_orig(&s->txn.http->l7_buffer), b_orig(&oc->buf), b_size(&oc->buf)); } } - if (s->txn->flags & TX_L7_RETRY) { - s->txn->l7_buffer.head = co_data(oc); - b_set_data(&s->txn->l7_buffer, co_data(oc)); + if (s->txn.http->flags & TX_L7_RETRY) { + s->txn.http->l7_buffer.head = co_data(oc); + b_set_data(&s->txn.http->l7_buffer, + co_data(oc)); } } } diff --git a/src/stream.c b/src/stream.c index ac9fc42d1..bb88c6288 100644 --- a/src/stream.c +++ b/src/stream.c @@ -546,7 +546,7 @@ void *stream_new(struct session *sess, struct stconn *sc, struct buffer *input) s->scb->ioto = TICK_ETERNITY; s->res.analyse_exp = TICK_ETERNITY; - s->txn = NULL; + s->txn.http = NULL; s->hlua[0] = s->hlua[1] = NULL; s->resolv_ctx.requester = NULL; @@ -683,7 +683,7 @@ void stream_free(struct stream *s) hlua_ctx_destroy(s->hlua[1]); s->hlua[0] = s->hlua[1] = NULL; - if (s->txn) + if (s->txn.http) http_destroy_txn(s); /* ensure the client-side transport layer is destroyed */ @@ -1299,8 +1299,8 @@ static int process_switching_rules(struct stream *s, struct channel *req, int an if (!(s->flags & SF_FINST_MASK)) s->flags |= SF_FINST_R; - if (s->txn) - s->txn->status = 500; + if (s->txn.http) + s->txn.http->status = 500; s->req.analysers &= AN_REQ_FLT_END; s->req.analyse_exp = TICK_ETERNITY; DBG_TRACE_DEVEL("leaving on error", STRM_EV_STRM_ANA|STRM_EV_STRM_ERR, s); @@ -1594,7 +1594,7 @@ int stream_set_http_mode(struct stream *s, const struct mux_proto_list *mux_prot s->req.analysers |= AN_REQ_WAIT_HTTP|AN_REQ_HTTP_PROCESS_FE; - if (unlikely(!s->txn && !http_create_txn(s))) + if (unlikely(!s->txn.http && !http_create_txn(s))) return 0; conn = sc_conn(sc); @@ -1913,8 +1913,8 @@ struct task *process_stream(struct task *t, void *context, unsigned int state) } /* this data may be no longer valid, clear it */ - if (s->txn) - memset(&s->txn->auth, 0, sizeof(s->txn->auth)); + if (s->txn.http) + memset(&s->txn.http->auth, 0, sizeof(s->txn.http->auth)); /* 1a: Check for low level timeouts if needed. We just set a flag on * stream connectors when their timeouts have expired. @@ -2460,8 +2460,8 @@ struct task *process_stream(struct task *t, void *context, unsigned int state) s->conn_retries = 0; if ((s->be->retry_type &~ PR_RE_CONN_FAILED) && (s->be->mode == PR_MODE_HTTP) && - !(s->txn->flags & TX_D_L7_RETRY)) - s->txn->flags |= TX_L7_RETRY; + !(s->txn.http->flags & TX_D_L7_RETRY)) + s->txn.http->flags |= TX_L7_RETRY; if (proxy_abrt_close(s->be)) { struct connection *conn = sc_conn(scf); @@ -2774,10 +2774,10 @@ struct task *process_stream(struct task *t, void *context, unsigned int state) stream_process_counters(s); - if (s->txn && s->txn->status) { + if (s->txn.http && s->txn.http->status) { int n; - n = s->txn->status / 100; + n = s->txn.http->status / 100; if (n < 1 || n > 5) n = 0; @@ -3627,14 +3627,17 @@ static void __strm_dump_to_buffer(struct buffer *buf, const struct show_sess_ctx " age=%s)\n", human_time(ns_to_sec(now_ns) - ns_to_sec(request_ts), 1)); - if (strm->txn) { + if (strm->txn.http) { chunk_appendf(buf, "%s txn=%p flags=0x%x meth=%d status=%d req.st=%s rsp.st=%s req.f=0x%02x rsp.f=0x%02x", pfx, - strm->txn, strm->txn->flags, strm->txn->meth, strm->txn->status, - h1_msg_state_str(strm->txn->req.msg_state), h1_msg_state_str(strm->txn->rsp.msg_state), - strm->txn->req.flags, strm->txn->rsp.flags); - if (ctx && (ctx->flags & CLI_SHOWSESS_F_DUMP_URI) && strm->txn->uri) - chunk_appendf(buf, " uri=\"%s\"", HA_ANON_STR(anon_key, strm->txn->uri)); + strm->txn.http, strm->txn.http->flags, + strm->txn.http->meth, strm->txn.http->status, + h1_msg_state_str(strm->txn.http->req.msg_state), + h1_msg_state_str(strm->txn.http->rsp.msg_state), + strm->txn.http->req.flags, strm->txn.http->rsp.flags); + if (ctx && (ctx->flags & CLI_SHOWSESS_F_DUMP_URI) && strm->txn.http->uri) + chunk_appendf(buf, " uri=\"%s\"", + HA_ANON_STR(anon_key, strm->txn.http->uri)); chunk_memcat(buf, "\n", 1); } @@ -4234,8 +4237,9 @@ static int cli_io_handler_dump_sess(struct appctx *appctx) if (task_in_rq(curr_strm->task)) chunk_appendf(&trash, " run(nice=%d)", curr_strm->task->nice); - if ((ctx->flags & CLI_SHOWSESS_F_DUMP_URI) && curr_strm->txn && curr_strm->txn->uri) - chunk_appendf(&trash, " uri=\"%s\"", HA_ANON_CLI(curr_strm->txn->uri)); + if ((ctx->flags & CLI_SHOWSESS_F_DUMP_URI) && curr_strm->txn.http && curr_strm->txn.http->uri) + chunk_appendf(&trash, " uri=\"%s\"", + HA_ANON_CLI(curr_strm->txn.http->uri)); chunk_appendf(&trash, "\n");