mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-16 00:14:31 +00:00
MINOR: h1: parse the Connection header field
The new function h1_parse_connection_header() is called when facing a connection header in the generic parser, and it will set up to 3 bits in h1m->flags indicating if at least one "close", "keep-alive" or "upgrade" tokens was seen.
This commit is contained in:
parent
ba5fbca33f
commit
98f5cf7a59
@ -141,6 +141,18 @@ enum h1m_state {
|
||||
#define H1_MF_RESP 0x00000004 // this message is the response message
|
||||
#define H1_MF_TOLOWER 0x00000008 // turn the header names to lower case
|
||||
#define H1_MF_VER_11 0x00000010 // message indicates version 1.1 or above
|
||||
#define H1_MF_CONN_CLO 0x00000020 // message contains "connection: close"
|
||||
#define H1_MF_CONN_KAL 0x00000040 // message contains "connection: keep-alive"
|
||||
#define H1_MF_CONN_UPG 0x00000080 // message contains "connection: upgrade"
|
||||
|
||||
/* Note: for a connection to be persistent, we need this for the request :
|
||||
* - one of CLEN or CHNK
|
||||
* - version 1.0 and KAL and not CLO
|
||||
* - or version 1.1 and not CLO
|
||||
* For the response it's the same except that UPG must not appear either.
|
||||
* So in short, for a request it's (CLEN|CHNK) > 0 && !CLO && (VER_11 || KAL)
|
||||
* and for a response it's (CLEN|CHNK) > 0 && !(CLO|UPG) && (VER_11 || KAL)
|
||||
*/
|
||||
|
||||
|
||||
/* basic HTTP/1 message state for use in parsers. The err_pos field is special,
|
||||
|
41
src/h1.c
41
src/h1.c
@ -659,6 +659,44 @@ void http_msg_analyzer(struct http_msg *msg, struct hdr_idx *idx)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Parse the Connection: header of an HTTP/1 request, looking for "close",
|
||||
* "keep-alive", and "upgrade" values, and updating h1m->flags according to
|
||||
* what was found there. Note that flags are only added, not removed, so the
|
||||
* function is safe for being called multiple times if multiple occurrences
|
||||
* are found.
|
||||
*/
|
||||
void h1_parse_connection_header(struct h1m *h1m, struct ist value)
|
||||
{
|
||||
char *e, *n;
|
||||
struct ist word;
|
||||
|
||||
word.ptr = value.ptr - 1; // -1 for next loop's pre-increment
|
||||
e = value.ptr + value.len;
|
||||
|
||||
while (++word.ptr < e) {
|
||||
/* skip leading delimitor and blanks */
|
||||
if (HTTP_IS_LWS(*word.ptr))
|
||||
continue;
|
||||
|
||||
n = http_find_hdr_value_end(word.ptr, e); // next comma or end of line
|
||||
word.len = n - word.ptr;
|
||||
|
||||
/* trim trailing blanks */
|
||||
while (word.len && HTTP_IS_LWS(word.ptr[word.len-1]))
|
||||
word.len--;
|
||||
|
||||
if (isteqi(word, ist("keep-alive")))
|
||||
h1m->flags |= H1_MF_CONN_KAL;
|
||||
else if (isteqi(word, ist("close")))
|
||||
h1m->flags |= H1_MF_CONN_CLO;
|
||||
else if (isteqi(word, ist("upgrade")))
|
||||
h1m->flags |= H1_MF_CONN_UPG;
|
||||
|
||||
word.ptr = n;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function parses a contiguous HTTP/1 headers block starting at <start>
|
||||
* 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>,
|
||||
@ -1244,6 +1282,9 @@ int h1_headers_to_hdr_list(char *start, const char *stop,
|
||||
strl2llrc(v.ptr, v.len, &cl);
|
||||
h1m->curr_len = h1m->body_len = cl;
|
||||
}
|
||||
else if (isteqi(n, ist("connection"))) {
|
||||
h1_parse_connection_header(h1m, v);
|
||||
}
|
||||
}
|
||||
|
||||
sol = ptr - start;
|
||||
|
Loading…
Reference in New Issue
Block a user