mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-04-08 10:11:40 +00:00
MINOR: http: add a new "replace-path" action
This action is very similar to "replace-uri" except that it only acts on the path component. This is assumed to better match users' expectations when they used to rely on "replace-uri" in HTTP/1 because mostly origin forms were used in H1 while mostly absolute URI form is used in H2, and their rules very often start with a '/', and as such do not match. It could help users to get this backported to 2.0 and 2.1.
This commit is contained in:
parent
0851fd5eef
commit
262c3f1a00
@ -4463,6 +4463,30 @@ http-request replace-header <name> <match-regex> <replace-fmt>
|
|||||||
# outputs:
|
# outputs:
|
||||||
User-Agent: foo
|
User-Agent: foo
|
||||||
|
|
||||||
|
http-request replace-path <match-regex> <replace-fmt>
|
||||||
|
[ { if | unless } <condition> ]
|
||||||
|
|
||||||
|
This works like "replace-header" except that it works on the request's path
|
||||||
|
component instead of a header. The path component starts at the first '/'
|
||||||
|
after an optional scheme+authority. It does contain the query string if any
|
||||||
|
is present. The replacement does not modify the scheme nor authority.
|
||||||
|
|
||||||
|
It is worth noting that regular expressions may be more expensive to evaluate
|
||||||
|
than certain ACLs, so rare replacements may benefit from a condition to avoid
|
||||||
|
performing the evaluation at all if it does not match.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
# prefix /foo : turn /bar?q=1 into /foo/bar?q=1 :
|
||||||
|
http-request replace-path (.*) /foo\1
|
||||||
|
|
||||||
|
# suffix /foo : turn /bar?q=1 into /bar/foo?q=1 :
|
||||||
|
http-request replace-path ([^?]*)(\?(.*))? \1/foo\2
|
||||||
|
|
||||||
|
# strip /foo : turn /foo/bar?q=1 into /bar?q=1
|
||||||
|
http-request replace-path /foo/(.*) /\1
|
||||||
|
# or more efficient if only some requests match :
|
||||||
|
http-request replace-path /foo/(.*) /\1 if { url_beg /foo/ }
|
||||||
|
|
||||||
http-request replace-uri <match-regex> <replace-fmt>
|
http-request replace-uri <match-regex> <replace-fmt>
|
||||||
[ { if | unless } <condition> ]
|
[ { if | unless } <condition> ]
|
||||||
|
|
||||||
@ -4484,7 +4508,8 @@ http-request replace-uri <match-regex> <replace-fmt>
|
|||||||
with HTTP/2, clients are encouraged to send absolute URIs only, which look
|
with HTTP/2, clients are encouraged to send absolute URIs only, which look
|
||||||
like the ones HTTP/1 clients use to talk to proxies. Such partial replace-uri
|
like the ones HTTP/1 clients use to talk to proxies. Such partial replace-uri
|
||||||
rules may then fail in HTTP/2 when they work in HTTP/1. Either the rules need
|
rules may then fail in HTTP/2 when they work in HTTP/1. Either the rules need
|
||||||
to be adapted to optionally match a scheme and authority.
|
to be adapted to optionally match a scheme and authority, or replace-path
|
||||||
|
should be used.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
# rewrite all "http" absolute requests to "https":
|
# rewrite all "http" absolute requests to "https":
|
||||||
|
@ -3694,7 +3694,7 @@ stats_error_parsing:
|
|||||||
}
|
}
|
||||||
else if (!strcmp(args[0], "cliexp") || !strcmp(args[0], "reqrep")) { /* replace request header from a regex */
|
else if (!strcmp(args[0], "cliexp") || !strcmp(args[0], "reqrep")) { /* replace request header from a regex */
|
||||||
ha_alert("parsing [%s:%d] : The '%s' directive is not supported anymore since HAProxy 2.1. "
|
ha_alert("parsing [%s:%d] : The '%s' directive is not supported anymore since HAProxy 2.1. "
|
||||||
"Use 'http-request replace-uri' and 'http-request replace-header' instead.\n",
|
"Use 'http-request replace-path', 'http-request replace-uri' or 'http-request replace-header' instead.\n",
|
||||||
file, linenum, args[0]);
|
file, linenum, args[0]);
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -133,6 +133,8 @@ static enum act_parse_ret parse_set_req_line(const char **args, int *orig_arg, s
|
|||||||
* <rule>.arg.act.p[]. It builds a string in the trash from the format string
|
* <rule>.arg.act.p[]. It builds a string in the trash from the format string
|
||||||
* previously filled by function parse_replace_uri() and will execute the regex
|
* previously filled by function parse_replace_uri() and will execute the regex
|
||||||
* in p[1] to replace the URI. It uses the format string present in act.p[2..3].
|
* in p[1] to replace the URI. It uses the format string present in act.p[2..3].
|
||||||
|
* The component to act on (path/uri) is taken from act.p[0] which contains 1
|
||||||
|
* for the path or 3 for the URI (values used by http_req_replace_stline()).
|
||||||
* It always returns ACT_RET_CONT. If an error occurs, the action is canceled,
|
* It always returns ACT_RET_CONT. If an error occurs, the action is canceled,
|
||||||
* but the rule processing continues.
|
* but the rule processing continues.
|
||||||
*/
|
*/
|
||||||
@ -149,6 +151,10 @@ static enum act_return http_action_replace_uri(struct act_rule *rule, struct pro
|
|||||||
if (!replace || !output)
|
if (!replace || !output)
|
||||||
goto leave;
|
goto leave;
|
||||||
uri = htx_sl_req_uri(http_get_stline(htxbuf(&s->req.buf)));
|
uri = htx_sl_req_uri(http_get_stline(htxbuf(&s->req.buf)));
|
||||||
|
|
||||||
|
if (rule->arg.act.p[0] == (void *)1)
|
||||||
|
uri = http_get_path(uri); // replace path
|
||||||
|
|
||||||
if (!regex_exec_match2(rule->arg.act.p[1], uri.ptr, uri.len, MAX_MATCH, pmatch, 0))
|
if (!regex_exec_match2(rule->arg.act.p[1], uri.ptr, uri.len, MAX_MATCH, pmatch, 0))
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
@ -161,8 +167,7 @@ static enum act_return http_action_replace_uri(struct act_rule *rule, struct pro
|
|||||||
if (len == -1)
|
if (len == -1)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
/* 3 is the set-uri action */
|
http_req_replace_stline((long)rule->arg.act.p[0], output->area, len, px, s);
|
||||||
http_req_replace_stline(3, output->area, len, px, s);
|
|
||||||
|
|
||||||
ret = ACT_RET_CONT;
|
ret = ACT_RET_CONT;
|
||||||
|
|
||||||
@ -172,9 +177,9 @@ leave:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse a "replace-uri" http-request action.
|
/* parse a "replace-uri" or "replace-path" http-request action.
|
||||||
* This action takes 2 arguments (a regex and a replacement format string).
|
* This action takes 2 arguments (a regex and a replacement format string).
|
||||||
* The resulting rule makes use of arg->act.p[0] to store the action (0 for now),
|
* The resulting rule makes use of arg->act.p[0] to store the action (1/3 for now),
|
||||||
* p[1] to store the compiled regex, and arg->act.p[2..3] to store the log-format
|
* p[1] to store the compiled regex, and arg->act.p[2..3] to store the log-format
|
||||||
* list head. It returns ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on error.
|
* list head. It returns ACT_RET_PRS_OK on success, ACT_RET_PRS_ERR on error.
|
||||||
*/
|
*/
|
||||||
@ -185,7 +190,11 @@ static enum act_parse_ret parse_replace_uri(const char **args, int *orig_arg, st
|
|||||||
char *error = NULL;
|
char *error = NULL;
|
||||||
|
|
||||||
rule->action = ACT_CUSTOM;
|
rule->action = ACT_CUSTOM;
|
||||||
rule->arg.act.p[0] = (void *)0; // replace-uri
|
if (strcmp(args[cur_arg-1], "replace-path") == 0)
|
||||||
|
rule->arg.act.p[0] = (void *)1; // replace-path
|
||||||
|
else
|
||||||
|
rule->arg.act.p[0] = (void *)3; // replace-uri
|
||||||
|
|
||||||
rule->action_ptr = http_action_replace_uri;
|
rule->action_ptr = http_action_replace_uri;
|
||||||
|
|
||||||
if (!*args[cur_arg] || !*args[cur_arg+1] ||
|
if (!*args[cur_arg] || !*args[cur_arg+1] ||
|
||||||
@ -691,6 +700,7 @@ static struct action_kw_list http_req_actions = {
|
|||||||
{ "capture", parse_http_req_capture },
|
{ "capture", parse_http_req_capture },
|
||||||
{ "reject", parse_http_action_reject },
|
{ "reject", parse_http_action_reject },
|
||||||
{ "disable-l7-retry", parse_http_req_disable_l7_retry },
|
{ "disable-l7-retry", parse_http_req_disable_l7_retry },
|
||||||
|
{ "replace-path", parse_replace_uri },
|
||||||
{ "replace-uri", parse_replace_uri },
|
{ "replace-uri", parse_replace_uri },
|
||||||
{ "set-method", parse_set_req_line },
|
{ "set-method", parse_set_req_line },
|
||||||
{ "set-path", parse_set_req_line },
|
{ "set-path", parse_set_req_line },
|
||||||
|
Loading…
Reference in New Issue
Block a user