View | Details | Raw Unified | Return to bug 65429
Collapse All | Expand All

(-)modules/proxy/mod_proxy.c (-3 / +19 lines)
Lines 1888-1895 static const char * Link Here
1888
        new->balancer = balancer;
1888
        new->balancer = balancer;
1889
    }
1889
    }
1890
    else {
1890
    else {
1891
        proxy_worker *worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, new->real);
1892
        int reuse = 0;
1891
        int reuse = 0;
1892
        proxy_worker *worker;
1893
        if (use_regex) {
1894
            worker = ap_proxy_get_match_worker(cmd->temp_pool, NULL,
1895
                                               conf, new->real);
1896
        }
1897
        else {
1898
            worker = ap_proxy_get_worker(cmd->temp_pool, NULL,
1899
                                         conf, new->real);
1900
        }
1893
        if (!worker) {
1901
        if (!worker) {
1894
            const char *err;
1902
            const char *err;
1895
            if (use_regex) {
1903
            if (use_regex) {
Lines 2671-2678 static const char *proxysection(cmd_parms *cmd, vo Link Here
2671
            }
2679
            }
2672
        }
2680
        }
2673
        else {
2681
        else {
2674
            worker = ap_proxy_get_worker(cmd->temp_pool, NULL, sconf,
2682
            if (use_regex) {
2675
                                         ap_proxy_de_socketfy(cmd->temp_pool, (char*)conf->p));
2683
                worker = ap_proxy_get_match_worker(cmd->temp_pool, NULL, sconf,
2684
                                      ap_proxy_de_socketfy(cmd->temp_pool,
2685
                                                           (char*)conf->p));
2686
            }
2687
            else {
2688
                worker = ap_proxy_get_worker(cmd->temp_pool, NULL, sconf,
2689
                                      ap_proxy_de_socketfy(cmd->temp_pool,
2690
                                                           (char*)conf->p));
2691
            }
2676
            if (!worker) {
2692
            if (!worker) {
2677
                if (use_regex) {
2693
                if (use_regex) {
2678
                    err = ap_proxy_define_match_worker(cmd->pool, &worker, NULL,
2694
                    err = ap_proxy_define_match_worker(cmd->pool, &worker, NULL,
(-)modules/proxy/mod_proxy.h (+13 lines)
Lines 754-760 PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker( Link Here
754
                                                  proxy_balancer *balancer,
754
                                                  proxy_balancer *balancer,
755
                                                  proxy_server_conf *conf,
755
                                                  proxy_server_conf *conf,
756
                                                  const char *url);
756
                                                  const char *url);
757
757
/**
758
/**
759
 * Get the matchable worker from proxy configuration
760
 * @param p        memory pool used for finding worker
761
 * @param balancer the balancer that the worker belongs to
762
 * @param conf     current proxy server configuration
763
 * @param url      url to find the worker from
764
 * @return         proxy_worker or NULL if not found
765
 */
766
PROXY_DECLARE(proxy_worker *) ap_proxy_get_match_worker(apr_pool_t *p,
767
                                                  proxy_balancer *balancer,
768
                                                  proxy_server_conf *conf,
769
                                                  const char *url);
770
 /**
758
 * Define and Allocate space for the worker to proxy configuration
771
 * Define and Allocate space for the worker to proxy configuration
759
 * @param p         memory pool to allocate worker from
772
 * @param p         memory pool to allocate worker from
760
 * @param worker    the new worker
773
 * @param worker    the new worker
(-)modules/proxy/proxy_util.c (-44 / +113 lines)
Lines 19-24 Link Here
19
#include "ap_mpm.h"
19
#include "ap_mpm.h"
20
#include "scoreboard.h"
20
#include "scoreboard.h"
21
#include "apr_version.h"
21
#include "apr_version.h"
22
#include "apr_strings.h"
22
#include "apr_hash.h"
23
#include "apr_hash.h"
23
#include "proxy_util.h"
24
#include "proxy_util.h"
24
#include "ajp.h"
25
#include "ajp.h"
Lines 1720-1729 static int ap_proxy_strcmp_ematch(const char *str, Link Here
1720
    return 0;
1721
    return 0;
1721
}
1722
}
1722
1723
1723
PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker(apr_pool_t *p,
1724
static proxy_worker *proxy_get_worker(apr_pool_t *p,
1724
                                                  proxy_balancer *balancer,
1725
                                      proxy_balancer *balancer,
1725
                                                  proxy_server_conf *conf,
1726
                                      proxy_server_conf *conf,
1726
                                                  const char *url)
1727
                                      const char *url,
1728
                                      int matchable)
1727
{
1729
{
1728
    proxy_worker *worker;
1730
    proxy_worker *worker;
1729
    proxy_worker *max_worker = NULL;
1731
    proxy_worker *max_worker = NULL;
Lines 1783-1793 static int ap_proxy_strcmp_ematch(const char *str, Link Here
1783
                && (worker_name_length >= min_match)
1785
                && (worker_name_length >= min_match)
1784
                && (worker_name_length > max_match)
1786
                && (worker_name_length > max_match)
1785
                && (worker->s->is_name_matchable
1787
                && (worker->s->is_name_matchable
1786
                    || strncmp(url_copy, worker->s->name,
1788
                    || (!matchable && strncmp(url_copy, worker->s->name,
1787
                               worker_name_length) == 0)
1789
                                              worker_name_length) == 0))
1788
                && (!worker->s->is_name_matchable
1790
                && (!worker->s->is_name_matchable
1789
                    || ap_proxy_strcmp_ematch(url_copy,
1791
                    || (matchable && ap_proxy_strcmp_ematch(url_copy,
1790
                                              worker->s->name) == 0) ) {
1792
                                              worker->s->name) == 0))) {
1791
                max_worker = worker;
1793
                max_worker = worker;
1792
                max_match = worker_name_length;
1794
                max_match = worker_name_length;
1793
            }
1795
            }
Lines 1799-1809 static int ap_proxy_strcmp_ematch(const char *str, Link Here
1799
                && (worker_name_length >= min_match)
1801
                && (worker_name_length >= min_match)
1800
                && (worker_name_length > max_match)
1802
                && (worker_name_length > max_match)
1801
                && (worker->s->is_name_matchable
1803
                && (worker->s->is_name_matchable
1802
                    || strncmp(url_copy, worker->s->name,
1804
                    || (!matchable && strncmp(url_copy, worker->s->name,
1803
                               worker_name_length) == 0)
1805
                                              worker_name_length) == 0))
1804
                && (!worker->s->is_name_matchable
1806
                && (!worker->s->is_name_matchable
1805
                    || ap_proxy_strcmp_ematch(url_copy,
1807
                    || (matchable && ap_proxy_strcmp_ematch(url_copy,
1806
                                              worker->s->name) == 0) ) {
1808
                                              worker->s->name) == 0))) {
1807
                max_worker = worker;
1809
                max_worker = worker;
1808
                max_match = worker_name_length;
1810
                max_match = worker_name_length;
1809
            }
1811
            }
Lines 1813-1818 static int ap_proxy_strcmp_ematch(const char *str, Link Here
1813
    return max_worker;
1815
    return max_worker;
1814
}
1816
}
1815
1817
1818
PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker(apr_pool_t *p,
1819
                                                  proxy_balancer *balancer,
1820
                                                  proxy_server_conf *conf,
1821
                                                  const char *url)
1822
{
1823
    return proxy_get_worker(p, balancer, conf, url, 0);
1824
}
1825
1826
PROXY_DECLARE(proxy_worker *) ap_proxy_get_match_worker(apr_pool_t *p,
1827
                                                  proxy_balancer *balancer,
1828
                                                  proxy_server_conf *conf,
1829
                                                  const char *url)
1830
{
1831
    return proxy_get_worker(p, balancer, conf, url, 1);
1832
}
1833
1816
/*
1834
/*
1817
 * To create a worker from scratch first we define the
1835
 * To create a worker from scratch first we define the
1818
 * specifics of the worker; this is all local data.
1836
 * specifics of the worker; this is all local data.
Lines 1820-1836 static int ap_proxy_strcmp_ematch(const char *str, Link Here
1820
 * shared. This allows for dynamic addition during
1838
 * shared. This allows for dynamic addition during
1821
 * config and runtime.
1839
 * config and runtime.
1822
 */
1840
 */
1823
PROXY_DECLARE(char *) ap_proxy_define_worker(apr_pool_t *p,
1841
static char *proxy_define_worker(apr_pool_t *p,
1824
                                             proxy_worker **worker,
1842
                                 proxy_worker **worker,
1825
                                             proxy_balancer *balancer,
1843
                                 proxy_balancer *balancer,
1826
                                             proxy_server_conf *conf,
1844
                                 proxy_server_conf *conf, const char *url,
1827
                                             const char *url,
1845
                                 int do_malloc, int matchable)
1828
                                             int do_malloc)
1829
{
1846
{
1830
    int rv;
1847
    apr_status_t rv;
1831
    apr_uri_t uri, urisock;
1832
    proxy_worker_shared *wshared;
1848
    proxy_worker_shared *wshared;
1833
    char *ptr, *sockpath = NULL;
1849
    const char *ptr = NULL, *sockpath = NULL, *pdollars = NULL;
1850
    apr_port_t port_of_scheme;
1851
    apr_uri_t uri;
1834
1852
1835
    /*
1853
    /*
1836
     * Look to see if we are using UDS:
1854
     * Look to see if we are using UDS:
Lines 1837-1856 static int ap_proxy_strcmp_ematch(const char *str, Link Here
1837
     * require format: unix:/path/foo/bar.sock|http://ignored/path2/
1855
     * require format: unix:/path/foo/bar.sock|http://ignored/path2/
1838
     * This results in talking http to the socket at /path/foo/bar.sock
1856
     * This results in talking http to the socket at /path/foo/bar.sock
1839
     */
1857
     */
1840
    ptr = ap_strchr((char *)url, '|');
1858
    if (!ap_cstr_casecmpn(url, "unix:", 5)
1841
    if (ptr) {
1859
            && (ptr = ap_strchr_c(url + 5, '|'))) {
1842
        *ptr = '\0';
1860
        rv = apr_uri_parse(p, apr_pstrmemdup(p, url, ptr - url), &uri);
1843
        rv = apr_uri_parse(p, url, &urisock);
1861
        if (rv == APR_SUCCESS) {
1844
        if (rv == APR_SUCCESS && !ap_cstr_casecmp(urisock.scheme, "unix")) {
1862
            sockpath = ap_runtime_dir_relative(p, uri.path);;
1845
            sockpath = ap_runtime_dir_relative(p, urisock.path);;
1863
            ptr++;    /* so we get the scheme for the uds */
1846
            url = ptr+1;    /* so we get the scheme for the uds */
1847
        }
1864
        }
1848
        else {
1865
        else {
1849
            *ptr = '|';
1866
            ptr = url;
1850
        }
1867
        }
1851
    }
1868
    }
1852
    rv = apr_uri_parse(p, url, &uri);
1869
    else {
1870
        ptr = url;
1871
    }
1853
1872
1873
    if (matchable) {
1874
        /* apr_uri_parse() will accept the '$' sign anywhere in the URL but
1875
         * in the :port part, and we don't want scheme://host:port$1$2/path
1876
         * to fail (e.g. "ProxyPassMatch ^/(a|b)(/.*)? http://host:port$2").
1877
         * So we trim all the $n from the :port and prepend them in uri.path
1878
         * afterward for apr_uri_unparse() to restore the original URL below.
1879
         */
1880
#define IS_REF(x) (x[0] == '$' && apr_isdigit(x[1]))
1881
        const char *pos = ap_strstr_c(ptr, "://");
1882
        if (pos) {
1883
            pos += 3;
1884
            while (*pos && *pos != ':' && *pos != '/') {
1885
                pos++;
1886
            }
1887
            if (*pos == ':') {
1888
                pos++;
1889
                while (*pos && !IS_REF(pos) && *pos != '/') {
1890
                    pos++;
1891
                }
1892
                if (IS_REF(pos)) {
1893
                    struct iovec vec[2];
1894
                    const char *path = pos + 2;
1895
                    while (*path && *path != '/') {
1896
                        path++;
1897
                    }
1898
                    pdollars = apr_pstrmemdup(p, pos, path - pos);
1899
                    vec[0].iov_base = (void *)ptr;
1900
                    vec[0].iov_len = pos - ptr;
1901
                    vec[1].iov_base = (void *)path;
1902
                    vec[1].iov_len = strlen(path);
1903
                    ptr = apr_pstrcatv(p, vec, 2, NULL);
1904
                }
1905
            }
1906
        }
1907
#undef IS_REF
1908
    }
1909
1910
    /* Normalize the url (worker name) */
1911
    rv = apr_uri_parse(p, ptr, &uri);
1854
    if (rv != APR_SUCCESS) {
1912
    if (rv != APR_SUCCESS) {
1855
        return apr_pstrcat(p, "Unable to parse URL: ", url, NULL);
1913
        return apr_pstrcat(p, "Unable to parse URL: ", url, NULL);
1856
    }
1914
    }
Lines 1857-1865 static int ap_proxy_strcmp_ematch(const char *str, Link Here
1857
    if (!uri.scheme) {
1915
    if (!uri.scheme) {
1858
        return apr_pstrcat(p, "URL must be absolute!: ", url, NULL);
1916
        return apr_pstrcat(p, "URL must be absolute!: ", url, NULL);
1859
    }
1917
    }
1860
    /* allow for unix:/path|http: */
1861
    if (!uri.hostname) {
1918
    if (!uri.hostname) {
1862
        if (sockpath) {
1919
        if (sockpath) {
1920
            /* allow for unix:/path|http: */
1863
            uri.hostname = "localhost";
1921
            uri.hostname = "localhost";
1864
        }
1922
        }
1865
        else {
1923
        else {
Lines 1870-1875 static int ap_proxy_strcmp_ematch(const char *str, Link Here
1870
        ap_str_tolower(uri.hostname);
1928
        ap_str_tolower(uri.hostname);
1871
    }
1929
    }
1872
    ap_str_tolower(uri.scheme);
1930
    ap_str_tolower(uri.scheme);
1931
    port_of_scheme = ap_proxy_port_of_scheme(uri.scheme);
1932
    if (uri.port && uri.port == port_of_scheme) {
1933
        uri.port = 0;
1934
    }
1935
    if (pdollars) {
1936
        /* Restore/prepend pdollars into the path. */
1937
        uri.path = apr_pstrcat(p, pdollars, uri.path, NULL);
1938
    }
1939
    ptr = apr_uri_unparse(p, &uri, APR_URI_UNP_REVEALPASSWORD);
1940
1873
    /*
1941
    /*
1874
     * Workers can be associated w/ balancers or on their
1942
     * Workers can be associated w/ balancers or on their
1875
     * own; ie: the generic reverse-proxy or a worker
1943
     * own; ie: the generic reverse-proxy or a worker
Lines 1893-1900 static int ap_proxy_strcmp_ematch(const char *str, Link Here
1893
        /* we need to allocate space here */
1961
        /* we need to allocate space here */
1894
        *worker = apr_palloc(p, sizeof(proxy_worker));
1962
        *worker = apr_palloc(p, sizeof(proxy_worker));
1895
    }
1963
    }
1896
1897
    memset(*worker, 0, sizeof(proxy_worker));
1964
    memset(*worker, 0, sizeof(proxy_worker));
1965
    
1898
    /* right here we just want to tuck away the worker info.
1966
    /* right here we just want to tuck away the worker info.
1899
     * if called during config, we don't have shm setup yet,
1967
     * if called during config, we don't have shm setup yet,
1900
     * so just note the info for later. */
1968
     * so just note the info for later. */
Lines 1902-1915 static int ap_proxy_strcmp_ematch(const char *str, Link Here
1902
        wshared = ap_malloc(sizeof(proxy_worker_shared));  /* will be freed ap_proxy_share_worker */
1970
        wshared = ap_malloc(sizeof(proxy_worker_shared));  /* will be freed ap_proxy_share_worker */
1903
    else
1971
    else
1904
        wshared = apr_palloc(p, sizeof(proxy_worker_shared));
1972
        wshared = apr_palloc(p, sizeof(proxy_worker_shared));
1905
1906
    memset(wshared, 0, sizeof(proxy_worker_shared));
1973
    memset(wshared, 0, sizeof(proxy_worker_shared));
1907
1974
1908
    wshared->port = (uri.port ? uri.port : ap_proxy_port_of_scheme(uri.scheme));
1909
    if (uri.port && uri.port == ap_proxy_port_of_scheme(uri.scheme)) {
1910
        uri.port = 0;
1911
    }
1912
    ptr = apr_uri_unparse(p, &uri, APR_URI_UNP_REVEALPASSWORD);
1913
    if (PROXY_STRNCPY(wshared->name, ptr) != APR_SUCCESS) {
1975
    if (PROXY_STRNCPY(wshared->name, ptr) != APR_SUCCESS) {
1914
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(02808)
1976
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(02808)
1915
        "Alert! worker name (%s) too long; truncated to: %s", ptr, wshared->name);
1977
        "Alert! worker name (%s) too long; truncated to: %s", ptr, wshared->name);
Lines 1926-1931 static int ap_proxy_strcmp_ematch(const char *str, Link Here
1926
        "worker hostname (%s) too long; truncated for legacy modules that do not use "
1988
        "worker hostname (%s) too long; truncated for legacy modules that do not use "
1927
        "proxy_worker_shared->hostname_ex: %s", uri.hostname, wshared->hostname);
1989
        "proxy_worker_shared->hostname_ex: %s", uri.hostname, wshared->hostname);
1928
    }
1990
    }
1991
    wshared->port = (uri.port) ? uri.port : port_of_scheme;
1929
    wshared->flush_packets = flush_off;
1992
    wshared->flush_packets = flush_off;
1930
    wshared->flush_wait = PROXY_FLUSH_WAIT;
1993
    wshared->flush_wait = PROXY_FLUSH_WAIT;
1931
    wshared->is_address_reusable = 1;
1994
    wshared->is_address_reusable = 1;
Lines 1960-1965 static int ap_proxy_strcmp_ematch(const char *str, Link Here
1960
    return NULL;
2023
    return NULL;
1961
}
2024
}
1962
2025
2026
PROXY_DECLARE(char *) ap_proxy_define_worker(apr_pool_t *p,
2027
                                             proxy_worker **worker,
2028
                                             proxy_balancer *balancer,
2029
                                             proxy_server_conf *conf,
2030
                                             const char *url,
2031
                                             int do_malloc)
2032
{
2033
    return proxy_define_worker(p, worker, balancer, conf, url, do_malloc, 0);
2034
}
2035
1963
PROXY_DECLARE(char *) ap_proxy_define_match_worker(apr_pool_t *p,
2036
PROXY_DECLARE(char *) ap_proxy_define_match_worker(apr_pool_t *p,
1964
                                             proxy_worker **worker,
2037
                                             proxy_worker **worker,
1965
                                             proxy_balancer *balancer,
2038
                                             proxy_balancer *balancer,
Lines 1968-1985 PROXY_DECLARE(char *) ap_proxy_define_match_worker Link Here
1968
                                             int do_malloc)
2041
                                             int do_malloc)
1969
{
2042
{
1970
    char *err;
2043
    char *err;
1971
    const char *pdollar = ap_strchr_c(url, '$');
1972
2044
1973
    if (pdollar != NULL) {
2045
    err = proxy_define_worker(p, worker, balancer, conf, url, do_malloc, 1);
1974
        url = apr_pstrmemdup(p, url, pdollar - url);
1975
    }
1976
    err = ap_proxy_define_worker(p, worker, balancer, conf, url, do_malloc);
1977
    if (err) {
2046
    if (err) {
1978
        return err;
2047
        return err;
1979
    }
2048
    }
1980
2049
1981
    (*worker)->s->is_name_matchable = 1;
2050
    (*worker)->s->is_name_matchable = 1;
1982
    if (pdollar) {
2051
    if (ap_strchr_c((*worker)->s->name, '$')) {
1983
        /* Before ap_proxy_define_match_worker() existed, a regex worker
2052
        /* Before ap_proxy_define_match_worker() existed, a regex worker
1984
         * with dollar substitution was never matched against the actual
2053
         * with dollar substitution was never matched against the actual
1985
         * URL thus the request fell through the generic worker. To avoid
2054
         * URL thus the request fell through the generic worker. To avoid

Return to bug 65429