MINOR: mux-h1/mux-fcgi: Don't set TUNNEL mode if payload length is unknown
Responses with no C-L and T-E headers are no longer switched in TUNNEL mode
and remains in DATA mode instead. The H1 and FCGI muxes are updated
accordingly. This change reflects the real message state. It is not a true
tunnel. Data received are still part of the message.
It is not a bug. However, this message may be backported after some
observation period (at least as far as 2.2).
diff --git a/src/h1_htx.c b/src/h1_htx.c
index dc6acca..5ef995f 100644
--- a/src/h1_htx.c
+++ b/src/h1_htx.c
@@ -296,10 +296,6 @@
/* Responses with a known body length. */
h1m->flags |= H1_MF_XFER_LEN;
}
- else {
- /* Responses with an unknown body length */
- h1m->state = H1_MSG_TUNNEL;
- }
used = htx_used_space(htx);
flags = h1m_htx_sl_flags(h1m);
diff --git a/src/mux_fcgi.c b/src/mux_fcgi.c
index 765cff3..65e511b 100644
--- a/src/mux_fcgi.c
+++ b/src/mux_fcgi.c
@@ -3374,6 +3374,16 @@
else if (h1m->state < H1_MSG_TRAILERS) {
TRACE_PROTO("parsing response payload", FCGI_EV_RSP_DATA|FCGI_EV_RSP_BODY, fconn->conn, fstrm);
ret = fcgi_strm_parse_data(fstrm, h1m, &htx, &fstrm->rxbuf, &total, count, buf);
+
+ if (!(h1m->flags & H1_MF_XFER_LEN) && fstrm->state != FCGI_SS_ERROR &&
+ (fstrm->flags & FCGI_SF_ES_RCVD) && b_data(&fstrm->rxbuf) == total) {
+ TRACE_DEVEL("end of data", FCGI_EV_RSP_DATA, fconn->conn, fstrm);
+ if (!(h1m->flags & H1_MF_VER_11))
+ fstrm->flags |= FCGI_SF_H1_PARSING_DONE;
+ h1m->state = H1_MSG_DONE;
+ TRACE_USER("H1 response fully rcvd", FCGI_EV_RSP_DATA|FCGI_EV_RSP_EOM, fconn->conn, fstrm, htx);
+ }
+
if (!ret && h1m->state != H1_MSG_DONE)
break;
@@ -3402,23 +3412,6 @@
}
break;
}
- else if (h1m->state == H1_MSG_TUNNEL) {
- TRACE_PROTO("parsing response tunneled data", FCGI_EV_RSP_DATA, fconn->conn, fstrm);
- ret = fcgi_strm_parse_data(fstrm, h1m, &htx, &fstrm->rxbuf, &total, count, buf);
-
- if (fstrm->state != FCGI_SS_ERROR &&
- (fstrm->flags & FCGI_SF_ES_RCVD) && b_data(&fstrm->rxbuf) == total) {
- TRACE_DEVEL("end of tunneled data", FCGI_EV_RSP_DATA, fconn->conn, fstrm);
- if ((h1m->flags & (H1_MF_VER_11|H1_MF_XFER_LEN)) != H1_MF_VER_11)
- fstrm->flags |= FCGI_SF_H1_PARSING_DONE;
- h1m->state = H1_MSG_DONE;
- TRACE_USER("H1 response fully rcvd", FCGI_EV_RSP_DATA|FCGI_EV_RSP_EOM, fconn->conn, fstrm, htx);
- }
- if (!ret && h1m->state != H1_MSG_DONE)
- break;
-
- TRACE_PROTO("rcvd H1 response tunneled data", FCGI_EV_RSP_DATA, fconn->conn, fstrm, htx);
- }
else {
htx->flags |= HTX_FL_PROCESSING_ERROR;
TRACE_PROTO("processing error", FCGI_EV_RSP_DATA, fconn->conn, fstrm);
diff --git a/src/mux_h1.c b/src/mux_h1.c
index 19f8240..00bb6dc 100644
--- a/src/mux_h1.c
+++ b/src/mux_h1.c
@@ -1651,8 +1651,9 @@
h1s->cs->flags &= ~(CS_FL_RCV_MORE | CS_FL_WANT_ROOM);
if (h1s->flags & H1S_F_REOS) {
h1s->cs->flags |= CS_FL_EOS;
- if (h1m->state >= H1_MSG_DONE) {
- /* DONE or TUNNEL, set EOI on the conn-stream */
+ if (h1m->state >= H1_MSG_DONE || !(h1m->flags & H1_MF_XFER_LEN)) {
+ /* DONE or TUNNEL or SHUTR without XFER_LEN, set
+ * EOI on the conn-stream */
h1s->cs->flags |= CS_FL_EOI;
}
else if (h1m->state > H1_MSG_LAST_LF && h1m->state < H1_MSG_DONE)