mirror of
https://github.com/apache/httpd.git
synced 2025-08-08 15:02:10 +03:00
Fold in ProxyPassMatch directive with docs. Support
full regex substitution but also allow for "simple" cases (ala JkMount) to work as well. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@537599 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -758,6 +758,38 @@ expressions</description>
|
|||||||
</usage>
|
</usage>
|
||||||
</directivesynopsis>
|
</directivesynopsis>
|
||||||
|
|
||||||
|
<directivesynopsis>
|
||||||
|
<name>ProxyPassMatch</name>
|
||||||
|
<description>Maps remote servers into the local server URL-space using regular expressions</description>
|
||||||
|
<syntax>ProxyPassMatch [<var>regex</var>] !|<var>url</var> [<var>key=value</var>
|
||||||
|
<var>[key=value</var> ...]]</syntax>
|
||||||
|
<contextlist><context>server config</context><context>virtual host</context>
|
||||||
|
<context>directory</context>
|
||||||
|
</contextlist>
|
||||||
|
|
||||||
|
<usage>
|
||||||
|
<p>This directive is equivalent to <directive module="mod_proxy">ProxyPass</directive>,
|
||||||
|
but makes use of regular expressions, instead of simple prefix matching. The
|
||||||
|
supplied regular expression is matched against the <var>url</var>, and if it
|
||||||
|
matches, the server will substitute any parenthesized matches into the given
|
||||||
|
string and use it as a new <var>url</var>.</p>
|
||||||
|
|
||||||
|
<p>Suppose the local server has address <code>http://example.com/</code>;
|
||||||
|
then</p>
|
||||||
|
|
||||||
|
<example>
|
||||||
|
ProxyPassMatch ^(/.*\.gif)$ http://backend.example.com$1
|
||||||
|
</example>
|
||||||
|
|
||||||
|
<p>will cause a local request for
|
||||||
|
<code>http://example.com/mirror/foo/bar.gif</code> to be internally converted
|
||||||
|
into a proxy request to <code>http://backend.example.com/foo/bar.gif</code>.</p>
|
||||||
|
|
||||||
|
<p>The <code>!</code> directive is useful in situations where you don't want
|
||||||
|
to reverse-proxy a subdirectory.</p>
|
||||||
|
</usage>
|
||||||
|
</directivesynopsis>
|
||||||
|
|
||||||
<directivesynopsis>
|
<directivesynopsis>
|
||||||
<name>ProxyPassReverse</name>
|
<name>ProxyPassReverse</name>
|
||||||
<description>Adjusts the URL in HTTP response headers sent from a reverse
|
<description>Adjusts the URL in HTTP response headers sent from a reverse
|
||||||
|
@@ -517,8 +517,28 @@ static int proxy_trans(request_rec *r)
|
|||||||
if ((real[0] == '!') && (real[1] == '\0')) {
|
if ((real[0] == '!') && (real[1] == '\0')) {
|
||||||
return DECLINED;
|
return DECLINED;
|
||||||
}
|
}
|
||||||
found = apr_pstrcat(r->pool, "proxy:", real,
|
found = ap_pregsub(r->pool, real, r->uri, AP_MAX_REG_MATCH,
|
||||||
r->uri, NULL);
|
regm);
|
||||||
|
/* Note: The strcmp() below catches cases where there
|
||||||
|
* was no regex substitution. This is so cases like:
|
||||||
|
*
|
||||||
|
* ProxyPassMatch \.gif balancer://foo
|
||||||
|
*
|
||||||
|
* will work "as expected". The upshot is that the 2
|
||||||
|
* directives below act the exact same way (ie: $1 is implied):
|
||||||
|
*
|
||||||
|
* ProxyPassMatch ^(/.*\.gif)$ balancer://foo
|
||||||
|
* ProxyPassMatch ^(/.*\.gif)$ balancer://foo$1
|
||||||
|
*
|
||||||
|
* which may be confusing.
|
||||||
|
*/
|
||||||
|
if (found && strcmp(found, real)) {
|
||||||
|
found = apr_pstrcat(r->pool, "proxy:", found, NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
found = apr_pstrcat(r->pool, "proxy:", real, r->uri,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -530,15 +550,15 @@ static int proxy_trans(request_rec *r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
found = apr_pstrcat(r->pool, "proxy:", real,
|
found = apr_pstrcat(r->pool, "proxy:", real,
|
||||||
r->uri + len, NULL);
|
r->uri + len, NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (found) {
|
if (found) {
|
||||||
r->filename = found;
|
r->filename = found;
|
||||||
r->handler = "proxy-server";
|
r->handler = "proxy-server";
|
||||||
r->proxyreq = PROXYREQ_REVERSE;
|
r->proxyreq = PROXYREQ_REVERSE;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return DECLINED;
|
return DECLINED;
|
||||||
@@ -1129,7 +1149,7 @@ static const char *
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
add_pass(cmd_parms *cmd, void *dummy, const char *arg)
|
add_pass(cmd_parms *cmd, void *dummy, const char *arg, int is_regex)
|
||||||
{
|
{
|
||||||
server_rec *s = cmd->server;
|
server_rec *s = cmd->server;
|
||||||
proxy_server_conf *conf =
|
proxy_server_conf *conf =
|
||||||
@@ -1142,12 +1162,15 @@ static const char *
|
|||||||
const apr_array_header_t *arr;
|
const apr_array_header_t *arr;
|
||||||
const apr_table_entry_t *elts;
|
const apr_table_entry_t *elts;
|
||||||
int i;
|
int i;
|
||||||
int use_regex = 0;
|
int use_regex = is_regex;
|
||||||
|
|
||||||
while (*arg) {
|
while (*arg) {
|
||||||
word = ap_getword_conf(cmd->pool, &arg);
|
word = ap_getword_conf(cmd->pool, &arg);
|
||||||
if (!f) {
|
if (!f) {
|
||||||
if (!strcmp(word, "~")) {
|
if (!strcmp(word, "~")) {
|
||||||
|
if (is_regex) {
|
||||||
|
return "ProxyPassMatch invalid syntax ('~' usage).";
|
||||||
|
}
|
||||||
use_regex = 1;
|
use_regex = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1160,16 +1183,16 @@ static const char *
|
|||||||
if (!val) {
|
if (!val) {
|
||||||
if (cmd->path) {
|
if (cmd->path) {
|
||||||
if (*r == '/') {
|
if (*r == '/') {
|
||||||
return "ProxyPass can not have a path when defined in "
|
return "ProxyPass|ProxyPassMatch can not have a path when defined in "
|
||||||
"a location.";
|
"a location.";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return "Invalid ProxyPass parameter. Parameter must "
|
return "Invalid ProxyPass|ProxyPassMatch parameter. Parameter must "
|
||||||
"be in the form 'key=value'.";
|
"be in the form 'key=value'.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return "Invalid ProxyPass parameter. Parameter must be "
|
return "Invalid ProxyPass|ProxyPassMatch parameter. Parameter must be "
|
||||||
"in the form 'key=value'.";
|
"in the form 'key=value'.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1180,7 +1203,7 @@ static const char *
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (r == NULL)
|
if (r == NULL)
|
||||||
return "ProxyPass needs a path when not defined in a location";
|
return "ProxyPass|ProxyPassMatch needs a path when not defined in a location";
|
||||||
|
|
||||||
new = apr_array_push(conf->aliases);
|
new = apr_array_push(conf->aliases);
|
||||||
new->fake = apr_pstrdup(cmd->pool, f);
|
new->fake = apr_pstrdup(cmd->pool, f);
|
||||||
@@ -1238,6 +1261,19 @@ static const char *
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
add_pass_noregex(cmd_parms *cmd, void *dummy, const char *arg)
|
||||||
|
{
|
||||||
|
return add_pass(cmd, dummy, arg, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
add_pass_regex(cmd_parms *cmd, void *dummy, const char *arg)
|
||||||
|
{
|
||||||
|
return add_pass(cmd, dummy, arg, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
add_pass_reverse(cmd_parms *cmd, void *dconf, const char *f, const char *r)
|
add_pass_reverse(cmd_parms *cmd, void *dconf, const char *f, const char *r)
|
||||||
{
|
{
|
||||||
@@ -1900,7 +1936,9 @@ static const command_rec proxy_cmds[] =
|
|||||||
AP_INIT_FLAG("ProxyPassInterpolateEnv", ap_set_flag_slot,
|
AP_INIT_FLAG("ProxyPassInterpolateEnv", ap_set_flag_slot,
|
||||||
(void*)APR_OFFSETOF(proxy_dir_conf, interpolate_env),
|
(void*)APR_OFFSETOF(proxy_dir_conf, interpolate_env),
|
||||||
RSRC_CONF|ACCESS_CONF, "Interpolate Env Vars in reverse Proxy") ,
|
RSRC_CONF|ACCESS_CONF, "Interpolate Env Vars in reverse Proxy") ,
|
||||||
AP_INIT_RAW_ARGS("ProxyPass", add_pass, NULL, RSRC_CONF|ACCESS_CONF,
|
AP_INIT_RAW_ARGS("ProxyPass", add_pass_noregex, NULL, RSRC_CONF|ACCESS_CONF,
|
||||||
|
"a virtual path and a URL"),
|
||||||
|
AP_INIT_RAW_ARGS("ProxyPassMatch", add_pass_regex, NULL, RSRC_CONF|ACCESS_CONF,
|
||||||
"a virtual path and a URL"),
|
"a virtual path and a URL"),
|
||||||
AP_INIT_TAKE12("ProxyPassReverse", add_pass_reverse, NULL, RSRC_CONF|ACCESS_CONF,
|
AP_INIT_TAKE12("ProxyPassReverse", add_pass_reverse, NULL, RSRC_CONF|ACCESS_CONF,
|
||||||
"a virtual path and a URL for reverse proxy behaviour"),
|
"a virtual path and a URL for reverse proxy behaviour"),
|
||||||
|
Reference in New Issue
Block a user