MINOR: http-ana: Simplify creation/destruction of HTTP transactions

Now allocation and initialization of HTTP transactions are performed in a
unique function. Historically, there were two functions because the same TXN
was reset for K/A connections in the legacy HTTP mode. Now, in HTX, K/A
connections are handled at the mux level. A new stream, and thus a new TXN,
is created for each request. In addition, the function responsible to end
the TXN is now also reponsible to release it.

So, now, http_create_txn() and http_destroy_txn() must be used to create and
destroy an HTTP transaction.
This commit is contained in:
Christopher Faulet 2021-03-08 19:12:58 +01:00
parent c2ac5e4f27
commit 75f619ad92
6 changed files with 25 additions and 39 deletions

View File

@ -57,9 +57,8 @@ int http_reply_to_htx(struct stream *s, struct htx *htx, struct http_reply *repl
int http_reply_message(struct stream *s, struct http_reply *reply);
int http_forward_proxy_resp(struct stream *s, int final);
struct http_txn *http_alloc_txn(struct stream *s);
void http_init_txn(struct stream *s);
void http_end_txn(struct stream *s);
struct http_txn *http_create_txn(struct stream *s);
void http_destroy_txn(struct stream *s);
/* for debugging, reports the HTTP/1 message state name (legacy version) */
static inline const char *h1_msg_state_str(enum h1_state msg_state)

View File

@ -145,17 +145,8 @@ int frontend_accept(struct stream *s)
goto out_free_reqcap; /* no memory */
}
if (fe->http_needed || IS_HTX_STRM(s)) {
/* we have to allocate header indexes only if we know
* that we may make use of them. This of course includes
* (mode == PR_MODE_HTTP).
*/
if (unlikely(!http_alloc_txn(s)))
goto out_free_rspcap; /* no memory */
/* and now initialize the HTTP transaction state */
http_init_txn(s);
}
if ((fe->http_needed || IS_HTX_STRM(s)) && !http_create_txn(s))
goto out_free_rspcap;
/* everything's OK, let's go on */
return 1;

View File

@ -5044,15 +5044,20 @@ void http_txn_reset_res(struct http_txn *txn)
}
/*
* Initialize a new HTTP transaction for stream <s>. It is assumed that all
* the required fields are properly allocated and that we only need to (re)init
* them. This should be used before processing any new request.
* Create and initialize a new HTTP transaction for stream <s>. This should be
* used before processing any new request. It returns the transaction or NLULL
* on error.
*/
void http_init_txn(struct stream *s)
struct http_txn *http_create_txn(struct stream *s)
{
struct http_txn *txn = s->txn;
struct http_txn *txn;
struct conn_stream *cs = objt_cs(s->si[0].end);
txn = pool_alloc(pool_head_http_txn);
if (!txn)
return NULL;
s->txn = txn;
txn->flags = ((cs && cs->flags & CS_FL_NOT_FIRST) ? TX_NOT_FIRST : 0);
txn->status = -1;
txn->http_reply = NULL;
@ -5075,10 +5080,12 @@ void http_init_txn(struct stream *s)
vars_init(&s->vars_txn, SCOPE_TXN);
vars_init(&s->vars_reqres, SCOPE_REQ);
return txn;
}
/* to be used at the end of a transaction */
void http_end_txn(struct stream *s)
void http_destroy_txn(struct stream *s)
{
struct http_txn *txn = s->txn;
@ -5097,6 +5104,9 @@ void http_end_txn(struct stream *s)
vars_prune(&s->vars_txn, s->sess, s);
if (!LIST_ISEMPTY(&s->vars_reqres.head))
vars_prune(&s->vars_reqres, s->sess, s);
pool_free(pool_head_http_txn, txn);
s->txn = NULL;
}

View File

@ -208,12 +208,8 @@ struct htx *smp_prefetch_htx(struct sample *smp, struct channel *chn, struct che
return NULL;
}
if (!s->txn) {
if (unlikely(!http_alloc_txn(s)))
return NULL; /* not enough memory */
http_init_txn(s);
txn = s->txn;
}
if (!s->txn && !http_create_txn(s))
return NULL;
txn = s->txn;
msg = (!(chn->flags & CF_ISRESP) ? &txn->req : &txn->rsp);

View File

@ -2145,13 +2145,8 @@ 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)) {
if (unlikely(!http_alloc_txn(s)))
return 0; /* not enough memory */
/* and now initialize the HTTP transaction state */
http_init_txn(s);
}
if (unlikely(!s->txn && be->http_needed && !http_create_txn(s)))
return 0;
if (s->txn) {
/* If we chain a TCP frontend to an HTX backend, we must upgrade

View File

@ -658,7 +658,7 @@ static void stream_free(struct stream *s)
hlua_ctx_destroy(s->hlua);
s->hlua = NULL;
if (s->txn)
http_end_txn(s);
http_destroy_txn(s);
/* ensure the client-side transport layer is destroyed */
if (cli_cs)
@ -671,11 +671,6 @@ static void stream_free(struct stream *s)
s->store[i].ts = NULL;
}
if (s->txn) {
pool_free(pool_head_http_txn, s->txn);
s->txn = NULL;
}
if (s->resolv_ctx.requester) {
__decl_thread(struct resolvers *resolvers = s->resolv_ctx.parent->arg.resolv.resolvers);