error = h2c_dec_hdrs(h2c, &rxbuf, &flags, &body_len, NULL);
- /* unrecoverable error ? */
- if (h2c->st0 >= H2_CS_ERROR) {
- /* This is mainly used for completeness, but a stream error is
- * currently not set by h2c_dec_hdrs().
- */
- TRACE_USER("Unrecoverable error decoding H2 request", H2_EV_RX_FRAME|H2_EV_RX_HDR|H2_EV_STRM_NEW|H2_EV_STRM_END, h2c->conn, 0, &rxbuf);
- goto strm_err;
+ if (error == 0) {
+ /* No error but missing data for demuxing, it is an incomplete frame */
+ if (!(h2c->flags &H2_CF_DEM_BLOCK_ANY))
+ h2c->flags |= H2_CF_DEM_SHORT_READ;
+ goto out;
}
- if (error <= 0) {
- if (error == 0) {
- /* Demux not blocked because of the stream, it is an incomplete frame */
- if (!(h2c->flags &H2_CF_DEM_BLOCK_ANY))
- h2c->flags |= H2_CF_DEM_SHORT_READ;
- goto out; // missing data
- }
+ /* Now we cannot roll back and we won't come back here anymore for this
+ * stream, so this stream ID is open from a protocol perspective, even
+ * if incomplete or broken, we want to count it as attempted.
+ */
+ if (h2c->dsi > h2c->max_id)
+ h2c->max_id = h2c->dsi;
+ h2c->stream_cnt++;
- /* Failed to decode this stream (e.g. too large request)
- * but the HPACK decompressor is still synchronized.
+ if (error < 0) {
+ /* Failed to decode this stream. This might be due to a
+ * recoverable error affecting only the stream (e.g. too large
+ * request for buffer, that leaves the HPACK decompressor still
+ * synchronized), or a non-recoverable error such as an invalid
+ * frame type sequence (e.g. other frame type interleaved with
+ * CONTINUATION), in which h2c_dec_hdrs() has already set the
+ * error code in the connection and counted it in the relevant
+ * stats. We still count a req error in both cases.
*/
+ sess_log(h2c->conn->owner);
+ session_inc_http_req_ctr(h2c->conn->owner);
+ session_inc_http_err_ctr(h2c->conn->owner);
+
+ if (h2c->st0 >= H2_CS_ERROR) {
+ TRACE_USER("Unrecoverable error decoding H2 request", H2_EV_RX_FRAME|H2_EV_RX_HDR|H2_EV_STRM_NEW|H2_EV_STRM_END, h2c->conn, 0, &rxbuf);
+ goto out;
+ }
+
+ /* recoverable stream error (e.g. too large request) */
TRACE_USER("rcvd unparsable H2 request", H2_EV_RX_FRAME|H2_EV_RX_HDR|H2_EV_STRM_NEW|H2_EV_STRM_END, h2c->conn, h2s, &rxbuf);
goto strm_err;
}
TRACE_USER("rcvd H2 request ", H2_EV_RX_FRAME|H2_EV_RX_HDR|H2_EV_STRM_NEW, h2c->conn, 0, &rxbuf);
- /* Now we cannot roll back and we won't come back here anymore for this
- * stream, this stream ID is open.
- */
- if (h2c->dsi > h2c->max_id)
- h2c->max_id = h2c->dsi;
- h2c->stream_cnt++;
-
/* Note: we don't emit any other logs below because if we return
* positively from h2c_frt_stream_new(), the stream will report the error,
* and if we return in error, h2c_frt_stream_new() will emit the error.
goto leave;
strm_err:
- sess_log(h2c->conn->owner);
- session_inc_http_req_ctr(h2c->conn->owner);
- session_inc_http_err_ctr(h2c->conn->owner);
-
h2s = (struct h2s*)h2_error_stream;
- /* This stream ID is now opened anyway until we send the RST on
- * it, it must not be reused.
- */
- if (h2c->dsi > h2c->max_id)
- h2c->max_id = h2c->dsi;
- h2c->stream_cnt++;
-
send_rst:
/* make the demux send an RST for the current stream. We may only
* do this if we're certain that the HEADERS frame was properly