#define H2_MSGF_BODY 0x0001 // a body is present
#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_MAX_STREAM_ID ((1U << 31) - 1)
#define H2_MAX_FRAME_LEN ((1U << 24) - 1)
sl->info.res.status = h * 100 + t * 10 + u;
+ /* On 1xx responses (except 101) 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.
+ */
+ if (sl->info.res.status < 200 &&
+ (sl->info.res.status == 100 || sl->info.res.status >= 102)) {
+ *msgf |= H2_MSGF_RSP_1XX;
+ *msgf &= ~H2_MSGF_BODY;
+ }
+
return sl;
fail:
return NULL;
}
done:
- /* indicate that a HEADERS frame was received for this stream */
- *flags |= H2_SF_HEADERS_RCVD;
+ /* indicate that a HEADERS frame was received for this stream, except
+ * for 1xx responses. For 1xx responses, another HEADERS frame is
+ * expected.
+ */
+ if (!(msgf & H2_MSGF_RSP_1XX))
+ *flags |= H2_SF_HEADERS_RCVD;
- if (h2c->dff & H2_F_HEADERS_END_STREAM) {
+ if ((h2c->dff & H2_F_HEADERS_END_STREAM) || (msgf & H2_MSGF_RSP_1XX)) {
/* Mark the end of message, either using EOM in HTX or with the
* trailing CRLF after the end of trailers. Note that DATA_CHNK
* is not set during headers with END_STREAM.
}
}
- /* we may need to add END_STREAM.
+ /* we may need to add END_STREAM except for 1xx responses.
* FIXME: we should also set it when we know for sure that the
* content-length is zero as well as on 204/304
*/
- if (blk_end && htx_get_blk_type(blk_end) == HTX_BLK_EOM)
+ if (blk_end && htx_get_blk_type(blk_end) == HTX_BLK_EOM &&
+ (h2s->status >= 200 || h2s->status == 101))
es_now = 1;
if (h2s->cs->flags & CS_FL_SHW)
/* commit the H2 response */
b_add(&h2c->mbuf, outbuf.data);
- h2s->flags |= H2_SF_HEADERS_SENT;
+
+ /* indicates the HEADERS frame was sent, except for 1xx responses. For
+ * 1xx responses, another HEADERS frame is expected.
+ */
+ if (h2s->status >= 200 || h2s->status == 101)
+ h2s->flags |= H2_SF_HEADERS_SENT;
if (es_now) {
h2s->flags |= H2_SF_ES_SENT;