mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-21 05:41:26 +02:00
MINOR: h2/mux-h2: Add flags to notify the response is known to have no body
The H2 message flag H2_MSGF_BODYLESS_RSP is now used during the request or the response parsing to notify the mux that, considering the parsed message, the response is known to have no body. This happens during HEAD requests parsing and during 204/304 responses parsing. On the H2 multiplexer, the equivalent flag is set on H2 streams. Thus the H2_SF_BODYLESS_RESP flag is set on a H2 stream if the H2_MSGF_BODYLESS_RSP is found after a HEADERS frame parsing. Conversely, this flag is also set when a HEADERS frame is emitted for HEAD requests and for 204/304 responses. The H2_SF_BODYLESS_RESP flag will be used to ignore data payload from the response but not the trailers.
This commit is contained in:
parent
f3e7619041
commit
7d247f0771
@ -177,6 +177,8 @@ enum h2_err {
|
||||
#define H2_MSGF_BODY_CL 0x0002 // content-length is present
|
||||
#define H2_MSGF_BODY_TUNNEL 0x0004 // a tunnel is in use (CONNECT)
|
||||
#define H2_MSGF_RSP_1XX 0x0010 // a 1xx ( != 101) HEADERS frame was received
|
||||
#define H2_MSGF_BODYLESS_RSP 0x0020 // response message is known to have no body
|
||||
// (response to HEAD request or 204/304 response)
|
||||
|
||||
#define H2_MAX_STREAM_ID ((1U << 31) - 1)
|
||||
#define H2_MAX_FRAME_LEN ((1U << 24) - 1)
|
||||
|
8
src/h2.c
8
src/h2.c
@ -294,6 +294,8 @@ static struct htx_sl *h2_prepare_htx_reqline(uint32_t fields, struct ist *phdr,
|
||||
goto fail;
|
||||
|
||||
sl->info.req.meth = find_http_meth(phdr[H2_PHDR_IDX_METH].ptr, phdr[H2_PHDR_IDX_METH].len);
|
||||
if (sl->info.req.meth == HTTP_METH_HEAD)
|
||||
*msgf |= H2_MSGF_BODYLESS_RSP;
|
||||
return sl;
|
||||
fail:
|
||||
return NULL;
|
||||
@ -547,6 +549,8 @@ static struct htx_sl *h2_prepare_htx_stsline(uint32_t fields, struct ist *phdr,
|
||||
* On 1xx responses there is no ES on the HEADERS frame but there is no
|
||||
* body. So remove the flag H2_MSGF_BODY and add H2_MSGF_RSP_1XX to
|
||||
* notify the decoder another HEADERS frame is expected.
|
||||
* 204/304 resposne have no body by definition. So remove the flag
|
||||
* H2_MSGF_BODY and set H2_MSGF_BODYLESS_RSP.
|
||||
*/
|
||||
if (status == 101)
|
||||
goto fail;
|
||||
@ -554,6 +558,10 @@ static struct htx_sl *h2_prepare_htx_stsline(uint32_t fields, struct ist *phdr,
|
||||
*msgf |= H2_MSGF_RSP_1XX;
|
||||
*msgf &= ~H2_MSGF_BODY;
|
||||
}
|
||||
else if (sl->info.res.status == 204 || sl->info.res.status == 304) {
|
||||
*msgf &= ~H2_MSGF_BODY;
|
||||
*msgf |= H2_MSGF_BODYLESS_RSP;
|
||||
}
|
||||
|
||||
/* Set HTX start-line flags */
|
||||
flags |= HTX_SL_F_VER_11; // V2 in fact
|
||||
|
@ -179,7 +179,7 @@ enum h2_ss {
|
||||
|
||||
/* stream flags indicating how data is supposed to be sent */
|
||||
#define H2_SF_DATA_CLEN 0x00000100 // data sent using content-length
|
||||
/* unused flags: 0x00000200 */
|
||||
#define H2_SF_BODYLESS_RESP 0x00000200 /* Bodyless response message */
|
||||
#define H2_SF_BODY_TUNNEL 0x00000400 // Attempt to establish a Tunnelled stream (the result depends on the status code)
|
||||
|
||||
|
||||
@ -4701,6 +4701,8 @@ next_frame:
|
||||
htx->extra = *body_len;
|
||||
}
|
||||
}
|
||||
if (msgf & H2_MSGF_BODYLESS_RSP)
|
||||
*flags |= H2_SF_BODYLESS_RESP;
|
||||
|
||||
if (msgf & H2_MSGF_BODY_TUNNEL)
|
||||
*flags |= H2_SF_BODY_TUNNEL;
|
||||
@ -4942,6 +4944,8 @@ static size_t h2s_frt_make_resp_headers(struct h2s *h2s, struct htx *htx)
|
||||
}
|
||||
sl = htx_get_blk_ptr(htx, blk);
|
||||
h2s->status = sl->info.res.status;
|
||||
if (h2s->status == 204 || h2s->status == 304)
|
||||
h2s->flags |= H2_SF_BODYLESS_RESP;
|
||||
if (h2s->status < 100 || h2s->status > 999) {
|
||||
TRACE_ERROR("will not encode an invalid status code", H2_EV_TX_FRAME|H2_EV_TX_HDR|H2_EV_H2S_ERR, h2c->conn, h2s);
|
||||
goto fail;
|
||||
@ -5165,6 +5169,8 @@ static size_t h2s_bck_make_req_headers(struct h2s *h2s, struct htx *htx)
|
||||
sl = htx_get_blk_ptr(htx, blk);
|
||||
meth = htx_sl_req_meth(sl);
|
||||
uri = htx_sl_req_uri(sl);
|
||||
if (sl->info.req.meth == HTTP_METH_HEAD)
|
||||
h2s->flags |= H2_SF_BODYLESS_RESP;
|
||||
if (unlikely(uri.len == 0)) {
|
||||
TRACE_ERROR("no URI in HTX request", H2_EV_TX_FRAME|H2_EV_TX_HDR|H2_EV_H2S_ERR, h2c->conn, h2s);
|
||||
goto fail;
|
||||
|
Loading…
x
Reference in New Issue
Block a user