2006-06-26 00:48:02 +00:00
|
|
|
/*
|
2009-10-04 13:56:38 +00:00
|
|
|
* include/proto/proto_http.h
|
|
|
|
* This file contains HTTP protocol definitions.
|
|
|
|
*
|
2011-01-06 16:51:27 +00:00
|
|
|
* Copyright (C) 2000-2011 Willy Tarreau - w@1wt.eu
|
2009-10-04 13:56:38 +00:00
|
|
|
*
|
|
|
|
* 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
|
|
|
|
*/
|
2006-06-26 00:48:02 +00:00
|
|
|
|
|
|
|
#ifndef _PROTO_PROTO_HTTP_H
|
|
|
|
#define _PROTO_PROTO_HTTP_H
|
|
|
|
|
2006-06-29 16:54:54 +00:00
|
|
|
#include <common/config.h>
|
2015-09-10 16:28:10 +00:00
|
|
|
#include <types/action.h>
|
2006-06-26 00:48:02 +00:00
|
|
|
#include <types/proto_http.h>
|
REORG/MAJOR: session: rename the "session" entity to "stream"
With HTTP/2, we'll have to support multiplexed streams. A stream is in
fact the largest part of what we currently call a session, it has buffers,
logs, etc.
In order to catch any error, this commit removes any reference to the
struct session and tries to rename most "session" occurrences in function
names to "stream" and "sess" to "strm" when that's related to a session.
The files stream.{c,h} were added and session.{c,h} removed.
The session will be reintroduced later and a few parts of the stream
will progressively be moved overthere. It will more or less contain
only what we need in an embryonic session.
Sample fetch functions and converters will have to change a bit so
that they'll use an L5 (session) instead of what's currently called
"L4" which is in fact L6 for now.
Once all changes are completed, we should see approximately this :
L7 - http_txn
L6 - stream
L5 - session
L4 - connection | applet
There will be at most one http_txn per stream, and a same session will
possibly be referenced by multiple streams. A connection will point to
a session and to a stream. The session will hold all the information
we need to keep even when we don't yet have a stream.
Some more cleanup is needed because some code was already far from
being clean. The server queue management still refers to sessions at
many places while comments talk about connections. This will have to
be cleaned up once we have a server-side connection pool manager.
Stream flags "SN_*" still need to be renamed, it doesn't seem like
any of them will need to move to the session.
2015-04-02 22:22:06 +00:00
|
|
|
#include <types/stream.h>
|
2006-06-26 00:48:02 +00:00
|
|
|
#include <types/task.h>
|
|
|
|
|
2006-12-04 01:26:12 +00:00
|
|
|
/*
|
|
|
|
* some macros used for the request parsing.
|
|
|
|
* from RFC2616:
|
|
|
|
* CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
|
2007-01-21 18:16:41 +00:00
|
|
|
* SEP = one of the 17 defined separators or SP or HT
|
|
|
|
* LWS = CR, LF, SP or HT
|
|
|
|
* SPHT = SP or HT. Use this macro and not a boolean expression for best speed.
|
|
|
|
* CRLF = CR or LF. Use this macro and not a boolean expression for best speed.
|
|
|
|
* token = any CHAR except CTL or SEP. Use this macro and not a boolean expression for best speed.
|
2007-03-04 17:13:58 +00:00
|
|
|
*
|
|
|
|
* added for ease of use:
|
|
|
|
* ver_token = 'H', 'P', 'T', '/', '.', and digits.
|
2006-12-04 01:26:12 +00:00
|
|
|
*/
|
|
|
|
|
2007-01-21 18:16:41 +00:00
|
|
|
extern const char http_is_ctl[256];
|
|
|
|
extern const char http_is_sep[256];
|
|
|
|
extern const char http_is_lws[256];
|
|
|
|
extern const char http_is_spht[256];
|
|
|
|
extern const char http_is_crlf[256];
|
|
|
|
extern const char http_is_token[256];
|
2007-03-04 17:13:58 +00:00
|
|
|
extern const char http_is_ver_token[256];
|
2007-01-21 18:16:41 +00:00
|
|
|
|
2011-05-11 14:10:11 +00:00
|
|
|
extern const int http_err_codes[HTTP_ERR_SIZE];
|
|
|
|
extern struct chunk http_err_chunks[HTTP_ERR_SIZE];
|
|
|
|
extern const char *HTTP_302;
|
|
|
|
extern const char *HTTP_303;
|
2012-10-29 19:44:36 +00:00
|
|
|
extern char *get_http_auth_buff;
|
2011-05-11 14:10:11 +00:00
|
|
|
|
2007-01-21 18:16:41 +00:00
|
|
|
#define HTTP_IS_CTL(x) (http_is_ctl[(unsigned char)(x)])
|
|
|
|
#define HTTP_IS_SEP(x) (http_is_sep[(unsigned char)(x)])
|
|
|
|
#define HTTP_IS_LWS(x) (http_is_lws[(unsigned char)(x)])
|
|
|
|
#define HTTP_IS_SPHT(x) (http_is_spht[(unsigned char)(x)])
|
|
|
|
#define HTTP_IS_CRLF(x) (http_is_crlf[(unsigned char)(x)])
|
|
|
|
#define HTTP_IS_TOKEN(x) (http_is_token[(unsigned char)(x)])
|
2007-03-04 17:13:58 +00:00
|
|
|
#define HTTP_IS_VER_TOKEN(x) (http_is_ver_token[(unsigned char)(x)])
|
2006-06-26 00:48:02 +00:00
|
|
|
|
REORG/MAJOR: session: rename the "session" entity to "stream"
With HTTP/2, we'll have to support multiplexed streams. A stream is in
fact the largest part of what we currently call a session, it has buffers,
logs, etc.
In order to catch any error, this commit removes any reference to the
struct session and tries to rename most "session" occurrences in function
names to "stream" and "sess" to "strm" when that's related to a session.
The files stream.{c,h} were added and session.{c,h} removed.
The session will be reintroduced later and a few parts of the stream
will progressively be moved overthere. It will more or less contain
only what we need in an embryonic session.
Sample fetch functions and converters will have to change a bit so
that they'll use an L5 (session) instead of what's currently called
"L4" which is in fact L6 for now.
Once all changes are completed, we should see approximately this :
L7 - http_txn
L6 - stream
L5 - session
L4 - connection | applet
There will be at most one http_txn per stream, and a same session will
possibly be referenced by multiple streams. A connection will point to
a session and to a stream. The session will hold all the information
we need to keep even when we don't yet have a stream.
Some more cleanup is needed because some code was already far from
being clean. The server queue management still refers to sessions at
many places while comments talk about connections. This will have to
be cleaned up once we have a server-side connection pool manager.
Stream flags "SN_*" still need to be renamed, it doesn't seem like
any of them will need to move to the session.
2015-04-02 22:22:06 +00:00
|
|
|
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);
|
2012-03-09 11:11:57 +00:00
|
|
|
int http_send_name_header(struct http_txn *txn, struct proxy* be, const char* svr_name);
|
REORG/MAJOR: session: rename the "session" entity to "stream"
With HTTP/2, we'll have to support multiplexed streams. A stream is in
fact the largest part of what we currently call a session, it has buffers,
logs, etc.
In order to catch any error, this commit removes any reference to the
struct session and tries to rename most "session" occurrences in function
names to "stream" and "sess" to "strm" when that's related to a session.
The files stream.{c,h} were added and session.{c,h} removed.
The session will be reintroduced later and a few parts of the stream
will progressively be moved overthere. It will more or less contain
only what we need in an embryonic session.
Sample fetch functions and converters will have to change a bit so
that they'll use an L5 (session) instead of what's currently called
"L4" which is in fact L6 for now.
Once all changes are completed, we should see approximately this :
L7 - http_txn
L6 - stream
L5 - session
L4 - connection | applet
There will be at most one http_txn per stream, and a same session will
possibly be referenced by multiple streams. A connection will point to
a session and to a stream. The session will hold all the information
we need to keep even when we don't yet have a stream.
Some more cleanup is needed because some code was already far from
being clean. The server queue management still refers to sessions at
many places while comments talk about connections. This will have to
be cleaned up once we have a server-side connection pool manager.
Stream flags "SN_*" still need to be renamed, it doesn't seem like
any of them will need to move to the session.
2015-04-02 22:22:06 +00:00
|
|
|
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);
|
2015-09-25 09:06:37 +00:00
|
|
|
void http_msg_analyzer(struct http_msg *msg, struct hdr_idx *idx);
|
2006-06-26 00:48:02 +00:00
|
|
|
|
REORG/MAJOR: session: rename the "session" entity to "stream"
With HTTP/2, we'll have to support multiplexed streams. A stream is in
fact the largest part of what we currently call a session, it has buffers,
logs, etc.
In order to catch any error, this commit removes any reference to the
struct session and tries to rename most "session" occurrences in function
names to "stream" and "sess" to "strm" when that's related to a session.
The files stream.{c,h} were added and session.{c,h} removed.
The session will be reintroduced later and a few parts of the stream
will progressively be moved overthere. It will more or less contain
only what we need in an embryonic session.
Sample fetch functions and converters will have to change a bit so
that they'll use an L5 (session) instead of what's currently called
"L4" which is in fact L6 for now.
Once all changes are completed, we should see approximately this :
L7 - http_txn
L6 - stream
L5 - session
L4 - connection | applet
There will be at most one http_txn per stream, and a same session will
possibly be referenced by multiple streams. A connection will point to
a session and to a stream. The session will hold all the information
we need to keep even when we don't yet have a stream.
Some more cleanup is needed because some code was already far from
being clean. The server queue management still refers to sessions at
many places while comments talk about connections. This will have to
be cleaned up once we have a server-side connection pool manager.
Stream flags "SN_*" still need to be renamed, it doesn't seem like
any of them will need to move to the session.
2015-04-02 22:22:06 +00:00
|
|
|
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_response_for_cacheability(struct stream *s, struct channel *rtr);
|
2011-03-10 10:25:07 +00:00
|
|
|
int stats_check_uri(struct stream_interface *si, struct http_txn *txn, struct proxy *backend);
|
2006-12-24 16:47:20 +00:00
|
|
|
void init_proto_http();
|
2013-06-10 16:39:42 +00:00
|
|
|
int http_find_full_header2(const char *name, int len,
|
|
|
|
char *sol, struct hdr_idx *idx,
|
|
|
|
struct hdr_ctx *ctx);
|
2008-04-14 18:47:37 +00:00
|
|
|
int http_find_header2(const char *name, int len,
|
2010-01-18 13:54:04 +00:00
|
|
|
char *sol, struct hdr_idx *idx,
|
2008-04-14 18:47:37 +00:00
|
|
|
struct hdr_ctx *ctx);
|
2013-10-15 09:43:19 +00:00
|
|
|
char *find_hdr_value_end(char *s, const char *e);
|
|
|
|
int http_header_match2(const char *hdr, const char *end, const char *name, int len);
|
|
|
|
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);
|
2015-04-03 23:09:08 +00:00
|
|
|
int http_replace_req_line(int action, const char *replace, int len, struct proxy *px, struct stream *s);
|
2015-08-26 14:21:56 +00:00
|
|
|
void http_set_status(unsigned int status, struct stream *s);
|
REORG/MAJOR: session: rename the "session" entity to "stream"
With HTTP/2, we'll have to support multiplexed streams. A stream is in
fact the largest part of what we currently call a session, it has buffers,
logs, etc.
In order to catch any error, this commit removes any reference to the
struct session and tries to rename most "session" occurrences in function
names to "stream" and "sess" to "strm" when that's related to a session.
The files stream.{c,h} were added and session.{c,h} removed.
The session will be reintroduced later and a few parts of the stream
will progressively be moved overthere. It will more or less contain
only what we need in an embryonic session.
Sample fetch functions and converters will have to change a bit so
that they'll use an L5 (session) instead of what's currently called
"L4" which is in fact L6 for now.
Once all changes are completed, we should see approximately this :
L7 - http_txn
L6 - stream
L5 - session
L4 - connection | applet
There will be at most one http_txn per stream, and a same session will
possibly be referenced by multiple streams. A connection will point to
a session and to a stream. The session will hold all the information
we need to keep even when we don't yet have a stream.
Some more cleanup is needed because some code was already far from
being clean. The server queue management still refers to sessions at
many places while comments talk about connections. This will have to
be cleaned up once we have a server-side connection pool manager.
Stream flags "SN_*" still need to be renamed, it doesn't seem like
any of them will need to move to the session.
2015-04-02 22:22:06 +00:00
|
|
|
int http_transform_header_str(struct stream* s, struct http_msg *msg, const char* name,
|
2015-03-16 10:15:50 +00:00
|
|
|
unsigned int name_len, const char *str, struct my_regex *re,
|
|
|
|
int action);
|
2015-03-16 11:03:44 +00:00
|
|
|
void inet_set_tos(int fd, struct sockaddr_storage from, int tos);
|
REORG/MAJOR: session: rename the "session" entity to "stream"
With HTTP/2, we'll have to support multiplexed streams. A stream is in
fact the largest part of what we currently call a session, it has buffers,
logs, etc.
In order to catch any error, this commit removes any reference to the
struct session and tries to rename most "session" occurrences in function
names to "stream" and "sess" to "strm" when that's related to a session.
The files stream.{c,h} were added and session.{c,h} removed.
The session will be reintroduced later and a few parts of the stream
will progressively be moved overthere. It will more or less contain
only what we need in an embryonic session.
Sample fetch functions and converters will have to change a bit so
that they'll use an L5 (session) instead of what's currently called
"L4" which is in fact L6 for now.
Once all changes are completed, we should see approximately this :
L7 - http_txn
L6 - stream
L5 - session
L4 - connection | applet
There will be at most one http_txn per stream, and a same session will
possibly be referenced by multiple streams. A connection will point to
a session and to a stream. The session will hold all the information
we need to keep even when we don't yet have a stream.
Some more cleanup is needed because some code was already far from
being clean. The server queue management still refers to sessions at
many places while comments talk about connections. This will have to
be cleaned up once we have a server-side connection pool manager.
Stream flags "SN_*" still need to be renamed, it doesn't seem like
any of them will need to move to the session.
2015-04-02 22:22:06 +00:00
|
|
|
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_bad_message(struct error_snapshot *es, struct stream *s,
|
2012-03-09 12:39:23 +00:00
|
|
|
struct http_msg *msg,
|
2013-12-06 23:01:53 +00:00
|
|
|
enum ht_state state, struct proxy *other_end);
|
2012-04-26 13:11:51 +00:00
|
|
|
unsigned int http_get_hdr(const struct http_msg *msg, const char *hname, int hlen,
|
2011-12-16 20:35:50 +00:00
|
|
|
struct hdr_idx *idx, int occ,
|
|
|
|
struct hdr_ctx *ctx, char **vptr, int *vlen);
|
2015-09-17 17:33:35 +00:00
|
|
|
char *http_get_path(struct http_txn *txn);
|
2015-09-18 15:59:23 +00:00
|
|
|
const char *get_reason(unsigned int status);
|
2006-06-26 00:48:02 +00:00
|
|
|
|
2015-04-03 21:46:31 +00:00
|
|
|
struct http_txn *http_alloc_txn(struct stream *s);
|
REORG/MAJOR: session: rename the "session" entity to "stream"
With HTTP/2, we'll have to support multiplexed streams. A stream is in
fact the largest part of what we currently call a session, it has buffers,
logs, etc.
In order to catch any error, this commit removes any reference to the
struct session and tries to rename most "session" occurrences in function
names to "stream" and "sess" to "strm" when that's related to a session.
The files stream.{c,h} were added and session.{c,h} removed.
The session will be reintroduced later and a few parts of the stream
will progressively be moved overthere. It will more or less contain
only what we need in an embryonic session.
Sample fetch functions and converters will have to change a bit so
that they'll use an L5 (session) instead of what's currently called
"L4" which is in fact L6 for now.
Once all changes are completed, we should see approximately this :
L7 - http_txn
L6 - stream
L5 - session
L4 - connection | applet
There will be at most one http_txn per stream, and a same session will
possibly be referenced by multiple streams. A connection will point to
a session and to a stream. The session will hold all the information
we need to keep even when we don't yet have a stream.
Some more cleanup is needed because some code was already far from
being clean. The server queue management still refers to sessions at
many places while comments talk about connections. This will have to
be cleaned up once we have a server-side connection pool manager.
Stream flags "SN_*" still need to be renamed, it doesn't seem like
any of them will need to move to the session.
2015-04-02 22:22:06 +00:00
|
|
|
void http_init_txn(struct stream *s);
|
|
|
|
void http_end_txn(struct stream *s);
|
|
|
|
void http_reset_txn(struct stream *s);
|
|
|
|
void http_adjust_conn_mode(struct stream *s, struct http_txn *txn, struct http_msg *msg);
|
2009-12-22 14:03:09 +00:00
|
|
|
|
2015-08-04 17:35:46 +00:00
|
|
|
struct act_rule *parse_http_req_cond(const char **args, const char *file, int linenum, struct proxy *proxy);
|
|
|
|
struct act_rule *parse_http_res_cond(const char **args, const char *file, int linenum, struct proxy *proxy);
|
2011-01-06 16:51:27 +00:00
|
|
|
void free_http_req_rules(struct list *r);
|
2014-06-16 18:05:59 +00:00
|
|
|
void free_http_res_rules(struct list *r);
|
REORG/MAJOR: session: rename the "session" entity to "stream"
With HTTP/2, we'll have to support multiplexed streams. A stream is in
fact the largest part of what we currently call a session, it has buffers,
logs, etc.
In order to catch any error, this commit removes any reference to the
struct session and tries to rename most "session" occurrences in function
names to "stream" and "sess" to "strm" when that's related to a session.
The files stream.{c,h} were added and session.{c,h} removed.
The session will be reintroduced later and a few parts of the stream
will progressively be moved overthere. It will more or less contain
only what we need in an embryonic session.
Sample fetch functions and converters will have to change a bit so
that they'll use an L5 (session) instead of what's currently called
"L4" which is in fact L6 for now.
Once all changes are completed, we should see approximately this :
L7 - http_txn
L6 - stream
L5 - session
L4 - connection | applet
There will be at most one http_txn per stream, and a same session will
possibly be referenced by multiple streams. A connection will point to
a session and to a stream. The session will hold all the information
we need to keep even when we don't yet have a stream.
Some more cleanup is needed because some code was already far from
being clean. The server queue management still refers to sessions at
many places while comments talk about connections. This will have to
be cleaned up once we have a server-side connection pool manager.
Stream flags "SN_*" still need to be renamed, it doesn't seem like
any of them will need to move to the session.
2015-04-02 22:22:06 +00:00
|
|
|
struct chunk *http_error_message(struct stream *s, int msgnum);
|
2013-11-29 11:15:45 +00:00
|
|
|
struct redirect_rule *http_parse_redirect_rule(const char *file, int linenum, struct proxy *curproxy,
|
2015-05-28 13:26:58 +00:00
|
|
|
const char **args, char **errmsg, int use_fmt, int dir);
|
2015-05-11 13:42:45 +00:00
|
|
|
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);
|
2011-01-06 16:51:27 +00:00
|
|
|
|
2013-12-17 00:10:10 +00:00
|
|
|
enum http_meth_t find_http_meth(const char *str, const int len);
|
|
|
|
|
2015-08-19 07:01:53 +00:00
|
|
|
struct action_kw *action_http_req_custom(const char *kw);
|
|
|
|
struct action_kw *action_http_res_custom(const char *kw);
|
2014-12-08 18:50:43 +00:00
|
|
|
int val_hdr(struct arg *arg, char **err_msg);
|
MEDIUM: http: register http-request and http-response keywords
The http_(res|req)_keywords_register() functions allow to register
new keywords.
You need to declare a keyword list:
struct http_req_action_kw_list test_kws = {
.scope = "testscope",
.kw = {
{ "test", parse_test },
{ NULL, NULL },
}
};
and a parsing function:
int parse_test(const char **args, int *cur_arg, struct proxy *px, struct http_req_rule *rule, char **err)
{
rule->action = HTTP_REQ_ACT_CUSTOM_STOP;
rule->action_ptr = action_function;
return 0;
}
http_req_keywords_register(&test_kws);
The HTTP_REQ_ACT_CUSTOM_STOP action stops evaluation of rules after
your rule, HTTP_REQ_ACT_CUSTOM_CONT permits the evaluation of rules
after your rule.
2014-04-24 12:38:37 +00:00
|
|
|
|
2015-09-18 16:11:16 +00:00
|
|
|
int smp_prefetch_http(struct proxy *px, struct stream *s, unsigned int opt,
|
|
|
|
const struct arg *args, struct sample *smp, int req_vol);
|
|
|
|
|
|
|
|
/* Note: these functions *do* modify the sample. Even in case of success, at
|
|
|
|
* least the type and uint value are modified.
|
|
|
|
*/
|
|
|
|
#define CHECK_HTTP_MESSAGE_FIRST() \
|
|
|
|
do { int r = smp_prefetch_http(smp->px, smp->strm, smp->opt, args, smp, 1); if (r <= 0) return r; } while (0)
|
|
|
|
|
|
|
|
#define CHECK_HTTP_MESSAGE_FIRST_PERM() \
|
|
|
|
do { int r = smp_prefetch_http(smp->px, smp->strm, smp->opt, args, smp, 0); if (r <= 0) return r; } while (0)
|
|
|
|
|
2015-08-19 07:01:53 +00:00
|
|
|
static inline void http_req_keywords_register(struct action_kw_list *kw_list)
|
MEDIUM: http: register http-request and http-response keywords
The http_(res|req)_keywords_register() functions allow to register
new keywords.
You need to declare a keyword list:
struct http_req_action_kw_list test_kws = {
.scope = "testscope",
.kw = {
{ "test", parse_test },
{ NULL, NULL },
}
};
and a parsing function:
int parse_test(const char **args, int *cur_arg, struct proxy *px, struct http_req_rule *rule, char **err)
{
rule->action = HTTP_REQ_ACT_CUSTOM_STOP;
rule->action_ptr = action_function;
return 0;
}
http_req_keywords_register(&test_kws);
The HTTP_REQ_ACT_CUSTOM_STOP action stops evaluation of rules after
your rule, HTTP_REQ_ACT_CUSTOM_CONT permits the evaluation of rules
after your rule.
2014-04-24 12:38:37 +00:00
|
|
|
{
|
|
|
|
LIST_ADDQ(&http_req_keywords.list, &kw_list->list);
|
|
|
|
}
|
|
|
|
|
2015-08-19 07:01:53 +00:00
|
|
|
static inline void http_res_keywords_register(struct action_kw_list *kw_list)
|
MEDIUM: http: register http-request and http-response keywords
The http_(res|req)_keywords_register() functions allow to register
new keywords.
You need to declare a keyword list:
struct http_req_action_kw_list test_kws = {
.scope = "testscope",
.kw = {
{ "test", parse_test },
{ NULL, NULL },
}
};
and a parsing function:
int parse_test(const char **args, int *cur_arg, struct proxy *px, struct http_req_rule *rule, char **err)
{
rule->action = HTTP_REQ_ACT_CUSTOM_STOP;
rule->action_ptr = action_function;
return 0;
}
http_req_keywords_register(&test_kws);
The HTTP_REQ_ACT_CUSTOM_STOP action stops evaluation of rules after
your rule, HTTP_REQ_ACT_CUSTOM_CONT permits the evaluation of rules
after your rule.
2014-04-24 12:38:37 +00:00
|
|
|
{
|
|
|
|
LIST_ADDQ(&http_res_keywords.list, &kw_list->list);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-29 17:12:29 +00:00
|
|
|
/* to be used when contents change in an HTTP message */
|
|
|
|
#define http_msg_move_end(msg, bytes) do { \
|
|
|
|
unsigned int _bytes = (bytes); \
|
2012-03-05 10:17:50 +00:00
|
|
|
(msg)->next += (_bytes); \
|
2009-11-29 17:12:29 +00:00
|
|
|
(msg)->sov += (_bytes); \
|
|
|
|
(msg)->eoh += (_bytes); \
|
|
|
|
} while (0)
|
|
|
|
|
2014-04-17 18:08:17 +00:00
|
|
|
|
2014-04-17 18:18:08 +00:00
|
|
|
/* 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.
|
2014-04-17 19:14:47 +00:00
|
|
|
* 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.
|
2014-04-17 18:18:08 +00:00
|
|
|
*/
|
|
|
|
static inline int http_hdr_rewind(const struct http_msg *msg)
|
|
|
|
{
|
2014-04-17 19:14:47 +00:00
|
|
|
return msg->eoh + msg->eol - msg->sov;
|
2014-04-17 18:18:08 +00:00
|
|
|
}
|
|
|
|
|
2014-04-17 18:24:24 +00:00
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2014-04-17 18:31:44 +00:00
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2014-04-17 18:08:17 +00:00
|
|
|
/* 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;
|
|
|
|
|
2014-04-17 19:14:47 +00:00
|
|
|
len = msg->chn->buf->i - msg->sov - msg->sol;
|
2014-04-17 18:08:17 +00:00
|
|
|
if (len > msg->body_len)
|
|
|
|
len = msg->body_len;
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2015-08-05 17:05:19 +00:00
|
|
|
/* for an http-request action ACT_HTTP_REQ_TRK_*, return a tracking index
|
2014-06-25 16:12:15 +00:00
|
|
|
* starting at zero for SC0. Unknown actions also return zero.
|
|
|
|
*/
|
|
|
|
static inline int http_req_trk_idx(int trk_action)
|
|
|
|
{
|
2015-08-05 17:05:19 +00:00
|
|
|
return trk_action - ACT_ACTION_TRK_SC0;
|
2014-06-25 16:12:15 +00:00
|
|
|
}
|
|
|
|
|
2012-11-21 20:50:04 +00:00
|
|
|
/* for debugging, reports the HTTP message state name */
|
|
|
|
static inline const char *http_msg_state_str(int 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_DONE: return "MSG_DONE";
|
|
|
|
case HTTP_MSG_CLOSING: return "MSG_CLOSING";
|
|
|
|
case HTTP_MSG_CLOSED: return "MSG_CLOSED";
|
|
|
|
case HTTP_MSG_TUNNEL: return "MSG_TUNNEL";
|
|
|
|
default: return "MSG_??????";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-06-26 00:48:02 +00:00
|
|
|
#endif /* _PROTO_PROTO_HTTP_H */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Local variables:
|
|
|
|
* c-indent-level: 8
|
|
|
|
* c-basic-offset: 8
|
|
|
|
* End:
|
|
|
|
*/
|