mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-09 16:47:18 +02:00
OPTIM: http: move all http character classs tables into a single one
We used to have 7 different character classes, each was 256 bytes long, resulting in almost 2kB being used in the L1 cache. It's as cheap to test a bit than to check the byte is not null, so let's store a 7-bit composite value and check for the respective bits there instead. The executable is now 4 kB smaller and the performance on small objects increased by about 1% to 222k requests/second with a config involving 4 http-request rules including 1 header lookup, one header replacement, and 2 variable assignments.
This commit is contained in:
parent
dc3a9e830c
commit
2235b261b6
@ -42,13 +42,23 @@
|
|||||||
* ver_token = 'H', 'P', 'T', '/', '.', and digits.
|
* ver_token = 'H', 'P', 'T', '/', '.', and digits.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern const char http_is_ctl[256];
|
extern const unsigned char http_char_classes[256];
|
||||||
extern const char http_is_sep[256];
|
|
||||||
extern const char http_is_lws[256];
|
#define HTTP_FLG_CTL 0x01
|
||||||
extern const char http_is_spht[256];
|
#define HTTP_FLG_SEP 0x02
|
||||||
extern const char http_is_crlf[256];
|
#define HTTP_FLG_LWS 0x04
|
||||||
extern const char http_is_token[256];
|
#define HTTP_FLG_SPHT 0x08
|
||||||
extern const char http_is_ver_token[256];
|
#define HTTP_FLG_CRLF 0x10
|
||||||
|
#define HTTP_FLG_TOK 0x20
|
||||||
|
#define HTTP_FLG_VER 0x40
|
||||||
|
|
||||||
|
#define HTTP_IS_CTL(x) (http_char_classes[(unsigned char)(x)] & HTTP_FLG_CTL)
|
||||||
|
#define HTTP_IS_SEP(x) (http_char_classes[(unsigned char)(x)] & HTTP_FLG_SEP)
|
||||||
|
#define HTTP_IS_LWS(x) (http_char_classes[(unsigned char)(x)] & HTTP_FLG_LWS)
|
||||||
|
#define HTTP_IS_SPHT(x) (http_char_classes[(unsigned char)(x)] & HTTP_FLG_SPHT)
|
||||||
|
#define HTTP_IS_CRLF(x) (http_char_classes[(unsigned char)(x)] & HTTP_FLG_CRLF)
|
||||||
|
#define HTTP_IS_TOKEN(x) (http_char_classes[(unsigned char)(x)] & HTTP_FLG_TOK)
|
||||||
|
#define HTTP_IS_VER_TOKEN(x) (http_char_classes[(unsigned char)(x)] & HTTP_FLG_VER)
|
||||||
|
|
||||||
extern const int http_err_codes[HTTP_ERR_SIZE];
|
extern const int http_err_codes[HTTP_ERR_SIZE];
|
||||||
extern struct chunk http_err_chunks[HTTP_ERR_SIZE];
|
extern struct chunk http_err_chunks[HTTP_ERR_SIZE];
|
||||||
@ -56,14 +66,6 @@ extern const char *HTTP_302;
|
|||||||
extern const char *HTTP_303;
|
extern const char *HTTP_303;
|
||||||
extern char *get_http_auth_buff;
|
extern char *get_http_auth_buff;
|
||||||
|
|
||||||
#define HTTP_IS_CTL(x) (http_is_ctl[(unsigned char)(x)])
|
|
||||||
#define HTTP_IS_SEP(x) (http_is_sep[(unsigned char)(x)])
|
|
||||||
#define HTTP_IS_LWS(x) (http_is_lws[(unsigned char)(x)])
|
|
||||||
#define HTTP_IS_SPHT(x) (http_is_spht[(unsigned char)(x)])
|
|
||||||
#define HTTP_IS_CRLF(x) (http_is_crlf[(unsigned char)(x)])
|
|
||||||
#define HTTP_IS_TOKEN(x) (http_is_token[(unsigned char)(x)])
|
|
||||||
#define HTTP_IS_VER_TOKEN(x) (http_is_ver_token[(unsigned char)(x)])
|
|
||||||
|
|
||||||
int process_cli(struct stream *s);
|
int process_cli(struct stream *s);
|
||||||
int process_srv_data(struct stream *s);
|
int process_srv_data(struct stream *s);
|
||||||
int process_srv_conn(struct stream *s);
|
int process_srv_conn(struct stream *s);
|
||||||
|
@ -343,12 +343,12 @@ select_compression_request_header(struct comp_state *st, struct stream *s,
|
|||||||
|
|
||||||
/* try to isolate the token from the optional q-value */
|
/* try to isolate the token from the optional q-value */
|
||||||
toklen = 0;
|
toklen = 0;
|
||||||
while (toklen < ctx.vlen && http_is_token[(unsigned char)*(ctx.line + ctx.val + toklen)])
|
while (toklen < ctx.vlen && HTTP_IS_TOKEN(*(ctx.line + ctx.val + toklen)))
|
||||||
toklen++;
|
toklen++;
|
||||||
|
|
||||||
qval = ctx.line + ctx.val + toklen;
|
qval = ctx.line + ctx.val + toklen;
|
||||||
while (1) {
|
while (1) {
|
||||||
while (qval < ctx.line + ctx.val + ctx.vlen && http_is_lws[(unsigned char)*qval])
|
while (qval < ctx.line + ctx.val + ctx.vlen && HTTP_IS_LWS(*qval))
|
||||||
qval++;
|
qval++;
|
||||||
|
|
||||||
if (qval >= ctx.line + ctx.val + ctx.vlen || *qval != ';') {
|
if (qval >= ctx.line + ctx.val + ctx.vlen || *qval != ';') {
|
||||||
@ -357,7 +357,7 @@ select_compression_request_header(struct comp_state *st, struct stream *s,
|
|||||||
}
|
}
|
||||||
qval++;
|
qval++;
|
||||||
|
|
||||||
while (qval < ctx.line + ctx.val + ctx.vlen && http_is_lws[(unsigned char)*qval])
|
while (qval < ctx.line + ctx.val + ctx.vlen && HTTP_IS_LWS(*qval))
|
||||||
qval++;
|
qval++;
|
||||||
|
|
||||||
if (qval >= ctx.line + ctx.val + ctx.vlen) {
|
if (qval >= ctx.line + ctx.val + ctx.vlen) {
|
||||||
|
258
src/proto_http.c
258
src/proto_http.c
@ -491,80 +491,144 @@ const struct http_method_name http_known_methods[HTTP_METH_OTHER] = {
|
|||||||
|
|
||||||
/* It is about twice as fast on recent architectures to lookup a byte in a
|
/* It is about twice as fast on recent architectures to lookup a byte in a
|
||||||
* table than to perform a boolean AND or OR between two tests. Refer to
|
* table than to perform a boolean AND or OR between two tests. Refer to
|
||||||
* RFC2616 for those chars.
|
* RFC2616/RFC5234/RFC7230 for those chars. A token is any ASCII char that is
|
||||||
|
* neither a separator nor a CTL char. An http ver_token is any ASCII which can
|
||||||
|
* be found in an HTTP version, which includes 'H', 'T', 'P', '/', '.' and any
|
||||||
|
* digit. Note: please do not overwrite values in assignment since gcc-2.95
|
||||||
|
* will not handle them correctly. It's worth noting that chars 128..255 are
|
||||||
|
* nothing, not even control chars.
|
||||||
*/
|
*/
|
||||||
|
const unsigned char http_char_classes[256] = {
|
||||||
const char http_is_spht[256] = {
|
[ 0] = HTTP_FLG_CTL,
|
||||||
[' '] = 1, ['\t'] = 1,
|
[ 1] = HTTP_FLG_CTL,
|
||||||
|
[ 2] = HTTP_FLG_CTL,
|
||||||
|
[ 3] = HTTP_FLG_CTL,
|
||||||
|
[ 4] = HTTP_FLG_CTL,
|
||||||
|
[ 5] = HTTP_FLG_CTL,
|
||||||
|
[ 6] = HTTP_FLG_CTL,
|
||||||
|
[ 7] = HTTP_FLG_CTL,
|
||||||
|
[ 8] = HTTP_FLG_CTL,
|
||||||
|
[ 9] = HTTP_FLG_SPHT | HTTP_FLG_LWS | HTTP_FLG_SEP | HTTP_FLG_CTL,
|
||||||
|
[ 10] = HTTP_FLG_CRLF | HTTP_FLG_LWS | HTTP_FLG_CTL,
|
||||||
|
[ 11] = HTTP_FLG_CTL,
|
||||||
|
[ 12] = HTTP_FLG_CTL,
|
||||||
|
[ 13] = HTTP_FLG_CRLF | HTTP_FLG_LWS | HTTP_FLG_CTL,
|
||||||
|
[ 14] = HTTP_FLG_CTL,
|
||||||
|
[ 15] = HTTP_FLG_CTL,
|
||||||
|
[ 16] = HTTP_FLG_CTL,
|
||||||
|
[ 17] = HTTP_FLG_CTL,
|
||||||
|
[ 18] = HTTP_FLG_CTL,
|
||||||
|
[ 19] = HTTP_FLG_CTL,
|
||||||
|
[ 20] = HTTP_FLG_CTL,
|
||||||
|
[ 21] = HTTP_FLG_CTL,
|
||||||
|
[ 22] = HTTP_FLG_CTL,
|
||||||
|
[ 23] = HTTP_FLG_CTL,
|
||||||
|
[ 24] = HTTP_FLG_CTL,
|
||||||
|
[ 25] = HTTP_FLG_CTL,
|
||||||
|
[ 26] = HTTP_FLG_CTL,
|
||||||
|
[ 27] = HTTP_FLG_CTL,
|
||||||
|
[ 28] = HTTP_FLG_CTL,
|
||||||
|
[ 29] = HTTP_FLG_CTL,
|
||||||
|
[ 30] = HTTP_FLG_CTL,
|
||||||
|
[ 31] = HTTP_FLG_CTL,
|
||||||
|
[' '] = HTTP_FLG_SPHT | HTTP_FLG_LWS | HTTP_FLG_SEP,
|
||||||
|
['!'] = HTTP_FLG_TOK,
|
||||||
|
['"'] = HTTP_FLG_SEP,
|
||||||
|
['#'] = HTTP_FLG_TOK,
|
||||||
|
['$'] = HTTP_FLG_TOK,
|
||||||
|
['%'] = HTTP_FLG_TOK,
|
||||||
|
['&'] = HTTP_FLG_TOK,
|
||||||
|
[ 39] = HTTP_FLG_TOK,
|
||||||
|
['('] = HTTP_FLG_SEP,
|
||||||
|
[')'] = HTTP_FLG_SEP,
|
||||||
|
['*'] = HTTP_FLG_TOK,
|
||||||
|
['+'] = HTTP_FLG_TOK,
|
||||||
|
[','] = HTTP_FLG_SEP,
|
||||||
|
['-'] = HTTP_FLG_TOK,
|
||||||
|
['.'] = HTTP_FLG_TOK | HTTP_FLG_VER,
|
||||||
|
['/'] = HTTP_FLG_SEP | HTTP_FLG_VER,
|
||||||
|
['0'] = HTTP_FLG_TOK | HTTP_FLG_VER,
|
||||||
|
['1'] = HTTP_FLG_TOK | HTTP_FLG_VER,
|
||||||
|
['2'] = HTTP_FLG_TOK | HTTP_FLG_VER,
|
||||||
|
['3'] = HTTP_FLG_TOK | HTTP_FLG_VER,
|
||||||
|
['4'] = HTTP_FLG_TOK | HTTP_FLG_VER,
|
||||||
|
['5'] = HTTP_FLG_TOK | HTTP_FLG_VER,
|
||||||
|
['6'] = HTTP_FLG_TOK | HTTP_FLG_VER,
|
||||||
|
['7'] = HTTP_FLG_TOK | HTTP_FLG_VER,
|
||||||
|
['8'] = HTTP_FLG_TOK | HTTP_FLG_VER,
|
||||||
|
['9'] = HTTP_FLG_TOK | HTTP_FLG_VER,
|
||||||
|
[':'] = HTTP_FLG_SEP,
|
||||||
|
[';'] = HTTP_FLG_SEP,
|
||||||
|
['<'] = HTTP_FLG_SEP,
|
||||||
|
['='] = HTTP_FLG_SEP,
|
||||||
|
['>'] = HTTP_FLG_SEP,
|
||||||
|
['?'] = HTTP_FLG_SEP,
|
||||||
|
['@'] = HTTP_FLG_SEP,
|
||||||
|
['A'] = HTTP_FLG_TOK,
|
||||||
|
['B'] = HTTP_FLG_TOK,
|
||||||
|
['C'] = HTTP_FLG_TOK,
|
||||||
|
['D'] = HTTP_FLG_TOK,
|
||||||
|
['E'] = HTTP_FLG_TOK,
|
||||||
|
['F'] = HTTP_FLG_TOK,
|
||||||
|
['G'] = HTTP_FLG_TOK,
|
||||||
|
['H'] = HTTP_FLG_TOK | HTTP_FLG_VER,
|
||||||
|
['I'] = HTTP_FLG_TOK,
|
||||||
|
['J'] = HTTP_FLG_TOK,
|
||||||
|
['K'] = HTTP_FLG_TOK,
|
||||||
|
['L'] = HTTP_FLG_TOK,
|
||||||
|
['M'] = HTTP_FLG_TOK,
|
||||||
|
['N'] = HTTP_FLG_TOK,
|
||||||
|
['O'] = HTTP_FLG_TOK,
|
||||||
|
['P'] = HTTP_FLG_TOK | HTTP_FLG_VER,
|
||||||
|
['Q'] = HTTP_FLG_TOK,
|
||||||
|
['R'] = HTTP_FLG_TOK | HTTP_FLG_VER,
|
||||||
|
['S'] = HTTP_FLG_TOK | HTTP_FLG_VER,
|
||||||
|
['T'] = HTTP_FLG_TOK | HTTP_FLG_VER,
|
||||||
|
['U'] = HTTP_FLG_TOK,
|
||||||
|
['V'] = HTTP_FLG_TOK,
|
||||||
|
['W'] = HTTP_FLG_TOK,
|
||||||
|
['X'] = HTTP_FLG_TOK,
|
||||||
|
['Y'] = HTTP_FLG_TOK,
|
||||||
|
['Z'] = HTTP_FLG_TOK,
|
||||||
|
['['] = HTTP_FLG_SEP,
|
||||||
|
[ 92] = HTTP_FLG_SEP,
|
||||||
|
[']'] = HTTP_FLG_SEP,
|
||||||
|
['^'] = HTTP_FLG_TOK,
|
||||||
|
['_'] = HTTP_FLG_TOK,
|
||||||
|
['`'] = HTTP_FLG_TOK,
|
||||||
|
['a'] = HTTP_FLG_TOK,
|
||||||
|
['b'] = HTTP_FLG_TOK,
|
||||||
|
['c'] = HTTP_FLG_TOK,
|
||||||
|
['d'] = HTTP_FLG_TOK,
|
||||||
|
['e'] = HTTP_FLG_TOK,
|
||||||
|
['f'] = HTTP_FLG_TOK,
|
||||||
|
['g'] = HTTP_FLG_TOK,
|
||||||
|
['h'] = HTTP_FLG_TOK,
|
||||||
|
['i'] = HTTP_FLG_TOK,
|
||||||
|
['j'] = HTTP_FLG_TOK,
|
||||||
|
['k'] = HTTP_FLG_TOK,
|
||||||
|
['l'] = HTTP_FLG_TOK,
|
||||||
|
['m'] = HTTP_FLG_TOK,
|
||||||
|
['n'] = HTTP_FLG_TOK,
|
||||||
|
['o'] = HTTP_FLG_TOK,
|
||||||
|
['p'] = HTTP_FLG_TOK,
|
||||||
|
['q'] = HTTP_FLG_TOK,
|
||||||
|
['r'] = HTTP_FLG_TOK,
|
||||||
|
['s'] = HTTP_FLG_TOK,
|
||||||
|
['t'] = HTTP_FLG_TOK,
|
||||||
|
['u'] = HTTP_FLG_TOK,
|
||||||
|
['v'] = HTTP_FLG_TOK,
|
||||||
|
['w'] = HTTP_FLG_TOK,
|
||||||
|
['x'] = HTTP_FLG_TOK,
|
||||||
|
['y'] = HTTP_FLG_TOK,
|
||||||
|
['z'] = HTTP_FLG_TOK,
|
||||||
|
['{'] = HTTP_FLG_SEP,
|
||||||
|
['|'] = HTTP_FLG_TOK,
|
||||||
|
['}'] = HTTP_FLG_SEP,
|
||||||
|
['~'] = HTTP_FLG_TOK,
|
||||||
|
[127] = HTTP_FLG_CTL,
|
||||||
};
|
};
|
||||||
|
|
||||||
const char http_is_crlf[256] = {
|
|
||||||
['\r'] = 1, ['\n'] = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
const char http_is_lws[256] = {
|
|
||||||
[' '] = 1, ['\t'] = 1,
|
|
||||||
['\r'] = 1, ['\n'] = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
const char http_is_sep[256] = {
|
|
||||||
['('] = 1, [')'] = 1, ['<'] = 1, ['>'] = 1,
|
|
||||||
['@'] = 1, [','] = 1, [';'] = 1, [':'] = 1,
|
|
||||||
['"'] = 1, ['/'] = 1, ['['] = 1, [']'] = 1,
|
|
||||||
['{'] = 1, ['}'] = 1, ['?'] = 1, ['='] = 1,
|
|
||||||
[' '] = 1, ['\t'] = 1, ['\\'] = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
const char http_is_ctl[256] = {
|
|
||||||
[0 ... 31] = 1,
|
|
||||||
[127] = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A token is any ASCII char that is neither a separator nor a CTL char.
|
|
||||||
* Do not overwrite values in assignment since gcc-2.95 will not handle
|
|
||||||
* them correctly. Instead, define every non-CTL char's status.
|
|
||||||
*/
|
|
||||||
const char http_is_token[256] = {
|
|
||||||
[' '] = 0, ['!'] = 1, ['"'] = 0, ['#'] = 1,
|
|
||||||
['$'] = 1, ['%'] = 1, ['&'] = 1, ['\''] = 1,
|
|
||||||
['('] = 0, [')'] = 0, ['*'] = 1, ['+'] = 1,
|
|
||||||
[','] = 0, ['-'] = 1, ['.'] = 1, ['/'] = 0,
|
|
||||||
['0'] = 1, ['1'] = 1, ['2'] = 1, ['3'] = 1,
|
|
||||||
['4'] = 1, ['5'] = 1, ['6'] = 1, ['7'] = 1,
|
|
||||||
['8'] = 1, ['9'] = 1, [':'] = 0, [';'] = 0,
|
|
||||||
['<'] = 0, ['='] = 0, ['>'] = 0, ['?'] = 0,
|
|
||||||
['@'] = 0, ['A'] = 1, ['B'] = 1, ['C'] = 1,
|
|
||||||
['D'] = 1, ['E'] = 1, ['F'] = 1, ['G'] = 1,
|
|
||||||
['H'] = 1, ['I'] = 1, ['J'] = 1, ['K'] = 1,
|
|
||||||
['L'] = 1, ['M'] = 1, ['N'] = 1, ['O'] = 1,
|
|
||||||
['P'] = 1, ['Q'] = 1, ['R'] = 1, ['S'] = 1,
|
|
||||||
['T'] = 1, ['U'] = 1, ['V'] = 1, ['W'] = 1,
|
|
||||||
['X'] = 1, ['Y'] = 1, ['Z'] = 1, ['['] = 0,
|
|
||||||
['\\'] = 0, [']'] = 0, ['^'] = 1, ['_'] = 1,
|
|
||||||
['`'] = 1, ['a'] = 1, ['b'] = 1, ['c'] = 1,
|
|
||||||
['d'] = 1, ['e'] = 1, ['f'] = 1, ['g'] = 1,
|
|
||||||
['h'] = 1, ['i'] = 1, ['j'] = 1, ['k'] = 1,
|
|
||||||
['l'] = 1, ['m'] = 1, ['n'] = 1, ['o'] = 1,
|
|
||||||
['p'] = 1, ['q'] = 1, ['r'] = 1, ['s'] = 1,
|
|
||||||
['t'] = 1, ['u'] = 1, ['v'] = 1, ['w'] = 1,
|
|
||||||
['x'] = 1, ['y'] = 1, ['z'] = 1, ['{'] = 0,
|
|
||||||
['|'] = 1, ['}'] = 0, ['~'] = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* An http ver_token is any ASCII which can be found in an HTTP version,
|
|
||||||
* which includes 'H', 'T', 'P', '/', '.' and any digit.
|
|
||||||
*/
|
|
||||||
const char http_is_ver_token[256] = {
|
|
||||||
['.'] = 1, ['/'] = 1,
|
|
||||||
['0'] = 1, ['1'] = 1, ['2'] = 1, ['3'] = 1, ['4'] = 1,
|
|
||||||
['5'] = 1, ['6'] = 1, ['7'] = 1, ['8'] = 1, ['9'] = 1,
|
|
||||||
['H'] = 1, ['P'] = 1, ['R'] = 1, ['S'] = 1, ['T'] = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Adds a header and its CRLF at the tail of the message's buffer, just before
|
* Adds a header and its CRLF at the tail of the message's buffer, just before
|
||||||
* the last CRLF. Text length is measured first, so it cannot be NULL.
|
* the last CRLF. Text length is measured first, so it cannot be NULL.
|
||||||
@ -676,7 +740,7 @@ int http_find_full_header2(const char *name, int len,
|
|||||||
(strncasecmp(sol, name, len) == 0)) {
|
(strncasecmp(sol, name, len) == 0)) {
|
||||||
ctx->del = len;
|
ctx->del = len;
|
||||||
sov = sol + len + 1;
|
sov = sol + len + 1;
|
||||||
while (sov < eol && http_is_lws[(unsigned char)*sov])
|
while (sov < eol && HTTP_IS_LWS(*sov))
|
||||||
sov++;
|
sov++;
|
||||||
|
|
||||||
ctx->line = sol;
|
ctx->line = sol;
|
||||||
@ -684,7 +748,7 @@ int http_find_full_header2(const char *name, int len,
|
|||||||
ctx->idx = cur_idx;
|
ctx->idx = cur_idx;
|
||||||
ctx->val = sov - sol;
|
ctx->val = sov - sol;
|
||||||
ctx->tws = 0;
|
ctx->tws = 0;
|
||||||
while (eol > sov && http_is_lws[(unsigned char)*(eol - 1)]) {
|
while (eol > sov && HTTP_IS_LWS(*(eol - 1))) {
|
||||||
eol--;
|
eol--;
|
||||||
ctx->tws++;
|
ctx->tws++;
|
||||||
}
|
}
|
||||||
@ -739,7 +803,7 @@ int http_find_next_header(char *sol, struct hdr_idx *idx, struct hdr_ctx *ctx)
|
|||||||
|
|
||||||
ctx->del = len;
|
ctx->del = len;
|
||||||
sov = sol + len + 1;
|
sov = sol + len + 1;
|
||||||
while (sov < eol && http_is_lws[(unsigned char)*sov])
|
while (sov < eol && HTTP_IS_LWS(*sov))
|
||||||
sov++;
|
sov++;
|
||||||
|
|
||||||
ctx->line = sol;
|
ctx->line = sol;
|
||||||
@ -748,7 +812,7 @@ int http_find_next_header(char *sol, struct hdr_idx *idx, struct hdr_ctx *ctx)
|
|||||||
ctx->val = sov - sol;
|
ctx->val = sov - sol;
|
||||||
ctx->tws = 0;
|
ctx->tws = 0;
|
||||||
|
|
||||||
while (eol > sov && http_is_lws[(unsigned char)*(eol - 1)]) {
|
while (eol > sov && HTTP_IS_LWS(*(eol - 1))) {
|
||||||
eol--;
|
eol--;
|
||||||
ctx->tws++;
|
ctx->tws++;
|
||||||
}
|
}
|
||||||
@ -819,7 +883,7 @@ int http_find_header2(const char *name, int len,
|
|||||||
* for later use (eg: for header deletion).
|
* for later use (eg: for header deletion).
|
||||||
*/
|
*/
|
||||||
sov++;
|
sov++;
|
||||||
while (sov < eol && http_is_lws[(unsigned char)*sov])
|
while (sov < eol && HTTP_IS_LWS((*sov)))
|
||||||
sov++;
|
sov++;
|
||||||
|
|
||||||
goto return_hdr;
|
goto return_hdr;
|
||||||
@ -845,7 +909,7 @@ int http_find_header2(const char *name, int len,
|
|||||||
(strncasecmp(sol, name, len) == 0)) {
|
(strncasecmp(sol, name, len) == 0)) {
|
||||||
ctx->del = len;
|
ctx->del = len;
|
||||||
sov = sol + len + 1;
|
sov = sol + len + 1;
|
||||||
while (sov < eol && http_is_lws[(unsigned char)*sov])
|
while (sov < eol && HTTP_IS_LWS(*sov))
|
||||||
sov++;
|
sov++;
|
||||||
|
|
||||||
ctx->line = sol;
|
ctx->line = sol;
|
||||||
@ -856,7 +920,7 @@ int http_find_header2(const char *name, int len,
|
|||||||
|
|
||||||
eol = find_hdr_value_end(sov, eol);
|
eol = find_hdr_value_end(sov, eol);
|
||||||
ctx->tws = 0;
|
ctx->tws = 0;
|
||||||
while (eol > sov && http_is_lws[(unsigned char)*(eol - 1)]) {
|
while (eol > sov && HTTP_IS_LWS(*(eol - 1))) {
|
||||||
eol--;
|
eol--;
|
||||||
ctx->tws++;
|
ctx->tws++;
|
||||||
}
|
}
|
||||||
@ -1233,7 +1297,7 @@ void capture_headers(char *som, struct hdr_idx *idx,
|
|||||||
col++;
|
col++;
|
||||||
|
|
||||||
sov = col + 1;
|
sov = col + 1;
|
||||||
while (sov < eol && http_is_lws[(unsigned char)*sov])
|
while (sov < eol && HTTP_IS_LWS(*sov))
|
||||||
sov++;
|
sov++;
|
||||||
|
|
||||||
for (h = cap_hdr; h; h = h->next) {
|
for (h = cap_hdr; h; h = h->next) {
|
||||||
@ -2136,7 +2200,7 @@ static inline int http_parse_chunk_size(struct http_msg *msg)
|
|||||||
if (unlikely(ptr == ptr_old))
|
if (unlikely(ptr == ptr_old))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
while (http_is_spht[(unsigned char)*ptr]) {
|
while (HTTP_IS_SPHT(*ptr)) {
|
||||||
if (++ptr >= end)
|
if (++ptr >= end)
|
||||||
ptr = buf->data;
|
ptr = buf->data;
|
||||||
if (unlikely(ptr == stop))
|
if (unlikely(ptr == stop))
|
||||||
@ -7350,28 +7414,28 @@ int del_hdr_value(struct buffer *buf, char **from, char *next)
|
|||||||
/* We're removing the first value, preserve the colon and add a
|
/* We're removing the first value, preserve the colon and add a
|
||||||
* space if possible.
|
* space if possible.
|
||||||
*/
|
*/
|
||||||
if (!http_is_crlf[(unsigned char)*next])
|
if (!HTTP_IS_CRLF(*next))
|
||||||
next++;
|
next++;
|
||||||
prev++;
|
prev++;
|
||||||
if (prev < next)
|
if (prev < next)
|
||||||
*prev++ = ' ';
|
*prev++ = ' ';
|
||||||
|
|
||||||
while (http_is_spht[(unsigned char)*next])
|
while (HTTP_IS_SPHT(*next))
|
||||||
next++;
|
next++;
|
||||||
} else {
|
} else {
|
||||||
/* Remove useless spaces before the old delimiter. */
|
/* Remove useless spaces before the old delimiter. */
|
||||||
while (http_is_spht[(unsigned char)*(prev-1)])
|
while (HTTP_IS_SPHT(*(prev-1)))
|
||||||
prev--;
|
prev--;
|
||||||
*from = prev;
|
*from = prev;
|
||||||
|
|
||||||
/* copy the delimiter and if possible a space if we're
|
/* copy the delimiter and if possible a space if we're
|
||||||
* not at the end of the line.
|
* not at the end of the line.
|
||||||
*/
|
*/
|
||||||
if (!http_is_crlf[(unsigned char)*next]) {
|
if (!HTTP_IS_CRLF(*next)) {
|
||||||
*prev++ = *next++;
|
*prev++ = *next++;
|
||||||
if (prev + 1 < next)
|
if (prev + 1 < next)
|
||||||
*prev++ = ' ';
|
*prev++ = ' ';
|
||||||
while (http_is_spht[(unsigned char)*next])
|
while (HTTP_IS_SPHT(*next))
|
||||||
next++;
|
next++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7470,7 +7534,7 @@ void manage_client_side_cookies(struct stream *s, struct channel *req)
|
|||||||
|
|
||||||
/* find att_beg */
|
/* find att_beg */
|
||||||
att_beg = prev + 1;
|
att_beg = prev + 1;
|
||||||
while (att_beg < hdr_end && http_is_spht[(unsigned char)*att_beg])
|
while (att_beg < hdr_end && HTTP_IS_SPHT(*att_beg))
|
||||||
att_beg++;
|
att_beg++;
|
||||||
|
|
||||||
/* find att_end : this is the first character after the last non
|
/* find att_end : this is the first character after the last non
|
||||||
@ -7481,7 +7545,7 @@ void manage_client_side_cookies(struct stream *s, struct channel *req)
|
|||||||
while (equal < hdr_end) {
|
while (equal < hdr_end) {
|
||||||
if (*equal == '=' || *equal == ',' || *equal == ';')
|
if (*equal == '=' || *equal == ',' || *equal == ';')
|
||||||
break;
|
break;
|
||||||
if (http_is_spht[(unsigned char)*equal++])
|
if (HTTP_IS_SPHT(*equal++))
|
||||||
continue;
|
continue;
|
||||||
att_end = equal;
|
att_end = equal;
|
||||||
}
|
}
|
||||||
@ -7494,7 +7558,7 @@ void manage_client_side_cookies(struct stream *s, struct channel *req)
|
|||||||
if (equal < hdr_end && *equal == '=') {
|
if (equal < hdr_end && *equal == '=') {
|
||||||
/* look for the beginning of the value */
|
/* look for the beginning of the value */
|
||||||
val_beg = equal + 1;
|
val_beg = equal + 1;
|
||||||
while (val_beg < hdr_end && http_is_spht[(unsigned char)*val_beg])
|
while (val_beg < hdr_end && HTTP_IS_SPHT(*val_beg))
|
||||||
val_beg++;
|
val_beg++;
|
||||||
|
|
||||||
/* find the end of the value, respecting quotes */
|
/* find the end of the value, respecting quotes */
|
||||||
@ -7502,7 +7566,7 @@ void manage_client_side_cookies(struct stream *s, struct channel *req)
|
|||||||
|
|
||||||
/* make val_end point to the first white space or delimitor after the value */
|
/* make val_end point to the first white space or delimitor after the value */
|
||||||
val_end = next;
|
val_end = next;
|
||||||
while (val_end > val_beg && http_is_spht[(unsigned char)*(val_end - 1)])
|
while (val_end > val_beg && HTTP_IS_SPHT(*(val_end - 1)))
|
||||||
val_end--;
|
val_end--;
|
||||||
} else {
|
} else {
|
||||||
val_beg = val_end = next = equal;
|
val_beg = val_end = next = equal;
|
||||||
@ -8132,7 +8196,7 @@ void manage_server_side_cookies(struct stream *s, struct channel *res)
|
|||||||
|
|
||||||
/* find att_beg */
|
/* find att_beg */
|
||||||
att_beg = prev + 1;
|
att_beg = prev + 1;
|
||||||
while (att_beg < hdr_end && http_is_spht[(unsigned char)*att_beg])
|
while (att_beg < hdr_end && HTTP_IS_SPHT(*att_beg))
|
||||||
att_beg++;
|
att_beg++;
|
||||||
|
|
||||||
/* find att_end : this is the first character after the last non
|
/* find att_end : this is the first character after the last non
|
||||||
@ -8143,7 +8207,7 @@ void manage_server_side_cookies(struct stream *s, struct channel *res)
|
|||||||
while (equal < hdr_end) {
|
while (equal < hdr_end) {
|
||||||
if (*equal == '=' || *equal == ';' || (is_cookie2 && *equal == ','))
|
if (*equal == '=' || *equal == ';' || (is_cookie2 && *equal == ','))
|
||||||
break;
|
break;
|
||||||
if (http_is_spht[(unsigned char)*equal++])
|
if (HTTP_IS_SPHT(*equal++))
|
||||||
continue;
|
continue;
|
||||||
att_end = equal;
|
att_end = equal;
|
||||||
}
|
}
|
||||||
@ -8156,7 +8220,7 @@ void manage_server_side_cookies(struct stream *s, struct channel *res)
|
|||||||
if (equal < hdr_end && *equal == '=') {
|
if (equal < hdr_end && *equal == '=') {
|
||||||
/* look for the beginning of the value */
|
/* look for the beginning of the value */
|
||||||
val_beg = equal + 1;
|
val_beg = equal + 1;
|
||||||
while (val_beg < hdr_end && http_is_spht[(unsigned char)*val_beg])
|
while (val_beg < hdr_end && HTTP_IS_SPHT(*val_beg))
|
||||||
val_beg++;
|
val_beg++;
|
||||||
|
|
||||||
/* find the end of the value, respecting quotes */
|
/* find the end of the value, respecting quotes */
|
||||||
@ -8164,7 +8228,7 @@ void manage_server_side_cookies(struct stream *s, struct channel *res)
|
|||||||
|
|
||||||
/* make val_end point to the first white space or delimitor after the value */
|
/* make val_end point to the first white space or delimitor after the value */
|
||||||
val_end = next;
|
val_end = next;
|
||||||
while (val_end > val_beg && http_is_spht[(unsigned char)*(val_end - 1)])
|
while (val_end > val_beg && HTTP_IS_SPHT(*(val_end - 1)))
|
||||||
val_end--;
|
val_end--;
|
||||||
} else {
|
} else {
|
||||||
/* <equal> points to next comma, semi-colon or EOL */
|
/* <equal> points to next comma, semi-colon or EOL */
|
||||||
@ -10878,7 +10942,7 @@ extract_cookie_value(char *hdr, const char *hdr_end,
|
|||||||
for (att_beg = hdr; att_beg + cookie_name_l + 1 < hdr_end; att_beg = next + 1) {
|
for (att_beg = hdr; att_beg + cookie_name_l + 1 < hdr_end; att_beg = next + 1) {
|
||||||
/* Iterate through all cookies on this line */
|
/* Iterate through all cookies on this line */
|
||||||
|
|
||||||
while (att_beg < hdr_end && http_is_spht[(unsigned char)*att_beg])
|
while (att_beg < hdr_end && HTTP_IS_SPHT(*att_beg))
|
||||||
att_beg++;
|
att_beg++;
|
||||||
|
|
||||||
/* find att_end : this is the first character after the last non
|
/* find att_end : this is the first character after the last non
|
||||||
@ -10889,7 +10953,7 @@ extract_cookie_value(char *hdr, const char *hdr_end,
|
|||||||
while (equal < hdr_end) {
|
while (equal < hdr_end) {
|
||||||
if (*equal == '=' || *equal == ';' || (list && *equal == ','))
|
if (*equal == '=' || *equal == ';' || (list && *equal == ','))
|
||||||
break;
|
break;
|
||||||
if (http_is_spht[(unsigned char)*equal++])
|
if (HTTP_IS_SPHT(*equal++))
|
||||||
continue;
|
continue;
|
||||||
att_end = equal;
|
att_end = equal;
|
||||||
}
|
}
|
||||||
@ -10902,7 +10966,7 @@ extract_cookie_value(char *hdr, const char *hdr_end,
|
|||||||
if (equal < hdr_end && *equal == '=') {
|
if (equal < hdr_end && *equal == '=') {
|
||||||
/* look for the beginning of the value */
|
/* look for the beginning of the value */
|
||||||
val_beg = equal + 1;
|
val_beg = equal + 1;
|
||||||
while (val_beg < hdr_end && http_is_spht[(unsigned char)*val_beg])
|
while (val_beg < hdr_end && HTTP_IS_SPHT(*val_beg))
|
||||||
val_beg++;
|
val_beg++;
|
||||||
|
|
||||||
/* find the end of the value, respecting quotes */
|
/* find the end of the value, respecting quotes */
|
||||||
@ -10910,7 +10974,7 @@ extract_cookie_value(char *hdr, const char *hdr_end,
|
|||||||
|
|
||||||
/* make val_end point to the first white space or delimitor after the value */
|
/* make val_end point to the first white space or delimitor after the value */
|
||||||
val_end = next;
|
val_end = next;
|
||||||
while (val_end > val_beg && http_is_spht[(unsigned char)*(val_end - 1)])
|
while (val_end > val_beg && HTTP_IS_SPHT(*(val_end - 1)))
|
||||||
val_end--;
|
val_end--;
|
||||||
} else {
|
} else {
|
||||||
val_beg = val_end = next = equal;
|
val_beg = val_end = next = equal;
|
||||||
|
@ -2570,7 +2570,7 @@ static int smp_check_const_meth(struct arg *args, char **err)
|
|||||||
* token = 1*tchar
|
* token = 1*tchar
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < args[0].data.str.len; i++) {
|
for (i = 0; i < args[0].data.str.len; i++) {
|
||||||
if (!http_is_token[(unsigned char)args[0].data.str.str[i]]) {
|
if (!HTTP_IS_TOKEN(args[0].data.str.str[i])) {
|
||||||
memprintf(err, "expects valid method.");
|
memprintf(err, "expects valid method.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user