proxy_util.c revision a5a16c0e1cfa8dfe987ab3f424dbb0d1746c0c6b
f743002678eb67b99bbc29fee116b65d9530fec0wrowe/* Licensed to the Apache Software Foundation (ASF) under one or more
80833bb9a1bf25dcf19e814438a4b311d2e1f4cffuankg * contributor license agreements. See the NOTICE file distributed with
6736c640e65e06990ef33af71ee81fac4df4ff5fjim * this work for additional information regarding copyright ownership.
50f8c80eb4d3989ebf3f1341aeef4d2d302af162sf * The ASF licenses this file to You under the Apache License, Version 2.0
50f8c80eb4d3989ebf3f1341aeef4d2d302af162sf * (the "License"); you may not use this file except in compliance with
4bb0a88a01fb7b494bb02a8b881b5eab0308bda6sf * the License. You may obtain a copy of the License at
295ba2e25e562ee52c7bf96808cf9d486ebfb325sf * Unless required by applicable law or agreed to in writing, software
3104923cb51cf5826c97368d1f0d5202c352cd4fsf * distributed under the License is distributed on an "AS IS" BASIS,
3104923cb51cf5826c97368d1f0d5202c352cd4fsf * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7b395e4e878c28a4784919cfd2e704ddd14a3390jorton * See the License for the specific language governing permissions and
7b395e4e878c28a4784919cfd2e704ddd14a3390jorton * limitations under the License.
536e48c08d674acac5d44929318f2ad928edc361jorton/* Utility routines for Apache proxy */
459eaf0826f995b73a0dc066f59ea10d2824e72dsf * Opaque structure containing target server info when
459eaf0826f995b73a0dc066f59ea10d2824e72dsf * using a forward proxy.
6d6cd31bddca0b7d9cf9d18e46cd2361530e24f3sf * Up to now only used in combination with HTTP CONNECT.
6d6cd31bddca0b7d9cf9d18e46cd2361530e24f3sftypedef struct {
53e9b27aba029b18be814df40bcf6f0428771d1efuankg int use_http_connect; /* Use SSL Tunneling via HTTP CONNECT */
fe2e0971201136f2dbc6b000ad5c006a1a6ff672sf/* Keep synced with mod_proxy.h! */
fe2e0971201136f2dbc6b000ad5c006a1a6ff672sfstatic struct wstat {
347074f011eae59e518ddf8d8474d35e029a2056sf unsigned int bit;
21da42a6b8f551ef603bd06356d3bf71d6d0c21dsf const char *name;
2876a591f17b0c6ed0cf28da929643965e67c953sf {PROXY_WORKER_INITIALIZED, PROXY_WORKER_INITIALIZED_FLAG, "Init "},
2876a591f17b0c6ed0cf28da929643965e67c953sf {PROXY_WORKER_IGNORE_ERRORS, PROXY_WORKER_IGNORE_ERRORS_FLAG, "Ign "},
2876a591f17b0c6ed0cf28da929643965e67c953sf {PROXY_WORKER_IN_SHUTDOWN, PROXY_WORKER_IN_SHUTDOWN_FLAG, "Shut "},
38eb64d29a17648e108852de42f23335aecaa8f8sf {PROXY_WORKER_DISABLED, PROXY_WORKER_DISABLED_FLAG, "Dis "},
976f49eaf81ffe917272e4f1834115dec06962b0sf {PROXY_WORKER_STOPPED, PROXY_WORKER_STOPPED_FLAG, "Stop "},
38eb64d29a17648e108852de42f23335aecaa8f8sf {PROXY_WORKER_IN_ERROR, PROXY_WORKER_IN_ERROR_FLAG, "Err "},
5a1f28ac93914b4bae892c69ac4b3e670bc10da8nd {PROXY_WORKER_HOT_STANDBY, PROXY_WORKER_HOT_STANDBY_FLAG, "Stby "},
0361488d59792d052a9f8024c0e5a1ef909252e6rpluem/* Global balancer counter */
6135cc8178d75a52828ad225b1d568cd1e97799erpluemstatic int lb_workers_limit = 0;
6135cc8178d75a52828ad225b1d568cd1e97799erpluemconst apr_strmatch_pattern PROXY_DECLARE_DATA *ap_proxy_strmatch_path;
44761f3e3072cf78a4997a88bb9a515ca101a1f4covenerconst apr_strmatch_pattern PROXY_DECLARE_DATA *ap_proxy_strmatch_domain;
44761f3e3072cf78a4997a88bb9a515ca101a1f4covenerstatic int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r);
2ba1586475aa4ec972ca7c19b06d53bf76f0ee7efuankgstatic int proxy_match_domainname(struct dirconn_entry *This, request_rec *r);
2ba1586475aa4ec972ca7c19b06d53bf76f0ee7efuankgstatic int proxy_match_hostname(struct dirconn_entry *This, request_rec *r);
c7502880be24058c7fc03771fda61f95bc238339sfstatic int proxy_match_word(struct dirconn_entry *This, request_rec *r);
c7502880be24058c7fc03771fda61f95bc238339sfAPR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(proxy, PROXY, int, create_req,
6bb524f1895f30265a1431afc460977d391cb36bsfPROXY_DECLARE(apr_status_t) ap_proxy_strncpy(char *dst, const char *src,
b40bfdb714672f972887f9f1f1e154e00125bb68covener /* Assume the typical case is smaller copying into bigger
b40bfdb714672f972887f9f1f1e154e00125bb68covener so we have a fast return */
b40bfdb714672f972887f9f1f1e154e00125bb68covener if ((thelen < dlen-1) || ((strlen(src)) == thelen)) {
e6dd71992459d05a676b98b7963423dc5dc1e24aminfrin /* XXX: APR_ENOSPACE would be better */
23f1535d6a60817d2846bac0aea230ea475d7dccminfrin/* already called in the knowledge that the characters are hex digits */
ec7520b24cd80d34d82bbcaca153cbb23cc04bc0rjung int ch = x[0];
return buf[0];
#if !APR_CHARSET_EBCDIC
int proxyreq)
int i, j, ch;
if (t == enc_path) {
else if (t == enc_search) {
else if (t == enc_user) {
else if (t == enc_fpath) {
if (t == enc_path) {
else if (t == enc_search) {
for (i = 0, j = 0; i < len; i++, j++) {
ch = x[i];
y[j] = ch;
return NULL;
y[j] = ch;
PROXY_DECLARE(char *)
return NULL;
NULL));
r->uri);
return statuscode;
return r->hostname;
return NULL;
url = apr_pstrdup(r->pool, &url[1]); /* make it point to "//", which is what proxy_canon_netloc expects */
int i, quads;
long bits;
char *tmp;
char *tmp;
++addr;
--quads;
/* "IP Address should be given in dotted-quad form, optionally followed by a netmask (e.g., 192.168.111.0/24)"; */
#if DEBUGGING
#if DEBUGGING
!= APR_SUCCESS) {
#if DEBUGGING
while (reqaddr) {
#if DEBUGGING
#if DEBUGGING
--d_len;
--h_len;
int h2_len;
int h1_len;
while (addr) {
--h2_len;
--h1_len;
return HTTP_FORBIDDEN;
if (!addr)
while (conf_addr) {
while (uri_addr) {
uaddr);
return HTTP_FORBIDDEN;
return OK;
return OK;
return url;
int n, l3 = 0;
if (urlpart) {
* BalancerMember balancer://alias http://example.com/foo
* translate url http://example.com/foo/bar/that to /bash/that
if (urlpart) {
--l2;
NULL);
worker++;
if (part) {
if (part) {
return url;
&proxy_module);
const char *pathp;
const char *domainp;
int ddiff = 0;
int pdiff = 0;
char *ret;
return str;
if (newpath) {
if (newdomain) {
if (newdomain) {
return ret;
const char *url,
int care)
return NULL;
return balancer;
balancer++;
return NULL;
const char *url)
return NULL;
const char *url,
const char *alias,
int do_malloc)
const char *sname;
if (!lbmethod) {
if (do_malloc)
&sname);
return APR_EINVAL;
if (lbmethod)
return APR_SUCCESS;
PROXY_DECLARE(apr_status_t) ap_proxy_initialize_balancer(proxy_balancer *balancer, server_rec *s, apr_pool_t *p)
unsigned int num;
if (!storage) {
return APR_EGENERAL;
return APR_EGENERAL;
return rv;
return APR_EGENERAL;
return rv;
return APR_SUCCESS;
return APR_SUCCESS;
return APR_SUCCESS;
if (conn->r) {
return APR_SUCCESS;
apr_pool_clear(p);
return APR_SUCCESS;
request_rec *r)
return APR_SUCCESS;
return APR_SUCCESS;
return APR_SUCCESS;
const char *url)
int max_match = 0;
int url_length;
int min_match;
int worker_name_length;
char *url_copy;
return NULL;
char *pathstart;
if (balancer) {
return max_worker;
const char *url,
int do_malloc)
int rv;
char *ptr;
* ProxyPass / http://www.example.com
if (balancer) {
} else if (conf) {
if (do_malloc)
return NULL;
return APR_EINVAL;
return APR_SUCCESS;
PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker, server_rec *s, apr_pool_t *p)
int mpm_threads;
return rv;
return APR_EGENERAL;
void *conn;
return rv;
server_rec *s)
return OK;
return DECLINED;
return OK;
request_rec *r,
int access_status;
if (*worker) {
return access_status;
request_rec *r,
if (balancer) {
return access_status;
const char *proxy_function,
const char *backend_name,
request_rec *r)
int connected = 0;
int loglevel;
server_rec *s)
return HTTP_SERVICE_UNAVAILABLE;
return HTTP_SERVICE_UNAVAILABLE;
return OK;
server_rec *s)
return OK;
PROXY_DECLARE(int)
char **url,
const char *proxyname,
char *server_portstr,
int server_portstr_size)
int server_port;
NULL));
if (!proxyname) {
if (proxyname) {
const char *proxy_auth;
return HTTP_INTERNAL_SERVER_ERROR;
return OK;
server_rec *s)
int status;
int complete = 0;
int len = 0;
if (!complete) {
buffer);
code_str);
return(status);
server_rec *s)
int connected = 0;
int loglevel;
sizeof(apr_sockaddr_t));
conn_rec *c,
server_rec *s)
int rc;
return OK;
0, NULL,
return HTTP_INTERNAL_SERVER_ERROR;
return HTTP_INTERNAL_SERVER_ERROR;
return rc;
return OK;
int ap_proxy_lb_workers(void)
if (!lb_workers_limit)
return lb_workers_limit;
apr_bucket *e;
if (r->main)
c->bucket_alloc);
PROXY_DECLARE(unsigned int)
unsigned int hash;
return hash;
unsigned int hash;
return hash;
if (set)
return APR_SUCCESS;
pwt++;
return APR_EINVAL;
pwt++;
if (PROXY_WORKER_IS_USABLE(w))
return ret;
int index;
return APR_SUCCESS;
if (lbmethod) {
int found;
return APR_EGENERAL;
found = 0;
if (!found) {
return rv;
if (b->s->need_reset) {
b->s->need_reset = 0;
return APR_SUCCESS;