842ae4bd224140319ae7feec1872b93dfd491143fielding/* Licensed to the Apache Software Foundation (ASF) under one or more
842ae4bd224140319ae7feec1872b93dfd491143fielding * contributor license agreements. See the NOTICE file distributed with
842ae4bd224140319ae7feec1872b93dfd491143fielding * this work for additional information regarding copyright ownership.
842ae4bd224140319ae7feec1872b93dfd491143fielding * The ASF licenses this file to You under the Apache License, Version 2.0
842ae4bd224140319ae7feec1872b93dfd491143fielding * (the "License"); you may not use this file except in compliance with
842ae4bd224140319ae7feec1872b93dfd491143fielding * the License. You may obtain a copy of the License at
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * Unless required by applicable law or agreed to in writing, software
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * distributed under the License is distributed on an "AS IS" BASIS,
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * See the License for the specific language governing permissions and
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * limitations under the License.
2555a6b5da21d61804f47084d8fcc98eb4acbc42wroweAPR_DECLARE_OPTIONAL_FN(int, ssl_proxy_enable, (conn_rec *));
2555a6b5da21d61804f47084d8fcc98eb4acbc42wroweAPR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *));
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturkAPR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * A Web proxy module. Stages:
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * translate_name: set filename to proxy:<URL>
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe * map_to_storage: run proxy_walk (rather than directory_walk/file_walk)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe * can't trust directory_walk/file_walk since these are
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe * not in our filesystem. Prevents mod_http from serving
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe * the TRACE request we will set aside to handle later.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * fix_ups: convert the URL stored in the filename to the
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * canonical form.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * handler: handle proxy requests
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* -------------------------------------------------------------- */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* Translate the URL into a 'filename' */
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe const char *key,
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe const char *val)
9f1a88897168c3f1e5009acb585daf01e38a0299jim /* Normalized load factor. Used with BalancerMamber,
9f1a88897168c3f1e5009acb585daf01e38a0299jim * it is a number between 1 and 100.
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim if (worker->s->lbfactor < 1 || worker->s->lbfactor > 100)
7af19efc4667363f74d332a8d010b49e88d56fd5trawick return "LoadFactor must be a number between 1..100";
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk /* If set it will give the retry timeout for the worker
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk * The default value is 60 seconds, meaning that if
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk * in error state, it will be retried after that timeout.
f251b576aa9caeb8876ce9f78fb10bf65eddc97emturk return "Retry must be a positive value";
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk /* Time in seconds that will destroy all the connections
0c888b8088644f3a39dcf1998e0304c289532057jim * that exceed the smax
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe return "TTL must be at least one second";
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk /* Initial number of connections to remote
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe return "Min must be a positive number";
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk /* Maximum number of connections to remote
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe return "Max must be a positive number";
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe /* XXX: More inteligent naming needed */
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk /* Maximum number of connections to remote that
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk * will not be destroyed
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe return "Smax must be a positive number";
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem /* Acquire timeout in given unit (default is milliseconds).
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk * If set this will be the maximum time to
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk * wait for a free connection.
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem if (ap_timeout_parameter_parse(val, &timeout, "ms") != APR_SUCCESS)
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem return "Acquire timeout has wrong format";
61d82a1991928d3fa5ee50dc57f2ae3f4b5c781ajim return "Acquire must be at least one millisecond";
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk /* Connection timeout in seconds.
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk * Defaults to server timeout.
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe return "Timeout must be at least one second";
5eb56df4054a0bca4d740eedd7ef277355a2c0adjim if (s < 512 && s) {
5eb56df4054a0bca4d740eedd7ef277355a2c0adjim return "IOBufferSize must be >= 512 bytes, or 0 for system default.";
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe return "ReceiveBufferSize must be >= 512 bytes, or 0 for system default.";
41c38e78e8e5dc73544571cc2b749d40869e84fawrowe return "KeepAlive must be On|Off";
b842b65e0618c5535233b197f03dc917d184adb3jim return "DisableReuse must be On|Off";
44b664206cee887b8b69862def5dd1832afc97ddcovener return "EnableReuse must be On|Off";
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk /* Worker route.
3a3a90e05e4cab7e0507557f197c60f4532fe6d5jim return apr_psprintf(p, "Route length must be < %d characters",
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk /* Worker redirection route.
3a3a90e05e4cab7e0507557f197c60f4532fe6d5jim return apr_psprintf(p, "Redirect length must be < %d characters",
f73a8fabbdc4ec11c8b475e9f48539de0c4f82ebmturk const char *v;
f73a8fabbdc4ec11c8b475e9f48539de0c4f82ebmturk /* Worker status.
f73a8fabbdc4ec11c8b475e9f48539de0c4f82ebmturk for (v = val; *v; v++) {
f73a8fabbdc4ec11c8b475e9f48539de0c4f82ebmturk if (*v == '+') {
f73a8fabbdc4ec11c8b475e9f48539de0c4f82ebmturk else if (*v == '-') {
7ce17736e4802a923eed275812647a7c3e9ad76ejim return "Unknown status parameter option";
07ac837c886b356dc96e83cf82fb348eb56406d9jim return "flushpackets must be on|off|auto";
07ac837c886b356dc96e83cf82fb348eb56406d9jim return "flushwait must be <= 1000, or 0 for system default of 10 millseconds.";
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->flush_wait = ival * 1000; /* change to microseconds */
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem /* Ping/Pong timeout in given unit (default is second).
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem if (ap_timeout_parameter_parse(val, &timeout, "s") != APR_SUCCESS)
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem return "Ping/Pong timeout has wrong format";
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem return "Ping/Pong timeout must be at least one millisecond";
f185ce14f5dd540ae54659f764989c017c619485jim return "lbset must be between 0 and 99";
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem /* Request timeout in given unit (default is second).
f921cd430a2ea23fcaedfdfc7439163f63c8472arpluem * Defaults to connection timeout
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem if (ap_timeout_parameter_parse(val, &timeout, "s") != APR_SUCCESS)
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem return "Connectiontimeout has wrong format";
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem return "Connectiontimeout must be at least one millisecond.";
3a3a90e05e4cab7e0507557f197c60f4532fe6d5jim apr_psprintf(p, "flusher name length must be < %d characters",
65efbf0826de766a90d745cc44427bfa4e2447b6mturk return "unknown Worker parameter";
1febae173a82bc2a71c3c0ba4105cf674000791bjimstatic const char *set_balancer_param(proxy_server_conf *conf,
4415d997ac73262e513c0a571bd5be4f609040bawrowe const char *key,
4415d997ac73262e513c0a571bd5be4f609040bawrowe const char *val)
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk /* Balancer sticky session name.
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk * Set to something like JSESSIONID or
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk * PHPSESSIONID, etc..,
3a3a90e05e4cab7e0507557f197c60f4532fe6d5jim apr_psprintf(p, "stickysession length must be < %d characters",
d20993e12a1caa8952c6d964ed0fbb92b7f97d79jim if ((path = strchr((char *)balancer->s->sticky, '|'))) {
20eead0b01d51fce0cc17d04b8f98ec38eac68aejim /* separator/delimiter for sessionid and route,
20eead0b01d51fce0cc17d04b8f98ec38eac68aejim * normally '.'
20eead0b01d51fce0cc17d04b8f98ec38eac68aejim return "stickysessionsep must be a single character or Off";
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk /* If set to 'on' the session will break
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk * if the worker is in error state or
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk * disabled.
4415d997ac73262e513c0a571bd5be4f609040bawrowe return "failover must be On|Off";
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk /* Balancer timeout in seconds.
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk * If set this will be the maximum time to
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk * wait for a free worker.
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk * Default is not to wait.
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe return "timeout must be at least one second";
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk /* Maximum number of failover attempts before
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk * giving up.
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk return "maximum number of attempts must be a positive number";
5b439d3976ab9363288cf5132902fad230777523jim return "unknown lbmethod";
361051c5d96d51ff2f707777b8f629a56799ef02jorton provider = ap_lookup_provider(PROXY_LBMETHOD, val, "0");
e32a2e2ca90ae7e7f1195d1e275f9ad6a581ffc6jim if (PROXY_STRNCPY(balancer->s->lbpname, val) == APR_SUCCESS) {
e32a2e2ca90ae7e7f1195d1e275f9ad6a581ffc6jim return "lbmethod name too large";
1febae173a82bc2a71c3c0ba4105cf674000791bjim return "unknown lbmethod";
ff4ec92f5bb8d43b3ba1979ccda94f07961bf323jim /* If set to 'on' then ';' will also be
ff4ec92f5bb8d43b3ba1979ccda94f07961bf323jim * used as a session path separator/delim (ala
ff4ec92f5bb8d43b3ba1979ccda94f07961bf323jim return "scolonpathdelim must be On|Off";
d46dfdce9351f52a971777948d9b02f8fc668ff8niq balancer->errstatuses = apr_array_make(p, 1, sizeof(int));
3a49a6c98ef80c71830e66e7f8f46083001b494ctrawick *(int *)apr_array_push(balancer->errstatuses) = ival;
b92a868b537899a51efd8c200c396fa51c63839dtrawick return "failonstatus must be one or more HTTP response codes";
fb5e4869b57545ff534add0a4b0ded84cc68212bdruggeri return "failontimeout must be On|Off";
e32a2e2ca90ae7e7f1195d1e275f9ad6a581ffc6jim if (PROXY_STRNCPY(balancer->s->nonce, val) != APR_SUCCESS) {
a652b68dea502131f70084ead7981d5fc754cd34jim return "Provided nonce is too large";
a652b68dea502131f70084ead7981d5fc754cd34jim return "growth must be between 1 and 100";
0361488d59792d052a9f8024c0e5a1ef909252e6rpluem return "forcerecovery must be On|Off";
65efbf0826de766a90d745cc44427bfa4e2447b6mturk return "unknown Balancer parameter";
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic int alias_match(const char *uri, const char *alias_fakename)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *end_fakename = alias_fakename + strlen(alias_fakename);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* any number of '/' in the alias matches any number in
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard * the supplied URI, but there must be at least one...
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* Other characters are compared literally */
00211b036b78699ace57a6d800a52e6c2d57652fnd /* fixup badly encoded stuff (e.g. % as last character) */
50b2d068ddf98cf75622a0020cd143d379d1b235jfclere /* We reach the end of the uri before the end of "alias_fakename"
50b2d068ddf98cf75622a0020cd143d379d1b235jfclere * for example uri is "/" and alias_fakename "/examples"
00211b036b78699ace57a6d800a52e6c2d57652fnd /* Check last alias path component matched all the way */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (aliasp[-1] != '/' && *urip != '\0' && *urip != '/')
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* Return number of characters from URI which matched (may be
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * greater than length of alias, since we may have matched
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * doubled slashes)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* Detect if an absoluteURI should be proxied or not. Note that we
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * have to do this during this phase because later phases are
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * "short-circuiting"... i.e. translate_names will end when the first
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * module returns OK. So for example, if the request is something like:
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * mod_alias will notice the /cgi-bin part and ScriptAlias it and
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * short-circuit the proxy... just because of the ordering in the
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * configuration file.
a812b025d139f465a31c76fc02ed162ed5271b03nd (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
16d38ac65d7e54cd44eeda7b23f84ee68b35094ewrowe /* Ick... msvc (perhaps others) promotes ternary short results to int */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* but it might be something vhosted */
7b6ba9c468f26bdb3492d5e8cb79628a3b04e8c8wrowe && !strcasecmp(r->parsed_uri.scheme, ap_http_scheme(r))
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard && ap_matches_request_vhost(r, r->parsed_uri.hostname,
e8f95a682820a599fe41b22977010636be5c2717jim (apr_port_t)(r->parsed_uri.port_str ? r->parsed_uri.port
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard r->filename = apr_pstrcat(r->pool, "proxy:", r->uri, NULL);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* We need special treatment for CONNECT proxying: it has no scheme part */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding else if (conf->req && r->method_number == M_CONNECT
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard r->filename = apr_pstrcat(r->pool, "proxy:", r->uri, NULL);
e99dfd55d29a7b4209b814efc7270d0b74ccee74niqstatic const char *proxy_interpolate(request_rec *r, const char *str)
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq /* Interpolate an env str in a configuration string
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq * Syntax ${var} --> value_of(var)
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq * Method: replace one var, and recurse on remainder of string
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq * Nothing clever here, and crap like nested vars may do silly things
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq * but we'll at least avoid sending the unwary into a loop
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq /* OK, this is syntax we want to interpolate. Is there such a var ? */
13fd8ef492c6bf438c0d29aaf42d5d596405e23cjailletc var = apr_pstrmemdup(r->pool, start+2, end-(start+2));
13fd8ef492c6bf438c0d29aaf42d5d596405e23cjailletc firstpart = apr_pstrmemdup(r->pool, str, (start-str));
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq apr_array_header_t *ret = apr_array_make(r->pool, hdr->nelts,
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq sizeof (struct proxy_alias));
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq struct proxy_alias *old = (struct proxy_alias *) hdr->elts;
e8ecc839fc57f2157ff10eba188d7aa3c0244174jimPROXY_DECLARE(int) ap_proxy_trans_match(request_rec *r, struct proxy_alias *ent,
df419be6d7d4b68823efa05722375552af49c2b6minfrin unsigned int nocanon = ent->flags & PROXYPASS_NOCANON;
df419be6d7d4b68823efa05722375552af49c2b6minfrin const char *use_uri = nocanon ? r->unparsed_uri : r->uri;
e8ecc839fc57f2157ff10eba188d7aa3c0244174jim if (dconf && (dconf->interpolate_env == 1) && (ent->flags & PROXYPASS_INTERPOLATE)) {
df419be6d7d4b68823efa05722375552af49c2b6minfrin if (!ap_regexec(ent->regex, r->uri, AP_MAX_REG_MATCH, regm, 0)) {
df419be6d7d4b68823efa05722375552af49c2b6minfrin /* test that we haven't reduced the URI */
df419be6d7d4b68823efa05722375552af49c2b6minfrin if (nocanon && ap_regexec(ent->regex, r->unparsed_uri,
df419be6d7d4b68823efa05722375552af49c2b6minfrin found = ap_pregsub(r->pool, real, use_uri, AP_MAX_REG_MATCH,
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01135)
4c138e467a7d384582aa6f8c9809af589e572feesf "Substitution in regular expression failed. "
4c138e467a7d384582aa6f8c9809af589e572feesf "Replacement too long?");
df419be6d7d4b68823efa05722375552af49c2b6minfrin /* Note: The strcmp() below catches cases where there
df419be6d7d4b68823efa05722375552af49c2b6minfrin * was no regex substitution. This is so cases like:
df419be6d7d4b68823efa05722375552af49c2b6minfrin * ProxyPassMatch \.gif balancer://foo
df419be6d7d4b68823efa05722375552af49c2b6minfrin * will work "as expected". The upshot is that the 2
df419be6d7d4b68823efa05722375552af49c2b6minfrin * directives below act the exact same way (ie: $1 is implied):
df419be6d7d4b68823efa05722375552af49c2b6minfrin * ProxyPassMatch ^(/.*\.gif)$ balancer://foo
df419be6d7d4b68823efa05722375552af49c2b6minfrin * ProxyPassMatch ^(/.*\.gif)$ balancer://foo$1
df419be6d7d4b68823efa05722375552af49c2b6minfrin * which may be confusing.
df419be6d7d4b68823efa05722375552af49c2b6minfrin found = apr_pstrcat(r->pool, "proxy:", found, NULL);
df419be6d7d4b68823efa05722375552af49c2b6minfrin found = apr_pstrcat(r->pool, "proxy:", real, use_uri, NULL);
df419be6d7d4b68823efa05722375552af49c2b6minfrin if (len != 0) {
df419be6d7d4b68823efa05722375552af49c2b6minfrin if (nocanon && len != alias_match(r->unparsed_uri, ent->fake)) {
df419be6d7d4b68823efa05722375552af49c2b6minfrin found = apr_pstrcat(r->pool, "proxy:", real, use_uri + len, NULL);
df419be6d7d4b68823efa05722375552af49c2b6minfrin /* We made a reducing transformation, so we can't safely use
df419be6d7d4b68823efa05722375552af49c2b6minfrin * unparsed_uri. Safe fallback is to ignore nocanon.
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01136)
df419be6d7d4b68823efa05722375552af49c2b6minfrin "Unescaped URL path matched ProxyPass; ignoring unsafe nocanon");
df419be6d7d4b68823efa05722375552af49c2b6minfrin /* mod_proxy_http needs to be told. Different module. */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* someone has already set up the proxy, it was possibly ourselves
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard * in proxy_detect
6be38922add55325d9acadb2406a4072cb8865detrawick if ((r->unparsed_uri[0] == '*' && r->unparsed_uri[1] == '\0')
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* XXX: since r->uri has been manipulated already we're not really
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * compliant with RFC1945 at this point. But this probably isn't
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * an issue because this is a hybrid proxy/origin server.
df419be6d7d4b68823efa05722375552af49c2b6minfrin dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
df419be6d7d4b68823efa05722375552af49c2b6minfrin /* short way - this location is reverse proxied? */
25524fd4a888fd31598556d9c323de90e431e237jim conf = (proxy_server_conf *) ap_get_module_config(r->server->module_config,
df419be6d7d4b68823efa05722375552af49c2b6minfrin /* long way - walk the list of aliases, find a match */
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe proxy_server_conf *sconf = ap_get_module_config(r->server->module_config,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_conf_vector_t *per_dir_defaults = r->server->lookup_defaults;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_conf_vector_t **sec_proxy = (ap_conf_vector_t **) sconf->sec_proxy->elts;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* XXX: shouldn't we use URI here? Canonicalize it first?
e8f95a682820a599fe41b22977010636be5c2717jim * Pass over "proxy:" prefix
e8f95a682820a599fe41b22977010636be5c2717jim for (j = 0; j < num_sec; ++j)
f596c8b1c00a251b54cff654fda122cfe815d536covener entry_proxy = ap_get_module_config(entry_config, &proxy_module);
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin if (entry_proxy->refs && entry_proxy->refs->nelts) {
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin pmatch = apr_palloc(rxpool, nmatch*sizeof(ap_regmatch_t));
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin if (ap_regexec(entry_proxy->r, proxyname, nmatch, pmatch, 0)) {
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin for (i = 0; i < nmatch; i++) {
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin /* XXX: What about case insensitive matching ???
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin * Compare regex, fnmatch or string as appropriate
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin * If the entry doesn't relate, then continue
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin entry_proxy->p_is_fnmatch ? apr_fnmatch(entry_proxy->p,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe per_dir_defaults = ap_merge_per_dir_configs(r->pool, per_dir_defaults,
8632261c895a84c88ae6ade6ea4c62b27bd22b3ebrianp if (!r->proxyreq || !r->filename || strncmp(r->filename, "proxy:", 6) != 0)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe /* Don't let the core or mod_http map_to_storage hooks handle this,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe * We don't need directory/file_walk, and we want to TRACE on our own.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* -------------------------------------------------------------- */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* Fixup the filename */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * Canonicalise the URL
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq proxy_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
45dac0729754e413ff7c673481b219e9ab1a11f1bnicholes if (!r->proxyreq || !r->filename || strncmp(r->filename, "proxy:", 6) != 0)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe /* XXX: Shouldn't we try this before we run the proxy_walk? */
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq if ((dconf->interpolate_env == 1) && (r->proxyreq == PROXYREQ_REVERSE)) {
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq /* create per-request copy of reverse proxy conf,
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq * and interpolate vars in it
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq proxy_req_conf *rconf = apr_palloc(r->pool, sizeof(proxy_req_conf));
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq ap_set_module_config(r->request_config, &proxy_module, rconf);
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq rconf->cookie_paths = proxy_vars(r, dconf->cookie_paths);
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq rconf->cookie_domains = proxy_vars(r, dconf->cookie_domains);
68ce856106f153813339db8670f6cd0ab8dea484minfrin /* canonicalise each specific scheme */
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin if ((access_status = proxy_run_canon_handler(r, url))) {
65efbf0826de766a90d745cc44427bfa4e2447b6mturk return OK; /* otherwise; we've done the best we can */
11c3b5180e1de6776035320b012a28bb146e7b46chuck/* Send a redirection if the request contains a hostname which is not */
11c3b5180e1de6776035320b012a28bb146e7b46chuck/* fully qualified, i.e. doesn't have a domain name appended. Some proxy */
11c3b5180e1de6776035320b012a28bb146e7b46chuck/* servers like Netscape's allow this and access hosts from the local */
11c3b5180e1de6776035320b012a28bb146e7b46chuck/* domain in this case. I think it is better to redirect to a FQDN, since */
11c3b5180e1de6776035320b012a28bb146e7b46chuck/* these will later be found in the bookmarks files. */
11c3b5180e1de6776035320b012a28bb146e7b46chuck/* The "ProxyDomain" directive determines what domain will be appended */
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic int proxy_needsdomain(request_rec *r, const char *url, const char *domain)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* We only want to worry about GETs */
d7387fcd4969206172e3a2a8bbcd25a3d7011ac5rbb if (!r->proxyreq || r->method_number != M_GET || !r->parsed_uri.hostname)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* If host does contain a dot already, or it is "localhost", decline */
d4a7ca64aa12da0c1b44b0281e93973a89cefeedmartin if (strchr(r->parsed_uri.hostname, '.') != NULL /* has domain, or IPv4 literal */
d4a7ca64aa12da0c1b44b0281e93973a89cefeedmartin || strchr(r->parsed_uri.hostname, ':') != NULL /* IPv6 literal */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding || strcasecmp(r->parsed_uri.hostname, "localhost") == 0)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* Reassemble the request, but insert the domain after the host name */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* Note that the domain name always starts with a dot */
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm r->parsed_uri.hostname = apr_pstrcat(r->pool, r->parsed_uri.hostname,
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01138)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* -------------------------------------------------------------- */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* Invoke handler */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding struct proxy_remote *ents = (struct proxy_remote *) proxies->elts;
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk struct dirconn_entry *list = (struct dirconn_entry *)conf->dirconn->elts;
35c9e4d2c0a6465746a98958ef756114834461e6minfrin /* is this for us? */
3f4de7a5b5425a595380c867e08ac8bc8f97cec3jim /* We may have forced the proxy handler via config or .htaccess */
3f4de7a5b5425a595380c867e08ac8bc8f97cec3jim r->filename = apr_pstrcat(r->pool, r->handler, r->filename, NULL);
35c9e4d2c0a6465746a98958ef756114834461e6minfrin /* handle max-forwards / OPTIONS / TRACE */
35c9e4d2c0a6465746a98958ef756114834461e6minfrin if ((str = apr_table_get(r->headers_in, "Max-Forwards"))) {
4860eae0821bbdf3e0da78be7b4057ebed5d86e4minfrin if (maxfwd < 0 || maxfwd == APR_INT64_MAX || *end) {
4860eae0821bbdf3e0da78be7b4057ebed5d86e4minfrin "Max-Forwards value '%s' could not be parsed", str));
4860eae0821bbdf3e0da78be7b4057ebed5d86e4minfrin else if (maxfwd == 0) {
e2b2e15108eb7cb566b1d70ce4e479276d951de5minfrin switch (r->method_number) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard "Max-Forwards has reached zero - proxy loop?");
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* set configured max-forwards */
3d81c6f18deabacd15101eda69f7d16bf466d22dniq if (maxfwd >= 0) {
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe /* Allow "error-notes" string to be printed by ap_send_error_response()
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe * Note; this goes nowhere, canned error response need an overhaul.
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe "TRACE forbidden by server configuration");
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01139)
994ced9dca1b824d03a44187f09d264215cd490csf "TRACE forbidden by server configuration");
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe /* Can't test ap_should_client_block, we aren't ready to send
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe * the client a 100 Continue response till the connection has
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe * been established
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe && (r->read_length || r->read_chunked || r->remaining))
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe /* Allow "error-notes" string to be printed by ap_send_error_response()
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe * Note; this goes nowhere, canned error response need an overhaul.
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe "TRACE with request body is not allowed");
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01140)
994ced9dca1b824d03a44187f09d264215cd490csf "TRACE with request body is not allowed");
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk if (p == NULL) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01141)
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk /* If the host doesn't have a domain name, add one and redirect. */
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk /* Check URI's destination host against NoProxy hosts */
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk /* Bypass ProxyRemote server lookup if configured as NoProxy */
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk for (direct_connect = i = 0; i < conf->dirconn->nelts &&
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk (direct_connect) ? "NoProxy for %s" : "UseProxy for %s",
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk /* Try to obtain the most suitable worker */
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk access_status = ap_proxy_pre_request(&worker, &balancer, r, conf, &url);
8cdc2e8b6f46a3f239a70184e9f785fc25463487rpluem * Only return if access_status is not HTTP_SERVICE_UNAVAILABLE
8cdc2e8b6f46a3f239a70184e9f785fc25463487rpluem * This gives other modules the chance to hook into the
8cdc2e8b6f46a3f239a70184e9f785fc25463487rpluem * request_status hook and decide what to do in this situation.
8cdc2e8b6f46a3f239a70184e9f785fc25463487rpluem * Ensure that balancer is NULL if worker is NULL to prevent
8cdc2e8b6f46a3f239a70184e9f785fc25463487rpluem * potential problems in the post_request hook.
6a4043fd04bbd44ca0d084c096318df035abc46djfclere /* Initialise worker if needed, note the shared area must be initialized by the balancer logic */
14c8c18e6caab1bdeb0f26b2b031e000fef58ef9jim ap_proxy_initialize_worker(worker, r->server, conf->pool);
cb7cf74a315df272e2ec329ce2ef1d50b82b8384jim if (balancer && balancer->s->max_attempts_set && !max_attempts)
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk /* firstly, try a proxy, unless a NoProxy directive is active */
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk p2 = ap_strchr_c(ents[i].scheme, ':'); /* is it a partial URL? */
b1306729566b49fb30aed5c46adaf07a637115afjerenkrantz ap_regexec(ents[i].regexp, url, 0, NULL, 0) == 0) ||
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk (p2 == NULL && strcasecmp(scheme, ents[i].scheme) == 0) ||
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk /* handle the scheme */
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01142)
994ced9dca1b824d03a44187f09d264215cd490csf "Trying to run scheme_handler against proxy");
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem /* Did the scheme handler process the request? */
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem * An fatal error or success, so no point in
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem * retrying with a direct connection.
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem cl_a = apr_table_get(r->headers_in, "Content-Length");
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem * The request body is of length > 0. We cannot
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem * retry with a direct connection since we already
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem * sent (parts of) the request body to the proxy
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem * and do not have any longer.
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem if (cl > 0) {
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem * Transfer-Encoding was set as input header, so we had
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem * a request body. We cannot retry with a direct
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem * connection for the same reason as above.
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem if (apr_table_get(r->headers_in, "Transfer-Encoding")) {
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk /* otherwise, try it direct */
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk /* N.B. what if we're behind a firewall, where we must use a proxy or
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk * give up??
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk /* handle the scheme */
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01143)
ea8e3350cface61eda0d549bfba28755e09fc322jim "Running scheme %s handler (attempt %d)",
a8523e2451f03f4a30030b7bda643a23a75d91demturk access_status = proxy_run_scheme_handler(r, worker, conf,
a8523e2451f03f4a30030b7bda643a23a75d91demturk else if (access_status == HTTP_INTERNAL_SERVER_ERROR) {
a8523e2451f03f4a30030b7bda643a23a75d91demturk /* Unrecoverable server error.
a8523e2451f03f4a30030b7bda643a23a75d91demturk * We can not failover to another worker.
a8523e2451f03f4a30030b7bda643a23a75d91demturk * Mark the worker as unusable if member of load balancer
caad2986f81ab263f7af41467dd622dc9add17f3ylavic && !(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)) {
a8523e2451f03f4a30030b7bda643a23a75d91demturk /* Recoverable server error.
e8f95a682820a599fe41b22977010636be5c2717jim * We can failover to another worker
a8523e2451f03f4a30030b7bda643a23a75d91demturk * Mark the worker as unusable if member of load balancer
caad2986f81ab263f7af41467dd622dc9add17f3ylavic && !(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)) {
a8523e2451f03f4a30030b7bda643a23a75d91demturk /* Unrecoverable error.
a8523e2451f03f4a30030b7bda643a23a75d91demturk * Return the origin status code to the client.
a8523e2451f03f4a30030b7bda643a23a75d91demturk /* Try again if the worker is unusable and the service is
a8523e2451f03f4a30030b7bda643a23a75d91demturk * unavailable.
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01144)
994ced9dca1b824d03a44187f09d264215cd490csf "No protocol handler was valid for the URL %s. "
994ced9dca1b824d03a44187f09d264215cd490csf "If you are using a DSO version of mod_proxy, make sure "
994ced9dca1b824d03a44187f09d264215cd490csf "the proxy submodules are included in the configuration "
0823a3f8e3ca10d08d036739d1c0c67aaf31255drpluem * Save current r->status and set it to the value of access_status which
0823a3f8e3ca10d08d036739d1c0c67aaf31255drpluem * might be different (e.g. r->status could be HTTP_OK if e.g. we override
0823a3f8e3ca10d08d036739d1c0c67aaf31255drpluem * the error page on the proxy or if the error was not generated by the
0823a3f8e3ca10d08d036739d1c0c67aaf31255drpluem * backend itself but by the proxy e.g. a bad gateway) in order to give
0823a3f8e3ca10d08d036739d1c0c67aaf31255drpluem * ap_proxy_post_request a chance to act correctly on the status code.
0823a3f8e3ca10d08d036739d1c0c67aaf31255drpluem * Only restore r->status if it has not been changed by
0823a3f8e3ca10d08d036739d1c0c67aaf31255drpluem * ap_proxy_post_request as we assume that this change was intentional.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* -------------------------------------------------------------- */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* Setup configurable data */
11c3b5180e1de6776035320b012a28bb146e7b46chuckstatic void * create_proxy_config(apr_pool_t *p, server_rec *s)
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe proxy_server_conf *ps = apr_pcalloc(p, sizeof(proxy_server_conf));
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe ps->sec_proxy = apr_array_make(p, 10, sizeof(ap_conf_vector_t *));
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe ps->proxies = apr_array_make(p, 10, sizeof(struct proxy_remote));
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe ps->aliases = apr_array_make(p, 10, sizeof(struct proxy_alias));
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe ps->noproxies = apr_array_make(p, 10, sizeof(struct noproxy_entry));
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe ps->dirconn = apr_array_make(p, 10, sizeof(struct dirconn_entry));
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe ps->workers = apr_array_make(p, 10, sizeof(proxy_worker));
5a5a6c22260854843c973e2ea9a14bec64362ab5wrowe ps->balancers = apr_array_make(p, 10, sizeof(proxy_balancer));
1b0760b10f93eb1e0f52e28aa20cd821c68ac217jim ps->id = apr_psprintf(p, "p%x", 1); /* simply for storage size */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ps->viaopt = via_off; /* initially backward compatible with 1.3.1 */
af952917c05e56874069e1e5f64e6473bb478b68minfrin ps->recv_buffer_size = 0; /* this default was left unset for some reason */
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluzastatic apr_array_header_t *merge_balancers(apr_pool_t *p,
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza apr_array_header_t *tocopy = apr_array_make(p, 1, sizeof(proxy_balancer));
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza /* Check if the balancer is defined in both override and base configs:
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza * a) If it is, Create copy of base balancer and change the configuration
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza * which can be changed by ProxyPass.
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza * b) Otherwise, copy the balancer to tocopy array and merge it later.
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza if (b1->hash.def == b2->hash.def && b1->hash.fnv == b2->hash.fnv) {
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza /* For shared memory entries, b2->s belongs to override
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza * balancer, so if some entry is not set there, we have to
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza * update it according to the base balancer. */
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza PROXY_STRNCPY(b2->s->sticky_path, b1->s->sticky_path);
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2->s->sticky_separator_set = b1->s->sticky_separator_set;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza if (!b2->s->max_attempts_set && b1->s->max_attempts_set) {
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza if (!b2->s->sticky_force_set && b1->s->sticky_force_set) {
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza if (!b2->s->scolonsep_set && b1->s->scolonsep_set) {
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza if (!b2->s->forcerecovery_set && b1->s->forcerecovery_set) {
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2->s->forcerecovery_set = b1->s->forcerecovery_set;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza /* For non-shared memory entries, b2 is copy of b1, so we have
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza * to use tmp copy of b1 to detect changes done in override. */
af952917c05e56874069e1e5f64e6473bb478b68minfrinstatic void * merge_proxy_config(apr_pool_t *p, void *basev, void *overridesv)
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe proxy_server_conf *ps = apr_pcalloc(p, sizeof(proxy_server_conf));
af952917c05e56874069e1e5f64e6473bb478b68minfrin proxy_server_conf *base = (proxy_server_conf *) basev;
af952917c05e56874069e1e5f64e6473bb478b68minfrin proxy_server_conf *overrides = (proxy_server_conf *) overridesv;
f4c820be3237778985b10dabd420c6301f65ee04rjung ps->inherit = (overrides->inherit_set == 0) ? base->inherit : overrides->inherit;
f4c820be3237778985b10dabd420c6301f65ee04rjung ps->inherit_set = overrides->inherit_set || base->inherit_set;
8ad2333769563eadfe4944407c32666160b641a0jim ps->ppinherit = (overrides->ppinherit_set == 0) ? base->ppinherit : overrides->ppinherit;
8ad2333769563eadfe4944407c32666160b641a0jim ps->ppinherit_set = overrides->ppinherit_set || base->ppinherit_set;
8ad2333769563eadfe4944407c32666160b641a0jim ps->proxies = apr_array_append(p, base->proxies, overrides->proxies);
a0c045dd686938d2d95b31b0bad3911a6ada611djim ps->sec_proxy = apr_array_append(p, base->sec_proxy, overrides->sec_proxy);
a0c045dd686938d2d95b31b0bad3911a6ada611djim ps->aliases = apr_array_append(p, base->aliases, overrides->aliases);
a0c045dd686938d2d95b31b0bad3911a6ada611djim ps->noproxies = apr_array_append(p, base->noproxies, overrides->noproxies);
a0c045dd686938d2d95b31b0bad3911a6ada611djim ps->dirconn = apr_array_append(p, base->dirconn, overrides->dirconn);
1e9c19df8bde7cbced53210a99eb0216ce79e1fbjim ps->workers = apr_array_append(p, base->workers, overrides->workers);
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza ps->balancers = merge_balancers(p, base->balancers, overrides->balancers);
609ecc54ccbd06a9286e1aaf891f80f62450b1aamturk ps->forward = overrides->forward ? overrides->forward : base->forward;
a865e849a3b00dc8524ecdda09a1699452876219mturk ps->reverse = overrides->reverse ? overrides->reverse : base->reverse;
af952917c05e56874069e1e5f64e6473bb478b68minfrin ps->domain = (overrides->domain == NULL) ? base->domain : overrides->domain;
cb7cf74a315df272e2ec329ce2ef1d50b82b8384jim ps->id = (overrides->id == NULL) ? base->id : overrides->id;
af952917c05e56874069e1e5f64e6473bb478b68minfrin ps->viaopt = (overrides->viaopt_set == 0) ? base->viaopt : overrides->viaopt;
82b8e88fd2a266002f6504d8fc4313ec7b5630c0niq ps->viaopt_set = overrides->viaopt_set || base->viaopt_set;
af952917c05e56874069e1e5f64e6473bb478b68minfrin ps->req = (overrides->req_set == 0) ? base->req : overrides->req;
7ce40500bfead8781bab964eb6e01944acbf3915jim ps->bgrowth = (overrides->bgrowth_set == 0) ? base->bgrowth : overrides->bgrowth;
7ce40500bfead8781bab964eb6e01944acbf3915jim ps->bgrowth_set = overrides->bgrowth_set || base->bgrowth_set;
7ce40500bfead8781bab964eb6e01944acbf3915jim ps->max_balancers = overrides->max_balancers || base->max_balancers;
af952917c05e56874069e1e5f64e6473bb478b68minfrin ps->recv_buffer_size = (overrides->recv_buffer_size_set == 0) ? base->recv_buffer_size : overrides->recv_buffer_size;
82b8e88fd2a266002f6504d8fc4313ec7b5630c0niq ps->recv_buffer_size_set = overrides->recv_buffer_size_set || base->recv_buffer_size_set;
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin ps->io_buffer_size = (overrides->io_buffer_size_set == 0) ? base->io_buffer_size : overrides->io_buffer_size;
82b8e88fd2a266002f6504d8fc4313ec7b5630c0niq ps->io_buffer_size_set = overrides->io_buffer_size_set || base->io_buffer_size_set;
35c9e4d2c0a6465746a98958ef756114834461e6minfrin ps->maxfwd = (overrides->maxfwd_set == 0) ? base->maxfwd : overrides->maxfwd;
82b8e88fd2a266002f6504d8fc4313ec7b5630c0niq ps->maxfwd_set = overrides->maxfwd_set || base->maxfwd_set;
35630e8756729a29273ef1a5c879b90df3594d66rjung ps->timeout = (overrides->timeout_set == 0) ? base->timeout : overrides->timeout;
82b8e88fd2a266002f6504d8fc4313ec7b5630c0niq ps->timeout_set = overrides->timeout_set || base->timeout_set;
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim ps->badopt = (overrides->badopt_set == 0) ? base->badopt : overrides->badopt;
82b8e88fd2a266002f6504d8fc4313ec7b5630c0niq ps->badopt_set = overrides->badopt_set || base->badopt_set;
00dd9a5a2b0c1f507c332b918ea390f9c1fa991cmturk ps->proxy_status = (overrides->proxy_status_set == 0) ? base->proxy_status : overrides->proxy_status;
82b8e88fd2a266002f6504d8fc4313ec7b5630c0niq ps->proxy_status_set = overrides->proxy_status_set || base->proxy_status_set;
b2b9b7f0644773b50aee41956a841ac884086250niq ps->source_address = (overrides->source_address_set == 0) ? base->source_address : overrides->source_address;
b2b9b7f0644773b50aee41956a841ac884086250niq ps->source_address_set = overrides->source_address_set || base->source_address_set;
b2b9b7f0644773b50aee41956a841ac884086250niqstatic const char *set_source_address(cmd_parms *parms, void *dummy,
b2b9b7f0644773b50aee41956a841ac884086250niq const char *arg)
b2b9b7f0644773b50aee41956a841ac884086250niq ap_get_module_config(parms->server->module_config, &proxy_module);
b2b9b7f0644773b50aee41956a841ac884086250niq if (APR_SUCCESS == apr_sockaddr_info_get(&addr, arg, APR_UNSPEC, 0, 0,
b2b9b7f0644773b50aee41956a841ac884086250niq return "ProxySourceAddress invalid value";
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowestatic void *create_proxy_dir_config(apr_pool_t *p, char *dummy)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe (proxy_dir_conf *) apr_pcalloc(p, sizeof(proxy_dir_conf));
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe /* Filled in by proxysection, when applicable */
f86b4df17588d404f3da535a8054f43b0642f92aniq /* Put these in the dir config so they work inside <Location> */
f86b4df17588d404f3da535a8054f43b0642f92aniq new->raliases = apr_array_make(p, 10, sizeof(struct proxy_alias));
f86b4df17588d404f3da535a8054f43b0642f92aniq new->cookie_paths = apr_array_make(p, 10, sizeof(struct proxy_alias));
f86b4df17588d404f3da535a8054f43b0642f92aniq new->cookie_domains = apr_array_make(p, 10, sizeof(struct proxy_alias));
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return (void *) new;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowestatic void *merge_proxy_dir_config(apr_pool_t *p, void *basev, void *addv)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe proxy_dir_conf *new = (proxy_dir_conf *) apr_pcalloc(p, sizeof(proxy_dir_conf));
f86b4df17588d404f3da535a8054f43b0642f92aniq /* Put these in the dir config so they work inside <Location> */
0b4d5285b176f443fd6c0fb07bef76f6b5eb81c7niq new->raliases = apr_array_append(p, base->raliases, add->raliases);
0b4d5285b176f443fd6c0fb07bef76f6b5eb81c7niq = apr_array_append(p, base->cookie_paths, add->cookie_paths);
0b4d5285b176f443fd6c0fb07bef76f6b5eb81c7niq = apr_array_append(p, base->cookie_domains, add->cookie_domains);
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq new->interpolate_env = (add->interpolate_env == -1) ? base->interpolate_env
3709b26f3370ae89c5324a3c03fab56a93b09ecdsf new->preserve_host = (add->preserve_host_set == 0) ? base->preserve_host
3709b26f3370ae89c5324a3c03fab56a93b09ecdsf new->preserve_host_set = add->preserve_host_set || base->preserve_host_set;
40b22d3b20454959fe51fdc89907908d77701078minfrin new->error_override = (add->error_override_set == 0) ? base->error_override
40b22d3b20454959fe51fdc89907908d77701078minfrin new->error_override_set = add->error_override_set || base->error_override_set;
df419be6d7d4b68823efa05722375552af49c2b6minfrin new->alias = (add->alias_set == 0) ? base->alias : add->alias;
93cf7fc650197b941ae31a7c7e51e901b129e954igalic new->add_forwarded_headers = add->add_forwarded_headers;
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic const char *
9379749d811388a7d0e3410940ddd6743a33d330jim add_proxy(cmd_parms *cmd, void *dummy, const char *f1, const char *r1, int regex)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding char *p, *q;
3c59b18ce62f97468aaa5951d4e21a5478ef36ecminfrin if (p == NULL || p[1] != '/' || p[2] != '/' || p[3] == '\0') {
9379749d811388a7d0e3410940ddd6743a33d330jim return "ProxyRemoteMatch: Bad syntax for a remote proxy server";
9379749d811388a7d0e3410940ddd6743a33d330jim return "ProxyRemote: Bad syntax for a remote proxy server";
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (q != NULL) {
9379749d811388a7d0e3410940ddd6743a33d330jim return "ProxyRemoteMatch: Bad syntax for a remote proxy server (bad port number)";
9379749d811388a7d0e3410940ddd6743a33d330jim return "ProxyRemote: Bad syntax for a remote proxy server (bad port number)";
9379749d811388a7d0e3410940ddd6743a33d330jim return "Regular expression for ProxyRemoteMatch could not be compiled.";
9379749d811388a7d0e3410940ddd6743a33d330jimstatic const char *
9379749d811388a7d0e3410940ddd6743a33d330jim add_proxy_noregex(cmd_parms *cmd, void *dummy, const char *f1, const char *r1)
9379749d811388a7d0e3410940ddd6743a33d330jimstatic const char *
9379749d811388a7d0e3410940ddd6743a33d330jim add_proxy_regex(cmd_parms *cmd, void *dummy, const char *f1, const char *r1)
8ef23ef065afb74b96b94ad7d58212bce634e7cecovenerPROXY_DECLARE(const char *) ap_proxy_de_socketfy(apr_pool_t *p, const char *url)
38161f83959979bc9916ece8ab84410ca72a9230jim * We could be passed a URL during the config stage that contains
38161f83959979bc9916ece8ab84410ca72a9230jim * the UDS path... ignore it
38161f83959979bc9916ece8ab84410ca72a9230jim /* move past the 'unix:...|' UDS path info */
38161f83959979bc9916ece8ab84410ca72a9230jim /* special case: "unix:....|scheme:" is OK, expand
38161f83959979bc9916ece8ab84410ca72a9230jim * to "unix:....|scheme://localhost"
38161f83959979bc9916ece8ab84410ca72a9230jim if (c == NULL) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic const char *
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim add_pass(cmd_parms *cmd, void *dummy, const char *arg, int is_regex)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module);
b588214d6e6fe09abe709e83e894921fbc7e25c8covener err = ap_check_cmd_context(cmd, NOT_IN_DIRECTORY|NOT_IN_FILES);
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe while (*arg) {
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim return "ProxyPassMatch invalid syntax ('~' usage).";
28fe44817329b1183f64e878c258962f90423a8dniq else if (!r) {
c7eeb0a294d58c75aee6ed86f73c6e1e8cf600a3rpluem if (*r == '/') {
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim return "ProxyPass|ProxyPassMatch can not have a path when defined in "
c7eeb0a294d58c75aee6ed86f73c6e1e8cf600a3rpluem "a location.";
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim return "Invalid ProxyPass|ProxyPassMatch parameter. Parameter must "
c7eeb0a294d58c75aee6ed86f73c6e1e8cf600a3rpluem "be in the form 'key=value'.";
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim return "Invalid ProxyPass|ProxyPassMatch parameter. Parameter must be "
c7eeb0a294d58c75aee6ed86f73c6e1e8cf600a3rpluem "in the form 'key=value'.";
df419be6d7d4b68823efa05722375552af49c2b6minfrin if (r == NULL) {
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim return "ProxyPass|ProxyPassMatch needs a path when not defined in a location";
df419be6d7d4b68823efa05722375552af49c2b6minfrin /* if per directory, save away the single alias */
df419be6d7d4b68823efa05722375552af49c2b6minfrin dconf->alias = apr_pcalloc(cmd->pool, sizeof(struct proxy_alias));
df419be6d7d4b68823efa05722375552af49c2b6minfrin /* if per server, add to the alias array */
44b664206cee887b8b69862def5dd1832afc97ddcovener new->real = apr_pstrdup(cmd->pool, ap_proxy_de_socketfy(cmd->pool, r));
dcda744296f197717c5105fd197e94ceba7880d7jim new->regex = ap_pregcomp(cmd->pool, f, AP_REG_EXTENDED);
dcda744296f197717c5105fd197e94ceba7880d7jim return "Regular expression could not be compiled.";
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq /* Distinguish the balancer from worker */
f66d52ac5f701eed7986e23d12960344f8bf6b61jim proxy_balancer *balancer = ap_proxy_get_balancer(cmd->pool, conf, r, 0);
e1f43cac62f6960a6945e1fb6e3288ef7082ac53rpluem * In the regex case supplying a fake URL doesn't make sense as it
e1f43cac62f6960a6945e1fb6e3288ef7082ac53rpluem * cannot be parsed anyway with apr_uri_parse later on in
e1f43cac62f6960a6945e1fb6e3288ef7082ac53rpluem * ap_proxy_define_balancer / ap_proxy_update_balancer
e1f43cac62f6960a6945e1fb6e3288ef7082ac53rpluem const char *err = ap_proxy_define_balancer(cmd->pool, &balancer, conf, r, fake_copy, 0);
de274dca1be855ebb66bb7857951aae26fcb54c7wrowe return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL);
e1f43cac62f6960a6945e1fb6e3288ef7082ac53rpluem ap_proxy_update_balancer(cmd->pool, balancer, fake_copy);
1febae173a82bc2a71c3c0ba4105cf674000791bjim const char *err = set_balancer_param(conf, cmd->pool, balancer, elts[i].key,
de274dca1be855ebb66bb7857951aae26fcb54c7wrowe return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL);
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza proxy_worker *worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, new->real);
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza err = ap_proxy_define_match_worker(cmd->pool, &worker, NULL,
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza err = ap_proxy_define_worker(cmd->pool, &worker, NULL,
de274dca1be855ebb66bb7857951aae26fcb54c7wrowe return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL);
fd6b36f31f155a2a1de18c1ad403fc983b20532cjkaluza else if ((use_regex != 0) ^ (worker->s->is_name_matchable != 0)) {
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza return apr_pstrcat(cmd->temp_pool, "ProxyPass/<Proxy> and "
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza "ProxyPassMatch/<ProxyMatch> can't be used "
4d3eb8fbdc3f2e06f95faba14fa9741f9a7208cetrawick "together with the same worker name ",
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_INFO, 0, cmd->server, APLOGNO(01145)
9acdc6e89570bd3d79206c6d2ca2b5ccf85b20c7jim "Sharing worker '%s' instead of creating new worker '%s'",
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(01146)
9acdc6e89570bd3d79206c6d2ca2b5ccf85b20c7jim "Ignoring parameter '%s=%s' for worker '%s' because of worker sharing",
9acdc6e89570bd3d79206c6d2ca2b5ccf85b20c7jim elts[i].key, elts[i].val, ap_proxy_worker_name(cmd->pool, worker));
06cdc8d205f0982074ab9b032d0b6d74c58f54carjung const char *err = set_worker_param(cmd->pool, worker, elts[i].key,
06cdc8d205f0982074ab9b032d0b6d74c58f54carjung return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL);
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jimstatic const char *
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim add_pass_noregex(cmd_parms *cmd, void *dummy, const char *arg)
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jimstatic const char *
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim add_pass_regex(cmd_parms *cmd, void *dummy, const char *arg)
997023faa943892aae20d092044aa983c2936982niqstatic const char * add_pass_reverse(cmd_parms *cmd, void *dconf, const char *f,
997023faa943892aae20d092044aa983c2936982niq const char *r, const char *i)
b588214d6e6fe09abe709e83e894921fbc7e25c8covener err = ap_check_cmd_context(cmd, NOT_IN_DIRECTORY|NOT_IN_FILES);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return "ProxyPassReverse needs a path when not defined in a location";
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return "ProxyPassReverse can not have a path when defined in a location";
997023faa943892aae20d092044aa983c2936982niqstatic const char* cookie_path(cmd_parms *cmd, void *dconf, const char *f,
997023faa943892aae20d092044aa983c2936982niq const char *r, const char *interp)
997023faa943892aae20d092044aa983c2936982niqstatic const char* cookie_domain(cmd_parms *cmd, void *dconf, const char *f,
997023faa943892aae20d092044aa983c2936982niq const char *r, const char *interp)
11c3b5180e1de6776035320b012a28bb146e7b46chuckstatic const char *
11c3b5180e1de6776035320b012a28bb146e7b46chuck set_proxy_exclude(cmd_parms *parms, void *dummy, const char *arg)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_get_module_config(s->module_config, &proxy_module);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding struct noproxy_entry *list = (struct noproxy_entry *) conf->noproxies->elts;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* Don't duplicate entries */
edc346c3223efd41e6a2057c37cea69744b73dccwrowe if (strcasecmp(arg, list[i].name) == 0) { /* ignore case for host names */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (APR_SUCCESS == apr_sockaddr_info_get(&addr, new->name, APR_UNSPEC, 0, 0, parms->pool)) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* Similar to set_proxy_exclude(), but defining directly connected hosts,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * which should never be accessed via the configured ProxyRemote servers
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic const char *
11c3b5180e1de6776035320b012a28bb146e7b46chuck set_proxy_dirconn(cmd_parms *parms, void *dummy, const char *arg)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_get_module_config(s->module_config, &proxy_module);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding struct dirconn_entry *list = (struct dirconn_entry *) conf->dirconn->elts;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* Don't duplicate entries */
2ee708a3c186643c065c486f851e1dd78f0a4adajailletc else if (ap_proxy_is_domainname(New, parms->pool)) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic const char *
11c3b5180e1de6776035320b012a28bb146e7b46chuck set_proxy_domain(cmd_parms *parms, void *dummy, const char *arg)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_get_module_config(parms->server->module_config, &proxy_module);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return "ProxyDomain: domain name must start with a dot.";
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic const char *
11c3b5180e1de6776035320b012a28bb146e7b46chuck set_proxy_req(cmd_parms *parms, void *dummy, int flag)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_get_module_config(parms->server->module_config, &proxy_module);
ff1234e45aca1b8171d711ecb87f58b9d9100a99ianhstatic const char *
40b22d3b20454959fe51fdc89907908d77701078minfrin set_proxy_error_override(cmd_parms *parms, void *dconf, int flag)
93cf7fc650197b941ae31a7c7e51e901b129e954igalicstatic const char *
93cf7fc650197b941ae31a7c7e51e901b129e954igalic add_proxy_http_headers(cmd_parms *parms, void *dconf, int flag)
fd3fa792f04fc9c4e8f5f83dceb0fc34e71f8570ianhstatic const char *
3709b26f3370ae89c5324a3c03fab56a93b09ecdsf set_preserve_host(cmd_parms *parms, void *dconf, int flag)
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic const char *
11c3b5180e1de6776035320b012a28bb146e7b46chuck set_recv_buffer_size(cmd_parms *parms, void *dummy, const char *arg)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_get_module_config(parms->server->module_config, &proxy_module);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (s < 512 && s != 0) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return "ProxyReceiveBufferSize must be >= 512 bytes, or 0 for system default.";
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrinstatic const char *
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin set_io_buffer_size(cmd_parms *parms, void *dummy, const char *arg)
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin ap_get_module_config(parms->server->module_config, &proxy_module);
5eb56df4054a0bca4d740eedd7ef277355a2c0adjim if (s < 512 && s) {
5eb56df4054a0bca4d740eedd7ef277355a2c0adjim return "ProxyIOBufferSize must be >= 512 bytes, or 0 for system default.";
35c9e4d2c0a6465746a98958ef756114834461e6minfrinstatic const char *
35c9e4d2c0a6465746a98958ef756114834461e6minfrin set_max_forwards(cmd_parms *parms, void *dummy, const char *arg)
35c9e4d2c0a6465746a98958ef756114834461e6minfrin ap_get_module_config(parms->server->module_config, &proxy_module);
4224d5789080ea5586d49420da1e1996f5653bb5ianhstatic const char*
4224d5789080ea5586d49420da1e1996f5653bb5ianh set_proxy_timeout(cmd_parms *parms, void *dummy, const char *arg)
4224d5789080ea5586d49420da1e1996f5653bb5ianh ap_get_module_config(parms->server->module_config, &proxy_module);
4224d5789080ea5586d49420da1e1996f5653bb5ianh return "Proxy Timeout must be at least 1 second.";
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic const char*
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb set_via_opt(cmd_parms *parms, void *dummy, const char *arg)
11c3b5180e1de6776035320b012a28bb146e7b46chuck ap_get_module_config(parms->server->module_config, &proxy_module);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return "ProxyVia must be one of: "
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard "off | on | full | block";
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jimstatic const char*
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim set_bad_opt(cmd_parms *parms, void *dummy, const char *arg)
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim ap_get_module_config(parms->server->module_config, &proxy_module);
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim return "ProxyBadHeader must be one of: "
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim "IsError | Ignore | StartBody";
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowestatic const char*
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe set_status_opt(cmd_parms *parms, void *dummy, const char *arg)
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe ap_get_module_config(parms->server->module_config, &proxy_module);
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe return "ProxyStatus must be one of: "
6c05afd314b4ddd545d63b4ff5de822cc30eec79trawick "off | on | full";
7ce40500bfead8781bab964eb6e01944acbf3915jimstatic const char *set_bgrowth(cmd_parms *parms, void *dummy, const char *arg)
7ce40500bfead8781bab964eb6e01944acbf3915jim ap_get_module_config(parms->server->module_config, &proxy_module);
7ce40500bfead8781bab964eb6e01944acbf3915jim return "BalancerGrowth must be between 0 and 1000";
57db302f0875a6c93a79333b8941cea4c1827272jimstatic const char *set_persist(cmd_parms *parms, void *dummy, int flag)
57db302f0875a6c93a79333b8941cea4c1827272jim ap_get_module_config(parms->server->module_config, &proxy_module);
1e9c19df8bde7cbced53210a99eb0216ce79e1fbjimstatic const char *set_inherit(cmd_parms *parms, void *dummy, int flag)
1e9c19df8bde7cbced53210a99eb0216ce79e1fbjim ap_get_module_config(parms->server->module_config, &proxy_module);
8ad2333769563eadfe4944407c32666160b641a0jimstatic const char *set_ppinherit(cmd_parms *parms, void *dummy, int flag)
8ad2333769563eadfe4944407c32666160b641a0jim ap_get_module_config(parms->server->module_config, &proxy_module);
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowestatic const char *add_member(cmd_parms *cmd, void *dummy, const char *arg)
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe ap_get_module_config(s->module_config, &proxy_module);
7c2df38555e33d4c30de9973722128cc9646a1b3sf /* XXX: Should this be NOT_IN_DIRECTORY|NOT_IN_FILES? */
7c2df38555e33d4c30de9973722128cc9646a1b3sf const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS);
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe while (*arg) {
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe return "BalancerMember can not have a balancer name when defined in a location";
433dc2d5dae74ed067db6175010ff973d02511e9jerenkrantz return "Invalid BalancerMember parameter. Parameter must "
433dc2d5dae74ed067db6175010ff973d02511e9jerenkrantz "be in the form 'key=value'";
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe return "BalancerMember must define balancer name when outside <Proxy > section";
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe return "BalancerMember must define remote proxy server";
65efbf0826de766a90d745cc44427bfa4e2447b6mturk ap_str_tolower(path); /* lowercase scheme://hostname */
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim /* Try to find the balancer */
f66d52ac5f701eed7986e23d12960344f8bf6b61jim balancer = ap_proxy_get_balancer(cmd->temp_pool, conf, path, 0);
aee938da5530729ca29b60015120c487d5e1bcacjim err = ap_proxy_define_balancer(cmd->pool, &balancer, conf, path, "/", 0);
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim return apr_pstrcat(cmd->temp_pool, "BalancerMember ", err, NULL);
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe /* Try to find existing worker */
44b664206cee887b8b69862def5dd1832afc97ddcovener worker = ap_proxy_get_worker(cmd->temp_pool, balancer, conf, ap_proxy_de_socketfy(cmd->temp_pool, name));
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01147)
0c4b0ffd3db7ae8e34662826098b5e46dadc1e88jim "Defining worker '%s' for balancer '%s'",
cb7cf74a315df272e2ec329ce2ef1d50b82b8384jim if ((err = ap_proxy_define_worker(cmd->pool, &worker, balancer, conf, name, 0)) != NULL)
e8f95a682820a599fe41b22977010636be5c2717jim return apr_pstrcat(cmd->temp_pool, "BalancerMember ", err, NULL);
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01148)
9acdc6e89570bd3d79206c6d2ca2b5ccf85b20c7jim "Defined worker '%s' for balancer '%s'",
9acdc6e89570bd3d79206c6d2ca2b5ccf85b20c7jim ap_proxy_worker_name(cmd->pool, worker), balancer->s->name);
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_INFO, 0, cmd->server, APLOGNO(01149)
9acdc6e89570bd3d79206c6d2ca2b5ccf85b20c7jim "Sharing worker '%s' instead of creating new worker '%s'",
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(01150)
9acdc6e89570bd3d79206c6d2ca2b5ccf85b20c7jim "Ignoring parameter '%s=%s' for worker '%s' because of worker sharing",
9acdc6e89570bd3d79206c6d2ca2b5ccf85b20c7jim elts[i].key, elts[i].val, ap_proxy_worker_name(cmd->pool, worker));
06cdc8d205f0982074ab9b032d0b6d74c58f54carjung return apr_pstrcat(cmd->temp_pool, "BalancerMember ", err, NULL);
65efbf0826de766a90d745cc44427bfa4e2447b6mturkstatic const char *
65efbf0826de766a90d745cc44427bfa4e2447b6mturk set_proxy_param(cmd_parms *cmd, void *dummy, const char *arg)
65efbf0826de766a90d745cc44427bfa4e2447b6mturk (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module);
7c2df38555e33d4c30de9973722128cc9646a1b3sf /* XXX: Should this be NOT_IN_DIRECTORY|NOT_IN_FILES? */
7c2df38555e33d4c30de9973722128cc9646a1b3sf const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS);
65efbf0826de766a90d745cc44427bfa4e2447b6mturk /* Directive inside <Proxy section
65efbf0826de766a90d745cc44427bfa4e2447b6mturk * Parent directive arg is the worker/balancer name.
65efbf0826de766a90d745cc44427bfa4e2447b6mturk /* Standard set directive with worker/balancer
65efbf0826de766a90d745cc44427bfa4e2447b6mturk * name as first param.
f66d52ac5f701eed7986e23d12960344f8bf6b61jim balancer = ap_proxy_get_balancer(cmd->pool, conf, name, 0);
aee938da5530729ca29b60015120c487d5e1bcacjim err = ap_proxy_define_balancer(cmd->pool, &balancer, conf, name, "/", 0);
fef95ce9cdb638443693c21f181dd2494b467469mturk return apr_pstrcat(cmd->temp_pool, "ProxySet can not find '",
44b664206cee887b8b69862def5dd1832afc97ddcovener worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, ap_proxy_de_socketfy(cmd->temp_pool, name));
fef95ce9cdb638443693c21f181dd2494b467469mturk return apr_pstrcat(cmd->temp_pool, "ProxySet can not find '",
65efbf0826de766a90d745cc44427bfa4e2447b6mturk while (*arg) {
65efbf0826de766a90d745cc44427bfa4e2447b6mturk return "Invalid ProxySet parameter. Parameter must be "
65efbf0826de766a90d745cc44427bfa4e2447b6mturk "in the form 'key=value'";
1febae173a82bc2a71c3c0ba4105cf674000791bjim err = set_balancer_param(conf, cmd->pool, balancer, word, val);
c332befc1519a1016d8de07608f0b859e6fab580jim return apr_pstrcat(cmd->temp_pool, "ProxySet: ", err, " ", word, "=", val, "; ", name, NULL);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowestatic void ap_add_per_proxy_conf(server_rec *s, ap_conf_vector_t *dir_config)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe proxy_server_conf *sconf = ap_get_module_config(s->module_config,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe void **new_space = (void **)apr_array_push(sconf->sec_proxy);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowestatic const char *proxysection(cmd_parms *cmd, void *mconfig, const char *arg)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_conf_vector_t *new_dir_conf = ap_create_per_dir_config(cmd->pool);
bdf8801c51d958b1d3ff40f60ab16ccfd999b0fawrowe const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk (proxy_server_conf *) ap_get_module_config(cmd->server->module_config, &proxy_module);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return "<ProxyMatch > block must specify a path";
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return "<Proxy > block must specify a path";
e8f95a682820a599fe41b22977010636be5c2717jim /* XXX Ignore case? What if we proxy a case-insensitive server?!?
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe * While we are at it, shouldn't we also canonicalize the entire
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe * scheme? See proxy_fixup()
ef5650b61a8e35f3cc93ec07e73efc17ea329894jorton r = ap_pregcomp(cmd->pool, cmd->path, AP_REG_EXTENDED);
e6c244ee56578707b20a86e0e938498299a93b6cnd return "Regex could not be compiled";
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe /* initialize our config and fetch it */
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe conf = ap_set_config_vectors(cmd->server, new_dir_conf, cmd->path,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_dir_conf);
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin conf->refs = apr_array_make(cmd->pool, 8, sizeof(char *));
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk return "Multiple <ProxyMatch> arguments not (yet) supported.";
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk "> arguments are not supported for wildchar url.",
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk "> arguments are not supported for non url.",
f66d52ac5f701eed7986e23d12960344f8bf6b61jim balancer = ap_proxy_get_balancer(cmd->pool, sconf, conf->p, 0);
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim worker = ap_proxy_get_worker(cmd->temp_pool, NULL, sconf,
44b664206cee887b8b69862def5dd1832afc97ddcovener ap_proxy_de_socketfy(cmd->temp_pool, (char*)conf->p));
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza err = ap_proxy_define_match_worker(cmd->pool, &worker, NULL,
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza err = ap_proxy_define_worker(cmd->pool, &worker, NULL,
fd6b36f31f155a2a1de18c1ad403fc983b20532cjkaluza else if ((use_regex != 0) ^ (worker->s->is_name_matchable != 0)) {
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza return apr_pstrcat(cmd->temp_pool, "ProxyPass/<Proxy> and "
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza "ProxyPassMatch/<ProxyMatch> can't be used "
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza "altogether with the same worker name ",
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk "> arguments are supported only for workers.",
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk while (*arg) {
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk return "Invalid Proxy parameter. Parameter must be "
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk "in the form 'key=value'";
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk return apr_pstrcat(cmd->temp_pool, thiscmd->name, " ", err, " ",
e8f95a682820a599fe41b22977010636be5c2717jim AP_INIT_RAW_ARGS("<Proxy", proxysection, NULL, RSRC_CONF,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe "Container for directives affecting resources located in the proxied "
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe "location"),
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe AP_INIT_RAW_ARGS("<ProxyMatch", proxysection, (void*)1, RSRC_CONF,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe "Container for directives affecting resources located in the proxied "
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe "location, in regular expression syntax"),
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb AP_INIT_FLAG("ProxyRequests", set_proxy_req, NULL, RSRC_CONF,
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb "on if the true proxy requests should be accepted"),
9379749d811388a7d0e3410940ddd6743a33d330jim AP_INIT_TAKE2("ProxyRemote", add_proxy_noregex, NULL, RSRC_CONF,
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb "a scheme, partial URL or '*' and a proxy server"),
9379749d811388a7d0e3410940ddd6743a33d330jim AP_INIT_TAKE2("ProxyRemoteMatch", add_proxy_regex, NULL, RSRC_CONF,
9379749d811388a7d0e3410940ddd6743a33d330jim "a regex pattern and a proxy server"),
b0ac1e83f8582a9b5a72bff798ffb31a419c8adesf AP_INIT_FLAG("ProxyPassInterpolateEnv", ap_set_flag_slot_char,
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq RSRC_CONF|ACCESS_CONF, "Interpolate Env Vars in reverse Proxy") ,
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim AP_INIT_RAW_ARGS("ProxyPass", add_pass_noregex, NULL, RSRC_CONF|ACCESS_CONF,
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim "a virtual path and a URL"),
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim AP_INIT_RAW_ARGS("ProxyPassMatch", add_pass_regex, NULL, RSRC_CONF|ACCESS_CONF,
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb "a virtual path and a URL"),
997023faa943892aae20d092044aa983c2936982niq AP_INIT_TAKE123("ProxyPassReverse", add_pass_reverse, NULL, RSRC_CONF|ACCESS_CONF,
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb "a virtual path and a URL for reverse proxy behaviour"),
997023faa943892aae20d092044aa983c2936982niq AP_INIT_TAKE23("ProxyPassReverseCookiePath", cookie_path, NULL,
a812b025d139f465a31c76fc02ed162ed5271b03nd RSRC_CONF|ACCESS_CONF, "Path rewrite rule for proxying cookies"),
997023faa943892aae20d092044aa983c2936982niq AP_INIT_TAKE23("ProxyPassReverseCookieDomain", cookie_domain, NULL,
a812b025d139f465a31c76fc02ed162ed5271b03nd RSRC_CONF|ACCESS_CONF, "Domain rewrite rule for proxying cookies"),
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb AP_INIT_ITERATE("ProxyBlock", set_proxy_exclude, NULL, RSRC_CONF,
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb "A list of names, hosts or domains to which the proxy will not connect"),
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb AP_INIT_TAKE1("ProxyReceiveBufferSize", set_recv_buffer_size, NULL, RSRC_CONF,
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb "Receive buffer size for outgoing HTTP and FTP connections in bytes"),
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin AP_INIT_TAKE1("ProxyIOBufferSize", set_io_buffer_size, NULL, RSRC_CONF,
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin "IO buffer size for outgoing HTTP and FTP connections in bytes"),
35c9e4d2c0a6465746a98958ef756114834461e6minfrin AP_INIT_TAKE1("ProxyMaxForwards", set_max_forwards, NULL, RSRC_CONF,
35c9e4d2c0a6465746a98958ef756114834461e6minfrin "The maximum number of proxies a request may be forwarded through."),
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb AP_INIT_ITERATE("NoProxy", set_proxy_dirconn, NULL, RSRC_CONF,
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb "A list of domains, hosts, or subnets to which the proxy will connect directly"),
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb AP_INIT_TAKE1("ProxyDomain", set_proxy_domain, NULL, RSRC_CONF,
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb "The default intranet domain name (in absence of a domain in the URL)"),
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb "Configure Via: proxy header header to one of: on | off | block | full"),
40b22d3b20454959fe51fdc89907908d77701078minfrin AP_INIT_FLAG("ProxyErrorOverride", set_proxy_error_override, NULL, RSRC_CONF|ACCESS_CONF,
4ecd546edd89824908c2a9ad2e07339d89368f9cmartin "use our error handling pages instead of the servers' we are proxying"),
3709b26f3370ae89c5324a3c03fab56a93b09ecdsf AP_INIT_FLAG("ProxyPreserveHost", set_preserve_host, NULL, RSRC_CONF|ACCESS_CONF,
4ecd546edd89824908c2a9ad2e07339d89368f9cmartin "on if we should preserve host header while proxying"),
4224d5789080ea5586d49420da1e1996f5653bb5ianh AP_INIT_TAKE1("ProxyTimeout", set_proxy_timeout, NULL, RSRC_CONF,
4224d5789080ea5586d49420da1e1996f5653bb5ianh "Set the timeout (in seconds) for a proxied connection. "
4224d5789080ea5586d49420da1e1996f5653bb5ianh "This overrides the server timeout"),
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim AP_INIT_TAKE1("ProxyBadHeader", set_bad_opt, NULL, RSRC_CONF,
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim "How to handle bad header line in response: IsError | Ignore | StartBody"),
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe AP_INIT_RAW_ARGS("BalancerMember", add_member, NULL, RSRC_CONF|ACCESS_CONF,
e8f95a682820a599fe41b22977010636be5c2717jim "A balancer name and scheme with list of params"),
7ce40500bfead8781bab964eb6e01944acbf3915jim AP_INIT_TAKE1("BalancerGrowth", set_bgrowth, NULL, RSRC_CONF,
7ce40500bfead8781bab964eb6e01944acbf3915jim "Number of additional Balancers that can be added post-config"),
57db302f0875a6c93a79333b8941cea4c1827272jim AP_INIT_FLAG("BalancerPersist", set_persist, NULL, RSRC_CONF,
57db302f0875a6c93a79333b8941cea4c1827272jim "on if the balancer should persist changes on reboot/restart made via the Balancer Manager"),
44da11d42e24f54f41ce6ebb6ab6ee1dfdf36171jim AP_INIT_FLAG("BalancerInherit", set_inherit, NULL, RSRC_CONF,
8ad2333769563eadfe4944407c32666160b641a0jim "on if this server should inherit Balancers and Workers defined in the main server "
72162c602ff8e9a1aa9f40aa59db8d1237fc30d4minfrin "(Setting to off recommended if using the Balancer Manager)"),
8ad2333769563eadfe4944407c32666160b641a0jim AP_INIT_FLAG("ProxyPassInherit", set_ppinherit, NULL, RSRC_CONF,
8ad2333769563eadfe4944407c32666160b641a0jim "on if this server should inherit all ProxyPass directives defined in the main server "
72162c602ff8e9a1aa9f40aa59db8d1237fc30d4minfrin "(Setting to off recommended if using the Balancer Manager)"),
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe AP_INIT_TAKE1("ProxyStatus", set_status_opt, NULL, RSRC_CONF,
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe "Configure Status: proxy status to one of: on | off | full"),
65efbf0826de766a90d745cc44427bfa4e2447b6mturk AP_INIT_RAW_ARGS("ProxySet", set_proxy_param, NULL, RSRC_CONF|ACCESS_CONF,
65efbf0826de766a90d745cc44427bfa4e2447b6mturk "A balancer or worker name with list of params"),
b2b9b7f0644773b50aee41956a841ac884086250niq AP_INIT_TAKE1("ProxySourceAddress", set_source_address, NULL, RSRC_CONF,
b2b9b7f0644773b50aee41956a841ac884086250niq "Configure local source IP used for request forward"),
93cf7fc650197b941ae31a7c7e51e901b129e954igalic AP_INIT_FLAG("ProxyAddHeaders", add_proxy_http_headers, NULL, RSRC_CONF|ACCESS_CONF,
93cf7fc650197b941ae31a7c7e51e901b129e954igalic "on if X-Forwarded-* headers should be added or completed"),
1723d9ccdd3b647f5b7bae44cab9ab3eca7a4874dougmstatic APR_OPTIONAL_FN_TYPE(ssl_proxy_enable) *proxy_ssl_enable = NULL;
621bd763d2e4d32f19013ac8b76b375b5a01851fdougmstatic APR_OPTIONAL_FN_TYPE(ssl_engine_disable) *proxy_ssl_disable = NULL;
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturkstatic APR_OPTIONAL_FN_TYPE(ssl_is_https) *proxy_is_https = NULL;
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturkstatic APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *proxy_ssl_val = NULL;
1723d9ccdd3b647f5b7bae44cab9ab3eca7a4874dougm * if c == NULL just check if the optional function was imported
1723d9ccdd3b647f5b7bae44cab9ab3eca7a4874dougm * else run the optional function so ssl filters are inserted
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturkPROXY_DECLARE(const char *) ap_proxy_ssl_val(apr_pool_t *p, server_rec *s,
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk const char *var)
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk /* XXX Perhaps the casting useless */
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk return (const char *)proxy_ssl_val(p, s, c, r, (char *)var);
e1d00c81dc34e2c644cc936b9dea75ec9ccfca2adougmstatic int proxy_post_config(apr_pool_t *pconf, apr_pool_t *plog,
c9147f126b25a20d45e5b39ea14efe6191628c41minfrin apr_status_t rv = ap_global_mutex_create(&proxy_mutex, NULL,
8441484e251cc256d4cef5ff4ba88c37aaa3dde6jim ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, plog, APLOGNO(02478)
e1d00c81dc34e2c644cc936b9dea75ec9ccfca2adougm proxy_ssl_enable = APR_RETRIEVE_OPTIONAL_FN(ssl_proxy_enable);
621bd763d2e4d32f19013ac8b76b375b5a01851fdougm proxy_ssl_disable = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_disable);
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk proxy_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk proxy_ssl_val = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
ac527defc56193af96fcb7ceffbda0e41bdb2d7csf ap_proxy_strmatch_path = apr_strmatch_precompile(pconf, "path=", 0);
ac527defc56193af96fcb7ceffbda0e41bdb2d7csf ap_proxy_strmatch_domain = apr_strmatch_precompile(pconf, "domain=", 0);
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe * proxy Extension to mod_status
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowestatic int proxy_status_hook(request_rec *r, int flags)
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rputs("<hr />\n<h1>Proxy LoadBalancer Status for ", r);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung "<th>SSes</th><th>Timeout</th><th>Method</th>"
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung "</tr>\n<tr>", r);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung if (strcmp(balancer->s->sticky, balancer->s->sticky_path)) {
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung "<th>Sch</th><th>Host</th><th>Stat</th>"
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung "<th>Route</th><th>Redir</th>"
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung "<th>F</th><th>Set</th><th>Acc</th><th>Wr</th><th>Rd</th>"
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung "</tr>\n", r);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rprintf(r, "ProxyBalancer[%d]Name: %s\n", i, balancer->s->name);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rvputs(r, "<tr>\n<td>", (*worker)->s->scheme, "</td>", NULL);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rvputs(r, "<td>", (*worker)->s->hostname, "</td><td>", NULL);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rvputs(r, ap_proxy_parse_wstatus(r->pool, *worker), NULL);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rvputs(r, "</td><td>", (*worker)->s->redirect, NULL);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rprintf(r, "</td><td>%d</td>", (*worker)->s->lbfactor);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rputs(apr_strfsize((*worker)->s->transferred, fbuf), r);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung /* TODO: Add the rest of dynamic worker data */
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rprintf(r, "ProxyBalancer[%d]Worker[%d]Name: %s\n",
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rprintf(r, "ProxyBalancer[%d]Worker[%d]Status: %s\n",
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rprintf(r, "ProxyBalancer[%d]Worker[%d]Sent: %s\n",
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rprintf(r, "ProxyBalancer[%d]Worker[%d]Rcvd: %s\n",
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung /* TODO: Add the rest of dynamic worker data */
b37601f1ea5db01521378c0a08939a44000a54b1rjung "<tr><th>SSes</th><td>Sticky session name</td></tr>\n"
b37601f1ea5db01521378c0a08939a44000a54b1rjung "<tr><th>Timeout</th><td>Balancer Timeout</td></tr>\n"
b37601f1ea5db01521378c0a08939a44000a54b1rjung "<tr><th>Sch</th><td>Connection scheme</td></tr>\n"
b37601f1ea5db01521378c0a08939a44000a54b1rjung "<tr><th>Host</th><td>Backend Hostname</td></tr>\n"
b37601f1ea5db01521378c0a08939a44000a54b1rjung "<tr><th>Stat</th><td>Worker status</td></tr>\n"
b37601f1ea5db01521378c0a08939a44000a54b1rjung "<tr><th>Route</th><td>Session Route</td></tr>\n"
b37601f1ea5db01521378c0a08939a44000a54b1rjung "<tr><th>Redir</th><td>Session Route Redirection</td></tr>\n"
b37601f1ea5db01521378c0a08939a44000a54b1rjung "<tr><th>F</th><td>Load Balancer Factor</td></tr>\n"
b37601f1ea5db01521378c0a08939a44000a54b1rjung "<tr><th>Acc</th><td>Number of uses</td></tr>\n"
b37601f1ea5db01521378c0a08939a44000a54b1rjung "<tr><th>Wr</th><td>Number of bytes transferred</td></tr>\n"
b37601f1ea5db01521378c0a08939a44000a54b1rjung "<tr><th>Rd</th><td>Number of bytes read</td></tr>\n"
b37601f1ea5db01521378c0a08939a44000a54b1rjung "</table>", r);
c3ffef98b00967c14c55056152a9411314b6f4bbjim apr_status_t rv = apr_global_mutex_child_init(&proxy_mutex,
8441484e251cc256d4cef5ff4ba88c37aaa3dde6jim ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(02479)
c3ffef98b00967c14c55056152a9411314b6f4bbjim "could not init proxy_mutex in child");
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim /* TODO */
888c31d26ec2735b6e744697dcaec1ab12877b01mturk while (s) {
888c31d26ec2735b6e744697dcaec1ab12877b01mturk conf = (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module);
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim * NOTE: non-balancer members don't use shm at all...
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim * after all, why should they?
834fc281be8e0f7f2614961f12d8bbf603382a17jfclere /* Create and initialize forward worker if defined */
cb7cf74a315df272e2ec329ce2ef1d50b82b8384jim ap_proxy_define_worker(p, &forward, NULL, NULL, "http://www.apache.org", 0);
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim ap_proxy_hashfunc(conf->forward->s->name, PROXY_HASHFUNC_DEFAULT);
14ce718783c7835d3bc89f3bb99ccb02dfb4058ajim ap_proxy_hashfunc(conf->forward->s->name, PROXY_HASHFUNC_FNV);
14ce718783c7835d3bc89f3bb99ccb02dfb4058ajim /* Do not disable worker in case of errors */
888c31d26ec2735b6e744697dcaec1ab12877b01mturk conf->forward->s->status |= PROXY_WORKER_IGNORE_ERRORS;
4ff6259a3db2f4e365f3681df5145dc46d071e6fjim /* Mark as the "generic" worker */
5c24acdc757b7557d33c389fafdb7cc455ce3740covener ap_proxy_initialize_worker(conf->forward, s, conf->pool);
e8f95a682820a599fe41b22977010636be5c2717jim /* Disable address cache for generic forward worker */
cb7cf74a315df272e2ec329ce2ef1d50b82b8384jim ap_proxy_define_worker(p, &reverse, NULL, NULL, "http://www.apache.org", 0);
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim ap_proxy_hashfunc(reverse->s->name, PROXY_HASHFUNC_DEFAULT);
14ce718783c7835d3bc89f3bb99ccb02dfb4058ajim ap_proxy_hashfunc(reverse->s->name, PROXY_HASHFUNC_FNV);
a865e849a3b00dc8524ecdda09a1699452876219mturk /* Do not disable worker in case of errors */
4ff6259a3db2f4e365f3681df5145dc46d071e6fjim /* Mark as the "generic" worker */
5c24acdc757b7557d33c389fafdb7cc455ce3740covener ap_proxy_initialize_worker(conf->reverse, s, conf->pool);
e8f95a682820a599fe41b22977010636be5c2717jim /* Disable address cache for generic reverse worker */
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe * This routine is called before the server processes the configuration
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowestatic int proxy_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
c9147f126b25a20d45e5b39ea14efe6191628c41minfrin apr_status_t rv = ap_mutex_register(pconf, proxy_id, NULL,
8441484e251cc256d4cef5ff4ba88c37aaa3dde6jim ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, plog, APLOGNO(02480)
c9147f126b25a20d45e5b39ea14efe6191628c41minfrin return 500; /* An HTTP status would be a misnomer! */
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe APR_OPTIONAL_HOOK(ap, status_hook, proxy_status_hook, NULL, NULL,
e8f95a682820a599fe41b22977010636be5c2717jim /* Reset workers count on gracefull restart */
65aeb4185d6a108b19c27b89f311dc57dab62239nd /* fixup before mod_rewrite, so that the proxied url will not
65aeb4185d6a108b19c27b89f311dc57dab62239nd * escaped accidentally by our fixup.
35630e8756729a29273ef1a5c879b90df3594d66rjung static const char * const aszSucc[] = { "mod_rewrite.c", NULL};
1d2ff7570139286b0f0d16f92187a16ed5932291mturk /* Only the mpm_winnt has child init hook handler.
1d2ff7570139286b0f0d16f92187a16ed5932291mturk * make sure that we are called after the mpm
1d2ff7570139286b0f0d16f92187a16ed5932291mturk * initializes.
4b155326ef6781820619c10e518dce1a44df7f91rjung static const char *const aszPred[] = { "mpm_winnt.c", "mod_proxy_balancer.c", NULL};
fdacf528f0125e0165de42b7783b1dcbf961a189chuck /* handler */
fdacf528f0125e0165de42b7783b1dcbf961a189chuck ap_hook_handler(proxy_handler, NULL, NULL, APR_HOOK_FIRST);
fdacf528f0125e0165de42b7783b1dcbf961a189chuck /* filename-to-URI translation */
e5882a36d7756850cc829f5f2286120b877458b1pquerna ap_hook_translate_name(proxy_trans, aszSucc, NULL, APR_HOOK_FIRST);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe /* walk <Proxy > entries and suppress default TRACE behavior */
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_hook_map_to_storage(proxy_map_location, NULL,NULL, APR_HOOK_FIRST);
fdacf528f0125e0165de42b7783b1dcbf961a189chuck /* fixups */
65aeb4185d6a108b19c27b89f311dc57dab62239nd ap_hook_fixups(proxy_fixup, NULL, aszSucc, APR_HOOK_FIRST);
fdacf528f0125e0165de42b7783b1dcbf961a189chuck /* post read_request handling */
b980ad7fdc218b4855cde9f75a747527f50c554dwrowe ap_hook_post_read_request(proxy_detect, NULL, NULL, APR_HOOK_FIRST);
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe /* pre config handling */
e8f95a682820a599fe41b22977010636be5c2717jim ap_hook_pre_config(proxy_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
e1d00c81dc34e2c644cc936b9dea75ec9ccfca2adougm /* post config handling */
e1d00c81dc34e2c644cc936b9dea75ec9ccfca2adougm ap_hook_post_config(proxy_post_config, NULL, NULL, APR_HOOK_MIDDLE);
1d2ff7570139286b0f0d16f92187a16ed5932291mturk /* child init handling */
e8f95a682820a599fe41b22977010636be5c2717jim ap_hook_child_init(child_init, aszPred, NULL, APR_HOOK_MIDDLE);
4ab0fd1b54ce76f0fb6812b89b0b4dc7541014d6minfrin /* register optional functions within proxy_util.c */
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe create_proxy_dir_config, /* create per-directory config structure */
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe merge_proxy_dir_config, /* merge per-directory config structures */
b9b3cd7661ec354e0eee71116faa1e4afdf3fcdcmturk create_proxy_config, /* create per-server config structure */
b9b3cd7661ec354e0eee71116faa1e4afdf3fcdcmturk merge_proxy_config, /* merge per-server config structures */
e8f95a682820a599fe41b22977010636be5c2717jimAPR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(proxy, PROXY, int, scheme_handler,
e8f95a682820a599fe41b22977010636be5c2717jimAPR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(proxy, PROXY, int, canon_handler,
d75bc22ab2702fa770f6935f07107efff16a76f0wroweAPR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(proxy, PROXY, int, pre_request, (
d75bc22ab2702fa770f6935f07107efff16a76f0wroweAPR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(proxy, PROXY, int, post_request,
67f62b7a48ff9eb8d9f31898dceaf9f89280a723dougmAPR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(proxy, PROXY, int, fixups,
bda7a7d57377f45932c237d5aba00b189d85c2a9ianhAPR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(proxy, PROXY, int, request_status,