mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 23:56:57 +02:00
REORG: http: move the HTTP semantics definitions to http.h/http.c
It's a bit painful to have to deal with HTTP semantics for each protocol version (H1 and H2), and working on the version-agnostic code further emphasizes the problem. This patch creates http.h and http.c which are agnostic to the version in use, and which borrow a few parts from proto_http and from h1. For example the once thought h1-specific h1_char_classes array is in fact dictated by RFC7231 and is used to parse HTTP headers. A few changes were made to a few files which were including proto_http.h while they only needed http.h. Certain string definitions pre-dated the introduction of indirect strings (ist) so some were used to simplify the definition of the known HTTP methods. The current lookup code saves 2 kB of a heavily used table and is faster than the previous table based lookup (typ. 14 ns vs 16 before).
This commit is contained in:
parent
123f1f6441
commit
35b51c6e5b
2
Makefile
2
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/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/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/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_OBJS = $(EBTREE_DIR)/ebtree.o $(EBTREE_DIR)/eb32sctree.o \
|
||||||
$(EBTREE_DIR)/eb32tree.o $(EBTREE_DIR)/eb64tree.o \
|
$(EBTREE_DIR)/eb32tree.o $(EBTREE_DIR)/eb64tree.o \
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#define _COMMON_BUF_H
|
#define _COMMON_BUF_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
/* Structure defining a buffer's head */
|
/* Structure defining a buffer's head */
|
||||||
struct buffer {
|
struct buffer {
|
||||||
|
125
include/common/http.h
Normal file
125
include/common/http.h
Normal file
@ -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 <common/buf.h>
|
||||||
|
#include <common/ist.h>
|
||||||
|
|
||||||
|
/* 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 <len> 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:
|
||||||
|
*/
|
@ -25,13 +25,12 @@
|
|||||||
#include <common/buffer.h>
|
#include <common/buffer.h>
|
||||||
#include <common/compiler.h>
|
#include <common/compiler.h>
|
||||||
#include <common/config.h>
|
#include <common/config.h>
|
||||||
|
#include <common/http.h>
|
||||||
#include <common/http-hdr.h>
|
#include <common/http-hdr.h>
|
||||||
#include <common/standard.h>
|
#include <common/standard.h>
|
||||||
#include <types/h1.h>
|
#include <types/h1.h>
|
||||||
#include <types/proto_http.h>
|
|
||||||
#include <proto/hdr_idx.h>
|
#include <proto/hdr_idx.h>
|
||||||
|
|
||||||
extern const uint8_t h1_char_classes[256];
|
|
||||||
const char *http_parse_reqline(struct http_msg *msg,
|
const char *http_parse_reqline(struct http_msg *msg,
|
||||||
enum h1_state state, const char *ptr, const char *end,
|
enum h1_state state, const char *ptr, const char *end,
|
||||||
unsigned int *ret_ptr, enum h1_state *ret_state);
|
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);
|
struct h1m *h1m);
|
||||||
int h1_measure_trailers(const struct buffer *buf, unsigned int ofs, unsigned int max);
|
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
|
/* 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.
|
* certain bytes (ef: LF) or to skip to next byte and yield in case of failure.
|
||||||
*/
|
*/
|
||||||
|
@ -44,11 +44,6 @@
|
|||||||
* ver_token = 'H', 'P', 'T', '/', '.', and digits.
|
* 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_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);
|
||||||
@ -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_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);
|
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_req_custom(const char *kw);
|
||||||
struct action_kw *action_http_res_custom(const char *kw);
|
struct action_kw *action_http_res_custom(const char *kw);
|
||||||
int val_hdr(struct arg *arg, char **err_msg);
|
int val_hdr(struct arg *arg, char **err_msg);
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <common/xref.h>
|
#include <common/xref.h>
|
||||||
|
|
||||||
|
#include <types/h1.h>
|
||||||
#include <types/proxy.h>
|
#include <types/proxy.h>
|
||||||
#include <types/server.h>
|
#include <types/server.h>
|
||||||
|
|
||||||
|
@ -22,8 +22,9 @@
|
|||||||
#ifndef _TYPES_PROTO_HTTP_H
|
#ifndef _TYPES_PROTO_HTTP_H
|
||||||
#define _TYPES_PROTO_HTTP_H
|
#define _TYPES_PROTO_HTTP_H
|
||||||
|
|
||||||
#include <common/chunk.h>
|
#include <common/buf.h>
|
||||||
#include <common/config.h>
|
#include <common/config.h>
|
||||||
|
#include <common/http.h>
|
||||||
#include <common/mini-clist.h>
|
#include <common/mini-clist.h>
|
||||||
#include <common/regex.h>
|
#include <common/regex.h>
|
||||||
|
|
||||||
@ -31,7 +32,7 @@
|
|||||||
#include <types/h1.h>
|
#include <types/h1.h>
|
||||||
#include <types/hdr_idx.h>
|
#include <types/hdr_idx.h>
|
||||||
#include <types/filters.h>
|
#include <types/filters.h>
|
||||||
#include <types/sample.h>
|
//#include <types/sample.h>
|
||||||
|
|
||||||
/* These are the flags that are found in txn->flags */
|
/* These are the flags that are found in txn->flags */
|
||||||
|
|
||||||
@ -170,13 +171,6 @@ enum {
|
|||||||
PERSIST_TYPE_IGNORE, /* ignore-persist */
|
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 */
|
/* final results for http-request rules */
|
||||||
enum rule_result {
|
enum rule_result {
|
||||||
HTTP_RULE_RES_CONT = 0, /* nothing special, continue rules evaluation */
|
HTTP_RULE_RES_CONT = 0, /* nothing special, continue rules evaluation */
|
||||||
@ -188,25 +182,6 @@ enum rule_result {
|
|||||||
HTTP_RULE_RES_BADREQ, /* bad request */
|
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 */
|
/* status codes available for the stats admin page */
|
||||||
enum {
|
enum {
|
||||||
STAT_STATUS_INIT = 0,
|
STAT_STATUS_INIT = 0,
|
||||||
@ -298,13 +273,6 @@ struct http_msg {
|
|||||||
unsigned long long body_len; /* total known length of the body, excluding encoding */
|
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 proxy;
|
||||||
struct http_txn;
|
struct http_txn;
|
||||||
struct stream;
|
struct stream;
|
||||||
@ -349,16 +317,9 @@ struct hdr_ctx {
|
|||||||
int prev; /* index of previous header */
|
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_req_keywords;
|
||||||
extern struct action_kw_list http_res_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;
|
extern struct pool_head *pool_head_http_txn;
|
||||||
|
|
||||||
#endif /* _TYPES_PROTO_HTTP_H */
|
#endif /* _TYPES_PROTO_HTTP_H */
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include <common/chunk.h>
|
#include <common/chunk.h>
|
||||||
#include <common/config.h>
|
#include <common/config.h>
|
||||||
|
#include <common/http.h>
|
||||||
#include <common/mini-clist.h>
|
#include <common/mini-clist.h>
|
||||||
#include <common/regex.h>
|
#include <common/regex.h>
|
||||||
#include <common/tools.h>
|
#include <common/tools.h>
|
||||||
@ -45,7 +46,6 @@
|
|||||||
#include <types/listener.h>
|
#include <types/listener.h>
|
||||||
#include <types/log.h>
|
#include <types/log.h>
|
||||||
#include <types/obj_type.h>
|
#include <types/obj_type.h>
|
||||||
#include <types/proto_http.h>
|
|
||||||
#include <types/sample.h>
|
#include <types/sample.h>
|
||||||
#include <types/server.h>
|
#include <types/server.h>
|
||||||
#include <types/stick_table.h>
|
#include <types/stick_table.h>
|
||||||
|
@ -26,7 +26,8 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#include <common/chunk.h>
|
#include <common/buf.h>
|
||||||
|
#include <common/http.h>
|
||||||
#include <common/mini-clist.h>
|
#include <common/mini-clist.h>
|
||||||
|
|
||||||
struct arg;
|
struct arg;
|
||||||
@ -210,19 +211,6 @@ enum {
|
|||||||
struct session;
|
struct session;
|
||||||
struct stream;
|
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
|
/* 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
|
* store information needed across multiple calls (eg: restart point for a
|
||||||
* next occurrence). By definition it may store up to 8 pointers, or any
|
* 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 <len> has
|
* sample will automatically be duplicated when a change larger than <len> has
|
||||||
* to be performed. Thus it is safe to always set size to zero.
|
* 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 {
|
union sample_value {
|
||||||
long long int sint; /* used for signed 64bits integers */
|
long long int sint; /* used for signed 64bits integers */
|
||||||
struct in_addr ipv4; /* used for ipv4 addresses */
|
struct in_addr ipv4; /* used for ipv4 addresses */
|
||||||
struct in6_addr ipv6; /* used for ipv6 addresses */
|
struct in6_addr ipv6; /* used for ipv6 addresses */
|
||||||
struct buffer str; /* used for char strings or buffers */
|
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 */
|
/* Used to store sample constant */
|
||||||
|
@ -49,7 +49,6 @@
|
|||||||
#include <proto/mux_pt.h>
|
#include <proto/mux_pt.h>
|
||||||
#include <proto/queue.h>
|
#include <proto/queue.h>
|
||||||
#include <proto/port_range.h>
|
#include <proto/port_range.h>
|
||||||
#include <proto/proto_http.h>
|
|
||||||
#include <proto/proto_tcp.h>
|
#include <proto/proto_tcp.h>
|
||||||
#include <proto/protocol.h>
|
#include <proto/protocol.h>
|
||||||
#include <proto/proxy.h>
|
#include <proto/proxy.h>
|
||||||
|
@ -37,7 +37,6 @@
|
|||||||
#include <proto/acl.h>
|
#include <proto/acl.h>
|
||||||
#include <proto/compression.h>
|
#include <proto/compression.h>
|
||||||
#include <proto/freq_ctr.h>
|
#include <proto/freq_ctr.h>
|
||||||
#include <proto/proto_http.h>
|
|
||||||
#include <proto/stream.h>
|
#include <proto/stream.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
#include <types/compression.h>
|
#include <types/compression.h>
|
||||||
#include <types/filters.h>
|
#include <types/filters.h>
|
||||||
#include <types/proto_http.h>
|
#include <types/h1.h>
|
||||||
#include <types/proxy.h>
|
#include <types/proxy.h>
|
||||||
#include <types/sample.h>
|
#include <types/sample.h>
|
||||||
|
|
||||||
|
141
src/h1.c
141
src/h1.c
@ -18,147 +18,6 @@
|
|||||||
#include <proto/h1.h>
|
#include <proto/h1.h>
|
||||||
#include <proto/hdr_idx.h>
|
#include <proto/hdr_idx.h>
|
||||||
|
|
||||||
/* 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 <ptr> and <end>, starting with
|
* This function parses a status line between <ptr> and <end>, starting with
|
||||||
* parser state <state>. Only states HTTP_MSG_RPVER, HTTP_MSG_RPVER_SP,
|
* parser state <state>. Only states HTTP_MSG_RPVER, HTTP_MSG_RPVER_SP,
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#include <types/proxy.h>
|
#include <types/proxy.h>
|
||||||
#include <types/stats.h>
|
#include <types/stats.h>
|
||||||
|
|
||||||
#include <proto/proto_http.h>
|
#include <proto/h1.h>
|
||||||
#include <proto/proxy.h>
|
#include <proto/proxy.h>
|
||||||
#include <proto/server.h>
|
#include <proto/server.h>
|
||||||
#include <proto/stats.h>
|
#include <proto/stats.h>
|
||||||
|
185
src/http.c
Normal file
185
src/http.c
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
/*
|
||||||
|
* HTTP semantics
|
||||||
|
*
|
||||||
|
* Copyright 2000-2018 Willy Tarreau <w@1wt.eu>
|
||||||
|
*
|
||||||
|
* 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 <ctype.h>
|
||||||
|
#include <common/config.h>
|
||||||
|
#include <common/http.h>
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
@ -20,8 +20,6 @@
|
|||||||
|
|
||||||
#include <proto/backend.h>
|
#include <proto/backend.h>
|
||||||
#include <proto/lb_map.h>
|
#include <proto/lb_map.h>
|
||||||
#include <proto/proto_http.h>
|
|
||||||
#include <proto/proto_tcp.h>
|
|
||||||
#include <proto/queue.h>
|
#include <proto/queue.h>
|
||||||
|
|
||||||
/* this function updates the map according to server <srv>'s new state.
|
/* this function updates the map according to server <srv>'s new state.
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
#include <proto/applet.h>
|
#include <proto/applet.h>
|
||||||
#include <proto/cli.h>
|
#include <proto/cli.h>
|
||||||
#include <proto/frontend.h>
|
#include <proto/frontend.h>
|
||||||
#include <proto/proto_http.h>
|
#include <proto/h1.h>
|
||||||
#include <proto/log.h>
|
#include <proto/log.h>
|
||||||
#include <proto/sample.h>
|
#include <proto/sample.h>
|
||||||
#include <proto/stream.h>
|
#include <proto/stream.h>
|
||||||
|
@ -39,8 +39,6 @@
|
|||||||
#include <proto/log.h>
|
#include <proto/log.h>
|
||||||
#include <proto/hdr_idx.h>
|
#include <proto/hdr_idx.h>
|
||||||
#include <proto/mux_pt.h>
|
#include <proto/mux_pt.h>
|
||||||
#include <proto/proto_tcp.h>
|
|
||||||
#include <proto/proto_http.h>
|
|
||||||
#include <proto/proxy.h>
|
#include <proto/proxy.h>
|
||||||
#include <proto/session.h>
|
#include <proto/session.h>
|
||||||
#include <proto/stream.h>
|
#include <proto/stream.h>
|
||||||
|
@ -487,55 +487,6 @@ void init_proto_http()
|
|||||||
pool_head_uniqueid = create_pool("uniqueid", UNIQUEID_LEN, MEM_F_SHARED);
|
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
|
* Adds a header and its CRLF at the tail of the message's buffer, just before
|
||||||
* the last CRLF.
|
* 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);
|
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
|
/* 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.
|
* phase) and look for the "/" beginning the PATH. If not found, return NULL.
|
||||||
* It is returned otherwise.
|
* It is returned otherwise.
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include <common/chunk.h>
|
#include <common/chunk.h>
|
||||||
#include <common/hash.h>
|
#include <common/hash.h>
|
||||||
|
#include <common/http.h>
|
||||||
#include <common/standard.h>
|
#include <common/standard.h>
|
||||||
#include <common/uri_auth.h>
|
#include <common/uri_auth.h>
|
||||||
#include <common/base64.h>
|
#include <common/base64.h>
|
||||||
@ -27,7 +28,6 @@
|
|||||||
#include <proto/arg.h>
|
#include <proto/arg.h>
|
||||||
#include <proto/auth.h>
|
#include <proto/auth.h>
|
||||||
#include <proto/log.h>
|
#include <proto/log.h>
|
||||||
#include <proto/proto_http.h>
|
|
||||||
#include <proto/proxy.h>
|
#include <proto/proxy.h>
|
||||||
#include <proto/sample.h>
|
#include <proto/sample.h>
|
||||||
#include <proto/stick_table.h>
|
#include <proto/stick_table.h>
|
||||||
@ -749,7 +749,7 @@ static int c_meth2str(struct sample *smp)
|
|||||||
else if (smp->data.u.meth.meth < HTTP_METH_OTHER) {
|
else if (smp->data.u.meth.meth < HTTP_METH_OTHER) {
|
||||||
/* The method is known, copy the pointer containing the string. */
|
/* The method is known, copy the pointer containing the string. */
|
||||||
meth = smp->data.u.meth.meth;
|
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->data.u.str.data = http_known_methods[meth].len;
|
||||||
smp->flags |= SMP_F_CONST;
|
smp->flags |= SMP_F_CONST;
|
||||||
smp->data.type = SMP_T_STR;
|
smp->data.type = SMP_T_STR;
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <common/config.h>
|
#include <common/config.h>
|
||||||
#include <common/buffer.h>
|
#include <common/buffer.h>
|
||||||
#include <common/debug.h>
|
#include <common/debug.h>
|
||||||
|
#include <common/http.h>
|
||||||
#include <common/memory.h>
|
#include <common/memory.h>
|
||||||
|
|
||||||
#include <types/global.h>
|
#include <types/global.h>
|
||||||
@ -21,7 +22,6 @@
|
|||||||
#include <proto/connection.h>
|
#include <proto/connection.h>
|
||||||
#include <proto/listener.h>
|
#include <proto/listener.h>
|
||||||
#include <proto/log.h>
|
#include <proto/log.h>
|
||||||
#include <proto/proto_http.h>
|
|
||||||
#include <proto/proxy.h>
|
#include <proto/proxy.h>
|
||||||
#include <proto/session.h>
|
#include <proto/session.h>
|
||||||
#include <proto/stream.h>
|
#include <proto/stream.h>
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <common/compat.h>
|
#include <common/compat.h>
|
||||||
#include <common/config.h>
|
#include <common/config.h>
|
||||||
#include <common/debug.h>
|
#include <common/debug.h>
|
||||||
|
#include <common/http.h>
|
||||||
#include <common/memory.h>
|
#include <common/memory.h>
|
||||||
#include <common/mini-clist.h>
|
#include <common/mini-clist.h>
|
||||||
#include <common/standard.h>
|
#include <common/standard.h>
|
||||||
@ -57,7 +58,6 @@
|
|||||||
#include <proto/pipe.h>
|
#include <proto/pipe.h>
|
||||||
#include <proto/listener.h>
|
#include <proto/listener.h>
|
||||||
#include <proto/map.h>
|
#include <proto/map.h>
|
||||||
#include <proto/proto_http.h>
|
|
||||||
#include <proto/proxy.h>
|
#include <proto/proxy.h>
|
||||||
#include <proto/sample.h>
|
#include <proto/sample.h>
|
||||||
#include <proto/session.h>
|
#include <proto/session.h>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include <common/cfgparse.h>
|
#include <common/cfgparse.h>
|
||||||
|
#include <common/http.h>
|
||||||
#include <common/mini-clist.h>
|
#include <common/mini-clist.h>
|
||||||
|
|
||||||
#include <types/vars.h>
|
#include <types/vars.h>
|
||||||
|
Loading…
Reference in New Issue
Block a user