diff --git a/include/proto/h1.h b/include/proto/h1.h index e6a4204ff..fb040d138 100644 --- a/include/proto/h1.h +++ b/include/proto/h1.h @@ -150,7 +150,6 @@ static inline const char *h1m_state_str(enum h1_state msg_state) case H1_MSG_HDR_L2_LF: return "MSG_HDR_L2_LF"; case H1_MSG_HDR_L2_LWS: return "MSG_HDR_L2_LWS"; case H1_MSG_LAST_LF: return "MSG_LAST_LF"; - case H1_MSG_BODY: return "MSG_BODY"; case H1_MSG_CHUNK_SIZE: return "MSG_CHUNK_SIZE"; case H1_MSG_DATA: return "MSG_DATA"; case H1_MSG_CHUNK_CRLF: return "MSG_CHUNK_CRLF"; diff --git a/include/types/h1.h b/include/types/h1.h index c6c97dcbd..26eafd339 100644 --- a/include/types/h1.h +++ b/include/types/h1.h @@ -120,21 +120,17 @@ enum h1m_state { H1_MSG_HDR_L2_LF = 23, // parsing header LWS (LF) inside/after value H1_MSG_HDR_L2_LWS = 24, // checking whether it's a new header or an LWS - H1_MSG_LAST_LF = 25, // parsing last LF + H1_MSG_LAST_LF = 25, // parsing last LF, last state for headers - /* Body processing. - * The state H1_MSG_BODY is a delimiter to know if we're waiting for headers - * or body. All the sub-states below also indicate we're processing the body, - * with some additional information. - */ - H1_MSG_BODY = 26, // parsing body at end of headers - H1_MSG_CHUNK_SIZE = 27, // parsing the chunk size (RFC7230 #4.1) - H1_MSG_DATA = 28, // skipping data chunk / content-length data - H1_MSG_CHUNK_CRLF = 29, // skipping CRLF after data chunk - H1_MSG_TRAILERS = 30, // trailers (post-data entity headers) + /* Body processing. */ + + H1_MSG_CHUNK_SIZE = 26, // parsing the chunk size (RFC7230 #4.1) + H1_MSG_DATA = 27, // skipping data chunk / content-length data + H1_MSG_CHUNK_CRLF = 28, // skipping CRLF after data chunk + H1_MSG_TRAILERS = 29, // trailers (post-data entity headers) /* we enter this state when we've received the end of the current message */ - H1_MSG_DONE = 31, // message end received, waiting for resync or close - H1_MSG_TUNNEL = 32, // tunneled data after DONE + H1_MSG_DONE = 30, // message end received, waiting for resync or close + H1_MSG_TUNNEL = 31, // tunneled data after DONE } __attribute__((packed)); diff --git a/src/h1.c b/src/h1.c index d88408efe..fc0b8da58 100644 --- a/src/h1.c +++ b/src/h1.c @@ -1073,7 +1073,21 @@ int h1_headers_to_hdr_list(char *start, const char *stop, } http_set_hdr(&hdr[hdr_count++], ist(""), ist("")); } - state = H1_MSG_BODY; + + /* reaching here we've parsed the whole message. We may detect + * that we were already continuing an interrupted parsing pass + * so we were silently looking for the end of message not + * updating anything before deciding to parse it fully at once. + * It's guaranteed that we won't match this test twice in a row + * since restarting will turn zero. + */ + if (restarting) + goto restart; + + if (h1m->flags & H1_MF_CHNK) + state = H1_MSG_CHUNK_SIZE; + else + state = H1_MSG_DATA; break; default: @@ -1081,14 +1095,9 @@ int h1_headers_to_hdr_list(char *start, const char *stop, goto http_msg_invalid; } - /* reaching here, we've parsed the whole message and the state is - * H1_MSG_BODY. We may discover that we were already continuing an - * interrupted parsing session, thus we were silently looking for - * the end of message before deciding to parse it fully at once. - * We won't come there again since restarting will turn zero. + /* Now we've left the headers state and are either in H1_MSG_DATA or + * H1_MSG_CHUNK_SIZE. */ - if (restarting) - goto restart; if (slp && !skip_update) *slp = sl; diff --git a/src/mux_h2.c b/src/mux_h2.c index d842cd8d2..922cabefe 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -3237,8 +3237,8 @@ static size_t h2s_frt_make_resp_headers(struct h2s *h2s, const struct buffer *bu h1m->err_pos = -1; // don't care about errors on the response path goto end; } - else - h1m->state = (h1m->flags & H1_MF_CHNK) ? H1_MSG_CHUNK_SIZE : H1_MSG_BODY; + + /* now the h1m state is either H1_MSG_CHUNK_SIZE or H1_MSG_DATA */ end: //fprintf(stderr, "[%d] sent simple H2 response (sid=%d) = %d bytes (%d in, ep=%u, es=%s)\n", h2c->st0, h2s->id, outbuf.len, ret, h1m->err_pos, h1_msg_state_str(h1m->err_state)); @@ -3568,7 +3568,7 @@ static size_t h2_snd_buf(struct conn_stream *cs, struct buffer *buf, size_t coun h2s->flags |= H2_SF_OUTGOING_DATA; while (h2s->h1m.state < H1_MSG_DONE && count) { - if (h2s->h1m.state < H1_MSG_BODY) { + if (h2s->h1m.state <= H1_MSG_LAST_LF) { ret = h2s_frt_make_resp_headers(h2s, buf, total, count); } else if (h2s->h1m.state < H1_MSG_TRAILERS) {