#define HTX_SL_F_HAS_AUTHORITY 0x00000400 /* The request authority is explicitly specified */
#define HTX_SL_F_NORMALIZED_URI 0x00000800 /* The received URI is normalized (an implicit absolute-uri form) */
#define HTX_SL_F_CONN_UPG 0x00001000 /* The message contains "connection: upgrade" header */
+#define HTX_SL_F_BODYLESS_RESP 0x00002000 /* The response to this message is bodyloess (only for reqyest) */
/* This function is used to report flags in debugging tools. Please reflect
* below any single-bit flag addition above in the same order via the
rxreq
txresp \
-status 200 \
- -bodylen 20000
+ -bodylen 50000
rxreq
txresp \
chunkedlen 15
chunkedlen 1024
chunkedlen 4048
+ chunkedlen 50000
chunkedlen 0
rxreq
txresp \
-status 200 \
-body "last response"
-} -repeat 2 -start
+} -repeat 3 -start
haproxy h1 -conf {
global
listen fe2
bind "fd@${fe2}"
server s1 ${h1_int_addr}:${h1_int_port} proto h2
+
+ listen fe3
+ bind "fd@${fe3}"
+ # Rewrite the method to be sure to get the response payload
+ # on the server side
+ http-request set-method GET
+ option splice-response
+ server s1 ${s1_addr}:${s1_port}
} -start
client c1 -connect ${h1_fe1_sock} {
expect resp.status == 200
expect resp.body == "last response"
} -run
+
+client c3 -connect ${h1_fe3_sock} {
+ txreq \
+ -req "HEAD" \
+ -url "/req1"
+ rxresp
+ expect resp.status == 200
+ expect resp.body == ""
+
+ txreq \
+ -req "HEAD" \
+ -url "/req2"
+ rxresp
+ expect resp.status == 200
+ expect resp.body == ""
+
+ txreq \
+ -req "HEAD" \
+ -url "/req3"
+ rxresp
+ expect resp.status == 200
+ expect resp.body == ""
+
+ # The last one have a body and validate the connection was not closed
+ # unexpectedly and no payload was received for previous requests
+ txreq \
+ -req "GET" \
+ -url "/req4"
+ rxresp
+ expect resp.status == 200
+ expect resp.body == "last response"
+} -run
{
struct htx_sl *sl;
struct ist meth, uri, vsn;
- unsigned int flags;
+ unsigned int flags = 0;
/* <h1sl> is always defined for a request */
meth = h1sl->rq.m;
h1m->flags &= ~(H1_MF_CLEN|H1_MF_CHNK);
h1m->curr_len = h1m->body_len = 0;
}
+ else if (h1sl->rq.meth == HTTP_METH_HEAD)
+ flags |= HTX_SL_F_BODYLESS_RESP;
- flags = h1m_htx_sl_flags(h1m);
+ flags |= h1m_htx_sl_flags(h1m);
if ((flags & (HTX_SL_F_CONN_UPG|HTX_SL_F_BODYLESS)) == HTX_SL_F_CONN_UPG) {
int i;
{
struct htx_sl *sl;
struct ist vsn, status, reason;
- unsigned int flags;
+ unsigned int flags = 0;
uint16_t code = 0;
if (h1sl) {
h1m->flags &= ~(H1_MF_CLEN|H1_MF_CHNK);
h1m->flags |= H1_MF_XFER_LEN;
h1m->curr_len = h1m->body_len = 0;
+ flags |= HTX_SL_F_BODYLESS_RESP;
}
else if (h1m->flags & (H1_MF_CLEN|H1_MF_CHNK)) {
/* Responses with a known body length. */
h1m->flags |= H1_MF_XFER_LEN;
}
- flags = h1m_htx_sl_flags(h1m);
+ flags |= h1m_htx_sl_flags(h1m);
sl = htx_add_stline(htx, HTX_BLK_RES_SL, flags, vsn, status, reason);
if (!sl || !htx_add_all_headers(htx, hdrs))
goto error;
}
/* Here h1s_sc(h1s) is always defined */
- if (h1m->state == H1_MSG_DATA || (h1m->state == H1_MSG_TUNNEL)) {
+ if ((!(h1m->flags & H1_MF_RESP) || !(h1s->flags & H1S_F_BODYLESS_RESP)) &&
+ (h1m->state == H1_MSG_DATA || h1m->state == H1_MSG_TUNNEL)) {
TRACE_STATE("notify the mux can use splicing", H1_EV_RX_DATA|H1_EV_RX_BODY, h1c->conn, h1s);
se_fl_set(h1s->sd, SE_FL_MAY_SPLICE);
}
h1m->flags |= H1_MF_XFER_LEN;
if (sl->flags & HTX_SL_F_BODYLESS)
h1m->flags |= H1_MF_CLEN;
- if (h1s->meth == HTTP_METH_HEAD)
+ if ((sl->flags & HTX_SL_F_BODYLESS_RESP) || h1s->meth == HTTP_METH_HEAD)
h1s->flags |= H1S_F_BODYLESS_RESP;
if (h1s->flags & H1S_F_RX_BLK) {
h1m->flags |= H1_MF_XFER_LEN;
if (h1s->status < 200)
h1s->flags |= H1S_F_HAVE_O_CONN;
- else if (h1s->status == 204 || h1s->status == 304)
+ else if ((sl->flags & HTX_SL_F_BODYLESS_RESP) || h1s->status == 204 || h1s->status == 304)
h1s->flags |= H1S_F_BODYLESS_RESP;
h1m->state = H1_MSG_HDR_NAME;
BUG_ON(sl); /* Only one start-line expected */
sl = htx_get_blk_ptr(htx, blk);
h2s->status = sl->info.res.status;
- if (h2s->status == 204 || h2s->status == 304)
+ if ((sl->flags & HTX_SL_F_BODYLESS_RESP) || 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);
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)
+ if ((sl->flags & HTX_SL_F_BODYLESS_RESP) || 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);