]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: http-ana: Simplify creation/destruction of HTTP transactions
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 8 Mar 2021 18:12:58 +0000 (19:12 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 1 Apr 2021 09:06:48 +0000 (11:06 +0200)
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.

include/haproxy/http_ana.h
src/frontend.c
src/http_ana.c
src/http_fetch.c
src/proxy.c
src/stream.c

index ce28a7cdc3bf9b0fb5dd72d06e3adbb77ccd1c18..d34fa56360b33e819bd96fdd41374b98fbf1f8e4 100644 (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)
index 93c8a8637792ec54cc4397d4c1d2d6ae19c48109..a8ed2c4884fdfce31b6b1ee59b6dbab59dba3236 100644 (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;
index b0067c307a419122df4206aad785b615769bfb44..51445e996bca4443c1d530878def55b20337ac45 100644 (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;
 }
 
 
index 6c569a75bb877f2716c39545602559301ca8428d..a4db061c16130885b0288af75c99c56213ee8cbf 100644 (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);
 
index d044150c077901044559e9e0a7681b2e3b7c6601..cd7ba512e9c12e0c312aa9b72906ca822b286066 100644 (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
index eb648077439706bfd2cc7578c9698e9d78320ec4..8b8e26da14bc2f1dc8bcfe2846194f8d42e4cb5a 100644 (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);