]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: h1: let the caller pass the initial parser's state
authorWilly Tarreau <w@1wt.eu>
Tue, 11 Sep 2018 13:33:32 +0000 (15:33 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 12 Sep 2018 15:38:25 +0000 (17:38 +0200)
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.

src/h1.c
src/mux_h2.c

index 2fafc358c2796847134d29a1bcc56d8a40d67f70..ed589d9b75696454db3e2337b7846b7340d692ca 100644 (file)
--- 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 <stop>, at once, and converts it a list of (name,value)
  * pairs representing header fields into the array <hdr> of size <hdr_num>,
  * whose last entry will have an empty name and an empty value. If <hdr_num> is
- * too small to represent the whole message, an error is returned. If <h1m> 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 <slp>, 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 <ptr> during state <state> */
        if (slp)
                *slp = sl;
 
+       h1m->state = state;
+       h1m->next  = ptr - start + skip;
        return 0;
 
  http_msg_invalid:
        /* invalid message, error at <ptr> */
-       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 <ptr> */
-       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;
 }
 
index 4d9a7bcd2931eb7b67c0ca59a9a1055f5275f3d5..d842cd8d2e5fbbec3e7286ed657eab418c5b2b21 100644 (file)
@@ -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) {