From d22e83abd90a6b52101c0a9efb59186f56154572 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 31 Oct 2017 08:02:24 +0100 Subject: [PATCH] MINOR: h1: store the status code in the H1 message It was painful not to have the status code available, especially when it was computed. Let's store it and ensure we don't claim content-length anymore on 1xx, only 0 body bytes. --- include/proto/h1.h | 1 + include/types/h1.h | 2 ++ src/h1.c | 10 ++++++---- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/include/proto/h1.h b/include/proto/h1.h index e7d364d3d..b7229507b 100644 --- a/include/proto/h1.h +++ b/include/proto/h1.h @@ -275,6 +275,7 @@ static inline int h1_parse_chunk_size(const struct buffer *buf, int start, int s static inline struct h1m *h1m_init(struct h1m *h1m) { h1m->state = HTTP_MSG_RQBEFORE; + h1m->status = 0; h1m->flags = 0; h1m->curr_len = 0; h1m->body_len = 0; diff --git a/include/types/h1.h b/include/types/h1.h index 230102c00..3956b6e6c 100644 --- a/include/types/h1.h +++ b/include/types/h1.h @@ -91,6 +91,8 @@ enum h1_state { /* basic HTTP/1 message state for use in parsers */ struct h1m { enum h1_state state; // H1 message state (HTTP_MSG_*) + /* 8 bits available here */ + uint16_t status; // HTTP status code uint32_t flags; // H1 message flags (H1_MF_*) uint64_t curr_len; // content-length or last chunk length uint64_t body_len; // total known size of the body length diff --git a/src/h1.c b/src/h1.c index 856b654dd..bbfaabcf7 100644 --- a/src/h1.c +++ b/src/h1.c @@ -910,7 +910,7 @@ int h1_headers_to_hdr_list(char *start, const char *stop, case HTTP_MSG_RPCODE: http_msg_rpcode: if (likely(!HTTP_IS_LWS(*ptr))) { - code = (code << 8) + *ptr; + code = code * 10 + *ptr - '0'; EAT_AND_JUMP_OR_RETURN(ptr, end, http_msg_rpcode, http_msg_ood, state, HTTP_MSG_RPCODE); } @@ -956,6 +956,8 @@ int h1_headers_to_hdr_list(char *start, const char *stop, goto http_output_full; } http_set_hdr(&hdr[hdr_count++], ist(":status"), ist2(start + st_c, st_c_l)); + if (h1m) + h1m->status = code; sol = ptr - start; if (likely(*ptr == '\r')) @@ -1127,9 +1129,9 @@ int h1_headers_to_hdr_list(char *start, const char *stop, if (h1m) { long long cl; - if (start[st_c] == '1' || /* 100..199 */ - isteq(ist2(start + st_c, st_c_l), ist("204")) || - isteq(ist2(start + st_c, st_c_l), ist("304"))) { + if (h1m->status >= 100 && h1m->status < 200) + h1m->curr_len = h1m->body_len = 0; + else if (h1m->status == 304 || h1m->status == 204) { /* no contents, claim c-len is present and set to zero */ h1m->flags |= H1_MF_CLEN; h1m->curr_len = h1m->body_len = 0;