From eb528db60bb7cce7ba484b16ddd3933917bbf8dc Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Wed, 12 Sep 2018 09:54:00 +0200 Subject: [PATCH] MINOR: h1: add H1_MF_TOLOWER to decide when to turn header names to lower case 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 | 1 + src/h1.c | 6 +++--- src/mux_h2.c | 2 ++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/types/h1.h b/include/types/h1.h index ec8cca0e2..2dd58dd69 100644 --- a/include/types/h1.h +++ b/include/types/h1.h @@ -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, diff --git a/src/h1.c b/src/h1.c index db717896e..47af9be32 100644 --- 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; diff --git a/src/mux_h2.c b/src/mux_h2.c index 9205c2f10..780bc57f6 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -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; }