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

(-)modules/proxy/proxy_util.c (-32 / +84 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 1820-1836 PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker( Link Here
1820
 * shared. This allows for dynamic addition during
1821
 * shared. This allows for dynamic addition during
1821
 * config and runtime.
1822
 * config and runtime.
1822
 */
1823
 */
1823
PROXY_DECLARE(char *) ap_proxy_define_worker(apr_pool_t *p,
1824
static char *proxy_define_worker(apr_pool_t *p,
1824
                                             proxy_worker **worker,
1825
                                 proxy_worker **worker,
1825
                                             proxy_balancer *balancer,
1826
                                 proxy_balancer *balancer,
1826
                                             proxy_server_conf *conf,
1827
                                 proxy_server_conf *conf, const char *url,
1827
                                             const char *url,
1828
                                 int do_malloc, int matchable)
1828
                                             int do_malloc)
1829
{
1829
{
1830
    int rv;
1830
    apr_status_t rv;
1831
    apr_uri_t uri, urisock;
1832
    proxy_worker_shared *wshared;
1831
    proxy_worker_shared *wshared;
1833
    char *ptr, *sockpath = NULL;
1832
    const char *ptr = NULL, *sockpath = NULL, *pdollars = NULL;
1833
    apr_port_t port_of_scheme;
1834
    apr_uri_t uri;
1834
1835
1835
    /*
1836
    /*
1836
     * Look to see if we are using UDS:
1837
     * Look to see if we are using UDS:
Lines 1837-1856 PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker( Link Here
1837
     * require format: unix:/path/foo/bar.sock|http://ignored/path2/
1838
     * require format: unix:/path/foo/bar.sock|http://ignored/path2/
1838
     * This results in talking http to the socket at /path/foo/bar.sock
1839
     * This results in talking http to the socket at /path/foo/bar.sock
1839
     */
1840
     */
1840
    ptr = ap_strchr((char *)url, '|');
1841
    if (!ap_cstr_casecmpn(url, "unix:", 5)
1841
    if (ptr) {
1842
            && (ptr = ap_strchr_c(url + 5, '|'))) {
1842
        *ptr = '\0';
1843
        rv = apr_uri_parse(p, apr_pstrmemdup(p, url, ptr - url), &uri);
1843
        rv = apr_uri_parse(p, url, &urisock);
1844
        if (rv == APR_SUCCESS) {
1844
        if (rv == APR_SUCCESS && !ap_cstr_casecmp(urisock.scheme, "unix")) {
1845
            sockpath = ap_runtime_dir_relative(p, uri.path);;
1845
            sockpath = ap_runtime_dir_relative(p, urisock.path);;
1846
            ptr++;    /* so we get the scheme for the uds */
1846
            url = ptr+1;    /* so we get the scheme for the uds */
1847
        }
1847
        }
1848
        else {
1848
        else {
1849
            *ptr = '|';
1849
            ptr = url;
1850
        }
1850
        }
1851
    }
1851
    }
1852
    rv = apr_uri_parse(p, url, &uri);
1852
    else {
1853
        ptr = url;
1854
    }
1853
1855
1856
    if (matchable) {
1857
        /* apr_uri_parse() will accept the '$' sign anywhere in the URL but
1858
         * in the :port part, and we don't want scheme://host:port$1$2/path
1859
         * to fail (e.g. "ProxyPassMatch ^/(a|b)(/.*)? http://host:port$2").
1860
         * So we trim all the $n from the :port and prepend them in uri.path
1861
         * afterward for apr_uri_unparse() to restore the original URL below.
1862
         */
1863
#define IS_REF(x) (x[0] == '$' && apr_isdigit(x[1]))
1864
        const char *pos = ap_strstr_c(ptr, "://");
1865
        if (pos) {
1866
            pos += 3;
1867
            while (*pos && *pos != ':' && *pos != '/') {
1868
                pos++;
1869
            }
1870
            if (*pos == ':') {
1871
                pos++;
1872
                while (*pos && !IS_REF(pos) && *pos != '/') {
1873
                    pos++;
1874
                }
1875
                if (IS_REF(pos)) {
1876
                    struct iovec vec[2];
1877
                    const char *path = pos + 2;
1878
                    while (*path && *path != '/') {
1879
                        path++;
1880
                    }
1881
                    pdollars = apr_pstrmemdup(p, pos, path - pos);
1882
                    vec[0].iov_base = (void *)ptr;
1883
                    vec[0].iov_len = pos - ptr;
1884
                    vec[1].iov_base = (void *)path;
1885
                    vec[1].iov_len = strlen(path);
1886
                    ptr = apr_pstrcatv(p, vec, 2, NULL);
1887
                }
1888
            }
1889
        }
1890
#undef IS_REF
1891
    }
1892
1893
    /* Normalize the url (worker name) */
1894
    rv = apr_uri_parse(p, ptr, &uri);
1854
    if (rv != APR_SUCCESS) {
1895
    if (rv != APR_SUCCESS) {
1855
        return apr_pstrcat(p, "Unable to parse URL: ", url, NULL);
1896
        return apr_pstrcat(p, "Unable to parse URL: ", url, NULL);
1856
    }
1897
    }
Lines 1857-1865 PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker( Link Here
1857
    if (!uri.scheme) {
1898
    if (!uri.scheme) {
1858
        return apr_pstrcat(p, "URL must be absolute!: ", url, NULL);
1899
        return apr_pstrcat(p, "URL must be absolute!: ", url, NULL);
1859
    }
1900
    }
1860
    /* allow for unix:/path|http: */
1861
    if (!uri.hostname) {
1901
    if (!uri.hostname) {
1862
        if (sockpath) {
1902
        if (sockpath) {
1903
            /* allow for unix:/path|http: */
1863
            uri.hostname = "localhost";
1904
            uri.hostname = "localhost";
1864
        }
1905
        }
1865
        else {
1906
        else {
Lines 1870-1875 PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker( Link Here
1870
        ap_str_tolower(uri.hostname);
1911
        ap_str_tolower(uri.hostname);
1871
    }
1912
    }
1872
    ap_str_tolower(uri.scheme);
1913
    ap_str_tolower(uri.scheme);
1914
    port_of_scheme = ap_proxy_port_of_scheme(uri.scheme);
1915
    if (uri.port && uri.port == port_of_scheme) {
1916
        uri.port = 0;
1917
    }
1918
    if (pdollars) {
1919
        /* Restore/prepend pdollars into the path. */
1920
        uri.path = apr_pstrcat(p, pdollars, uri.path, NULL);
1921
    }
1922
    ptr = apr_uri_unparse(p, &uri, APR_URI_UNP_REVEALPASSWORD);
1923
1873
    /*
1924
    /*
1874
     * Workers can be associated w/ balancers or on their
1925
     * Workers can be associated w/ balancers or on their
1875
     * own; ie: the generic reverse-proxy or a worker
1926
     * own; ie: the generic reverse-proxy or a worker
Lines 1893-1900 PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker( Link Here
1893
        /* we need to allocate space here */
1944
        /* we need to allocate space here */
1894
        *worker = apr_palloc(p, sizeof(proxy_worker));
1945
        *worker = apr_palloc(p, sizeof(proxy_worker));
1895
    }
1946
    }
1896
1897
    memset(*worker, 0, sizeof(proxy_worker));
1947
    memset(*worker, 0, sizeof(proxy_worker));
1948
    
1898
    /* right here we just want to tuck away the worker info.
1949
    /* right here we just want to tuck away the worker info.
1899
     * if called during config, we don't have shm setup yet,
1950
     * if called during config, we don't have shm setup yet,
1900
     * so just note the info for later. */
1951
     * so just note the info for later. */
Lines 1902-1915 PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker( Link Here
1902
        wshared = ap_malloc(sizeof(proxy_worker_shared));  /* will be freed ap_proxy_share_worker */
1953
        wshared = ap_malloc(sizeof(proxy_worker_shared));  /* will be freed ap_proxy_share_worker */
1903
    else
1954
    else
1904
        wshared = apr_palloc(p, sizeof(proxy_worker_shared));
1955
        wshared = apr_palloc(p, sizeof(proxy_worker_shared));
1905
1906
    memset(wshared, 0, sizeof(proxy_worker_shared));
1956
    memset(wshared, 0, sizeof(proxy_worker_shared));
1907
1957
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) {
1958
    if (PROXY_STRNCPY(wshared->name, ptr) != APR_SUCCESS) {
1914
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(02808)
1959
        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);
1960
        "Alert! worker name (%s) too long; truncated to: %s", ptr, wshared->name);
Lines 1926-1931 PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker( Link Here
1926
        "worker hostname (%s) too long; truncated for legacy modules that do not use "
1971
        "worker hostname (%s) too long; truncated for legacy modules that do not use "
1927
        "proxy_worker_shared->hostname_ex: %s", uri.hostname, wshared->hostname);
1972
        "proxy_worker_shared->hostname_ex: %s", uri.hostname, wshared->hostname);
1928
    }
1973
    }
1974
    wshared->port = (uri.port) ? uri.port : port_of_scheme;
1929
    wshared->flush_packets = flush_off;
1975
    wshared->flush_packets = flush_off;
1930
    wshared->flush_wait = PROXY_FLUSH_WAIT;
1976
    wshared->flush_wait = PROXY_FLUSH_WAIT;
1931
    wshared->is_address_reusable = 1;
1977
    wshared->is_address_reusable = 1;
Lines 1960-1965 PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker( Link Here
1960
    return NULL;
2006
    return NULL;
1961
}
2007
}
1962
2008
2009
PROXY_DECLARE(char *) ap_proxy_define_worker(apr_pool_t *p,
2010
                                             proxy_worker **worker,
2011
                                             proxy_balancer *balancer,
2012
                                             proxy_server_conf *conf,
2013
                                             const char *url,
2014
                                             int do_malloc)
2015
{
2016
    return proxy_define_worker(p, worker, balancer, conf, url, do_malloc, 0);
2017
}
2018
1963
PROXY_DECLARE(char *) ap_proxy_define_match_worker(apr_pool_t *p,
2019
PROXY_DECLARE(char *) ap_proxy_define_match_worker(apr_pool_t *p,
1964
                                             proxy_worker **worker,
2020
                                             proxy_worker **worker,
1965
                                             proxy_balancer *balancer,
2021
                                             proxy_balancer *balancer,
Lines 1968-1985 PROXY_DECLARE(char *) ap_proxy_define_match_worker Link Here
1968
                                             int do_malloc)
2024
                                             int do_malloc)
1969
{
2025
{
1970
    char *err;
2026
    char *err;
1971
    const char *pdollar = ap_strchr_c(url, '$');
1972
2027
1973
    if (pdollar != NULL) {
2028
    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) {
2029
    if (err) {
1978
        return err;
2030
        return err;
1979
    }
2031
    }
1980
2032
1981
    (*worker)->s->is_name_matchable = 1;
2033
    (*worker)->s->is_name_matchable = 1;
1982
    if (pdollar) {
2034
    if (ap_strchr_c((*worker)->s->name, '$')) {
1983
        /* Before ap_proxy_define_match_worker() existed, a regex worker
2035
        /* Before ap_proxy_define_match_worker() existed, a regex worker
1984
         * with dollar substitution was never matched against the actual
2036
         * with dollar substitution was never matched against the actual
1985
         * URL thus the request fell through the generic worker. To avoid
2037
         * URL thus the request fell through the generic worker. To avoid

Return to bug 65419