diff --git a/Makefile b/Makefile index c49239958..d68d26368 100644 --- a/Makefile +++ b/Makefile @@ -876,7 +876,7 @@ OBJS = src/proto_http.o src/cfgparse.o src/server.o src/stream.o \ src/sha1.o src/hpack-tbl.o src/hpack-enc.o src/uri_auth.o \ src/time.o src/proto_udp.o src/arg.o src/signal.o \ src/protocol.o src/lru.o src/hdr_idx.o src/hpack-huff.o \ - src/mailers.o src/h2.o src/base64.o src/hash.o + src/mailers.o src/h2.o src/base64.o src/hash.o src/http.o EBTREE_OBJS = $(EBTREE_DIR)/ebtree.o $(EBTREE_DIR)/eb32sctree.o \ $(EBTREE_DIR)/eb32tree.o $(EBTREE_DIR)/eb64tree.o \ diff --git a/include/common/buf.h b/include/common/buf.h index a1355e653..420882026 100644 --- a/include/common/buf.h +++ b/include/common/buf.h @@ -29,6 +29,7 @@ #define _COMMON_BUF_H #include +#include /* Structure defining a buffer's head */ struct buffer { diff --git a/include/common/http.h b/include/common/http.h new file mode 100644 index 000000000..d283e2977 --- /dev/null +++ b/include/common/http.h @@ -0,0 +1,125 @@ +/* + * include/common/http.h + * + * Version-agnostic and implementation-agnostic HTTP protocol definitions. + * + * Copyright (C) 2000-2018 Willy Tarreau - w@1wt.eu + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, version 2.1 + * exclusively. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _COMMON_HTTP_H +#define _COMMON_HTTP_H + +#include +#include + +/* these macros are used mainly when parsing header fields */ +#define HTTP_FLG_CTL 0x01 +#define HTTP_FLG_SEP 0x02 +#define HTTP_FLG_LWS 0x04 +#define HTTP_FLG_SPHT 0x08 +#define HTTP_FLG_CRLF 0x10 +#define HTTP_FLG_TOK 0x20 +#define HTTP_FLG_VER 0x40 +#define HTTP_FLG_DIG 0x80 + +#define HTTP_IS_CTL(x) (http_char_classes[(uint8_t)(x)] & HTTP_FLG_CTL) +#define HTTP_IS_SEP(x) (http_char_classes[(uint8_t)(x)] & HTTP_FLG_SEP) +#define HTTP_IS_LWS(x) (http_char_classes[(uint8_t)(x)] & HTTP_FLG_LWS) +#define HTTP_IS_SPHT(x) (http_char_classes[(uint8_t)(x)] & HTTP_FLG_SPHT) +#define HTTP_IS_CRLF(x) (http_char_classes[(uint8_t)(x)] & HTTP_FLG_CRLF) +#define HTTP_IS_TOKEN(x) (http_char_classes[(uint8_t)(x)] & HTTP_FLG_TOK) +#define HTTP_IS_VER_TOKEN(x) (http_char_classes[(uint8_t)(x)] & HTTP_FLG_VER) +#define HTTP_IS_DIGIT(x) (http_char_classes[(uint8_t)(x)] & HTTP_FLG_DIG) + +/* Known HTTP methods */ +enum http_meth_t { + HTTP_METH_OPTIONS, + HTTP_METH_GET, + HTTP_METH_HEAD, + HTTP_METH_POST, + HTTP_METH_PUT, + HTTP_METH_DELETE, + HTTP_METH_TRACE, + HTTP_METH_CONNECT, + HTTP_METH_OTHER, /* Must be the last entry */ +} __attribute__((packed)); + +/* Known HTTP authentication schemes */ +enum ht_auth_m { + HTTP_AUTH_WRONG = -1, /* missing or unknown */ + HTTP_AUTH_UNKNOWN = 0, + HTTP_AUTH_BASIC, + HTTP_AUTH_DIGEST, +} __attribute__((packed)); + +/* All implemented HTTP status codes */ +enum { + HTTP_ERR_200 = 0, + HTTP_ERR_400, + HTTP_ERR_403, + HTTP_ERR_405, + HTTP_ERR_408, + HTTP_ERR_421, + HTTP_ERR_425, + HTTP_ERR_429, + HTTP_ERR_500, + HTTP_ERR_502, + HTTP_ERR_503, + HTTP_ERR_504, + HTTP_ERR_SIZE +}; + +/* Note: the strings below make use of chunks. Chunks may carry an allocated + * size in addition to the length. The size counts from the beginning (str) + * to the end. If the size is unknown, it MUST be zero, in which case the + * sample will automatically be duplicated when a change larger than has + * to be performed. Thus it is safe to always set size to zero. + */ +struct http_meth { + enum http_meth_t meth; + struct buffer str; +}; + +struct http_auth_data { + enum ht_auth_m method; /* one of HTTP_AUTH_* */ + /* 7 bytes unused here */ + struct buffer method_data; /* points to the creditial part from 'Authorization:' header */ + char *user, *pass; /* extracted username & password */ +}; + +struct http_method_desc { + enum http_meth_t meth; + const struct ist text; +}; + +extern const int http_err_codes[HTTP_ERR_SIZE]; +extern struct buffer http_err_chunks[HTTP_ERR_SIZE]; +const struct ist http_known_methods[HTTP_METH_OTHER]; +extern const uint8_t http_char_classes[256]; +extern const char *HTTP_302; +extern const char *HTTP_303; + +enum http_meth_t find_http_meth(const char *str, const int len); + +#endif /* _COMMON_HTTP_H */ + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + */ diff --git a/include/proto/h1.h b/include/proto/h1.h index eef310f8f..299738330 100644 --- a/include/proto/h1.h +++ b/include/proto/h1.h @@ -25,13 +25,12 @@ #include #include #include +#include #include #include #include -#include #include -extern const uint8_t h1_char_classes[256]; const char *http_parse_reqline(struct http_msg *msg, enum h1_state state, const char *ptr, const char *end, unsigned int *ret_ptr, enum h1_state *ret_state); @@ -45,25 +44,6 @@ int h1_headers_to_hdr_list(char *start, const char *stop, struct h1m *h1m); int h1_measure_trailers(const struct buffer *buf, unsigned int ofs, unsigned int max); -#define H1_FLG_CTL 0x01 -#define H1_FLG_SEP 0x02 -#define H1_FLG_LWS 0x04 -#define H1_FLG_SPHT 0x08 -#define H1_FLG_CRLF 0x10 -#define H1_FLG_TOK 0x20 -#define H1_FLG_VER 0x40 -#define H1_FLG_DIG 0x80 - -#define HTTP_IS_CTL(x) (h1_char_classes[(uint8_t)(x)] & H1_FLG_CTL) -#define HTTP_IS_SEP(x) (h1_char_classes[(uint8_t)(x)] & H1_FLG_SEP) -#define HTTP_IS_LWS(x) (h1_char_classes[(uint8_t)(x)] & H1_FLG_LWS) -#define HTTP_IS_SPHT(x) (h1_char_classes[(uint8_t)(x)] & H1_FLG_SPHT) -#define HTTP_IS_CRLF(x) (h1_char_classes[(uint8_t)(x)] & H1_FLG_CRLF) -#define HTTP_IS_TOKEN(x) (h1_char_classes[(uint8_t)(x)] & H1_FLG_TOK) -#define HTTP_IS_VER_TOKEN(x) (h1_char_classes[(uint8_t)(x)] & H1_FLG_VER) -#define HTTP_IS_DIGIT(x) (h1_char_classes[(uint8_t)(x)] & H1_FLG_DIG) - - /* Macros used in the HTTP/1 parser, to check for the expected presence of * certain bytes (ef: LF) or to skip to next byte and yield in case of failure. */ diff --git a/include/proto/proto_http.h b/include/proto/proto_http.h index 7849e1548..b537d4534 100644 --- a/include/proto/proto_http.h +++ b/include/proto/proto_http.h @@ -44,11 +44,6 @@ * ver_token = 'H', 'P', 'T', '/', '.', and digits. */ -extern const int http_err_codes[HTTP_ERR_SIZE]; -extern struct buffer http_err_chunks[HTTP_ERR_SIZE]; -extern const char *HTTP_302; -extern const char *HTTP_303; - int process_cli(struct stream *s); int process_srv_data(struct stream *s); int process_srv_conn(struct stream *s); @@ -126,8 +121,6 @@ struct redirect_rule *http_parse_redirect_rule(const char *file, int linenum, st int smp_fetch_cookie(const struct arg *args, struct sample *smp, const char *kw, void *private); int smp_fetch_base32(const struct arg *args, struct sample *smp, const char *kw, void *private); -enum http_meth_t find_http_meth(const char *str, const int len); - struct action_kw *action_http_req_custom(const char *kw); struct action_kw *action_http_res_custom(const char *kw); int val_hdr(struct arg *arg, char **err_msg); diff --git a/include/types/hlua.h b/include/types/hlua.h index 5a8173f3b..4fb63099d 100644 --- a/include/types/hlua.h +++ b/include/types/hlua.h @@ -8,6 +8,7 @@ #include +#include #include #include diff --git a/include/types/proto_http.h b/include/types/proto_http.h index 9c3905639..5cb058944 100644 --- a/include/types/proto_http.h +++ b/include/types/proto_http.h @@ -22,8 +22,9 @@ #ifndef _TYPES_PROTO_HTTP_H #define _TYPES_PROTO_HTTP_H -#include +#include #include +#include #include #include @@ -31,7 +32,7 @@ #include #include #include -#include +//#include /* These are the flags that are found in txn->flags */ @@ -170,13 +171,6 @@ enum { PERSIST_TYPE_IGNORE, /* ignore-persist */ }; -enum ht_auth_m { - HTTP_AUTH_WRONG = -1, /* missing or unknown */ - HTTP_AUTH_UNKNOWN = 0, - HTTP_AUTH_BASIC, - HTTP_AUTH_DIGEST, -} __attribute__((packed)); - /* final results for http-request rules */ enum rule_result { HTTP_RULE_RES_CONT = 0, /* nothing special, continue rules evaluation */ @@ -188,25 +182,6 @@ enum rule_result { HTTP_RULE_RES_BADREQ, /* bad request */ }; -/* - * All implemented return codes - */ -enum { - HTTP_ERR_200 = 0, - HTTP_ERR_400, - HTTP_ERR_403, - HTTP_ERR_405, - HTTP_ERR_408, - HTTP_ERR_421, - HTTP_ERR_425, - HTTP_ERR_429, - HTTP_ERR_500, - HTTP_ERR_502, - HTTP_ERR_503, - HTTP_ERR_504, - HTTP_ERR_SIZE -}; - /* status codes available for the stats admin page */ enum { STAT_STATUS_INIT = 0, @@ -298,13 +273,6 @@ struct http_msg { unsigned long long body_len; /* total known length of the body, excluding encoding */ }; -struct http_auth_data { - enum ht_auth_m method; /* one of HTTP_AUTH_* */ - /* 7 bytes unused here */ - struct buffer method_data; /* points to the creditial part from 'Authorization:' header */ - char *user, *pass; /* extracted username & password */ -}; - struct proxy; struct http_txn; struct stream; @@ -349,16 +317,9 @@ struct hdr_ctx { int prev; /* index of previous header */ }; -struct http_method_name { - char *name; - int len; -}; - extern struct action_kw_list http_req_keywords; extern struct action_kw_list http_res_keywords; -extern const struct http_method_name http_known_methods[HTTP_METH_OTHER]; - extern struct pool_head *pool_head_http_txn; #endif /* _TYPES_PROTO_HTTP_H */ diff --git a/include/types/proxy.h b/include/types/proxy.h index 2d1b88196..70bfeeef0 100644 --- a/include/types/proxy.h +++ b/include/types/proxy.h @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -45,7 +46,6 @@ #include #include #include -#include #include #include #include diff --git a/include/types/sample.h b/include/types/sample.h index 987a099a2..015c5ae88 100644 --- a/include/types/sample.h +++ b/include/types/sample.h @@ -26,7 +26,8 @@ #include #include -#include +#include +#include #include struct arg; @@ -210,19 +211,6 @@ enum { struct session; struct stream; -/* Known HTTP methods */ -enum http_meth_t { - HTTP_METH_OPTIONS, - HTTP_METH_GET, - HTTP_METH_HEAD, - HTTP_METH_POST, - HTTP_METH_PUT, - HTTP_METH_DELETE, - HTTP_METH_TRACE, - HTTP_METH_CONNECT, - HTTP_METH_OTHER, /* Must be the last entry */ -} __attribute__((packed)); - /* a sample context might be used by any sample fetch function in order to * store information needed across multiple calls (eg: restart point for a * next occurrence). By definition it may store up to 8 pointers, or any @@ -242,17 +230,12 @@ union smp_ctx { * sample will automatically be duplicated when a change larger than has * to be performed. Thus it is safe to always set size to zero. */ -struct meth { - enum http_meth_t meth; - struct buffer str; -}; - union sample_value { long long int sint; /* used for signed 64bits integers */ struct in_addr ipv4; /* used for ipv4 addresses */ struct in6_addr ipv6; /* used for ipv6 addresses */ struct buffer str; /* used for char strings or buffers */ - struct meth meth; /* used for http method */ + struct http_meth meth; /* used for http method */ }; /* Used to store sample constant */ diff --git a/src/checks.c b/src/checks.c index 28ee4c473..b64d32e20 100644 --- a/src/checks.c +++ b/src/checks.c @@ -49,7 +49,6 @@ #include #include #include -#include #include #include #include diff --git a/src/compression.c b/src/compression.c index 3e98402db..e7ce90a1f 100644 --- a/src/compression.c +++ b/src/compression.c @@ -37,7 +37,6 @@ #include #include #include -#include #include diff --git a/src/flt_http_comp.c b/src/flt_http_comp.c index bf8f81ae5..81e1b4244 100644 --- a/src/flt_http_comp.c +++ b/src/flt_http_comp.c @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include diff --git a/src/h1.c b/src/h1.c index 63ff99399..325f5b6c4 100644 --- a/src/h1.c +++ b/src/h1.c @@ -18,147 +18,6 @@ #include #include -/* 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 - * 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 h1_char_classes[256] = { - [ 0] = H1_FLG_CTL, - [ 1] = H1_FLG_CTL, - [ 2] = H1_FLG_CTL, - [ 3] = H1_FLG_CTL, - [ 4] = H1_FLG_CTL, - [ 5] = H1_FLG_CTL, - [ 6] = H1_FLG_CTL, - [ 7] = H1_FLG_CTL, - [ 8] = H1_FLG_CTL, - [ 9] = H1_FLG_SPHT | H1_FLG_LWS | H1_FLG_SEP | H1_FLG_CTL, - [ 10] = H1_FLG_CRLF | H1_FLG_LWS | H1_FLG_CTL, - [ 11] = H1_FLG_CTL, - [ 12] = H1_FLG_CTL, - [ 13] = H1_FLG_CRLF | H1_FLG_LWS | H1_FLG_CTL, - [ 14] = H1_FLG_CTL, - [ 15] = H1_FLG_CTL, - [ 16] = H1_FLG_CTL, - [ 17] = H1_FLG_CTL, - [ 18] = H1_FLG_CTL, - [ 19] = H1_FLG_CTL, - [ 20] = H1_FLG_CTL, - [ 21] = H1_FLG_CTL, - [ 22] = H1_FLG_CTL, - [ 23] = H1_FLG_CTL, - [ 24] = H1_FLG_CTL, - [ 25] = H1_FLG_CTL, - [ 26] = H1_FLG_CTL, - [ 27] = H1_FLG_CTL, - [ 28] = H1_FLG_CTL, - [ 29] = H1_FLG_CTL, - [ 30] = H1_FLG_CTL, - [ 31] = H1_FLG_CTL, - [' '] = H1_FLG_SPHT | H1_FLG_LWS | H1_FLG_SEP, - ['!'] = H1_FLG_TOK, - ['"'] = H1_FLG_SEP, - ['#'] = H1_FLG_TOK, - ['$'] = H1_FLG_TOK, - ['%'] = H1_FLG_TOK, - ['&'] = H1_FLG_TOK, - [ 39] = H1_FLG_TOK, - ['('] = H1_FLG_SEP, - [')'] = H1_FLG_SEP, - ['*'] = H1_FLG_TOK, - ['+'] = H1_FLG_TOK, - [','] = H1_FLG_SEP, - ['-'] = H1_FLG_TOK, - ['.'] = H1_FLG_TOK | H1_FLG_VER, - ['/'] = H1_FLG_SEP | H1_FLG_VER, - ['0'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG, - ['1'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG, - ['2'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG, - ['3'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG, - ['4'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG, - ['5'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG, - ['6'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG, - ['7'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG, - ['8'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG, - ['9'] = H1_FLG_TOK | H1_FLG_VER | H1_FLG_DIG, - [':'] = H1_FLG_SEP, - [';'] = H1_FLG_SEP, - ['<'] = H1_FLG_SEP, - ['='] = H1_FLG_SEP, - ['>'] = H1_FLG_SEP, - ['?'] = H1_FLG_SEP, - ['@'] = H1_FLG_SEP, - ['A'] = H1_FLG_TOK, - ['B'] = H1_FLG_TOK, - ['C'] = H1_FLG_TOK, - ['D'] = H1_FLG_TOK, - ['E'] = H1_FLG_TOK, - ['F'] = H1_FLG_TOK, - ['G'] = H1_FLG_TOK, - ['H'] = H1_FLG_TOK | H1_FLG_VER, - ['I'] = H1_FLG_TOK, - ['J'] = H1_FLG_TOK, - ['K'] = H1_FLG_TOK, - ['L'] = H1_FLG_TOK, - ['M'] = H1_FLG_TOK, - ['N'] = H1_FLG_TOK, - ['O'] = H1_FLG_TOK, - ['P'] = H1_FLG_TOK | H1_FLG_VER, - ['Q'] = H1_FLG_TOK, - ['R'] = H1_FLG_TOK | H1_FLG_VER, - ['S'] = H1_FLG_TOK | H1_FLG_VER, - ['T'] = H1_FLG_TOK | H1_FLG_VER, - ['U'] = H1_FLG_TOK, - ['V'] = H1_FLG_TOK, - ['W'] = H1_FLG_TOK, - ['X'] = H1_FLG_TOK, - ['Y'] = H1_FLG_TOK, - ['Z'] = H1_FLG_TOK, - ['['] = H1_FLG_SEP, - [ 92] = H1_FLG_SEP, - [']'] = H1_FLG_SEP, - ['^'] = H1_FLG_TOK, - ['_'] = H1_FLG_TOK, - ['`'] = H1_FLG_TOK, - ['a'] = H1_FLG_TOK, - ['b'] = H1_FLG_TOK, - ['c'] = H1_FLG_TOK, - ['d'] = H1_FLG_TOK, - ['e'] = H1_FLG_TOK, - ['f'] = H1_FLG_TOK, - ['g'] = H1_FLG_TOK, - ['h'] = H1_FLG_TOK, - ['i'] = H1_FLG_TOK, - ['j'] = H1_FLG_TOK, - ['k'] = H1_FLG_TOK, - ['l'] = H1_FLG_TOK, - ['m'] = H1_FLG_TOK, - ['n'] = H1_FLG_TOK, - ['o'] = H1_FLG_TOK, - ['p'] = H1_FLG_TOK, - ['q'] = H1_FLG_TOK, - ['r'] = H1_FLG_TOK, - ['s'] = H1_FLG_TOK, - ['t'] = H1_FLG_TOK, - ['u'] = H1_FLG_TOK, - ['v'] = H1_FLG_TOK, - ['w'] = H1_FLG_TOK, - ['x'] = H1_FLG_TOK, - ['y'] = H1_FLG_TOK, - ['z'] = H1_FLG_TOK, - ['{'] = H1_FLG_SEP, - ['|'] = H1_FLG_TOK, - ['}'] = H1_FLG_SEP, - ['~'] = H1_FLG_TOK, - [127] = H1_FLG_CTL, -}; - - /* * This function parses a status line between and , starting with * parser state . Only states HTTP_MSG_RPVER, HTTP_MSG_RPVER_SP, diff --git a/src/hlua_fcn.c b/src/hlua_fcn.c index cebce2244..57214455f 100644 --- a/src/hlua_fcn.c +++ b/src/hlua_fcn.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/http.c b/src/http.c new file mode 100644 index 000000000..ad620a9f2 --- /dev/null +++ b/src/http.c @@ -0,0 +1,185 @@ +/* + * HTTP semantics + * + * Copyright 2000-2018 Willy Tarreau + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include +#include +#include + +/* 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 + * 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] = { + [ 0] = HTTP_FLG_CTL, + [ 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 | HTTP_FLG_DIG, + ['1'] = HTTP_FLG_TOK | HTTP_FLG_VER | HTTP_FLG_DIG, + ['2'] = HTTP_FLG_TOK | HTTP_FLG_VER | HTTP_FLG_DIG, + ['3'] = HTTP_FLG_TOK | HTTP_FLG_VER | HTTP_FLG_DIG, + ['4'] = HTTP_FLG_TOK | HTTP_FLG_VER | HTTP_FLG_DIG, + ['5'] = HTTP_FLG_TOK | HTTP_FLG_VER | HTTP_FLG_DIG, + ['6'] = HTTP_FLG_TOK | HTTP_FLG_VER | HTTP_FLG_DIG, + ['7'] = HTTP_FLG_TOK | HTTP_FLG_VER | HTTP_FLG_DIG, + ['8'] = HTTP_FLG_TOK | HTTP_FLG_VER | HTTP_FLG_DIG, + ['9'] = HTTP_FLG_TOK | HTTP_FLG_VER | HTTP_FLG_DIG, + [':'] = 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 struct ist http_known_methods[HTTP_METH_OTHER] = { + [HTTP_METH_OPTIONS] = IST("OPTIONS"), + [HTTP_METH_GET] = IST("GET"), + [HTTP_METH_HEAD] = IST("HEAD"), + [HTTP_METH_POST] = IST("POST"), + [HTTP_METH_PUT] = IST("PUT"), + [HTTP_METH_DELETE] = IST("DELETE"), + [HTTP_METH_TRACE] = IST("TRACE"), + [HTTP_METH_CONNECT] = IST("CONNECT"), +}; + +/* + * returns a known method among HTTP_METH_* or HTTP_METH_OTHER for all unknown + * ones. + */ +enum http_meth_t find_http_meth(const char *str, const int len) +{ + const struct ist m = ist2(str, len); + + if (isteq(m, ist("GET"))) return HTTP_METH_GET; + else if (isteq(m, ist("HEAD"))) return HTTP_METH_HEAD; + else if (isteq(m, ist("POST"))) return HTTP_METH_POST; + else if (isteq(m, ist("CONNECT"))) return HTTP_METH_CONNECT; + else if (isteq(m, ist("PUT"))) return HTTP_METH_PUT; + else if (isteq(m, ist("OPTIONS"))) return HTTP_METH_OPTIONS; + else if (isteq(m, ist("DELETE"))) return HTTP_METH_DELETE; + else if (isteq(m, ist("TRACE"))) return HTTP_METH_TRACE; + else return HTTP_METH_OTHER; +} diff --git a/src/lb_map.c b/src/lb_map.c index 54569b0a2..2d8faa9ae 100644 --- a/src/lb_map.c +++ b/src/lb_map.c @@ -20,8 +20,6 @@ #include #include -#include -#include #include /* this function updates the map according to server 's new state. diff --git a/src/log.c b/src/log.c index 3bd228583..11e75ec41 100644 --- a/src/log.c +++ b/src/log.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/peers.c b/src/peers.c index 1fefa9431..50aee870d 100644 --- a/src/peers.c +++ b/src/peers.c @@ -39,8 +39,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/src/proto_http.c b/src/proto_http.c index b97c6bf38..b153b1413 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -487,55 +487,6 @@ void init_proto_http() pool_head_uniqueid = create_pool("uniqueid", UNIQUEID_LEN, MEM_F_SHARED); } -/* - * We have 26 list of methods (1 per first letter), each of which can have - * up to 3 entries (2 valid, 1 null). - */ -struct http_method_desc { - enum http_meth_t meth; - int len; - const char text[8]; -}; - -const struct http_method_desc http_methods[26][3] = { - ['C' - 'A'] = { - [0] = { .meth = HTTP_METH_CONNECT , .len=7, .text="CONNECT" }, - }, - ['D' - 'A'] = { - [0] = { .meth = HTTP_METH_DELETE , .len=6, .text="DELETE" }, - }, - ['G' - 'A'] = { - [0] = { .meth = HTTP_METH_GET , .len=3, .text="GET" }, - }, - ['H' - 'A'] = { - [0] = { .meth = HTTP_METH_HEAD , .len=4, .text="HEAD" }, - }, - ['O' - 'A'] = { - [0] = { .meth = HTTP_METH_OPTIONS , .len=7, .text="OPTIONS" }, - }, - ['P' - 'A'] = { - [0] = { .meth = HTTP_METH_POST , .len=4, .text="POST" }, - [1] = { .meth = HTTP_METH_PUT , .len=3, .text="PUT" }, - }, - ['T' - 'A'] = { - [0] = { .meth = HTTP_METH_TRACE , .len=5, .text="TRACE" }, - }, - /* rest is empty like this : - * [0] = { .meth = HTTP_METH_OTHER , .len=0, .text="" }, - */ -}; - -const struct http_method_name http_known_methods[HTTP_METH_OTHER] = { - [HTTP_METH_OPTIONS] = { "OPTIONS", 7 }, - [HTTP_METH_GET] = { "GET", 3 }, - [HTTP_METH_HEAD] = { "HEAD", 4 }, - [HTTP_METH_POST] = { "POST", 4 }, - [HTTP_METH_PUT] = { "PUT", 3 }, - [HTTP_METH_DELETE] = { "DELETE", 6 }, - [HTTP_METH_TRACE] = { "TRACE", 5 }, - [HTTP_METH_CONNECT] = { "CONNECT", 7 }, -}; - /* * Adds a header and its CRLF at the tail of the message's buffer, just before * the last CRLF. @@ -959,28 +910,6 @@ http_reply_and_close(struct stream *s, short status, struct buffer *msg) stream_int_retnclose(&s->si[0], msg); } -/* - * returns a known method among HTTP_METH_* or HTTP_METH_OTHER for all unknown - * ones. - */ -enum http_meth_t find_http_meth(const char *str, const int len) -{ - unsigned char m; - const struct http_method_desc *h; - - m = ((unsigned)*str - 'A'); - - if (m < 26) { - for (h = http_methods[m]; h->len > 0; h++) { - if (unlikely(h->len != len)) - continue; - if (likely(memcmp(str, h->text, h->len) == 0)) - return h->meth; - }; - } - return HTTP_METH_OTHER; -} - /* Parse the URI from the given transaction (which is assumed to be in request * phase) and look for the "/" beginning the PATH. If not found, return NULL. * It is returned otherwise. diff --git a/src/sample.c b/src/sample.c index e3dea1bf4..138390d9d 100644 --- a/src/sample.c +++ b/src/sample.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -27,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -749,7 +749,7 @@ static int c_meth2str(struct sample *smp) else if (smp->data.u.meth.meth < HTTP_METH_OTHER) { /* The method is known, copy the pointer containing the string. */ meth = smp->data.u.meth.meth; - smp->data.u.str.area = http_known_methods[meth].name; + smp->data.u.str.area = http_known_methods[meth].ptr; smp->data.u.str.data = http_known_methods[meth].len; smp->flags |= SMP_F_CONST; smp->data.type = SMP_T_STR; diff --git a/src/session.c b/src/session.c index c9d50df5b..3454925ad 100644 --- a/src/session.c +++ b/src/session.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -21,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/src/stats.c b/src/stats.c index 4cea77686..da960f5c9 100644 --- a/src/stats.c +++ b/src/stats.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -57,7 +58,6 @@ #include #include #include -#include #include #include #include diff --git a/src/vars.c b/src/vars.c index 5787cf6ed..905e20c4f 100644 --- a/src/vars.c +++ b/src/vars.c @@ -1,6 +1,7 @@ #include #include +#include #include #include