H2_CS_SETTINGS1, // preface OK, waiting for first settings frame
H2_CS_FRAME_H, // first settings frame ok, waiting for frame header
H2_CS_FRAME_P, // frame header OK, waiting for frame payload
- H2_CS_FRAME_A, // frame payload OK, trying to send ACK/RST frame
+ H2_CS_FRAME_A, // frame payload OK, trying to send ACK frame
+ H2_CS_FRAME_E, // frame payload OK, trying to send RST frame
H2_CS_ERROR, // send GOAWAY(errcode) and close the connection ASAP
H2_CS_ERROR2, // GOAWAY(errcode) sent, close the connection ASAP
H2_CS_ENTRIES // must be last
strm_err:
if (h2s) {
h2s_error(h2s, error);
- h2c->st0 = H2_CS_FRAME_A;
+ h2c->st0 = H2_CS_FRAME_E;
}
else
h2c_error(h2c, error);
if (h2s->st >= H2_SS_ERROR) {
/* stream error : send RST_STREAM */
- h2c->st0 = H2_CS_FRAME_A;
+ h2c->st0 = H2_CS_FRAME_E;
}
else {
/* update the max stream ID if the request is being processed */
strm_err:
if (h2s) {
h2s_error(h2s, error);
- h2c->st0 = H2_CS_FRAME_A;
+ h2c->st0 = H2_CS_FRAME_E;
}
else
h2c_error(h2c, error);
if (h2s->st >= H2_SS_ERROR) {
/* stream error : send RST_STREAM */
- h2c->st0 = H2_CS_FRAME_A;
+ h2c->st0 = H2_CS_FRAME_E;
}
/* check for completion : the callee will change this to FRAME_A or
strm_err:
if (h2s) {
h2s_error(h2s, error);
- h2c->st0 = H2_CS_FRAME_A;
+ h2c->st0 = H2_CS_FRAME_E;
}
else
h2c_error(h2c, error);
h2_skip_frame_hdr(h2c->dbuf);
}
+ if (h2c->st0 == H2_CS_FRAME_E)
+ goto strm_err;
+
/* Only H2_CS_FRAME_P and H2_CS_FRAME_A here */
h2s = h2c_st_by_id(h2c, h2c->dsi);
* this state MUST be treated as a stream error
*/
h2s_error(h2s, H2_ERR_STREAM_CLOSED);
+ h2c->st0 = H2_CS_FRAME_E;
goto strm_err;
}
* we have nowhere to store the partial HEADERS frame.
* Let's abort the stream on an INTERNAL_ERROR here.
*/
- if (h2c->st0 == H2_CS_FRAME_P)
+ if (h2c->st0 == H2_CS_FRAME_P) {
h2s_error(h2s, H2_ERR_INTERNAL_ERROR);
+ h2c->st0 = H2_CS_FRAME_E;
+ }
break;
case H2_FT_HEADERS:
}
strm_err:
- /* RST are sent similarly to frame acks */
- if (h2s->st == H2_SS_ERROR) {
- if (h2c->st0 == H2_CS_FRAME_P)
- h2c->st0 = H2_CS_FRAME_A;
+ /* We may have to send an RST if not done yet */
+ if (h2s->st == H2_SS_ERROR)
+ h2c->st0 = H2_CS_FRAME_E;
- if (h2c->st0 == H2_CS_FRAME_A)
- ret = h2c_send_rst_stream(h2c, h2s);
- }
+ if (h2c->st0 == H2_CS_FRAME_E)
+ ret = h2c_send_rst_stream(h2c, h2s);
/* error or missing data condition met above ? */
if (ret <= 0)
if (!h2c->dfl) {
h2s_error(h2s, H2_ERR_PROTOCOL_ERROR); // empty headers frame!
+ h2c->st0 = H2_CS_FRAME_E;
return 0;
}