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 |