Commit 0e2d732f authored by Jim Jagielski's avatar Jim Jagielski
Browse files

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
parent 48d7cdf5
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -758,6 +758,38 @@ expressions</description>
</usage>
</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>
<name>ProxyPassReverse</name>
<description>Adjusts the URL in HTTP response headers sent from a reverse
+52 −14
Original line number Diff line number Diff line
@@ -517,8 +517,28 @@ static int proxy_trans(request_rec *r)
                if ((real[0] == '!') && (real[1] == '\0')) {
                    return DECLINED;
                }
                found = apr_pstrcat(r->pool, "proxy:", real,
                                    r->uri, NULL);
                found = ap_pregsub(r->pool, real, r->uri, AP_MAX_REG_MATCH,
                                   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 {
@@ -1129,7 +1149,7 @@ 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;
    proxy_server_conf *conf =
@@ -1142,12 +1162,15 @@ static const char *
    const apr_array_header_t *arr;
    const apr_table_entry_t *elts;
    int i;
    int use_regex = 0;
    int use_regex = is_regex;

    while (*arg) {
        word = ap_getword_conf(cmd->pool, &arg);
        if (!f) {
            if (!strcmp(word, "~")) {
                if (is_regex) {
                    return "ProxyPassMatch invalid syntax ('~' usage).";
                }
                use_regex = 1;
                continue;
            }
@@ -1160,16 +1183,16 @@ static const char *
            if (!val) {
                if (cmd->path) {
                    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.";
                    }
                    else {
                        return "Invalid ProxyPass parameter. Parameter must "
                        return "Invalid ProxyPass|ProxyPassMatch parameter. Parameter must "
                               "be in the form 'key=value'.";
                    }
                }
                else {
                    return "Invalid ProxyPass parameter. Parameter must be "
                    return "Invalid ProxyPass|ProxyPassMatch parameter. Parameter must be "
                           "in the form 'key=value'.";
                }
            }
@@ -1180,7 +1203,7 @@ static const char *
    };

    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->fake = apr_pstrdup(cmd->pool, f);
@@ -1238,6 +1261,19 @@ static const char *
    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 *
    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,
        (void*)APR_OFFSETOF(proxy_dir_conf, interpolate_env),
        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"),
    AP_INIT_TAKE12("ProxyPassReverse", add_pass_reverse, NULL, RSRC_CONF|ACCESS_CONF,
     "a virtual path and a URL for reverse proxy behaviour"),