MINOR: http: factor 103 emission into start/end helpers

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.
This commit is contained in:
Maxime Henrion 2026-06-26 16:43:12 -04:00 committed by Willy Tarreau
parent e1b02eba9b
commit 7f3c30d96c
3 changed files with 46 additions and 19 deletions

View 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);

View 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))
if (!http_early_hint_end(s))
goto error;
if (!http_forward_proxy_resp(s, 0))
goto error;
s->txn.http->status = 0;
}
leave:

View 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)
{