]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: h1: add H1_MF_TOLOWER to decide when to turn header names to lower case
authorWilly Tarreau <w@1wt.eu>
Wed, 12 Sep 2018 07:54:00 +0000 (09:54 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 12 Sep 2018 15:38:26 +0000 (17:38 +0200)
The h1 parser used to systematically turn header field names to lower
case because it was designed for H2. Let's add a flag which is off by
default to condition this behaviour so that when using it from an H1
parser it will not affect the message.

include/types/h1.h
src/h1.c
src/mux_h2.c

index ec8cca0e207e3d9af7f9fe62265bcc2114507713..2dd58dd699925992a02c7298d9729194b1e2048d 100644 (file)
@@ -139,6 +139,7 @@ enum h1m_state {
 #define H1_MF_CLEN              0x00000001 // content-length present
 #define H1_MF_CHNK              0x00000002 // chunk present, exclusive with c-l
 #define H1_MF_RESP              0x00000004 // this message is the response message
+#define H1_MF_TOLOWER           0x00000008 // turn the header names to lower case
 
 
 /* basic HTTP/1 message state for use in parsers. The err_pos field is special,
index db717896e7bb69b78ef321c2ebb2b0cfa3a526d8..47af9be32dea7914c813eb46b10414bfbd2b1f26 100644 (file)
--- a/src/h1.c
+++ b/src/h1.c
@@ -1082,7 +1082,7 @@ int h1_headers_to_hdr_list(char *start, const char *stop,
                /* assumes sol points to the first char */
                if (likely(HTTP_IS_TOKEN(*ptr))) {
                        /* turn it to lower case if needed */
-                       if (isupper((unsigned char)*ptr))
+                       if (isupper((unsigned char)*ptr) && h1m->flags & H1_MF_TOLOWER)
                                *ptr = tolower(*ptr);
                        EAT_AND_JUMP_OR_RETURN(ptr, end, http_msg_hdr_name, http_msg_ood, state, H1_MSG_HDR_NAME);
                }
@@ -1231,11 +1231,11 @@ int h1_headers_to_hdr_list(char *start, const char *stop,
                                h1m->flags |= H1_MF_CLEN;
                                h1m->curr_len = h1m->body_len = 0;
                        }
-                       else if (isteq(n, ist("transfer-encoding"))) {
+                       else if (isteqi(n, ist("transfer-encoding"))) {
                                h1m->flags &= ~H1_MF_CLEN;
                                h1m->flags |= H1_MF_CHNK;
                        }
-                       else if (isteq(n, ist("content-length")) && !(h1m->flags & H1_MF_CHNK)) {
+                       else if (isteqi(n, ist("content-length")) && !(h1m->flags & H1_MF_CHNK)) {
                                h1m->flags |= H1_MF_CLEN;
                                strl2llrc(v.ptr, v.len, &cl);
                                h1m->curr_len = h1m->body_len = cl;
index 9205c2f10b0de0b50ab62eb3dca5c186dfc11780..780bc57f6011ec89e9b9df1929219baa716514be 100644 (file)
@@ -694,6 +694,7 @@ static struct h2s *h2c_stream_new(struct h2c *h2c, int id)
        h2s->rxbuf     = BUF_NULL;
        h1m_init_res(&h2s->h1m);
        h2s->h1m.err_pos = -1; // don't care about errors on the response path
+       h2s->h1m.flags |= H1_MF_TOLOWER;
        h2s->by_id.key = h2s->id = id;
        h2c->max_id    = id;
 
@@ -3239,6 +3240,7 @@ static size_t h2s_frt_make_resp_headers(struct h2s *h2s, const struct buffer *bu
                /* we'll let the caller check if it has more headers to send */
                h1m_init_res(h1m);
                h1m->err_pos = -1; // don't care about errors on the response path
+               h2s->h1m.flags |= H1_MF_TOLOWER;
                goto end;
        }