From: Willy Tarreau Date: Tue, 11 Sep 2018 13:33:32 +0000 (+0200) Subject: MEDIUM: h1: let the caller pass the initial parser's state X-Git-Tag: v1.9-dev2~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4433c083ec480c22dfdb5fd934a5bc8fb7536242;p=thirdparty%2Fhaproxy.git MEDIUM: h1: let the caller pass the initial parser's state This way the caller controls if it's the request or response which has to be used, and it will allow to restart after an incomplete parsing. --- diff --git a/src/h1.c b/src/h1.c index 2fafc358c2..ed589d9b75 100644 --- a/src/h1.c +++ b/src/h1.c @@ -663,12 +663,14 @@ void http_msg_analyzer(struct http_msg *msg, struct hdr_idx *idx) * and ending before , at once, and converts it a list of (name,value) * pairs representing header fields into the array of size , * whose last entry will have an empty name and an empty value. If is - * too small to represent the whole message, an error is returned. If is - * not NULL, some protocol elements such as content-length and transfer-encoding - * will be parsed and stored there as well. + * too small to represent the whole message, an error is returned. Some + * protocol elements such as content-length and transfer-encoding will be + * parsed and stored into h1m as well. * * For now it's limited to the response. If the header block is incomplete, * 0 is returned, waiting to be called again with more data to try it again. + * The caller is responsible for initializing h1m->state to H1_MSG_RPBEFORE, + * and h1m->next to zero. * * A pointer to a start line descriptor may be passed in , in which case * the parser will fill it with whatever it found. @@ -698,8 +700,8 @@ int h1_headers_to_hdr_list(char *start, const char *stop, struct http_hdr *hdr, unsigned int hdr_num, struct h1m *h1m, union h1_sl *slp) { - enum h1m_state state = H1_MSG_RPBEFORE; - register char *ptr = start; + enum h1m_state state = h1m->state; + register char *ptr = start + h1m->next; register const char *end = stop; unsigned int hdr_count = 0; unsigned int sol = 0; /* start of line */ @@ -1051,37 +1053,35 @@ int h1_headers_to_hdr_list(char *start, const char *stop, if (slp) *slp = sl; - return ptr - start + skip; + h1m->state = state; + h1m->next = ptr - start + skip; + return h1m->next; http_msg_ood: /* out of data at during state */ if (slp) *slp = sl; + h1m->state = state; + h1m->next = ptr - start + skip; return 0; http_msg_invalid: /* invalid message, error at */ - if (h1m) { - h1m->err_state = state; - h1m->err_pos = ptr - start + skip; - } - if (slp) *slp = sl; + h1m->err_state = h1m->state = state; + h1m->err_pos = h1m->next = ptr - start + skip; return -1; http_output_full: /* no more room to store the current header, error at */ - if (h1m) { - h1m->err_state = state; - h1m->err_pos = ptr - start + skip; - } - if (slp) *slp = sl; + h1m->err_state = h1m->state = state; + h1m->err_pos = h1m->next = ptr - start + skip; return -2; } diff --git a/src/mux_h2.c b/src/mux_h2.c index 4d9a7bcd29..d842cd8d2e 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -3103,6 +3103,8 @@ static size_t h2s_frt_make_resp_headers(struct h2s *h2s, const struct buffer *bu * block does not wrap and we can safely read it this way without * having to realign the buffer. */ + h1m->state = H1_MSG_RPBEFORE; + h1m->next = 0; ret = h1_headers_to_hdr_list(b_peek(buf, ofs), b_peek(buf, ofs) + max, list, sizeof(list)/sizeof(list[0]), h1m, NULL); if (ret <= 0) {