MAJOR: http: Remove the HTTP legacy code

First of all, all legacy HTTP analyzers and all functions exclusively used by
them were removed. So the most of the functions in proto_http.{c,h} were
removed. Only functions to deal with the HTTP transaction have been kept. Then,
http_msg and hdr_idx modules were entirely removed. And finally the structure
http_msg was lightened of all its useless information about the legacy HTTP. The
structure hdr_ctx was also removed because unused now, just like unused states
in the enum h1_state. Note that the memory pool "hdr_idx" was removed and
"http_txn" is now smaller.
This commit is contained in:
Christopher Faulet 2019-07-16 14:16:10 +02:00
parent bcac786b36
commit 711ed6ae4a
26 changed files with 26 additions and 9078 deletions

View File

@ -774,8 +774,8 @@ OBJS = src/proto_http.o src/cfgparse-listen.o src/proto_htx.o src/stream.o \
src/http_htx.o src/buffer.o src/hpack-tbl.o src/shctx.o src/sha1.o \
src/http.o src/hpack-dec.o src/action.o src/proto_udp.o src/http_acl.o \
src/xxhash.o src/hpack-enc.o src/h2.o src/freq_ctr.o src/lru.o \
src/protocol.o src/arg.o src/hpack-huff.o src/hdr_idx.o src/base64.o \
src/hash.o src/mailers.o src/activity.o src/http_msg.o src/version.o \
src/protocol.o src/arg.o src/hpack-huff.o src/base64.o \
src/hash.o src/mailers.o src/activity.o src/version.o \
src/mworker.o src/mworker-prog.o src/debug.o src/wdt.o src/dict.o \
src/xprt_handshake.o

View File

@ -22,10 +22,8 @@
#include <types/stream.h>
#include <proto/arg.h>
#include <proto/hdr_idx.h>
#include <proto/hlua.h>
#include <proto/log.h>
#include <proto/proto_http.h>
#include <proto/spoe.h>
#include <api.h>

View File

@ -1,96 +0,0 @@
/*
* include/proto/hdr_idx.h
* This file defines function prototypes for fast header indexation.
*
* Copyright (C) 2000-2011 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 _PROTO_HDR_IDX_H
#define _PROTO_HDR_IDX_H
#include <common/config.h>
#include <types/hdr_idx.h>
extern struct pool_head *pool_head_hdr_idx;
/*
* Initialize the list pointers.
* list->size must already be set. If list->size is set and list->v is
* non-null, list->v is also initialized..
*/
static inline void hdr_idx_init(struct hdr_idx *list)
{
if (list->size && list->v) {
register struct hdr_idx_elem e = { .len=0, .cr=0, .next=0};
list->v[0] = e;
}
list->tail = 0;
list->used = list->last = 1;
}
/*
* Return index of the first entry in the list. Usually, it means the index of
* the first header just after the request or response. If zero is returned, it
* means that the list is empty.
*/
static inline int hdr_idx_first_idx(const struct hdr_idx *list)
{
return list->v[0].next;
}
/*
* Return position of the first entry in the list. Usually, it means the
* position of the first header just after the request, but it can also be the
* end of the headers if the request has no header. hdr_idx_start_idx() should
* be checked before to ensure there is a valid header.
*/
static inline int hdr_idx_first_pos(const struct hdr_idx *list)
{
return list->v[0].len + list->v[0].cr + 1;
}
/*
* Sets the information about the start line. Its length and the presence of
* the CR are registered so that hdr_idx_first_pos() knows exactly where to
* find the first header.
*/
static inline void hdr_idx_set_start(struct hdr_idx *list, int len, int cr)
{
list->v[0].len = len;
list->v[0].cr = cr;
}
/*
* Add a header entry to <list> after element <after>. <after> is ignored when
* the list is empty or full. Common usage is to set <after> to list->tail.
*
* Returns the position of the new entry in the list (from 1 to size-1), or 0
* if the array is already full. An effort is made to fill the array linearly,
* but once the last entry has been used, we have to search for unused blocks,
* which takes much more time. For this reason, it's important to size is
* appropriately.
*/
int hdr_idx_add(int len, int cr, struct hdr_idx *list, int after);
#endif /* _PROTO_HDR_IDX_H */
/*
* Local variables:
* c-indent-level: 8
* c-basic-offset: 8
* End:
*/

View File

@ -23,6 +23,7 @@
#define _PROTO_PROTO_HTTP_H
#include <common/config.h>
#include <common/htx.h>
#include <types/proto_http.h>
#include <types/stream.h>
#include <types/task.h>
@ -31,43 +32,6 @@
extern struct pool_head *pool_head_uniqueid;
int process_cli(struct stream *s);
int process_srv_data(struct stream *s);
int process_srv_conn(struct stream *s);
int http_wait_for_request(struct stream *s, struct channel *req, int an_bit);
int http_process_req_common(struct stream *s, struct channel *req, int an_bit, struct proxy *px);
int http_process_request(struct stream *s, struct channel *req, int an_bit);
int http_process_tarpit(struct stream *s, struct channel *req, int an_bit);
int http_wait_for_request_body(struct stream *s, struct channel *req, int an_bit);
int http_send_name_header(struct stream *s, struct proxy* be, const char* svr_name);
int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit);
int http_process_res_common(struct stream *s, struct channel *rep, int an_bit, struct proxy *px);
int http_request_forward_body(struct stream *s, struct channel *req, int an_bit);
int http_response_forward_body(struct stream *s, struct channel *res, int an_bit);
int http_upgrade_v09_to_v10(struct http_txn *txn);
void http_msg_analyzer(struct http_msg *msg, struct hdr_idx *idx);
void http_txn_reset_req(struct http_txn *txn);
void http_txn_reset_res(struct http_txn *txn);
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);
const char *http_parse_stsline(struct http_msg *msg,
enum h1_state state, const char *ptr, const char *end,
unsigned int *ret_ptr, enum h1_state *ret_state);
int http_forward_trailers(struct http_msg *msg);
int http_legacy_replace_header(struct hdr_idx *idx, struct http_msg *msg,
const char *name, unsigned int name_len,
const char *str, struct my_regex *re,
struct buffer *output);
int http_legacy_replace_full_header(struct hdr_idx *idx, struct http_msg *msg,
const char *name, unsigned int name_len,
const char *str, struct my_regex *re,
struct buffer *output);
/* Export HTX analyzers and helpers */
// FIXME: Rename all these functions http_* once legacy code will be removed
struct htx;
int htx_wait_for_request(struct stream *s, struct channel *req, int an_bit);
int htx_process_req_common(struct stream *s, struct channel *req, int an_bit, struct proxy *px);
int htx_process_request(struct stream *s, struct channel *req, int an_bit);
@ -92,171 +56,20 @@ void htx_reply_and_close(struct stream *s, short status, struct buffer *msg);
void htx_return_srv_error(struct stream *s, struct stream_interface *si);
struct buffer *htx_error_message(struct stream *s);
void debug_hdr(const char *dir, struct stream *s, const char *start, const char *end);
int apply_filter_to_req_headers(struct stream *s, struct channel *req, struct hdr_exp *exp);
int apply_filter_to_req_line(struct stream *s, struct channel *req, struct hdr_exp *exp);
int apply_filters_to_request(struct stream *s, struct channel *req, struct proxy *px);
int apply_filters_to_response(struct stream *s, struct channel *rtr, struct proxy *px);
void manage_client_side_cookies(struct stream *s, struct channel *req);
void manage_server_side_cookies(struct stream *s, struct channel *rtr);
void check_request_for_cacheability(struct stream *s, struct channel *chn);
void check_response_for_cacheability(struct stream *s, struct channel *rtr);
int stats_check_uri(struct stream_interface *si, struct http_txn *txn, struct proxy *backend);
int http_find_full_header2(const char *name, int len,
char *sol, struct hdr_idx *idx,
struct hdr_ctx *ctx);
int http_find_header2(const char *name, int len,
char *sol, struct hdr_idx *idx,
struct hdr_ctx *ctx);
int http_find_next_header(char *sol, struct hdr_idx *idx,
struct hdr_ctx *ctx);
int http_remove_header2(struct http_msg *msg, struct hdr_idx *idx, struct hdr_ctx *ctx);
int http_header_add_tail2(struct http_msg *msg, struct hdr_idx *hdr_idx, const char *text, int len);
int http_replace_req_line(int action, const char *replace, int len, struct proxy *px, struct stream *s);
void http_set_status(unsigned int status, const char *reason, struct stream *s);
int http_transform_header_str(struct stream* s, struct http_msg *msg, const char* name,
unsigned int name_len, const char *str, struct my_regex *re,
int action);
int http_handle_stats(struct stream *s, struct channel *req);
enum rule_result http_req_get_intercept_rule(struct proxy *px, struct list *rules,
struct stream *s, int *deny_status);
enum rule_result http_res_get_intercept_rule(struct proxy *px, struct list *rules,
struct stream *s);
int http_apply_redirect_rule(struct redirect_rule *rule, struct stream *s, struct http_txn *txn);
void http_perform_server_redirect(struct stream *s, struct stream_interface *si);
void http_return_srv_error(struct stream *s, struct stream_interface *si);
void http_capture_headers(char *som, struct hdr_idx *idx,
char **cap, struct cap_hdr *cap_hdr);
void http_capture_bad_message(struct proxy *proxy, struct stream *s,
struct http_msg *msg,
enum h1_state state, struct proxy *other_end);
unsigned int http_get_hdr(const struct http_msg *msg, const char *hname, int hlen,
struct hdr_idx *idx, int occ,
struct hdr_ctx *ctx, char **vptr, size_t *vlen);
unsigned int http_get_fhdr(const struct http_msg *msg, const char *hname, int hlen,
struct hdr_idx *idx, int occ,
struct hdr_ctx *ctx, char **vptr, size_t *vlen);
char *http_txn_get_path(const struct http_txn *txn);
struct http_txn *http_alloc_txn(struct stream *s);
void http_init_txn(struct stream *s);
void http_end_txn(struct stream *s);
void http_reset_txn(struct stream *s);
void http_end_txn_clean_session(struct stream *s);
void http_resync_states(struct stream *s);
void http_parse_connection_header(struct http_txn *txn, struct http_msg *msg, int to_del);
void http_change_connection_header(struct http_txn *txn, struct http_msg *msg, int wanted);
void http_adjust_conn_mode(struct stream *s, struct http_txn *txn, struct http_msg *msg);
int http_msg_forward_body(struct stream *s, struct http_msg *msg);
int http_msg_forward_chunked_body(struct stream *s, struct http_msg *msg);
void http_reply_and_close(struct stream *s, short status, struct buffer *msg);
struct buffer *http_error_message(struct stream *s);
/* to be used when contents change in an HTTP message */
#define http_msg_move_end(msg, bytes) do { \
unsigned int _bytes = (bytes); \
(msg)->next += (_bytes); \
(msg)->sov += (_bytes); \
(msg)->eoh += (_bytes); \
} while (0)
/* Return the amount of bytes that need to be rewound before buf->p to access
* the current message's headers. The purpose is to be able to easily fetch
* the message's beginning before headers are forwarded, as well as after.
* The principle is that msg->eoh and msg->eol are immutable while msg->sov
* equals the sum of the two before forwarding and is zero after forwarding,
* so the difference cancels the rewinding.
*/
static inline int http_hdr_rewind(const struct http_msg *msg)
{
return msg->eoh + msg->eol - msg->sov;
}
/* Return the amount of bytes that need to be rewound before buf->p to access
* the current message's URI. The purpose is to be able to easily fetch
* the message's beginning before headers are forwarded, as well as after.
*/
static inline int http_uri_rewind(const struct http_msg *msg)
{
return http_hdr_rewind(msg) - msg->sl.rq.u;
}
/* Return the amount of bytes that need to be rewound before buf->p to access
* the current message's BODY. The purpose is to be able to easily fetch
* the message's beginning before headers are forwarded, as well as after.
*/
static inline int http_body_rewind(const struct http_msg *msg)
{
return http_hdr_rewind(msg) - msg->eoh - msg->eol;
}
/* Return the amount of bytes that need to be rewound before buf->p to access
* the current message's DATA. The difference with the function above is that
* if a chunk is present and has already been parsed, its size is skipped so
* that the byte pointed to is the first byte of actual data. The function is
* safe for use in state HTTP_MSG_DATA regardless of whether the headers were
* already forwarded or not.
*/
static inline int http_data_rewind(const struct http_msg *msg)
{
return http_body_rewind(msg) - msg->sol;
}
/* Return the maximum amount of bytes that may be read after the beginning of
* the message body, according to the advertised length. The function is safe
* for use between HTTP_MSG_BODY and HTTP_MSG_DATA regardless of whether the
* headers were already forwarded or not.
*/
static inline int http_body_bytes(const struct http_msg *msg)
{
int len;
len = ci_data(msg->chn) - msg->sov - msg->sol;
if (len > msg->body_len)
len = msg->body_len;
return len;
}
/* for debugging, reports the HTTP/1 message state name (legacy version) */
static inline const char *h1_msg_state_str(enum h1_state msg_state)
{
switch (msg_state) {
case HTTP_MSG_RQBEFORE: return "MSG_RQBEFORE";
case HTTP_MSG_RQBEFORE_CR: return "MSG_RQBEFORE_CR";
case HTTP_MSG_RQMETH: return "MSG_RQMETH";
case HTTP_MSG_RQMETH_SP: return "MSG_RQMETH_SP";
case HTTP_MSG_RQURI: return "MSG_RQURI";
case HTTP_MSG_RQURI_SP: return "MSG_RQURI_SP";
case HTTP_MSG_RQVER: return "MSG_RQVER";
case HTTP_MSG_RQLINE_END: return "MSG_RQLINE_END";
case HTTP_MSG_RPBEFORE: return "MSG_RPBEFORE";
case HTTP_MSG_RPBEFORE_CR: return "MSG_RPBEFORE_CR";
case HTTP_MSG_RPVER: return "MSG_RPVER";
case HTTP_MSG_RPVER_SP: return "MSG_RPVER_SP";
case HTTP_MSG_RPCODE: return "MSG_RPCODE";
case HTTP_MSG_RPCODE_SP: return "MSG_RPCODE_SP";
case HTTP_MSG_RPREASON: return "MSG_RPREASON";
case HTTP_MSG_RPLINE_END: return "MSG_RPLINE_END";
case HTTP_MSG_HDR_FIRST: return "MSG_HDR_FIRST";
case HTTP_MSG_HDR_NAME: return "MSG_HDR_NAME";
case HTTP_MSG_HDR_COL: return "MSG_HDR_COL";
case HTTP_MSG_HDR_L1_SP: return "MSG_HDR_L1_SP";
case HTTP_MSG_HDR_L1_LF: return "MSG_HDR_L1_LF";
case HTTP_MSG_HDR_L1_LWS: return "MSG_HDR_L1_LWS";
case HTTP_MSG_HDR_VAL: return "MSG_HDR_VAL";
case HTTP_MSG_HDR_L2_LF: return "MSG_HDR_L2_LF";
case HTTP_MSG_HDR_L2_LWS: return "MSG_HDR_L2_LWS";
case HTTP_MSG_LAST_LF: return "MSG_LAST_LF";
case HTTP_MSG_ERROR: return "MSG_ERROR";
case HTTP_MSG_BODY: return "MSG_BODY";
case HTTP_MSG_100_SENT: return "MSG_100_SENT";
case HTTP_MSG_CHUNK_SIZE: return "MSG_CHUNK_SIZE";
case HTTP_MSG_DATA: return "MSG_DATA";
case HTTP_MSG_CHUNK_CRLF: return "MSG_CHUNK_CRLF";
case HTTP_MSG_TRAILERS: return "MSG_TRAILERS";
case HTTP_MSG_ENDING: return "MSG_ENDING";
case HTTP_MSG_DONE: return "MSG_DONE";
case HTTP_MSG_CLOSING: return "MSG_CLOSING";

View File

@ -1,84 +0,0 @@
/*
include/types/hdr_idx.h
This file defines everything related to fast header indexation.
Copyright (C) 2000-2006 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
*/
/*
* The type of structure described here is a finite linked list used to
* reference small number of objects of small size. This is typically used
* to index HTTP headers within one request or response, in order to be able
* to add, remove, modify and check them in an efficient way. The overhead is
* very low : 32 bits are used per list element. This is enough to reference
* 32k headers of at most 64kB each, with one bit to indicate if the header
* is terminated by 1 or 2 chars. It may also evolve towards something like
* 1k headers of at most 64B for the name and 32kB of data + CR/CRLF.
*
* A future evolution of this concept may allow for fast header manipulation
* without data movement through the use of vectors. This is not yet possible
* in this version, whose goal is only to avoid parsing whole lines for each
* consultation.
*
*/
#ifndef _TYPES_HDR_IDX_H
#define _TYPES_HDR_IDX_H
/*
* This describes one element of the hdr_idx array.
* It's a tiny linked list of at most 32k 32bit elements. The first one has a
* special meaning, it's used as the head of the list and cannod be removed.
* That way, we know that 'next==0' is not possible so we use it to indicate
* an end of list. Also, [0]->next always designates the head of the list. The
* first allocatable element is at 1. By convention, [0]->len indicates how
* many chars should be skipped in the original buffer before finding the first
* header.
*
*/
struct hdr_idx_elem {
unsigned len :16; /* length of this header not counting CRLF. 0=unused entry. */
unsigned cr : 1; /* CR present (1=CRLF, 0=LF). Total line size=len+cr+1. */
unsigned next :15; /* offset of next header if len>0. 0=end of list. */
};
/*
* This structure provides necessary information to store, find, remove
* index entries from a list. This list cannot reference more than 32k
* elements of 64k each.
*/
struct hdr_idx {
struct hdr_idx_elem *v; /* the array itself */
short size; /* size of the array including the head */
short used; /* # of elements really used (1..size) */
short last; /* length of the allocated area (1..size) */
signed short tail; /* last used element, 0..size-1 */
};
#endif /* _TYPES_HDR_IDX_H */
/*
* Local variables:
* c-indent-level: 8
* c-basic-offset: 8
* End:
*/

View File

@ -29,7 +29,6 @@
#include <common/regex.h>
#include <types/channel.h>
#include <types/hdr_idx.h>
#include <types/filters.h>
//#include <types/sample.h>
@ -188,110 +187,30 @@ enum rule_result {
*/
enum h1_state {
HTTP_MSG_RQBEFORE = 0, // request: leading LF, before start line
HTTP_MSG_RQBEFORE_CR = 1, // request: leading CRLF, before start line
/* these ones define a request start line */
HTTP_MSG_RQMETH = 2, // parsing the Method
HTTP_MSG_RQMETH_SP = 3, // space(s) after the Method
HTTP_MSG_RQURI = 4, // parsing the Request URI
HTTP_MSG_RQURI_SP = 5, // space(s) after the Request URI
HTTP_MSG_RQVER = 6, // parsing the Request Version
HTTP_MSG_RQLINE_END = 7, // end of request line (CR or LF)
HTTP_MSG_RPBEFORE = 8, // response: leading LF, before start line
HTTP_MSG_RPBEFORE_CR = 9, // response: leading CRLF, before start line
/* these ones define a response start line */
HTTP_MSG_RPVER = 10, // parsing the Response Version
HTTP_MSG_RPVER_SP = 11, // space(s) after the Response Version
HTTP_MSG_RPCODE = 12, // response code
HTTP_MSG_RPCODE_SP = 13, // space(s) after the response code
HTTP_MSG_RPREASON = 14, // response reason
HTTP_MSG_RPLINE_END = 15, // end of response line (CR or LF)
/* common header processing */
HTTP_MSG_HDR_FIRST = 16, // waiting for first header or last CRLF (no LWS possible)
HTTP_MSG_HDR_NAME = 17, // parsing header name
HTTP_MSG_HDR_COL = 18, // parsing header colon
HTTP_MSG_HDR_L1_SP = 19, // parsing header LWS (SP|HT) before value
HTTP_MSG_HDR_L1_LF = 20, // parsing header LWS (LF) before value
HTTP_MSG_HDR_L1_LWS = 21, // checking whether it's a new header or an LWS
HTTP_MSG_HDR_VAL = 22, // parsing header value
HTTP_MSG_HDR_L2_LF = 23, // parsing header LWS (LF) inside/after value
HTTP_MSG_HDR_L2_LWS = 24, // checking whether it's a new header or an LWS
HTTP_MSG_LAST_LF = 25, // parsing last LF
HTTP_MSG_RPBEFORE = 1, // response: leading LF, before start line
/* error state : must be before HTTP_MSG_BODY so that (>=BODY) always indicates
* that data are being processed.
*/
HTTP_MSG_ERROR = 26, // an error occurred
HTTP_MSG_ERROR = 2, // an error occurred
/* Body processing.
* The state HTTP_MSG_BODY is a delimiter to know if we're waiting for headers
* or body. All the sub-states below also indicate we're processing the body,
* with some additional information.
*/
HTTP_MSG_BODY = 27, // parsing body at end of headers
HTTP_MSG_100_SENT = 28, // parsing body after a 100-Continue was sent
HTTP_MSG_CHUNK_SIZE = 29, // parsing the chunk size (RFC7230 #4.1)
HTTP_MSG_DATA = 30, // skipping data chunk / content-length data
HTTP_MSG_CHUNK_CRLF = 31, // skipping CRLF after data chunk
HTTP_MSG_TRAILERS = 32, // trailers (post-data entity headers)
HTTP_MSG_BODY = 3, // parsing body at end of headers
HTTP_MSG_DATA = 4, // skipping data chunk / content-length data
/* we enter this state when we've received the end of the current message */
HTTP_MSG_ENDING = 33, // message end received, wait that the filters end too
HTTP_MSG_DONE = 34, // message end received, waiting for resync or close
HTTP_MSG_CLOSING = 35, // shutdown_w done, not all bytes sent yet
HTTP_MSG_CLOSED = 36, // shutdown_w done, all bytes sent
HTTP_MSG_TUNNEL = 37, // tunneled data after DONE
HTTP_MSG_ENDING = 5, // message end received, wait that the filters end too
HTTP_MSG_DONE = 6, // message end received, waiting for resync or close
HTTP_MSG_CLOSING = 7, // shutdown_w done, not all bytes sent yet
HTTP_MSG_CLOSED = 8, // shutdown_w done, all bytes sent
HTTP_MSG_TUNNEL = 9, // tunneled data after DONE
} __attribute__((packed));
/* This is an HTTP message, as described in RFC7230. It can be either a request
* message or a response message.
*
* The values there are a little bit obscure, because their meaning can change
* during the parsing. Please read carefully doc/internal/body-parsing.txt if
* you need to manipulate them. Quick reminder :
*
* - eoh (End of Headers) : relative offset in the buffer of first byte that
* is not part of a completely processed header.
* During parsing, it points to last header seen
* for states after START. When in HTTP_MSG_BODY,
* eoh points to the first byte of the last CRLF
* preceding data. Relative to buffer's origin.
* This value then remains unchanged till the end
* so that we can rewind the buffer to change some
* headers if needed (eg: http-send-name-header).
*
* - sov (start of value) : Before HTTP_MSG_BODY, points to the value of
* the header being parsed. Starting from
* HTTP_MSG_BODY, will point to the start of the
* body (relative to buffer's origin). It can be
* negative when forwarding data. It stops growing
* once data start to leave the buffer.
*
* - next (parse pointer) : next relative byte to be parsed. Always points
* to a byte matching the current state.
*
* - sol (start of line) : start of current line before MSG_BODY. Starting
* from MSG_BODY and until MSG_TRAILERS, contains
* the length of the last parsed chunk size so that
* when added to sov it always points to the
* beginning of the current data chunk.
* in MSG_TRAILERS state, it contains the length of
* the last parsed part of the trailer headers.
*
* - eol (End of Line) : Before HTTP_MSG_BODY, relative offset in the
* buffer of the first byte which marks the end of
* the line current (LF or CRLF).
* From HTTP_MSG_BODY to the end, contains the
* length of the last CRLF (1 for a plain LF, or 2
* for a true CRLF). So eoh+eol always contain the
* exact size of the header size.
*
* Note that all offsets are relative to the origin of the buffer (buf->p)
* which always points to the beginning of the message (request or response).
* Since a message may not wrap, pointer computations may be one without any
* care for wrapping (no addition overflow nor subtract underflow).
/* This is the state of an HTTP seen from the analyzers point of view. It can be
* either a request message or a response message.
*/
struct http_msg {
enum h1_state msg_state; /* where we are in the current message parsing */
@ -299,39 +218,12 @@ struct http_msg {
unsigned char flags; /* flags describing the message (HTTP version, ...) */
/* 5 bytes unused here */
struct channel *chn; /* pointer to the channel transporting the message */
unsigned int next; /* pointer to next byte to parse, relative to buf->p */
int sov; /* current header: start of value ; data: start of body */
unsigned int eoh; /* End Of Headers, relative to buffer */
unsigned int sol; /* start of current line during parsing otherwise zero */
unsigned int eol; /* end of line */
int err_pos; /* err handling: -2=block, -1=pass, 0+=detected */
union { /* useful start line pointers, relative to ->sol */
struct {
int l; /* request line length (not including CR) */
int m_l; /* METHOD length (method starts at buf->p) */
int u, u_l; /* URI, length */
int v, v_l; /* VERSION, length */
} rq; /* request line : field, length */
struct {
int l; /* status line length (not including CR) */
int v_l; /* VERSION length (version starts at buf->p) */
int c, c_l; /* CODE, length */
int r, r_l; /* REASON, length */
} st; /* status line : field, length */
} sl; /* start line */
unsigned long long chunk_len; /* cache for last chunk size or content-length header value */
unsigned long long body_len; /* total known length of the body, excluding encoding */
};
struct proxy;
struct http_txn;
struct stream;
/* This is an HTTP transaction. It contains both a request message and a
* response message (which can be empty).
*/
struct http_txn {
struct hdr_idx hdr_idx; /* array of header indexes (max: global.tune.max_http_hdr) */
struct http_msg rsp; /* HTTP response message */
struct http_msg req; /* HTTP request message */
unsigned int flags; /* transaction flags */
@ -349,24 +241,6 @@ struct http_txn {
struct http_auth_data auth; /* HTTP auth data */
};
/* This structure is used by http_find_header() to return values of headers.
* The header starts at <line>, the value (excluding leading and trailing white
* spaces) at <line>+<val> for <vlen> bytes, followed by optional <tws> trailing
* white spaces, and sets <line>+<del> to point to the last delimitor (colon or
* comma) before this value. <prev> points to the index of the header whose next
* is this one.
*/
struct hdr_ctx {
char *line;
int idx;
int val; /* relative to line, may skip some leading white spaces */
int vlen; /* relative to line+val, stops before trailing white spaces */
int tws; /* added to vlen if some trailing white spaces are present */
int del; /* relative to line */
int prev; /* index of previous header */
};
extern struct pool_head *pool_head_http_txn;
#endif /* _TYPES_PROTO_HTTP_H */

View File

@ -133,7 +133,7 @@ enum {
SMP_USE_TXFIN = 1 << SMP_SRC_TXFIN, /* final information about the transaction (eg: #comp rate) */
SMP_USE_SSFIN = 1 << SMP_SRC_SSFIN, /* final information about the stream (eg: #requests, final flags) */
/* This composite one is useful to detect if an hdr_idx needs to be allocated */
/* This composite one is useful to detect if an http_txn needs to be allocated */
SMP_USE_HTTP_ANY = SMP_USE_HRQHV | SMP_USE_HRQHP | SMP_USE_HRQBO |
SMP_USE_HRSHV | SMP_USE_HRSHP | SMP_USE_HRSBO,
};

View File

@ -22,7 +22,6 @@
#include <proto/channel.h>
#include <proto/cli.h>
#include <proto/proxy.h>
#include <proto/hdr_idx.h>
#include <proto/http_htx.h>
#include <proto/filters.h>
#include <proto/http_rules.h>

View File

@ -1829,7 +1829,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
}
}
/* check if we need to allocate an hdr_idx struct for HTTP parsing */
/* check if we need to allocate an http_txn struct for HTTP parsing */
curproxy->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
if (strcmp(args[myidx], "table") == 0) {

View File

@ -63,7 +63,6 @@
#include <proto/stats.h>
#include <proto/filters.h>
#include <proto/frontend.h>
#include <proto/hdr_idx.h>
#include <proto/http_rules.h>
#include <proto/lb_chash.h>
#include <proto/lb_fas.h>
@ -4056,10 +4055,6 @@ out_uri_auth_compat:
curproxy->server_state_file_name = strdup(curproxy->id);
}
pool_head_hdr_idx = create_pool("hdr_idx",
global.tune.max_http_hdr * sizeof(struct hdr_idx_elem),
MEM_F_SHARED);
list_for_each_entry(curr_resolvers, &dns_resolvers, list) {
if (LIST_ISEMPTY(&curr_resolvers->nameservers)) {
ha_warning("config : resolvers '%s' [%s:%d] has no nameservers configured!\n",

View File

@ -24,7 +24,6 @@
#include <proto/compression.h>
#include <proto/filters.h>
#include <proto/hdr_idx.h>
#include <proto/http_htx.h>
#include <proto/proto_http.h>
#include <proto/sample.h>

View File

@ -26,7 +26,6 @@
#include <types/stream.h>
#include <proto/filters.h>
#include <proto/hdr_idx.h>
#include <proto/http_htx.h>
#include <proto/log.h>
#include <proto/proto_http.h>

View File

@ -38,7 +38,6 @@
#include <proto/fd.h>
#include <proto/frontend.h>
#include <proto/log.h>
#include <proto/hdr_idx.h>
#include <proto/proto_tcp.h>
#include <proto/proto_http.h>
#include <proto/proxy.h>

View File

@ -16,7 +16,6 @@
#include <common/http-hdr.h>
#include <proto/channel.h>
#include <proto/hdr_idx.h>
/* Parse the Content-Length header field of an HTTP/1 request. The function
* checks all possible occurrences of a comma-delimited value, and verifies

View File

@ -108,7 +108,6 @@
#include <proto/connection.h>
#include <proto/fd.h>
#include <proto/filters.h>
#include <proto/hdr_idx.h>
#include <proto/hlua.h>
#include <proto/http_rules.h>
#include <proto/listener.h>

View File

@ -1,72 +0,0 @@
/*
* Header indexation functions.
*
* Copyright 2000-2011 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 <common/config.h>
#include <common/memory.h>
#include <proto/hdr_idx.h>
struct pool_head *pool_head_hdr_idx = NULL;
/*
* Add a header entry to <list> after element <after>. <after> is ignored when
* the list is empty or full. Common usage is to set <after> to list->tail.
*
* Returns the position of the new entry in the list (from 1 to size-1), or 0
* if the array is already full. An effort is made to fill the array linearly,
* but once the last entry has been used, we have to search for unused blocks,
* which takes much more time. For this reason, it's important to size is
* appropriately.
*/
int hdr_idx_add(int len, int cr, struct hdr_idx *list, int after)
{
register struct hdr_idx_elem e = { .len=0, .cr=0, .next=0};
int new;
e.len = len;
e.cr = cr;
if (list->used == list->size) {
/* list is full */
return -1;
}
if (list->last < list->size) {
/* list is not completely used, we can fill linearly */
new = list->last++;
} else {
/* That's the worst situation :
* we have to scan the list for holes. We know that we
* will find a place because the list is not full.
*/
new = 1;
while (list->v[new].len)
new++;
}
/* insert the new element between <after> and the next one (or end) */
e.next = list->v[after].next;
list->v[after].next = new;
list->used++;
list->v[new] = e;
list->tail = new;
return new;
}
/*
* Local variables:
* c-indent-level: 8
* c-basic-offset: 8
* End:
*/

View File

@ -42,7 +42,6 @@
#include <proto/cli.h>
#include <proto/connection.h>
#include <proto/stats.h>
#include <proto/hdr_idx.h>
#include <proto/hlua.h>
#include <proto/hlua_fcn.h>
#include <proto/http_fetch.h>

View File

@ -33,7 +33,6 @@
#include <proto/arg.h>
#include <proto/auth.h>
#include <proto/hdr_idx.h>
#include <proto/http_fetch.h>
#include <proto/http_htx.h>
#include <proto/log.h>
@ -1332,7 +1331,7 @@ static int smp_fetch_capture_req_ver(const struct arg *args, struct sample *smp,
{
struct http_txn *txn = smp->strm->txn;
if (!txn || txn->req.msg_state < HTTP_MSG_HDR_FIRST)
if (!txn || txn->req.msg_state >= HTTP_MSG_BODY)
return 0;
if (txn->req.flags & HTTP_MSGF_VER_11)
@ -1354,7 +1353,7 @@ static int smp_fetch_capture_res_ver(const struct arg *args, struct sample *smp,
{
struct http_txn *txn = smp->strm->txn;
if (!txn || txn->rsp.msg_state < HTTP_MSG_HDR_FIRST)
if (!txn || txn->rsp.msg_state >= HTTP_MSG_BODY)
return 0;
if (txn->rsp.flags & HTTP_MSGF_VER_11)

File diff suppressed because it is too large Load Diff

View File

@ -517,7 +517,7 @@ int add_sample_to_logformat_list(char *text, char *arg, int arg_len, struct prox
goto error_free;
}
/* check if we need to allocate an hdr_idx struct for HTTP parsing */
/* check if we need to allocate an http_txn struct for HTTP parsing */
/* Note, we may also need to set curpx->to_log with certain fetches */
curpx->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);

View File

@ -40,7 +40,6 @@
#include <proto/fd.h>
#include <proto/frontend.h>
#include <proto/log.h>
#include <proto/hdr_idx.h>
#include <proto/mux_pt.h>
#include <proto/peers.h>
#include <proto/proxy.h>

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,6 @@
#include <proto/checks.h>
#include <proto/connection.h>
#include <proto/filters.h>
#include <proto/hdr_idx.h>
#include <proto/http_htx.h>
#include <proto/log.h>
#include <proto/pattern.h>

View File

@ -41,7 +41,6 @@
#include <proto/backend.h>
#include <proto/fd.h>
#include <proto/filters.h>
#include <proto/hdr_idx.h>
#include <proto/listener.h>
#include <proto/log.h>
#include <proto/proto_tcp.h>
@ -1428,7 +1427,7 @@ int stream_set_backend(struct stream *s, struct proxy *be)
s->req.analysers |= be->be_req_ana & ~(strm_li(s) ? strm_li(s)->analysers : 0);
/* If the target backend requires HTTP processing, we have to allocate
* the HTTP transaction and hdr_idx if we did not have one.
* the HTTP transaction if we did not have one.
*/
if (unlikely(!s->txn && be->http_needed)) {
if (unlikely(!http_alloc_txn(s)))
@ -1444,9 +1443,6 @@ int stream_set_backend(struct stream *s, struct proxy *be)
s->req.analysers |= AN_REQ_FLT_HTTP_HDRS;
if (s->txn) {
if (be->options2 & PR_O2_RSPBUG_OK)
s->txn->rsp.err_pos = -1; /* let buggy responses pass */
/* If we chain a TCP frontend to an HTX backend, we must upgrade
* the client mux */
if (!IS_HTX_STRM(s) && be->mode == PR_MODE_HTTP) {
@ -1478,8 +1474,7 @@ int stream_set_backend(struct stream *s, struct proxy *be)
s->txn->req.flags |= HTTP_MSGF_WAIT_CONN;
/* we may request to parse a request body */
if ((be->options & PR_O_WREQ_BODY) &&
(s->txn->req.body_len || (s->txn->req.flags & HTTP_MSGF_TE_CHNK)))
if (be->options & PR_O_WREQ_BODY)
s->req.analysers |= AN_REQ_HTTP_BODY;
}

View File

@ -46,7 +46,6 @@
#include <proto/filters.h>
#include <proto/freq_ctr.h>
#include <proto/frontend.h>
#include <proto/hdr_idx.h>
#include <proto/hlua.h>
#include <proto/http_rules.h>
#include <proto/listener.h>
@ -429,7 +428,6 @@ static void stream_free(struct stream *s)
}
if (s->txn) {
pool_free(pool_head_hdr_idx, s->txn->hdr_idx.v);
pool_free(pool_head_http_txn, s->txn);
s->txn = NULL;
}
@ -495,7 +493,6 @@ static void stream_free(struct stream *s)
if (fe && unlikely(fe->state == PR_STSTOPPED)) {
pool_flush(pool_head_buffer);
pool_flush(pool_head_http_txn);
pool_flush(pool_head_hdr_idx);
pool_flush(pool_head_requri);
pool_flush(pool_head_capture);
pool_flush(pool_head_stream);

View File

@ -743,7 +743,7 @@ static int tcp_parse_request_rule(char **args, int arg, int section_type,
curpx->req_cap = hdr;
curpx->to_log |= LW_REQHDR;
/* check if we need to allocate an hdr_idx struct for HTTP parsing */
/* check if we need to allocate an http_txn struct for HTTP parsing */
curpx->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
rule->arg.cap.expr = expr;
@ -781,7 +781,7 @@ static int tcp_parse_request_rule(char **args, int arg, int section_type,
return -1;
}
/* check if we need to allocate an hdr_idx struct for HTTP parsing */
/* check if we need to allocate an http_txn struct for HTTP parsing */
curpx->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
if (strcmp(args[arg], "table") == 0) {