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.
This commit is contained in:
Willy Tarreau 2018-09-12 09:54:00 +02:00
parent c2ab9f5163
commit eb528db60b
3 changed files with 6 additions and 3 deletions

View File

@ -139,6 +139,7 @@ enum h1m_state {
#define H1_MF_CLEN 0x00000001 // content-length present #define H1_MF_CLEN 0x00000001 // content-length present
#define H1_MF_CHNK 0x00000002 // chunk present, exclusive with c-l #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_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, /* basic HTTP/1 message state for use in parsers. The err_pos field is special,

View File

@ -1082,7 +1082,7 @@ int h1_headers_to_hdr_list(char *start, const char *stop,
/* assumes sol points to the first char */ /* assumes sol points to the first char */
if (likely(HTTP_IS_TOKEN(*ptr))) { if (likely(HTTP_IS_TOKEN(*ptr))) {
/* turn it to lower case if needed */ /* 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); *ptr = tolower(*ptr);
EAT_AND_JUMP_OR_RETURN(ptr, end, http_msg_hdr_name, http_msg_ood, state, H1_MSG_HDR_NAME); 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->flags |= H1_MF_CLEN;
h1m->curr_len = h1m->body_len = 0; 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_CLEN;
h1m->flags |= H1_MF_CHNK; 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; h1m->flags |= H1_MF_CLEN;
strl2llrc(v.ptr, v.len, &cl); strl2llrc(v.ptr, v.len, &cl);
h1m->curr_len = h1m->body_len = cl; h1m->curr_len = h1m->body_len = cl;

View File

@ -694,6 +694,7 @@ static struct h2s *h2c_stream_new(struct h2c *h2c, int id)
h2s->rxbuf = BUF_NULL; h2s->rxbuf = BUF_NULL;
h1m_init_res(&h2s->h1m); h1m_init_res(&h2s->h1m);
h2s->h1m.err_pos = -1; // don't care about errors on the response path 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; h2s->by_id.key = h2s->id = id;
h2c->max_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 */ /* we'll let the caller check if it has more headers to send */
h1m_init_res(h1m); h1m_init_res(h1m);
h1m->err_pos = -1; // don't care about errors on the response path h1m->err_pos = -1; // don't care about errors on the response path
h2s->h1m.flags |= H1_MF_TOLOWER;
goto end; goto end;
} }