mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-01-30 14:31:08 +01:00
MEDIUM: proxy/http_ext: implement dynamic http_ext
proxy http-only options implemented in http_ext were statically stored
within proxy struct.
We're making some changes so that http_ext are now stored in a dynamically
allocated structs.
http_ext related structs are only allocated when needed to save some space
whenever possible, and they are automatically freed upon proxy deletion.
Related PX_O_HTTP{7239,XFF,XOT) option flags were removed because we're now
considering an http_ext option as 'active' if it is allocated (ptr is not NULL)
A few checks (and BUG_ON) were added to make these changes safe because
it adds some (acceptable) complexity to the previous design.
Also, proxy.http was renamed to proxy.http_ext to make things more explicit.
This commit is contained in:
parent
d745a3f117
commit
b2e2ec51b3
@ -132,4 +132,18 @@ struct http_ext_xot {
|
||||
struct net_addr except_net; /* don't forward x-original-to for this address. */
|
||||
};
|
||||
|
||||
/* http_ext options */
|
||||
struct http_ext {
|
||||
/* forwarded header (RFC 7239) */
|
||||
struct http_ext_7239 *fwd;
|
||||
/* x-forward-for:
|
||||
* conditionally insert x-forwarded-for with client address
|
||||
*/
|
||||
struct http_ext_xff *xff;
|
||||
/* x-original-to:
|
||||
* insert x-original-to with destination address
|
||||
*/
|
||||
struct http_ext_xot *xot;
|
||||
};
|
||||
|
||||
#endif /* !_HAPROXY_HTTPEXT_T_H */
|
||||
|
||||
@ -33,17 +33,26 @@ int http_handle_7239_header(struct stream *s, struct channel *req);
|
||||
int http_handle_xff_header(struct stream *s, struct channel *req);
|
||||
int http_handle_xot_header(struct stream *s, struct channel *req);
|
||||
|
||||
void http_ext_7239_clean(struct http_ext_7239 *);
|
||||
void http_ext_xff_clean(struct http_ext_xff *);
|
||||
void http_ext_xot_clean(struct http_ext_xot *);
|
||||
|
||||
void http_ext_7239_copy(struct http_ext_7239 *dest, const struct http_ext_7239 *orig);
|
||||
void http_ext_xff_copy(struct http_ext_xff *dest, const struct http_ext_xff *orig);
|
||||
void http_ext_xot_copy(struct http_ext_xot *dest, const struct http_ext_xot *orig);
|
||||
|
||||
int proxy_http_parse_7239(char **args, int cur_arg, struct proxy *curproxy, const struct proxy *defpx, const char *file, int linenum);
|
||||
int proxy_http_compile_7239(struct proxy *curproxy);
|
||||
int proxy_http_parse_xff(char **args, int cur_arg, struct proxy *curproxy, const struct proxy *defpx, const char *file, int linenum);
|
||||
int proxy_http_parse_xot(char **args, int cur_arg, struct proxy *curproxy, const struct proxy *defpx, const char *file, int linenum);
|
||||
|
||||
int http_ext_7239_prepare(struct proxy *cur);
|
||||
int http_ext_xff_prepare(struct proxy *cur);
|
||||
int http_ext_xot_prepare(struct proxy *cur);
|
||||
|
||||
void http_ext_7239_dup(const struct proxy *def, struct proxy *cpy);
|
||||
void http_ext_xff_dup(const struct proxy *def, struct proxy *cpy);
|
||||
void http_ext_xot_dup(const struct proxy *def, struct proxy *cpy);
|
||||
|
||||
void http_ext_7239_clean(struct proxy *cur);
|
||||
void http_ext_xff_clean(struct proxy *cur);
|
||||
void http_ext_xot_clean(struct proxy *cur);
|
||||
|
||||
int http_ext_prepare(struct proxy *cur);
|
||||
void http_ext_dup(const struct proxy *def, struct proxy *cpy);
|
||||
void http_ext_clean(struct proxy *cur);
|
||||
void http_ext_softclean(struct proxy *cur);
|
||||
|
||||
#endif /* !_HAPROXY_HTTPEXT_H */
|
||||
|
||||
@ -88,7 +88,7 @@ enum PR_SRV_STATE_FILE {
|
||||
#define PR_O_PREF_LAST 0x00000020 /* prefer last server */
|
||||
#define PR_O_DISPATCH 0x00000040 /* use dispatch mode */
|
||||
#define PR_O_FORCED_ID 0x00000080 /* proxy's ID was forced in the configuration */
|
||||
#define PR_O_HTTP_XFF 0x00000100 /* conditionally insert x-forwarded-for with client address */
|
||||
/* unused: 0x00000100 */
|
||||
#define PR_O_IGNORE_PRB 0x00000200 /* ignore empty requests (aborts and timeouts) */
|
||||
#define PR_O_NULLNOLOG 0x00000400 /* a connect without request will not be logged */
|
||||
#define PR_O_WREQ_BODY 0x00000800 /* always wait for the HTTP request body */
|
||||
@ -101,7 +101,7 @@ enum PR_SRV_STATE_FILE {
|
||||
#define PR_O_TCP_CLI_KA 0x00040000 /* enable TCP keep-alive on client-side streams */
|
||||
#define PR_O_TCP_SRV_KA 0x00080000 /* enable TCP keep-alive on server-side streams */
|
||||
#define PR_O_USE_ALL_BK 0x00100000 /* load-balance between backup servers */
|
||||
#define PR_O_HTTP_7239 0x00200000 /* insert 7239 forwarded header */
|
||||
/* unused: 0x00200000 */
|
||||
#define PR_O_TCP_NOLING 0x00400000 /* disable lingering on client and server connections */
|
||||
#define PR_O_ABRT_CLOSE 0x00800000 /* immediately abort request when client closes */
|
||||
|
||||
@ -115,7 +115,7 @@ enum PR_SRV_STATE_FILE {
|
||||
#define PR_O_CONTSTATS 0x10000000 /* continuous counters */
|
||||
/* unused: 0x20000000 */
|
||||
#define PR_O_DISABLE404 0x40000000 /* Disable a server on a 404 response to a health-check */
|
||||
#define PR_O_HTTP_XOT 0x80000000 /* insert x-original-to with destination address */
|
||||
/* unused: 0x80000000 */
|
||||
|
||||
/* bits for proxy->options2 */
|
||||
#define PR_O2_SPLIC_REQ 0x00000001 /* transfer requests using linux kernel's splice() */
|
||||
@ -267,16 +267,6 @@ struct error_snapshot {
|
||||
char buf[VAR_ARRAY]; /* copy of the beginning of the message for bufsize bytes */
|
||||
};
|
||||
|
||||
/* http options */
|
||||
struct proxy_http {
|
||||
/* forwarded header (RFC 7239) */
|
||||
struct http_ext_7239 fwd;
|
||||
/* x-forward-for */
|
||||
struct http_ext_xff xff;
|
||||
/* x-original-to */
|
||||
struct http_ext_xot xot;
|
||||
};
|
||||
|
||||
struct proxy {
|
||||
enum obj_type obj_type; /* object type == OBJ_TYPE_PROXY */
|
||||
char flags; /* bit field PR_FL_* */
|
||||
@ -448,7 +438,7 @@ struct proxy {
|
||||
char *elfs_file;
|
||||
int elfs_line;
|
||||
} conf; /* config information */
|
||||
struct proxy_http http; /* http only options */
|
||||
struct http_ext *http_ext; /* http ext options */
|
||||
struct eb_root used_server_addr; /* list of server addresses in use */
|
||||
void *parent; /* parent of the proxy when applicable */
|
||||
struct comp *comp; /* http compression */
|
||||
|
||||
@ -2038,7 +2038,8 @@ stats_error_parsing:
|
||||
goto out;
|
||||
}
|
||||
else if (kwm == KWM_NO) {
|
||||
curproxy->options &= ~PR_O_HTTP_7239;
|
||||
if (curproxy->http_ext)
|
||||
http_ext_7239_clean(curproxy);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3670,8 +3670,9 @@ out_uri_auth_compat:
|
||||
else
|
||||
curproxy->http_needed |= !!(curproxy->lbprm.expr->fetch->use & SMP_USE_HTTP_ANY);
|
||||
}
|
||||
|
||||
/* option "forwarded" may need to compile its expressions */
|
||||
if ((curproxy->mode == PR_MODE_HTTP) && curproxy->options & PR_O_HTTP_7239)
|
||||
if ((curproxy->mode == PR_MODE_HTTP) && curproxy->http_ext && curproxy->http_ext->fwd)
|
||||
cfgerr += proxy_http_compile_7239(curproxy);
|
||||
|
||||
/* only now we can check if some args remain unresolved.
|
||||
@ -3968,25 +3969,26 @@ out_uri_auth_compat:
|
||||
err_code |= ERR_WARN;
|
||||
}
|
||||
|
||||
if (curproxy->options & PR_O_HTTP_7239) {
|
||||
ha_warning("'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
|
||||
"forwarded", proxy_type_str(curproxy), curproxy->id);
|
||||
err_code |= ERR_WARN;
|
||||
curproxy->options &= ~PR_O_HTTP_7239;
|
||||
}
|
||||
|
||||
if (curproxy->options & PR_O_HTTP_XFF) {
|
||||
ha_warning("'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
|
||||
"forwardfor", proxy_type_str(curproxy), curproxy->id);
|
||||
err_code |= ERR_WARN;
|
||||
curproxy->options &= ~PR_O_HTTP_XFF;
|
||||
}
|
||||
|
||||
if (curproxy->options & PR_O_HTTP_XOT) {
|
||||
ha_warning("'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
|
||||
"originalto", proxy_type_str(curproxy), curproxy->id);
|
||||
err_code |= ERR_WARN;
|
||||
curproxy->options &= ~PR_O_HTTP_XOT;
|
||||
if (curproxy->http_ext) {
|
||||
/* consistency checks for http_ext */
|
||||
if (curproxy->http_ext->fwd) {
|
||||
ha_warning("'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
|
||||
"forwarded", proxy_type_str(curproxy), curproxy->id);
|
||||
err_code |= ERR_WARN;
|
||||
http_ext_7239_clean(curproxy);
|
||||
}
|
||||
if (curproxy->http_ext->xff) {
|
||||
ha_warning("'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
|
||||
"forwardfor", proxy_type_str(curproxy), curproxy->id);
|
||||
err_code |= ERR_WARN;
|
||||
http_ext_xff_clean(curproxy);
|
||||
}
|
||||
if (curproxy->http_ext->xot) {
|
||||
ha_warning("'option %s' ignored for %s '%s' as it requires HTTP mode.\n",
|
||||
"originalto", proxy_type_str(curproxy), curproxy->id);
|
||||
err_code |= ERR_WARN;
|
||||
http_ext_xot_clean(curproxy);
|
||||
}
|
||||
}
|
||||
|
||||
for (optnum = 0; cfg_opts[optnum].name; optnum++) {
|
||||
@ -4221,6 +4223,8 @@ out_uri_auth_compat:
|
||||
rules->flags = 0;
|
||||
}
|
||||
}
|
||||
/* http_ext post init early cleanup */
|
||||
http_ext_softclean(curproxy);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -662,29 +662,13 @@ int http_process_request(struct stream *s, struct channel *req, int an_bit)
|
||||
goto return_fail_rewrite;
|
||||
}
|
||||
|
||||
/* add forwarded header (RFC 7239) (ignored for frontends) */
|
||||
if (s->be->options & PR_O_HTTP_7239) {
|
||||
if (unlikely(!http_handle_7239_header(s, req)))
|
||||
goto return_fail_rewrite;
|
||||
}
|
||||
|
||||
/*
|
||||
* add X-Forwarded-For if either the frontend or the backend
|
||||
* asks for it.
|
||||
*/
|
||||
if ((sess->fe->options | s->be->options) & PR_O_HTTP_XFF) {
|
||||
if (unlikely(!http_handle_xff_header(s, req)))
|
||||
goto return_fail_rewrite;
|
||||
}
|
||||
|
||||
/*
|
||||
* add X-Original-To if either the frontend or the backend
|
||||
* asks for it.
|
||||
*/
|
||||
if ((sess->fe->options | s->be->options) & PR_O_HTTP_XOT) {
|
||||
if (unlikely(!http_handle_xot_header(s, req)))
|
||||
goto return_fail_rewrite;
|
||||
}
|
||||
/* handle http extensions (if configured) */
|
||||
if (unlikely(!http_handle_7239_header(s, req)))
|
||||
goto return_fail_rewrite;
|
||||
if (unlikely(!http_handle_xff_header(s, req)))
|
||||
goto return_fail_rewrite;
|
||||
if (unlikely(!http_handle_xot_header(s, req)))
|
||||
goto return_fail_rewrite;
|
||||
|
||||
/* Filter the request headers if there are filters attached to the
|
||||
* stream.
|
||||
|
||||
768
src/http_ext.c
768
src/http_ext.c
File diff suppressed because it is too large
Load Diff
17
src/proxy.c
17
src/proxy.c
@ -352,9 +352,8 @@ void free_proxy(struct proxy *p)
|
||||
pxdf->fct(p);
|
||||
|
||||
free(p->desc);
|
||||
http_ext_7239_clean(&p->http.fwd);
|
||||
http_ext_xff_clean(&p->http.xff);
|
||||
http_ext_xot_clean(&p->http.xot);
|
||||
|
||||
http_ext_clean(p);
|
||||
|
||||
task_destroy(p->task);
|
||||
|
||||
@ -1467,9 +1466,7 @@ void proxy_free_defaults(struct proxy *defproxy)
|
||||
ha_free(&defproxy->conn_src.iface_name);
|
||||
istfree(&defproxy->server_id_hdr_name);
|
||||
|
||||
http_ext_7239_clean(&defproxy->http.fwd);
|
||||
http_ext_xff_clean(&defproxy->http.xff);
|
||||
http_ext_xot_clean(&defproxy->http.xot);
|
||||
http_ext_clean(defproxy);
|
||||
|
||||
list_for_each_entry_safe(acl, aclb, &defproxy->acl, list) {
|
||||
LIST_DELETE(&acl->list);
|
||||
@ -1650,10 +1647,8 @@ static int proxy_defproxy_cpy(struct proxy *curproxy, const struct proxy *defpro
|
||||
curproxy->tcp_req.inspect_delay = defproxy->tcp_req.inspect_delay;
|
||||
curproxy->tcp_rep.inspect_delay = defproxy->tcp_rep.inspect_delay;
|
||||
|
||||
if (defproxy->options & PR_O_HTTP_XFF)
|
||||
http_ext_xff_copy(&curproxy->http.xff, &defproxy->http.xff);
|
||||
if (defproxy->options & PR_O_HTTP_XOT)
|
||||
http_ext_xot_copy(&curproxy->http.xot, &defproxy->http.xot);
|
||||
http_ext_clean(curproxy);
|
||||
http_ext_dup(defproxy, curproxy);
|
||||
|
||||
if (isttest(defproxy->server_id_hdr_name))
|
||||
curproxy->server_id_hdr_name = istdup(defproxy->server_id_hdr_name);
|
||||
@ -1697,8 +1692,6 @@ static int proxy_defproxy_cpy(struct proxy *curproxy, const struct proxy *defpro
|
||||
}
|
||||
|
||||
curproxy->ck_opts = defproxy->ck_opts;
|
||||
if (defproxy->options & PR_O_HTTP_7239)
|
||||
http_ext_7239_copy(&curproxy->http.fwd, &defproxy->http.fwd);
|
||||
|
||||
if (defproxy->cookie_name)
|
||||
curproxy->cookie_name = strdup(defproxy->cookie_name);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user