]> git.kaiwu.me - haproxy.git/commitdiff
MINOR: http: factor 103 emission into start/end helpers
authorMaxime Henrion <mhenrion@haproxy.com>
Fri, 26 Jun 2026 20:43:12 +0000 (16:43 -0400)
committerWilly Tarreau <w@1wt.eu>
Fri, 10 Jul 2026 14:42:35 +0000 (16:42 +0200)
Pull the 103 emission code out of http_action_early_hint() and split
it into http_early_hint_start() (open the response and return the htx)
and http_early_hint_end() (close with EOH and forward). The split
shape lets callers add their own Link headers in between, which is
what the HTTP cache will need when it gets support for sending 103
Early Hints from cached responses.

include/haproxy/http_ana.h
src/http_act.c
src/http_ana.c

index 6215c50cc8ce4efb81b50a7d68cc912dc3596180..4dd80e64743562726fb179bcaeee7780d213bacf 100644 (file)
@@ -58,6 +58,8 @@ struct http_reply *http_error_message(struct stream *s);
 int http_reply_to_htx(struct stream *s, struct htx *htx, struct http_reply *reply);
 int http_reply_message(struct stream *s, struct http_reply *reply);
 int http_forward_proxy_resp(struct stream *s, int final);
+struct htx *http_early_hint_start(struct stream *s);
+int http_early_hint_end(struct stream *s);
 
 struct http_txn *http_create_txn(struct stream *s);
 void http_destroy_txn(struct stream *s);
index 7b6914909ab87f718e7a0944197dec4138547521..bf0d9a47c62d4390170f55cf6cf5ccebcd237d2f 100644 (file)
@@ -1370,21 +1370,8 @@ static enum act_return http_action_early_hint(struct act_rule *rule, struct prox
                goto error;
        }
 
-       /* if there is no pending 103 response, start a new response. Otherwise,
-        * continue to add link to a previously started response
-         */
-       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);
-
-               sl = htx_add_stline(htx, HTX_BLK_RES_SL, flags,
-                                   ist("HTTP/1.1"), ist("103"), ist("Early Hints"));
-               if (!sl)
-                       goto error;
-               sl->info.res.status = 103;
-               s->txn.http->status = 103;
-       }
+       if (!http_early_hint_start(s))
+               goto error;
 
        /* Add the HTTP Early Hint HTTP 103 response header */
        value->data = build_logline(s, b_tail(value), b_room(value), &rule->arg.http.fmt);
@@ -1396,11 +1383,8 @@ static enum act_return http_action_early_hint(struct act_rule *rule, struct prox
         */
        next_rule = LIST_NEXT(&rule->list, typeof(rule), list);
        if (&next_rule->list == s->current_rule_list || next_rule->action_ptr != http_action_early_hint || next_rule->cond) {
-               if (!htx_add_endof(htx, HTX_BLK_EOH))
-                       goto error;
-               if (!http_forward_proxy_resp(s, 0))
+               if (!http_early_hint_end(s))
                        goto error;
-               s->txn.http->status = 0;
        }
 
   leave:
index 4806afd653793f447f1f7dc6bb4d33d4035ca628..749f7919eaeea32b34dc8bde8d77e54aeda15ba2 100644 (file)
@@ -4765,6 +4765,47 @@ int http_forward_proxy_resp(struct stream *s, int final)
        return 1;
 }
 
+/*
+ * Start a 103 Early Hints response in the response buffer if not already in
+ * progress (txn->status != 103). The caller is responsible for skipping this
+ * call for HTTP/1.0 clients. Returns the htx to which the caller can add Link
+ * headers, or NULL on error.
+ */
+struct htx *http_early_hint_start(struct stream *s)
+{
+       struct htx *htx = htx_from_buf(&s->res.buf);
+
+       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);
+
+               sl = htx_add_stline(htx, HTX_BLK_RES_SL, flags,
+                                   ist("HTTP/1.1"), ist("103"), ist("Early Hints"));
+               if (!sl)
+                       return NULL;
+               sl->info.res.status = 103;
+               s->txn.http->status = 103;
+       }
+       return htx;
+}
+
+/*
+ * Finalize a 103 Early Hints response. Returns 1 on success, 0 on error
+ * (caller is responsible for truncating the response buffer on failure).
+ */
+int http_early_hint_end(struct stream *s)
+{
+       struct htx *htx = htxbuf(&s->res.buf);
+
+       if (!htx_add_endof(htx, HTX_BLK_EOH))
+               return 0;
+       if (!http_forward_proxy_resp(s, 0))
+               return 0;
+       s->txn.http->status = 0;
+       return 1;
+}
+
 void http_server_error(struct stream *s, struct stconn *sc, int err,
                       int finst, struct http_reply *msg)
 {