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
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * http://www.apache.org/licenses/LICENSE-2.0
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
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.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#include "mod_proxy.h"
36a72c96fc2dda27eadbae8a108fa428cc1419c1wrowe#include "mod_core.h"
1723d9ccdd3b647f5b7bae44cab9ab3eca7a4874dougm#include "apr_optional.h"
59b96ad34c087942eea06884c97d12c2796a977amturk#include "scoreboard.h"
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe#include "mod_status.h"
4ab0fd1b54ce76f0fb6812b89b0b4dc7541014d6minfrin#include "proxy_util.h"
2555a6b5da21d61804f47084d8fcc98eb4acbc42wrowe
2555a6b5da21d61804f47084d8fcc98eb4acbc42wrowe#if (MODULE_MAGIC_NUMBER_MAJOR > 20020903)
70535d6421eb979ac79d8f49d31cd94d75dd8b2fjorton#include "mod_ssl.h"
2555a6b5da21d61804f47084d8fcc98eb4acbc42wrowe#else
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 *));
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturkAPR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup,
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk (apr_pool_t *, server_rec *,
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk conn_rec *, request_rec *, char *));
2555a6b5da21d61804f47084d8fcc98eb4acbc42wrowe#endif
1723d9ccdd3b647f5b7bae44cab9ab3eca7a4874dougm
e9501b71b8a1e76384cb010b1e41e76a1e47aacctrawick#ifndef MAX
e9501b71b8a1e76384cb010b1e41e76a1e47aacctrawick#define MAX(x,y) ((x) >= (y) ? (x) : (y))
e9501b71b8a1e76384cb010b1e41e76a1e47aacctrawick#endif
6335eb31f0f0ed54628a04ed32946360b8b77684minfrin
c9147f126b25a20d45e5b39ea14efe6191628c41minfrinstatic const char * const proxy_id = "proxy";
c9147f126b25a20d45e5b39ea14efe6191628c41minfrinapr_global_mutex_t *proxy_mutex = NULL;
c9147f126b25a20d45e5b39ea14efe6191628c41minfrin
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/*
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * A Web proxy module. Stages:
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
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
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* -------------------------------------------------------------- */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* Translate the URL into a 'filename' */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowestatic const char *set_worker_param(apr_pool_t *p,
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe proxy_worker *worker,
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe const char *key,
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe const char *val)
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe{
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe int ival;
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem apr_interval_time_t timeout;
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe if (!strcasecmp(key, "loadfactor")) {
9f1a88897168c3f1e5009acb585daf01e38a0299jim /* Normalized load factor. Used with BalancerMamber,
9f1a88897168c3f1e5009acb585daf01e38a0299jim * it is a number between 1 and 100.
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk */
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->lbfactor = atoi(val);
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim if (worker->s->lbfactor < 1 || worker->s->lbfactor > 100)
7af19efc4667363f74d332a8d010b49e88d56fd5trawick return "LoadFactor must be a number between 1..100";
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe }
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe else if (!strcasecmp(key, "retry")) {
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.
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk */
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe ival = atoi(val);
f251b576aa9caeb8876ce9f78fb10bf65eddc97emturk if (ival < 0)
f251b576aa9caeb8876ce9f78fb10bf65eddc97emturk return "Retry must be a positive value";
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->retry = apr_time_from_sec(ival);
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->retry_set = 1;
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe }
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe else if (!strcasecmp(key, "ttl")) {
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk /* Time in seconds that will destroy all the connections
0c888b8088644f3a39dcf1998e0304c289532057jim * that exceed the smax
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk */
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe ival = atoi(val);
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe if (ival < 1)
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe return "TTL must be at least one second";
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->ttl = apr_time_from_sec(ival);
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe }
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe else if (!strcasecmp(key, "min")) {
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk /* Initial number of connections to remote
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk */
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe ival = atoi(val);
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe if (ival < 0)
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe return "Min must be a positive number";
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->min = ival;
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe }
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe else if (!strcasecmp(key, "max")) {
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk /* Maximum number of connections to remote
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk */
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe ival = atoi(val);
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe if (ival < 0)
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe return "Max must be a positive number";
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->hmax = ival;
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe }
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe /* XXX: More inteligent naming needed */
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe else if (!strcasecmp(key, "smax")) {
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk /* Maximum number of connections to remote that
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk * will not be destroyed
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk */
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe ival = atoi(val);
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe if (ival < 0)
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe return "Smax must be a positive number";
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->smax = ival;
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe }
9621e4c4056383e4a2b844b14687bae500b33a82wrowe else if (!strcasecmp(key, "acquire")) {
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.
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk */
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem if (ap_timeout_parameter_parse(val, &timeout, "ms") != APR_SUCCESS)
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem return "Acquire timeout has wrong format";
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem if (timeout < 1000)
61d82a1991928d3fa5ee50dc57f2ae3f4b5c781ajim return "Acquire must be at least one millisecond";
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->acquire = timeout;
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->acquire_set = 1;
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe }
4c67ef499845a08771e81254ce6eb2324a160bc7wrowe else if (!strcasecmp(key, "timeout")) {
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk /* Connection timeout in seconds.
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk * Defaults to server timeout.
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk */
4c67ef499845a08771e81254ce6eb2324a160bc7wrowe ival = atoi(val);
4c67ef499845a08771e81254ce6eb2324a160bc7wrowe if (ival < 1)
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe return "Timeout must be at least one second";
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->timeout = apr_time_from_sec(ival);
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->timeout_set = 1;
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe }
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe else if (!strcasecmp(key, "iobuffersize")) {
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe long s = atol(val);
5eb56df4054a0bca4d740eedd7ef277355a2c0adjim if (s < 512 && s) {
5eb56df4054a0bca4d740eedd7ef277355a2c0adjim return "IOBufferSize must be >= 512 bytes, or 0 for system default.";
5eb56df4054a0bca4d740eedd7ef277355a2c0adjim }
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->io_buffer_size = (s ? s : AP_IOBUFSIZE);
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->io_buffer_size_set = 1;
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe }
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe else if (!strcasecmp(key, "receivebuffersize")) {
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe ival = atoi(val);
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe if (ival < 512 && ival != 0) {
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe return "ReceiveBufferSize must be >= 512 bytes, or 0 for system default.";
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe }
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->recv_buffer_size = ival;
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->recv_buffer_size_set = 1;
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe }
41c38e78e8e5dc73544571cc2b749d40869e84fawrowe else if (!strcasecmp(key, "keepalive")) {
41c38e78e8e5dc73544571cc2b749d40869e84fawrowe if (!strcasecmp(val, "on"))
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->keepalive = 1;
41c38e78e8e5dc73544571cc2b749d40869e84fawrowe else if (!strcasecmp(val, "off"))
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->keepalive = 0;
41c38e78e8e5dc73544571cc2b749d40869e84fawrowe else
41c38e78e8e5dc73544571cc2b749d40869e84fawrowe return "KeepAlive must be On|Off";
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->keepalive_set = 1;
e8f95a682820a599fe41b22977010636be5c2717jim }
b842b65e0618c5535233b197f03dc917d184adb3jim else if (!strcasecmp(key, "disablereuse")) {
b842b65e0618c5535233b197f03dc917d184adb3jim if (!strcasecmp(val, "on"))
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->disablereuse = 1;
b842b65e0618c5535233b197f03dc917d184adb3jim else if (!strcasecmp(val, "off"))
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->disablereuse = 0;
b842b65e0618c5535233b197f03dc917d184adb3jim else
b842b65e0618c5535233b197f03dc917d184adb3jim return "DisableReuse must be On|Off";
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->disablereuse_set = 1;
b842b65e0618c5535233b197f03dc917d184adb3jim }
44b664206cee887b8b69862def5dd1832afc97ddcovener else if (!strcasecmp(key, "enablereuse")) {
44b664206cee887b8b69862def5dd1832afc97ddcovener if (!strcasecmp(val, "on"))
44b664206cee887b8b69862def5dd1832afc97ddcovener worker->s->disablereuse = 0;
44b664206cee887b8b69862def5dd1832afc97ddcovener else if (!strcasecmp(val, "off"))
44b664206cee887b8b69862def5dd1832afc97ddcovener worker->s->disablereuse = 1;
44b664206cee887b8b69862def5dd1832afc97ddcovener else
44b664206cee887b8b69862def5dd1832afc97ddcovener return "EnableReuse must be On|Off";
44b664206cee887b8b69862def5dd1832afc97ddcovener worker->s->disablereuse_set = 1;
44b664206cee887b8b69862def5dd1832afc97ddcovener }
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe else if (!strcasecmp(key, "route")) {
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk /* Worker route.
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk */
3a3a90e05e4cab7e0507557f197c60f4532fe6d5jim if (strlen(val) >= sizeof(worker->s->route))
3a3a90e05e4cab7e0507557f197c60f4532fe6d5jim return apr_psprintf(p, "Route length must be < %d characters",
3a3a90e05e4cab7e0507557f197c60f4532fe6d5jim (int)sizeof(worker->s->route));
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim PROXY_STRNCPY(worker->s->route, val);
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe }
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe else if (!strcasecmp(key, "redirect")) {
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk /* Worker redirection route.
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk */
3a3a90e05e4cab7e0507557f197c60f4532fe6d5jim if (strlen(val) >= sizeof(worker->s->redirect))
3a3a90e05e4cab7e0507557f197c60f4532fe6d5jim return apr_psprintf(p, "Redirect length must be < %d characters",
3a3a90e05e4cab7e0507557f197c60f4532fe6d5jim (int)sizeof(worker->s->redirect));
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim PROXY_STRNCPY(worker->s->redirect, val);
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe }
f73a8fabbdc4ec11c8b475e9f48539de0c4f82ebmturk else if (!strcasecmp(key, "status")) {
f73a8fabbdc4ec11c8b475e9f48539de0c4f82ebmturk const char *v;
f73a8fabbdc4ec11c8b475e9f48539de0c4f82ebmturk int mode = 1;
4e0b7720fce1e872ea6afd2421b8b6addacf9bd0jim apr_status_t rv;
f73a8fabbdc4ec11c8b475e9f48539de0c4f82ebmturk /* Worker status.
f73a8fabbdc4ec11c8b475e9f48539de0c4f82ebmturk */
f73a8fabbdc4ec11c8b475e9f48539de0c4f82ebmturk for (v = val; *v; v++) {
f73a8fabbdc4ec11c8b475e9f48539de0c4f82ebmturk if (*v == '+') {
f73a8fabbdc4ec11c8b475e9f48539de0c4f82ebmturk mode = 1;
e8f95a682820a599fe41b22977010636be5c2717jim v++;
f73a8fabbdc4ec11c8b475e9f48539de0c4f82ebmturk }
f73a8fabbdc4ec11c8b475e9f48539de0c4f82ebmturk else if (*v == '-') {
f73a8fabbdc4ec11c8b475e9f48539de0c4f82ebmturk mode = 0;
e8f95a682820a599fe41b22977010636be5c2717jim v++;
f73a8fabbdc4ec11c8b475e9f48539de0c4f82ebmturk }
e2b702094817c78498e6de567b9548ef794c33d3jim rv = ap_proxy_set_wstatus(*v, mode, worker);
4e0b7720fce1e872ea6afd2421b8b6addacf9bd0jim if (rv != APR_SUCCESS)
7ce17736e4802a923eed275812647a7c3e9ad76ejim return "Unknown status parameter option";
f73a8fabbdc4ec11c8b475e9f48539de0c4f82ebmturk }
e8f95a682820a599fe41b22977010636be5c2717jim }
07ac837c886b356dc96e83cf82fb348eb56406d9jim else if (!strcasecmp(key, "flushpackets")) {
5d392744e2077f71f34ce098ab49d2c0ddcf4ea3jim if (!strcasecmp(val, "on"))
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->flush_packets = flush_on;
5d392744e2077f71f34ce098ab49d2c0ddcf4ea3jim else if (!strcasecmp(val, "off"))
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->flush_packets = flush_off;
5d392744e2077f71f34ce098ab49d2c0ddcf4ea3jim else if (!strcasecmp(val, "auto"))
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->flush_packets = flush_auto;
5d392744e2077f71f34ce098ab49d2c0ddcf4ea3jim else
07ac837c886b356dc96e83cf82fb348eb56406d9jim return "flushpackets must be on|off|auto";
5d392744e2077f71f34ce098ab49d2c0ddcf4ea3jim }
07ac837c886b356dc96e83cf82fb348eb56406d9jim else if (!strcasecmp(key, "flushwait")) {
5d392744e2077f71f34ce098ab49d2c0ddcf4ea3jim ival = atoi(val);
5d392744e2077f71f34ce098ab49d2c0ddcf4ea3jim if (ival > 1000 || ival < 0) {
07ac837c886b356dc96e83cf82fb348eb56406d9jim return "flushwait must be <= 1000, or 0 for system default of 10 millseconds.";
5d392744e2077f71f34ce098ab49d2c0ddcf4ea3jim }
5d392744e2077f71f34ce098ab49d2c0ddcf4ea3jim if (ival == 0)
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->flush_wait = PROXY_FLUSH_WAIT;
5d392744e2077f71f34ce098ab49d2c0ddcf4ea3jim else
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->flush_wait = ival * 1000; /* change to microseconds */
5d392744e2077f71f34ce098ab49d2c0ddcf4ea3jim }
188befd3a49e3a126bd801d7dc5a7f6e63ad4332mturk else if (!strcasecmp(key, "ping")) {
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem /* Ping/Pong timeout in given unit (default is second).
188befd3a49e3a126bd801d7dc5a7f6e63ad4332mturk */
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem if (ap_timeout_parameter_parse(val, &timeout, "s") != APR_SUCCESS)
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem return "Ping/Pong timeout has wrong format";
56c721887b9c93721a7fe3afc45c89a94e3f07c1jim if (timeout < 1000 && timeout >= 0)
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem return "Ping/Pong timeout must be at least one millisecond";
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->ping_timeout = timeout;
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->ping_timeout_set = 1;
188befd3a49e3a126bd801d7dc5a7f6e63ad4332mturk }
f185ce14f5dd540ae54659f764989c017c619485jim else if (!strcasecmp(key, "lbset")) {
f185ce14f5dd540ae54659f764989c017c619485jim ival = atoi(val);
f185ce14f5dd540ae54659f764989c017c619485jim if (ival < 0 || ival > 99)
f185ce14f5dd540ae54659f764989c017c619485jim return "lbset must be between 0 and 99";
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->lbset = ival;
f185ce14f5dd540ae54659f764989c017c619485jim }
f921cd430a2ea23fcaedfdfc7439163f63c8472arpluem else if (!strcasecmp(key, "connectiontimeout")) {
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem /* Request timeout in given unit (default is second).
f921cd430a2ea23fcaedfdfc7439163f63c8472arpluem * Defaults to connection timeout
f921cd430a2ea23fcaedfdfc7439163f63c8472arpluem */
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem if (ap_timeout_parameter_parse(val, &timeout, "s") != APR_SUCCESS)
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem return "Connectiontimeout has wrong format";
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem if (timeout < 1000)
90f18725dbb9bdfba94da22aa60f94dfb759a8ferpluem return "Connectiontimeout must be at least one millisecond.";
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->conn_timeout = timeout;
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim worker->s->conn_timeout_set = 1;
f921cd430a2ea23fcaedfdfc7439163f63c8472arpluem }
bf3f3b52289ee37f40842fc836ff92dd202742afpquerna else if (!strcasecmp(key, "flusher")) {
3a3a90e05e4cab7e0507557f197c60f4532fe6d5jim if (strlen(val) >= sizeof(worker->s->flusher))
3a3a90e05e4cab7e0507557f197c60f4532fe6d5jim apr_psprintf(p, "flusher name length must be < %d characters",
3a3a90e05e4cab7e0507557f197c60f4532fe6d5jim (int)sizeof(worker->s->flusher));
2f1146e06a1bfa371573a3f3fb0379448e18aaedjim PROXY_STRNCPY(worker->s->flusher, val);
bf3f3b52289ee37f40842fc836ff92dd202742afpquerna }
4415d997ac73262e513c0a571bd5be4f609040bawrowe else {
65efbf0826de766a90d745cc44427bfa4e2447b6mturk return "unknown Worker parameter";
4415d997ac73262e513c0a571bd5be4f609040bawrowe }
4415d997ac73262e513c0a571bd5be4f609040bawrowe return NULL;
4415d997ac73262e513c0a571bd5be4f609040bawrowe}
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe
1febae173a82bc2a71c3c0ba4105cf674000791bjimstatic const char *set_balancer_param(proxy_server_conf *conf,
1febae173a82bc2a71c3c0ba4105cf674000791bjim apr_pool_t *p,
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe proxy_balancer *balancer,
4415d997ac73262e513c0a571bd5be4f609040bawrowe const char *key,
4415d997ac73262e513c0a571bd5be4f609040bawrowe const char *val)
4415d997ac73262e513c0a571bd5be4f609040bawrowe{
4415d997ac73262e513c0a571bd5be4f609040bawrowe
4415d997ac73262e513c0a571bd5be4f609040bawrowe int ival;
4415d997ac73262e513c0a571bd5be4f609040bawrowe if (!strcasecmp(key, "stickysession")) {
c3dc78855363fa6e8ecfc2bb8e2927efcd31d31djfclere char *path;
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk /* Balancer sticky session name.
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk * Set to something like JSESSIONID or
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk * PHPSESSIONID, etc..,
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk */
3a3a90e05e4cab7e0507557f197c60f4532fe6d5jim if (strlen(val) >= sizeof(balancer->s->sticky_path))
3a3a90e05e4cab7e0507557f197c60f4532fe6d5jim apr_psprintf(p, "stickysession length must be < %d characters",
3a3a90e05e4cab7e0507557f197c60f4532fe6d5jim (int)sizeof(balancer->s->sticky_path));
cb7cf74a315df272e2ec329ce2ef1d50b82b8384jim PROXY_STRNCPY(balancer->s->sticky_path, val);
cb7cf74a315df272e2ec329ce2ef1d50b82b8384jim PROXY_STRNCPY(balancer->s->sticky, val);
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim
d20993e12a1caa8952c6d964ed0fbb92b7f97d79jim if ((path = strchr((char *)balancer->s->sticky, '|'))) {
c3dc78855363fa6e8ecfc2bb8e2927efcd31d31djfclere *path++ = '\0';
cb7cf74a315df272e2ec329ce2ef1d50b82b8384jim PROXY_STRNCPY(balancer->s->sticky_path, path);
c3dc78855363fa6e8ecfc2bb8e2927efcd31d31djfclere }
4415d997ac73262e513c0a571bd5be4f609040bawrowe }
20eead0b01d51fce0cc17d04b8f98ec38eac68aejim else if (!strcasecmp(key, "stickysessionsep")) {
20eead0b01d51fce0cc17d04b8f98ec38eac68aejim /* separator/delimiter for sessionid and route,
20eead0b01d51fce0cc17d04b8f98ec38eac68aejim * normally '.'
20eead0b01d51fce0cc17d04b8f98ec38eac68aejim */
20eead0b01d51fce0cc17d04b8f98ec38eac68aejim if (strlen(val) != 1) {
20eead0b01d51fce0cc17d04b8f98ec38eac68aejim if (!strcasecmp(val, "off"))
20eead0b01d51fce0cc17d04b8f98ec38eac68aejim balancer->s->sticky_separator = 0;
20eead0b01d51fce0cc17d04b8f98ec38eac68aejim else
20eead0b01d51fce0cc17d04b8f98ec38eac68aejim return "stickysessionsep must be a single character or Off";
20eead0b01d51fce0cc17d04b8f98ec38eac68aejim }
20eead0b01d51fce0cc17d04b8f98ec38eac68aejim else
20eead0b01d51fce0cc17d04b8f98ec38eac68aejim balancer->s->sticky_separator = *val;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza balancer->s->sticky_separator_set = 1;
20eead0b01d51fce0cc17d04b8f98ec38eac68aejim }
4415d997ac73262e513c0a571bd5be4f609040bawrowe else if (!strcasecmp(key, "nofailover")) {
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk /* If set to 'on' the session will break
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk * if the worker is in error state or
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk * disabled.
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk */
4415d997ac73262e513c0a571bd5be4f609040bawrowe if (!strcasecmp(val, "on"))
cb7cf74a315df272e2ec329ce2ef1d50b82b8384jim balancer->s->sticky_force = 1;
4415d997ac73262e513c0a571bd5be4f609040bawrowe else if (!strcasecmp(val, "off"))
cb7cf74a315df272e2ec329ce2ef1d50b82b8384jim balancer->s->sticky_force = 0;
4415d997ac73262e513c0a571bd5be4f609040bawrowe else
4415d997ac73262e513c0a571bd5be4f609040bawrowe return "failover must be On|Off";
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza balancer->s->sticky_force_set = 1;
4415d997ac73262e513c0a571bd5be4f609040bawrowe }
4415d997ac73262e513c0a571bd5be4f609040bawrowe else if (!strcasecmp(key, "timeout")) {
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.
01261c7d9578aadd1891f94c8ee03f32ba51db3dmturk */
4415d997ac73262e513c0a571bd5be4f609040bawrowe ival = atoi(val);
4415d997ac73262e513c0a571bd5be4f609040bawrowe if (ival < 1)
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe return "timeout must be at least one second";
cb7cf74a315df272e2ec329ce2ef1d50b82b8384jim balancer->s->timeout = apr_time_from_sec(ival);
4415d997ac73262e513c0a571bd5be4f609040bawrowe }
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk else if (!strcasecmp(key, "maxattempts")) {
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk /* Maximum number of failover attempts before
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk * giving up.
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk */
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk ival = atoi(val);
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk if (ival < 0)
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk return "maximum number of attempts must be a positive number";
cb7cf74a315df272e2ec329ce2ef1d50b82b8384jim balancer->s->max_attempts = ival;
cb7cf74a315df272e2ec329ce2ef1d50b82b8384jim balancer->s->max_attempts_set = 1;
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk }
9e3209bc06ddf32f23e4b254faa45914bc323cc9jim else if (!strcasecmp(key, "lbmethod")) {
c332befc1519a1016d8de07608f0b859e6fab580jim proxy_balancer_method *provider;
5b439d3976ab9363288cf5132902fad230777523jim if (strlen(val) > (sizeof(balancer->s->lbpname)-1))
5b439d3976ab9363288cf5132902fad230777523jim return "unknown lbmethod";
361051c5d96d51ff2f707777b8f629a56799ef02jorton provider = ap_lookup_provider(PROXY_LBMETHOD, val, "0");
361051c5d96d51ff2f707777b8f629a56799ef02jorton if (provider) {
5b439d3976ab9363288cf5132902fad230777523jim balancer->lbmethod = provider;
e32a2e2ca90ae7e7f1195d1e275f9ad6a581ffc6jim if (PROXY_STRNCPY(balancer->s->lbpname, val) == APR_SUCCESS) {
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza balancer->lbmethod_set = 1;
e32a2e2ca90ae7e7f1195d1e275f9ad6a581ffc6jim return NULL;
e32a2e2ca90ae7e7f1195d1e275f9ad6a581ffc6jim }
e32a2e2ca90ae7e7f1195d1e275f9ad6a581ffc6jim else {
e32a2e2ca90ae7e7f1195d1e275f9ad6a581ffc6jim return "lbmethod name too large";
e32a2e2ca90ae7e7f1195d1e275f9ad6a581ffc6jim }
1febae173a82bc2a71c3c0ba4105cf674000791bjim }
1febae173a82bc2a71c3c0ba4105cf674000791bjim return "unknown lbmethod";
9e3209bc06ddf32f23e4b254faa45914bc323cc9jim }
ff4ec92f5bb8d43b3ba1979ccda94f07961bf323jim else if (!strcasecmp(key, "scolonpathdelim")) {
ff4ec92f5bb8d43b3ba1979ccda94f07961bf323jim /* If set to 'on' then ';' will also be
ff4ec92f5bb8d43b3ba1979ccda94f07961bf323jim * used as a session path separator/delim (ala
ff4ec92f5bb8d43b3ba1979ccda94f07961bf323jim * mod_jk)
ff4ec92f5bb8d43b3ba1979ccda94f07961bf323jim */
ff4ec92f5bb8d43b3ba1979ccda94f07961bf323jim if (!strcasecmp(val, "on"))
cb7cf74a315df272e2ec329ce2ef1d50b82b8384jim balancer->s->scolonsep = 1;
ff4ec92f5bb8d43b3ba1979ccda94f07961bf323jim else if (!strcasecmp(val, "off"))
cb7cf74a315df272e2ec329ce2ef1d50b82b8384jim balancer->s->scolonsep = 0;
ff4ec92f5bb8d43b3ba1979ccda94f07961bf323jim else
ff4ec92f5bb8d43b3ba1979ccda94f07961bf323jim return "scolonpathdelim must be On|Off";
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza balancer->s->scolonsep_set = 1;
ff4ec92f5bb8d43b3ba1979ccda94f07961bf323jim }
b92a868b537899a51efd8c200c396fa51c63839dtrawick else if (!strcasecmp(key, "failonstatus")) {
9f22e9ea026e74271ddced44f6d54fa846ddc9bcwrowe char *val_split;
d46dfdce9351f52a971777948d9b02f8fc668ff8niq char *status;
d46dfdce9351f52a971777948d9b02f8fc668ff8niq char *tok_state;
d46dfdce9351f52a971777948d9b02f8fc668ff8niq
9f22e9ea026e74271ddced44f6d54fa846ddc9bcwrowe val_split = apr_pstrdup(p, val);
9f22e9ea026e74271ddced44f6d54fa846ddc9bcwrowe
d46dfdce9351f52a971777948d9b02f8fc668ff8niq balancer->errstatuses = apr_array_make(p, 1, sizeof(int));
d46dfdce9351f52a971777948d9b02f8fc668ff8niq
9f22e9ea026e74271ddced44f6d54fa846ddc9bcwrowe status = apr_strtok(val_split, ", ", &tok_state);
d46dfdce9351f52a971777948d9b02f8fc668ff8niq while (status != NULL) {
d46dfdce9351f52a971777948d9b02f8fc668ff8niq ival = atoi(status);
d46dfdce9351f52a971777948d9b02f8fc668ff8niq if (ap_is_HTTP_VALID_RESPONSE(ival)) {
3a49a6c98ef80c71830e66e7f8f46083001b494ctrawick *(int *)apr_array_push(balancer->errstatuses) = ival;
d46dfdce9351f52a971777948d9b02f8fc668ff8niq }
d46dfdce9351f52a971777948d9b02f8fc668ff8niq else {
b92a868b537899a51efd8c200c396fa51c63839dtrawick return "failonstatus must be one or more HTTP response codes";
d46dfdce9351f52a971777948d9b02f8fc668ff8niq }
d46dfdce9351f52a971777948d9b02f8fc668ff8niq status = apr_strtok(NULL, ", ", &tok_state);
d46dfdce9351f52a971777948d9b02f8fc668ff8niq }
d46dfdce9351f52a971777948d9b02f8fc668ff8niq
d46dfdce9351f52a971777948d9b02f8fc668ff8niq }
fb5e4869b57545ff534add0a4b0ded84cc68212bdruggeri else if (!strcasecmp(key, "failontimeout")) {
fb5e4869b57545ff534add0a4b0ded84cc68212bdruggeri if (!strcasecmp(val, "on"))
fb5e4869b57545ff534add0a4b0ded84cc68212bdruggeri balancer->failontimeout = 1;
fb5e4869b57545ff534add0a4b0ded84cc68212bdruggeri else if (!strcasecmp(val, "off"))
fb5e4869b57545ff534add0a4b0ded84cc68212bdruggeri balancer->failontimeout = 0;
fb5e4869b57545ff534add0a4b0ded84cc68212bdruggeri else
fb5e4869b57545ff534add0a4b0ded84cc68212bdruggeri return "failontimeout must be On|Off";
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza balancer->failontimeout_set = 1;
fb5e4869b57545ff534add0a4b0ded84cc68212bdruggeri }
a652b68dea502131f70084ead7981d5fc754cd34jim else if (!strcasecmp(key, "nonce")) {
a652b68dea502131f70084ead7981d5fc754cd34jim if (!strcasecmp(val, "None")) {
cb7cf74a315df272e2ec329ce2ef1d50b82b8384jim *balancer->s->nonce = '\0';
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim }
a652b68dea502131f70084ead7981d5fc754cd34jim else {
e32a2e2ca90ae7e7f1195d1e275f9ad6a581ffc6jim if (PROXY_STRNCPY(balancer->s->nonce, val) != APR_SUCCESS) {
a652b68dea502131f70084ead7981d5fc754cd34jim return "Provided nonce is too large";
a652b68dea502131f70084ead7981d5fc754cd34jim }
a652b68dea502131f70084ead7981d5fc754cd34jim }
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza balancer->s->nonce_set = 1;
a652b68dea502131f70084ead7981d5fc754cd34jim }
a652b68dea502131f70084ead7981d5fc754cd34jim else if (!strcasecmp(key, "growth")) {
a652b68dea502131f70084ead7981d5fc754cd34jim ival = atoi(val);
a652b68dea502131f70084ead7981d5fc754cd34jim if (ival < 1 || ival > 100) /* arbitrary limit here */
a652b68dea502131f70084ead7981d5fc754cd34jim return "growth must be between 1 and 100";
a652b68dea502131f70084ead7981d5fc754cd34jim balancer->growth = ival;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza balancer->growth_set = 1;
a652b68dea502131f70084ead7981d5fc754cd34jim }
0361488d59792d052a9f8024c0e5a1ef909252e6rpluem else if (!strcasecmp(key, "forcerecovery")) {
0361488d59792d052a9f8024c0e5a1ef909252e6rpluem if (!strcasecmp(val, "on"))
0361488d59792d052a9f8024c0e5a1ef909252e6rpluem balancer->s->forcerecovery = 1;
0361488d59792d052a9f8024c0e5a1ef909252e6rpluem else if (!strcasecmp(val, "off"))
0361488d59792d052a9f8024c0e5a1ef909252e6rpluem balancer->s->forcerecovery = 0;
0361488d59792d052a9f8024c0e5a1ef909252e6rpluem else
0361488d59792d052a9f8024c0e5a1ef909252e6rpluem return "forcerecovery must be On|Off";
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza balancer->s->forcerecovery_set = 1;
0361488d59792d052a9f8024c0e5a1ef909252e6rpluem }
4415d997ac73262e513c0a571bd5be4f609040bawrowe else {
65efbf0826de766a90d745cc44427bfa4e2447b6mturk return "unknown Balancer parameter";
4415d997ac73262e513c0a571bd5be4f609040bawrowe }
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe return NULL;
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe}
38fd849bd99e2765ee633b6dc576b5f17acdc455wrowe
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic int alias_match(const char *uri, const char *alias_fakename)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *end_fakename = alias_fakename + strlen(alias_fakename);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *aliasp = alias_fakename, *urip = uri;
00211b036b78699ace57a6d800a52e6c2d57652fnd const char *end_uri = uri + strlen(uri);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
00211b036b78699ace57a6d800a52e6c2d57652fnd while (aliasp < end_fakename && urip < end_uri) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (*aliasp == '/') {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* any number of '/' in the alias matches any number in
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard * the supplied URI, but there must be at least one...
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (*urip != '/')
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return 0;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard while (*aliasp == '/')
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard ++aliasp;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard while (*urip == '/')
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard ++urip;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard else {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* Other characters are compared literally */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (*urip++ != *aliasp++)
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return 0;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
00211b036b78699ace57a6d800a52e6c2d57652fnd /* fixup badly encoded stuff (e.g. % as last character) */
00211b036b78699ace57a6d800a52e6c2d57652fnd if (aliasp > end_fakename) {
00211b036b78699ace57a6d800a52e6c2d57652fnd aliasp = end_fakename;
00211b036b78699ace57a6d800a52e6c2d57652fnd }
00211b036b78699ace57a6d800a52e6c2d57652fnd if (urip > end_uri) {
00211b036b78699ace57a6d800a52e6c2d57652fnd urip = end_uri;
00211b036b78699ace57a6d800a52e6c2d57652fnd }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
50b2d068ddf98cf75622a0020cd143d379d1b235jfclere /* We reach the end of the uri before the end of "alias_fakename"
50b2d068ddf98cf75622a0020cd143d379d1b235jfclere * for example uri is "/" and alias_fakename "/examples"
50b2d068ddf98cf75622a0020cd143d379d1b235jfclere */
35630e8756729a29273ef1a5c879b90df3594d66rjung if (urip == end_uri && aliasp != end_fakename) {
50b2d068ddf98cf75622a0020cd143d379d1b235jfclere return 0;
50b2d068ddf98cf75622a0020cd143d379d1b235jfclere }
50b2d068ddf98cf75622a0020cd143d379d1b235jfclere
00211b036b78699ace57a6d800a52e6c2d57652fnd /* Check last alias path component matched all the way */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (aliasp[-1] != '/' && *urip != '\0' && *urip != '/')
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return 0;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
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 */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return urip - uri;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
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 *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * GET http://othervhost/cgi-bin/printenv HTTP/1.0
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
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.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic int proxy_detect(request_rec *r)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding void *sconf = r->server->module_config;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq proxy_server_conf *conf =
a812b025d139f465a31c76fc02ed162ed5271b03nd (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
16d38ac65d7e54cd44eeda7b23f84ee68b35094ewrowe /* Ick... msvc (perhaps others) promotes ternary short results to int */
16d38ac65d7e54cd44eeda7b23f84ee68b35094ewrowe
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (conf->req && r->parsed_uri.scheme) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* but it might be something vhosted */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (!(r->parsed_uri.hostname
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 : ap_default_port(r))))) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard r->proxyreq = PROXYREQ_PROXY;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard r->uri = r->unparsed_uri;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard r->filename = apr_pstrcat(r->pool, "proxy:", r->uri, NULL);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard r->handler = "proxy-server";
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
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->parsed_uri.hostname
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard && r->parsed_uri.port_str) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard r->proxyreq = PROXYREQ_PROXY;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard r->uri = r->unparsed_uri;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard r->filename = apr_pstrcat(r->pool, "proxy:", r->uri, NULL);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard r->handler = "proxy-server";
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return DECLINED;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
e99dfd55d29a7b4209b814efc7270d0b74ccee74niqstatic const char *proxy_interpolate(request_rec *r, const char *str)
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq{
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 */
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq const char *start;
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq const char *end;
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq const char *var;
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq const char *val;
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq const char *firstpart;
188befd3a49e3a126bd801d7dc5a7f6e63ad4332mturk
9df9016759ec9327e256d7fff1af56ddfadb721cniq start = ap_strstr_c(str, "${");
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq if (start == NULL) {
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq return str;
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq }
9df9016759ec9327e256d7fff1af56ddfadb721cniq end = ap_strchr_c(start+2, '}');
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq if (end == NULL) {
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq return str;
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq }
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));
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq val = apr_table_get(r->subprocess_env, var);
13fd8ef492c6bf438c0d29aaf42d5d596405e23cjailletc firstpart = apr_pstrmemdup(r->pool, str, (start-str));
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq if (val == NULL) {
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq return apr_pstrcat(r->pool, firstpart,
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq proxy_interpolate(r, end+1), NULL);
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq }
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq else {
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq return apr_pstrcat(r->pool, firstpart, val,
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq proxy_interpolate(r, end+1), NULL);
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq }
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq}
e99dfd55d29a7b4209b814efc7270d0b74ccee74niqstatic apr_array_header_t *proxy_vars(request_rec *r,
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq apr_array_header_t *hdr)
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq{
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq int i;
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;
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq for (i = 0; i < hdr->nelts; ++i) {
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq struct proxy_alias *newcopy = apr_array_push(ret);
997023faa943892aae20d092044aa983c2936982niq newcopy->fake = (old[i].flags & PROXYPASS_INTERPOLATE)
997023faa943892aae20d092044aa983c2936982niq ? proxy_interpolate(r, old[i].fake) : old[i].fake;
997023faa943892aae20d092044aa983c2936982niq newcopy->real = (old[i].flags & PROXYPASS_INTERPOLATE)
997023faa943892aae20d092044aa983c2936982niq ? proxy_interpolate(r, old[i].real) : old[i].real;
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq }
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq return ret;
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq}
df419be6d7d4b68823efa05722375552af49c2b6minfrin
e8ecc839fc57f2157ff10eba188d7aa3c0244174jimPROXY_DECLARE(int) ap_proxy_trans_match(request_rec *r, struct proxy_alias *ent,
e8ecc839fc57f2157ff10eba188d7aa3c0244174jim proxy_dir_conf *dconf)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
df419be6d7d4b68823efa05722375552af49c2b6minfrin int len;
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq const char *fake;
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq const char *real;
dcda744296f197717c5105fd197e94ceba7880d7jim ap_regmatch_t regm[AP_MAX_REG_MATCH];
28fe44817329b1183f64e878c258962f90423a8dniq ap_regmatch_t reg1[AP_MAX_REG_MATCH];
dcda744296f197717c5105fd197e94ceba7880d7jim char *found = NULL;
28fe44817329b1183f64e878c258962f90423a8dniq int mismatch = 0;
df419be6d7d4b68823efa05722375552af49c2b6minfrin unsigned int nocanon = ent->flags & PROXYPASS_NOCANON;
df419be6d7d4b68823efa05722375552af49c2b6minfrin const char *use_uri = nocanon ? r->unparsed_uri : r->uri;
df419be6d7d4b68823efa05722375552af49c2b6minfrin
e8ecc839fc57f2157ff10eba188d7aa3c0244174jim if (dconf && (dconf->interpolate_env == 1) && (ent->flags & PROXYPASS_INTERPOLATE)) {
df419be6d7d4b68823efa05722375552af49c2b6minfrin fake = proxy_interpolate(r, ent->fake);
df419be6d7d4b68823efa05722375552af49c2b6minfrin real = proxy_interpolate(r, ent->real);
df419be6d7d4b68823efa05722375552af49c2b6minfrin }
df419be6d7d4b68823efa05722375552af49c2b6minfrin else {
df419be6d7d4b68823efa05722375552af49c2b6minfrin fake = ent->fake;
df419be6d7d4b68823efa05722375552af49c2b6minfrin real = ent->real;
df419be6d7d4b68823efa05722375552af49c2b6minfrin }
df419be6d7d4b68823efa05722375552af49c2b6minfrin if (ent->regex) {
df419be6d7d4b68823efa05722375552af49c2b6minfrin if (!ap_regexec(ent->regex, r->uri, AP_MAX_REG_MATCH, regm, 0)) {
df419be6d7d4b68823efa05722375552af49c2b6minfrin if ((real[0] == '!') && (real[1] == '\0')) {
df419be6d7d4b68823efa05722375552af49c2b6minfrin return DECLINED;
df419be6d7d4b68823efa05722375552af49c2b6minfrin }
df419be6d7d4b68823efa05722375552af49c2b6minfrin /* test that we haven't reduced the URI */
df419be6d7d4b68823efa05722375552af49c2b6minfrin if (nocanon && ap_regexec(ent->regex, r->unparsed_uri,
df419be6d7d4b68823efa05722375552af49c2b6minfrin AP_MAX_REG_MATCH, reg1, 0)) {
df419be6d7d4b68823efa05722375552af49c2b6minfrin mismatch = 1;
df419be6d7d4b68823efa05722375552af49c2b6minfrin use_uri = r->uri;
df419be6d7d4b68823efa05722375552af49c2b6minfrin }
df419be6d7d4b68823efa05722375552af49c2b6minfrin found = ap_pregsub(r->pool, real, use_uri, AP_MAX_REG_MATCH,
df419be6d7d4b68823efa05722375552af49c2b6minfrin (use_uri == r->uri) ? regm : reg1);
4c138e467a7d384582aa6f8c9809af589e572feesf if (!found) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01135)
4c138e467a7d384582aa6f8c9809af589e572feesf "Substitution in regular expression failed. "
4c138e467a7d384582aa6f8c9809af589e572feesf "Replacement too long?");
4c138e467a7d384582aa6f8c9809af589e572feesf return HTTP_INTERNAL_SERVER_ERROR;
4c138e467a7d384582aa6f8c9809af589e572feesf }
4c138e467a7d384582aa6f8c9809af589e572feesf
df419be6d7d4b68823efa05722375552af49c2b6minfrin /* Note: The strcmp() below catches cases where there
df419be6d7d4b68823efa05722375552af49c2b6minfrin * was no regex substitution. This is so cases like:
df419be6d7d4b68823efa05722375552af49c2b6minfrin *
df419be6d7d4b68823efa05722375552af49c2b6minfrin * ProxyPassMatch \.gif balancer://foo
df419be6d7d4b68823efa05722375552af49c2b6minfrin *
df419be6d7d4b68823efa05722375552af49c2b6minfrin * will work "as expected". The upshot is that the 2
df419be6d7d4b68823efa05722375552af49c2b6minfrin * directives below act the exact same way (ie: $1 is implied):
df419be6d7d4b68823efa05722375552af49c2b6minfrin *
df419be6d7d4b68823efa05722375552af49c2b6minfrin * ProxyPassMatch ^(/.*\.gif)$ balancer://foo
df419be6d7d4b68823efa05722375552af49c2b6minfrin * ProxyPassMatch ^(/.*\.gif)$ balancer://foo$1
df419be6d7d4b68823efa05722375552af49c2b6minfrin *
df419be6d7d4b68823efa05722375552af49c2b6minfrin * which may be confusing.
df419be6d7d4b68823efa05722375552af49c2b6minfrin */
4c138e467a7d384582aa6f8c9809af589e572feesf if (strcmp(found, real) != 0) {
df419be6d7d4b68823efa05722375552af49c2b6minfrin found = apr_pstrcat(r->pool, "proxy:", found, NULL);
df419be6d7d4b68823efa05722375552af49c2b6minfrin }
df419be6d7d4b68823efa05722375552af49c2b6minfrin else {
df419be6d7d4b68823efa05722375552af49c2b6minfrin found = apr_pstrcat(r->pool, "proxy:", real, use_uri, NULL);
df419be6d7d4b68823efa05722375552af49c2b6minfrin }
df419be6d7d4b68823efa05722375552af49c2b6minfrin }
df419be6d7d4b68823efa05722375552af49c2b6minfrin }
df419be6d7d4b68823efa05722375552af49c2b6minfrin else {
df419be6d7d4b68823efa05722375552af49c2b6minfrin len = alias_match(r->uri, fake);
df419be6d7d4b68823efa05722375552af49c2b6minfrin
df419be6d7d4b68823efa05722375552af49c2b6minfrin if (len != 0) {
df419be6d7d4b68823efa05722375552af49c2b6minfrin if ((real[0] == '!') && (real[1] == '\0')) {
df419be6d7d4b68823efa05722375552af49c2b6minfrin return DECLINED;
df419be6d7d4b68823efa05722375552af49c2b6minfrin }
df419be6d7d4b68823efa05722375552af49c2b6minfrin if (nocanon && len != alias_match(r->unparsed_uri, ent->fake)) {
df419be6d7d4b68823efa05722375552af49c2b6minfrin mismatch = 1;
df419be6d7d4b68823efa05722375552af49c2b6minfrin use_uri = r->uri;
df419be6d7d4b68823efa05722375552af49c2b6minfrin }
df419be6d7d4b68823efa05722375552af49c2b6minfrin found = apr_pstrcat(r->pool, "proxy:", real, use_uri + len, NULL);
df419be6d7d4b68823efa05722375552af49c2b6minfrin }
df419be6d7d4b68823efa05722375552af49c2b6minfrin }
df419be6d7d4b68823efa05722375552af49c2b6minfrin if (mismatch) {
df419be6d7d4b68823efa05722375552af49c2b6minfrin /* We made a reducing transformation, so we can't safely use
df419be6d7d4b68823efa05722375552af49c2b6minfrin * unparsed_uri. Safe fallback is to ignore nocanon.
df419be6d7d4b68823efa05722375552af49c2b6minfrin */
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01136)
df419be6d7d4b68823efa05722375552af49c2b6minfrin "Unescaped URL path matched ProxyPass; ignoring unsafe nocanon");
df419be6d7d4b68823efa05722375552af49c2b6minfrin }
df419be6d7d4b68823efa05722375552af49c2b6minfrin
df419be6d7d4b68823efa05722375552af49c2b6minfrin if (found) {
df419be6d7d4b68823efa05722375552af49c2b6minfrin r->filename = found;
df419be6d7d4b68823efa05722375552af49c2b6minfrin r->handler = "proxy-server";
df419be6d7d4b68823efa05722375552af49c2b6minfrin r->proxyreq = PROXYREQ_REVERSE;
df419be6d7d4b68823efa05722375552af49c2b6minfrin if (nocanon && !mismatch) {
df419be6d7d4b68823efa05722375552af49c2b6minfrin /* mod_proxy_http needs to be told. Different module. */
df419be6d7d4b68823efa05722375552af49c2b6minfrin apr_table_setn(r->notes, "proxy-nocanon", "1");
df419be6d7d4b68823efa05722375552af49c2b6minfrin }
63f0a4cce2c24181e97940eb9d61b75591ee6ed8jim if (ent->flags & PROXYPASS_NOQUERY) {
63f0a4cce2c24181e97940eb9d61b75591ee6ed8jim apr_table_setn(r->notes, "proxy-noquery", "1");
63f0a4cce2c24181e97940eb9d61b75591ee6ed8jim }
df419be6d7d4b68823efa05722375552af49c2b6minfrin return OK;
df419be6d7d4b68823efa05722375552af49c2b6minfrin }
df419be6d7d4b68823efa05722375552af49c2b6minfrin
df419be6d7d4b68823efa05722375552af49c2b6minfrin return DONE;
df419be6d7d4b68823efa05722375552af49c2b6minfrin}
df419be6d7d4b68823efa05722375552af49c2b6minfrin
df419be6d7d4b68823efa05722375552af49c2b6minfrinstatic int proxy_trans(request_rec *r)
df419be6d7d4b68823efa05722375552af49c2b6minfrin{
df419be6d7d4b68823efa05722375552af49c2b6minfrin int i;
df419be6d7d4b68823efa05722375552af49c2b6minfrin struct proxy_alias *ent;
df419be6d7d4b68823efa05722375552af49c2b6minfrin proxy_dir_conf *dconf;
df419be6d7d4b68823efa05722375552af49c2b6minfrin proxy_server_conf *conf;
a812b025d139f465a31c76fc02ed162ed5271b03nd
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (r->proxyreq) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* someone has already set up the proxy, it was possibly ourselves
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard * in proxy_detect
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return OK;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
a812b025d139f465a31c76fc02ed162ed5271b03nd
6be38922add55325d9acadb2406a4072cb8865detrawick if ((r->unparsed_uri[0] == '*' && r->unparsed_uri[1] == '\0')
6be38922add55325d9acadb2406a4072cb8865detrawick || !r->uri || r->uri[0] != '/') {
8ff777ad06909c2e06d7b5ba2142195ddfae22a9jorton return DECLINED;
8ff777ad06909c2e06d7b5ba2142195ddfae22a9jorton }
8ff777ad06909c2e06d7b5ba2142195ddfae22a9jorton
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.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
df419be6d7d4b68823efa05722375552af49c2b6minfrin dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
df419be6d7d4b68823efa05722375552af49c2b6minfrin /* short way - this location is reverse proxied? */
df419be6d7d4b68823efa05722375552af49c2b6minfrin if (dconf->alias) {
e8ecc839fc57f2157ff10eba188d7aa3c0244174jim int rv = ap_proxy_trans_match(r, dconf->alias, dconf);
df419be6d7d4b68823efa05722375552af49c2b6minfrin if (DONE != rv) {
df419be6d7d4b68823efa05722375552af49c2b6minfrin return rv;
28fe44817329b1183f64e878c258962f90423a8dniq }
df419be6d7d4b68823efa05722375552af49c2b6minfrin }
28fe44817329b1183f64e878c258962f90423a8dniq
25524fd4a888fd31598556d9c323de90e431e237jim conf = (proxy_server_conf *) ap_get_module_config(r->server->module_config,
25524fd4a888fd31598556d9c323de90e431e237jim &proxy_module);
df419be6d7d4b68823efa05722375552af49c2b6minfrin
df419be6d7d4b68823efa05722375552af49c2b6minfrin /* long way - walk the list of aliases, find a match */
df419be6d7d4b68823efa05722375552af49c2b6minfrin if (conf->aliases->nelts) {
df419be6d7d4b68823efa05722375552af49c2b6minfrin ent = (struct proxy_alias *) conf->aliases->elts;
df419be6d7d4b68823efa05722375552af49c2b6minfrin for (i = 0; i < conf->aliases->nelts; i++) {
e8ecc839fc57f2157ff10eba188d7aa3c0244174jim int rv = ap_proxy_trans_match(r, &ent[i], dconf);
df419be6d7d4b68823efa05722375552af49c2b6minfrin if (DONE != rv) {
df419be6d7d4b68823efa05722375552af49c2b6minfrin return rv;
28fe44817329b1183f64e878c258962f90423a8dniq }
dcda744296f197717c5105fd197e94ceba7880d7jim }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return DECLINED;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
9b3001f2097437c3c605d29e353fda5131b9952bminfrinstatic int proxy_walk(request_rec *r)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe{
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe proxy_server_conf *sconf = ap_get_module_config(r->server->module_config,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe &proxy_module);
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;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_conf_vector_t *entry_config;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe proxy_dir_conf *entry_proxy;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe int num_sec = sconf->sec_proxy->nelts;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* XXX: shouldn't we use URI here? Canonicalize it first?
e8f95a682820a599fe41b22977010636be5c2717jim * Pass over "proxy:" prefix
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard */
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe const char *proxyname = r->filename + 6;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe int j;
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin apr_pool_t *rxpool = NULL;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
e8f95a682820a599fe41b22977010636be5c2717jim for (j = 0; j < num_sec; ++j)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe {
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin int nmatch = 0;
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin int i;
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin ap_regmatch_t *pmatch = NULL;
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin
f596c8b1c00a251b54cff654fda122cfe815d536covener entry_config = sec_proxy[j];
f596c8b1c00a251b54cff654fda122cfe815d536covener entry_proxy = ap_get_module_config(entry_config, &proxy_module);
f596c8b1c00a251b54cff654fda122cfe815d536covener
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin if (entry_proxy->r) {
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin if (entry_proxy->refs && entry_proxy->refs->nelts) {
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin if (!rxpool) {
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin apr_pool_create(&rxpool, r->pool);
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin }
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin nmatch = entry_proxy->refs->nelts;
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin pmatch = apr_palloc(rxpool, nmatch*sizeof(ap_regmatch_t));
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin }
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin if (ap_regexec(entry_proxy->r, proxyname, nmatch, pmatch, 0)) {
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin continue;
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin }
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin for (i = 0; i < nmatch; i++) {
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin if (pmatch[i].rm_so >= 0 && pmatch[i].rm_eo >= 0 &&
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin ((const char **)entry_proxy->refs->elts)[i]) {
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin apr_table_setn(r->subprocess_env,
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin ((const char **)entry_proxy->refs->elts)[i],
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin apr_pstrndup(r->pool,
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin proxyname + pmatch[i].rm_so,
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin pmatch[i].rm_eo - pmatch[i].rm_so));
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin }
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin }
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin }
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin else if (
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 */
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin entry_proxy->p_is_fnmatch ? apr_fnmatch(entry_proxy->p,
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin proxyname, 0) :
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin strncmp(proxyname, entry_proxy->p,
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin strlen(entry_proxy->p))) {
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe continue;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe per_dir_defaults = ap_merge_per_dir_configs(r->pool, per_dir_defaults,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe entry_config);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe r->per_dir_config = per_dir_defaults;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin if (rxpool) {
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin apr_pool_destroy(rxpool);
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin }
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return OK;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe}
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowestatic int proxy_map_location(request_rec *r)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe{
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe int access_status;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
8632261c895a84c88ae6ade6ea4c62b27bd22b3ebrianp if (!r->proxyreq || !r->filename || strncmp(r->filename, "proxy:", 6) != 0)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return DECLINED;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
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.
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe */
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if ((access_status = proxy_walk(r))) {
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_die(access_status, r);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return access_status;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return OK;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe}
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* -------------------------------------------------------------- */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* Fixup the filename */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/*
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * Canonicalise the URL
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic int proxy_fixup(request_rec *r)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding char *url, *p;
68ce856106f153813339db8670f6cd0ab8dea484minfrin int access_status;
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq proxy_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq &proxy_module);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
45dac0729754e413ff7c673481b219e9ab1a11f1bnicholes if (!r->proxyreq || !r->filename || strncmp(r->filename, "proxy:", 6) != 0)
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return DECLINED;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe /* XXX: Shouldn't we try this before we run the proxy_walk? */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding url = &r->filename[6];
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
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 */
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->raliases = proxy_vars(r, dconf->raliases);
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq rconf->cookie_paths = proxy_vars(r, dconf->cookie_paths);
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq rconf->cookie_domains = proxy_vars(r, dconf->cookie_domains);
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq }
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq
68ce856106f153813339db8670f6cd0ab8dea484minfrin /* canonicalise each specific scheme */
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin if ((access_status = proxy_run_canon_handler(r, url))) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return access_status;
68ce856106f153813339db8670f6cd0ab8dea484minfrin }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding p = strchr(url, ':');
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (p == NULL || p == url)
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return HTTP_BAD_REQUEST;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
65efbf0826de766a90d745cc44427bfa4e2447b6mturk return OK; /* otherwise; we've done the best we can */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
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{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding char *nuri;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *ref;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* We only want to worry about GETs */
d7387fcd4969206172e3a2a8bbcd25a3d7011ac5rbb if (!r->proxyreq || r->method_number != M_GET || !r->parsed_uri.hostname)
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return DECLINED;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
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)
65efbf0826de766a90d745cc44427bfa4e2447b6mturk return DECLINED; /* host name has a dot already */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm ref = apr_table_get(r->headers_in, "Referer");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
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,
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard domain, NULL);
b999f6ba2a266bf9a92687f31bb7e76021ac5891ianh nuri = apr_uri_unparse(r->pool,
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard &r->parsed_uri,
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard APR_URI_UNP_REVEALPASSWORD);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
e2de0e939faab767454a164c7d2e8ea710fd1a26sf apr_table_setn(r->headers_out, "Location", nuri);
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01138)
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard "Domain missing: %s sent to %s%s%s", r->uri,
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard apr_uri_unparse(r->pool, &r->parsed_uri,
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard APR_URI_UNP_OMITUSERINFO),
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard ref ? " from " : "", ref ? ref : "");
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return HTTP_MOVED_PERMANENTLY;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* -------------------------------------------------------------- */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* Invoke handler */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic int proxy_handler(request_rec *r)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
a8523e2451f03f4a30030b7bda643a23a75d91demturk char *uri, *scheme, *p;
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb const char *p2;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding void *sconf = r->server->module_config;
5babe00918c88eda487771fa6d6d4a1a19c0ced0chuck proxy_server_conf *conf = (proxy_server_conf *)
5babe00918c88eda487771fa6d6d4a1a19c0ced0chuck ap_get_module_config(sconf, &proxy_module);
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm apr_array_header_t *proxies = conf->proxies;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding struct proxy_remote *ents = (struct proxy_remote *) proxies->elts;
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin int i, rc, access_status;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding int direct_connect = 0;
35c9e4d2c0a6465746a98958ef756114834461e6minfrin const char *str;
4860eae0821bbdf3e0da78be7b4057ebed5d86e4minfrin apr_int64_t maxfwd;
5a5a6c22260854843c973e2ea9a14bec64362ab5wrowe proxy_balancer *balancer = NULL;
d75bc22ab2702fa770f6935f07107efff16a76f0wrowe proxy_worker *worker = NULL;
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk int attempts = 0, max_attempts = 0;
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk struct dirconn_entry *list = (struct dirconn_entry *)conf->dirconn->elts;
0823a3f8e3ca10d08d036739d1c0c67aaf31255drpluem int saved_status;
11c3b5180e1de6776035320b012a28bb146e7b46chuck
35c9e4d2c0a6465746a98958ef756114834461e6minfrin /* is this for us? */
3f4de7a5b5425a595380c867e08ac8bc8f97cec3jim if (!r->filename) {
3f4de7a5b5425a595380c867e08ac8bc8f97cec3jim return DECLINED;
3f4de7a5b5425a595380c867e08ac8bc8f97cec3jim }
3f4de7a5b5425a595380c867e08ac8bc8f97cec3jim
3f4de7a5b5425a595380c867e08ac8bc8f97cec3jim if (!r->proxyreq) {
3f4de7a5b5425a595380c867e08ac8bc8f97cec3jim /* We may have forced the proxy handler via config or .htaccess */
3f4de7a5b5425a595380c867e08ac8bc8f97cec3jim if (r->handler &&
3f4de7a5b5425a595380c867e08ac8bc8f97cec3jim strncmp(r->handler, "proxy:", 6) == 0 &&
3f4de7a5b5425a595380c867e08ac8bc8f97cec3jim strncmp(r->filename, "proxy:", 6) != 0) {
3f4de7a5b5425a595380c867e08ac8bc8f97cec3jim r->proxyreq = PROXYREQ_REVERSE;
3f4de7a5b5425a595380c867e08ac8bc8f97cec3jim r->filename = apr_pstrcat(r->pool, r->handler, r->filename, NULL);
3f4de7a5b5425a595380c867e08ac8bc8f97cec3jim }
3f4de7a5b5425a595380c867e08ac8bc8f97cec3jim else {
3f4de7a5b5425a595380c867e08ac8bc8f97cec3jim return DECLINED;
3f4de7a5b5425a595380c867e08ac8bc8f97cec3jim }
3f4de7a5b5425a595380c867e08ac8bc8f97cec3jim } else if (strncmp(r->filename, "proxy:", 6) != 0) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return DECLINED;
3f4de7a5b5425a595380c867e08ac8bc8f97cec3jim }
11c3b5180e1de6776035320b012a28bb146e7b46chuck
35c9e4d2c0a6465746a98958ef756114834461e6minfrin /* handle max-forwards / OPTIONS / TRACE */
35c9e4d2c0a6465746a98958ef756114834461e6minfrin if ((str = apr_table_get(r->headers_in, "Max-Forwards"))) {
4860eae0821bbdf3e0da78be7b4057ebed5d86e4minfrin char *end;
4860eae0821bbdf3e0da78be7b4057ebed5d86e4minfrin maxfwd = apr_strtoi64(str, &end, 10);
4860eae0821bbdf3e0da78be7b4057ebed5d86e4minfrin if (maxfwd < 0 || maxfwd == APR_INT64_MAX || *end) {
4860eae0821bbdf3e0da78be7b4057ebed5d86e4minfrin return ap_proxyerror(r, HTTP_BAD_REQUEST,
4860eae0821bbdf3e0da78be7b4057ebed5d86e4minfrin apr_psprintf(r->pool,
4860eae0821bbdf3e0da78be7b4057ebed5d86e4minfrin "Max-Forwards value '%s' could not be parsed", str));
4860eae0821bbdf3e0da78be7b4057ebed5d86e4minfrin }
4860eae0821bbdf3e0da78be7b4057ebed5d86e4minfrin else if (maxfwd == 0) {
e2b2e15108eb7cb566b1d70ce4e479276d951de5minfrin switch (r->method_number) {
e2b2e15108eb7cb566b1d70ce4e479276d951de5minfrin case M_TRACE: {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard int access_status;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard r->proxyreq = PROXYREQ_NONE;
7a1dee936d2bd3e4e70dd8a6e0090f8582ee2a8bylavic access_status = ap_send_http_trace(r);
7a1dee936d2bd3e4e70dd8a6e0090f8582ee2a8bylavic ap_die(access_status, r);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return OK;
e2b2e15108eb7cb566b1d70ce4e479276d951de5minfrin }
e2b2e15108eb7cb566b1d70ce4e479276d951de5minfrin case M_OPTIONS: {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard int access_status;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard r->proxyreq = PROXYREQ_NONE;
7a1dee936d2bd3e4e70dd8a6e0090f8582ee2a8bylavic access_status = ap_send_http_options(r);
7a1dee936d2bd3e4e70dd8a6e0090f8582ee2a8bylavic ap_die(access_status, r);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return OK;
e2b2e15108eb7cb566b1d70ce4e479276d951de5minfrin }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard default: {
4860eae0821bbdf3e0da78be7b4057ebed5d86e4minfrin return ap_proxyerror(r, HTTP_BAD_REQUEST,
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard "Max-Forwards has reached zero - proxy loop?");
e2b2e15108eb7cb566b1d70ce4e479276d951de5minfrin }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard maxfwd = (maxfwd > 0) ? maxfwd - 1 : 0;
35c9e4d2c0a6465746a98958ef756114834461e6minfrin }
35c9e4d2c0a6465746a98958ef756114834461e6minfrin else {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard /* set configured max-forwards */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard maxfwd = conf->maxfwd;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
3d81c6f18deabacd15101eda69f7d16bf466d22dniq if (maxfwd >= 0) {
04d6458a2cd3b44376f00a56804bb6bf6bc46865sf apr_table_setn(r->headers_in, "Max-Forwards",
fc3150b2b0146214a5005f730efef09448dd043csf apr_psprintf(r->pool, "%" APR_INT64_T_FMT, maxfwd));
3d81c6f18deabacd15101eda69f7d16bf466d22dniq }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe if (r->method_number == M_TRACE) {
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe core_server_config *coreconf = (core_server_config *)
7184de27ec1d62a83c41cdeac0953ca9fd661e8csf ap_get_core_module_config(sconf);
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe
e8f95a682820a599fe41b22977010636be5c2717jim if (coreconf->trace_enable == AP_TRACE_DISABLE)
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe {
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 */
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe apr_table_setn(r->notes, "error-notes",
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe "TRACE forbidden by server configuration");
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe apr_table_setn(r->notes, "verbose-error-to", "*");
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01139)
994ced9dca1b824d03a44187f09d264215cd490csf "TRACE forbidden by server configuration");
b5983a3623a081981a69c201fb66f765586aaa9eniq return HTTP_METHOD_NOT_ALLOWED;
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe }
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe
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 */
e8f95a682820a599fe41b22977010636be5c2717jim if (coreconf->trace_enable != AP_TRACE_EXTENDED
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe && (r->read_length || r->read_chunked || r->remaining))
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe {
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 */
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe apr_table_setn(r->notes, "error-notes",
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe "TRACE with request body is not allowed");
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe apr_table_setn(r->notes, "verbose-error-to", "*");
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01140)
994ced9dca1b824d03a44187f09d264215cd490csf "TRACE with request body is not allowed");
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe return HTTP_REQUEST_ENTITY_TOO_LARGE;
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe }
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe }
d1b3d9a6f29078146ee970791123a8720bf38c39wrowe
a8523e2451f03f4a30030b7bda643a23a75d91demturk uri = r->filename + 6;
a8523e2451f03f4a30030b7bda643a23a75d91demturk p = strchr(uri, ':');
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk if (p == NULL) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01141)
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk "proxy_handler no URL in %s", r->filename);
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk return HTTP_BAD_REQUEST;
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk /* If the host doesn't have a domain name, add one and redirect. */
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk if (conf->domain != NULL) {
a8523e2451f03f4a30030b7bda643a23a75d91demturk rc = proxy_needsdomain(r, uri, conf->domain);
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk if (ap_is_HTTP_REDIRECT(rc))
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk return HTTP_MOVED_PERMANENTLY;
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk }
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk
13fd8ef492c6bf438c0d29aaf42d5d596405e23cjailletc scheme = apr_pstrmemdup(r->pool, uri, p - uri);
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; i++) {
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk direct_connect = list[i].matcher(&list[i], r);
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#if DEBUGGING
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk (direct_connect) ? "NoProxy for %s" : "UseProxy for %s",
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk r->uri);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk
e2458a81ee951feeff648c2ca5cad2c5a744d8e5mturk do {
a8523e2451f03f4a30030b7bda643a23a75d91demturk char *url = uri;
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk /* Try to obtain the most suitable worker */
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk access_status = ap_proxy_pre_request(&worker, &balancer, r, conf, &url);
8cdc2e8b6f46a3f239a70184e9f785fc25463487rpluem if (access_status != OK) {
8cdc2e8b6f46a3f239a70184e9f785fc25463487rpluem /*
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 */
8cdc2e8b6f46a3f239a70184e9f785fc25463487rpluem if (access_status != HTTP_SERVICE_UNAVAILABLE)
8cdc2e8b6f46a3f239a70184e9f785fc25463487rpluem return access_status;
8cdc2e8b6f46a3f239a70184e9f785fc25463487rpluem /*
8cdc2e8b6f46a3f239a70184e9f785fc25463487rpluem * Ensure that balancer is NULL if worker is NULL to prevent
8cdc2e8b6f46a3f239a70184e9f785fc25463487rpluem * potential problems in the post_request hook.
8cdc2e8b6f46a3f239a70184e9f785fc25463487rpluem */
8cdc2e8b6f46a3f239a70184e9f785fc25463487rpluem if (!worker)
8cdc2e8b6f46a3f239a70184e9f785fc25463487rpluem balancer = NULL;
8cdc2e8b6f46a3f239a70184e9f785fc25463487rpluem goto cleanup;
8cdc2e8b6f46a3f239a70184e9f785fc25463487rpluem }
6a4043fd04bbd44ca0d084c096318df035abc46djfclere
6a4043fd04bbd44ca0d084c096318df035abc46djfclere /* Initialise worker if needed, note the shared area must be initialized by the balancer logic */
6a4043fd04bbd44ca0d084c096318df035abc46djfclere if (balancer) {
14c8c18e6caab1bdeb0f26b2b031e000fef58ef9jim ap_proxy_initialize_worker(worker, r->server, conf->pool);
6a4043fd04bbd44ca0d084c096318df035abc46djfclere }
6a4043fd04bbd44ca0d084c096318df035abc46djfclere
cb7cf74a315df272e2ec329ce2ef1d50b82b8384jim if (balancer && balancer->s->max_attempts_set && !max_attempts)
cb7cf74a315df272e2ec329ce2ef1d50b82b8384jim max_attempts = balancer->s->max_attempts;
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk /* firstly, try a proxy, unless a NoProxy directive is active */
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk if (!direct_connect) {
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk for (i = 0; i < proxies->nelts; i++) {
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk p2 = ap_strchr_c(ents[i].scheme, ':'); /* is it a partial URL? */
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk if (strcmp(ents[i].scheme, "*") == 0 ||
b1306729566b49fb30aed5c46adaf07a637115afjerenkrantz (ents[i].use_regex &&
b1306729566b49fb30aed5c46adaf07a637115afjerenkrantz ap_regexec(ents[i].regexp, url, 0, NULL, 0) == 0) ||
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk (p2 == NULL && strcasecmp(scheme, ents[i].scheme) == 0) ||
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk (p2 != NULL &&
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk strncasecmp(url, ents[i].scheme,
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk strlen(ents[i].scheme)) == 0)) {
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk /* handle the scheme */
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01142)
994ced9dca1b824d03a44187f09d264215cd490csf "Trying to run scheme_handler against proxy");
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk access_status = proxy_run_scheme_handler(r, worker,
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk conf, url,
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk ents[i].hostname,
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk ents[i].port);
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem /* Did the scheme handler process the request? */
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem if (access_status != DECLINED) {
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem const char *cl_a;
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem char *end;
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem apr_off_t cl;
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem /*
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem * An fatal error or success, so no point in
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem * retrying with a direct connection.
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem */
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem if (access_status != HTTP_BAD_GATEWAY) {
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem goto cleanup;
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem }
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem cl_a = apr_table_get(r->headers_in, "Content-Length");
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem if (cl_a) {
a41735e84d5aa22d04556c481929addf28c8f052sf apr_strtoff(&cl, cl_a, &end, 10);
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem /*
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 */
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem if (cl > 0) {
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem goto cleanup;
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem }
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem }
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem /*
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 */
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem if (apr_table_get(r->headers_in, "Transfer-Encoding")) {
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem goto cleanup;
5fbd1e97905738791e7359ccbc9b02e913948d2erpluem }
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin
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 */
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk /* handle the scheme */
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01143)
ea8e3350cface61eda0d549bfba28755e09fc322jim "Running scheme %s handler (attempt %d)",
ea8e3350cface61eda0d549bfba28755e09fc322jim scheme, attempts);
a42b70fa75429d73ef00d6ae212676f8a652f51cpquerna AP_PROXY_RUN(r, worker, conf, url, attempts);
a8523e2451f03f4a30030b7bda643a23a75d91demturk access_status = proxy_run_scheme_handler(r, worker, conf,
a8523e2451f03f4a30030b7bda643a23a75d91demturk url, NULL, 0);
a8523e2451f03f4a30030b7bda643a23a75d91demturk if (access_status == OK)
a8523e2451f03f4a30030b7bda643a23a75d91demturk break;
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
a8523e2451f03f4a30030b7bda643a23a75d91demturk */
caad2986f81ab263f7af41467dd622dc9add17f3ylavic if (balancer
caad2986f81ab263f7af41467dd622dc9add17f3ylavic && !(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)) {
a8523e2451f03f4a30030b7bda643a23a75d91demturk worker->s->status |= PROXY_WORKER_IN_ERROR;
12d1342bd29aa7b15080f28cd8ed65d33ce00328rpluem worker->s->error_time = apr_time_now();
12d1342bd29aa7b15080f28cd8ed65d33ce00328rpluem }
00b70ae978854b5eb51722cbeda99c9067b5faf2mturk break;
a8523e2451f03f4a30030b7bda643a23a75d91demturk }
a8523e2451f03f4a30030b7bda643a23a75d91demturk else if (access_status == HTTP_SERVICE_UNAVAILABLE) {
a8523e2451f03f4a30030b7bda643a23a75d91demturk /* Recoverable server error.
e8f95a682820a599fe41b22977010636be5c2717jim * We can failover to another worker
a8523e2451f03f4a30030b7bda643a23a75d91demturk * Mark the worker as unusable if member of load balancer
a8523e2451f03f4a30030b7bda643a23a75d91demturk */
caad2986f81ab263f7af41467dd622dc9add17f3ylavic if (balancer
caad2986f81ab263f7af41467dd622dc9add17f3ylavic && !(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)) {
a8523e2451f03f4a30030b7bda643a23a75d91demturk worker->s->status |= PROXY_WORKER_IN_ERROR;
12d1342bd29aa7b15080f28cd8ed65d33ce00328rpluem worker->s->error_time = apr_time_now();
a8523e2451f03f4a30030b7bda643a23a75d91demturk }
a8523e2451f03f4a30030b7bda643a23a75d91demturk }
a8523e2451f03f4a30030b7bda643a23a75d91demturk else {
a8523e2451f03f4a30030b7bda643a23a75d91demturk /* Unrecoverable error.
a8523e2451f03f4a30030b7bda643a23a75d91demturk * Return the origin status code to the client.
a8523e2451f03f4a30030b7bda643a23a75d91demturk */
a8523e2451f03f4a30030b7bda643a23a75d91demturk break;
a8523e2451f03f4a30030b7bda643a23a75d91demturk }
a8523e2451f03f4a30030b7bda643a23a75d91demturk /* Try again if the worker is unusable and the service is
a8523e2451f03f4a30030b7bda643a23a75d91demturk * unavailable.
a8523e2451f03f4a30030b7bda643a23a75d91demturk */
e8f95a682820a599fe41b22977010636be5c2717jim } while (!PROXY_WORKER_IS_USABLE(worker) &&
67d13599fd4a5f73a2d3fc2b566a9aad60b1c892mturk max_attempts > attempts++);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin if (DECLINED == access_status) {
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 "
994ced9dca1b824d03a44187f09d264215cd490csf "using LoadModule.", r->uri);
0280926d9c3e5deb48961117a60a817d6905dd3dniq access_status = HTTP_INTERNAL_SERVER_ERROR;
c1c0628ca9788908a5fc7502d04a89c348b75ee6wrowe goto cleanup;
9865751743e928ea0a9ad83faa04a738001932deminfrin }
c1c0628ca9788908a5fc7502d04a89c348b75ee6wrowecleanup:
0823a3f8e3ca10d08d036739d1c0c67aaf31255drpluem /*
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 */
0823a3f8e3ca10d08d036739d1c0c67aaf31255drpluem saved_status = r->status;
0823a3f8e3ca10d08d036739d1c0c67aaf31255drpluem r->status = access_status;
d9efe39afed3db4bbdc32e40ddb67075c56e689djim ap_proxy_post_request(worker, balancer, r, conf);
0823a3f8e3ca10d08d036739d1c0c67aaf31255drpluem /*
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.
0823a3f8e3ca10d08d036739d1c0c67aaf31255drpluem */
0823a3f8e3ca10d08d036739d1c0c67aaf31255drpluem if (r->status == access_status) {
0823a3f8e3ca10d08d036739d1c0c67aaf31255drpluem r->status = saved_status;
0823a3f8e3ca10d08d036739d1c0c67aaf31255drpluem }
bda7a7d57377f45932c237d5aba00b189d85c2a9ianh
bda7a7d57377f45932c237d5aba00b189d85c2a9ianh proxy_run_request_status(&access_status, r);
a42b70fa75429d73ef00d6ae212676f8a652f51cpquerna AP_PROXY_RUN_FINISHED(r, attempts, access_status);
bda7a7d57377f45932c237d5aba00b189d85c2a9ianh
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin return access_status;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* -------------------------------------------------------------- */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* Setup configurable data */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
11c3b5180e1de6776035320b012a28bb146e7b46chuckstatic void * create_proxy_config(apr_pool_t *p, server_rec *s)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe proxy_server_conf *ps = apr_pcalloc(p, sizeof(proxy_server_conf));
9b4c60b689b8a3f2d48d19c55d857b276d405f85wrowe
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));
609ecc54ccbd06a9286e1aaf891f80f62450b1aamturk ps->forward = NULL;
a865e849a3b00dc8524ecdda09a1699452876219mturk ps->reverse = NULL;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ps->domain = NULL;
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->viaopt_set = 0; /* 0 means default */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ps->req = 0;
7ce40500bfead8781bab964eb6e01944acbf3915jim ps->max_balancers = 0;
57db302f0875a6c93a79333b8941cea4c1827272jim ps->bal_persist = 0;
64e4059542fdf5ae9096d5485d3405b3bc98a82ejim ps->inherit = 1;
f4c820be3237778985b10dabd420c6301f65ee04rjung ps->inherit_set = 0;
8ad2333769563eadfe4944407c32666160b641a0jim ps->ppinherit = 1;
8ad2333769563eadfe4944407c32666160b641a0jim ps->ppinherit_set = 0;
7ce40500bfead8781bab964eb6e01944acbf3915jim ps->bgrowth = 5;
7ce40500bfead8781bab964eb6e01944acbf3915jim ps->bgrowth_set = 0;
af952917c05e56874069e1e5f64e6473bb478b68minfrin ps->req_set = 0;
af952917c05e56874069e1e5f64e6473bb478b68minfrin ps->recv_buffer_size = 0; /* this default was left unset for some reason */
af952917c05e56874069e1e5f64e6473bb478b68minfrin ps->recv_buffer_size_set = 0;
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin ps->io_buffer_size = AP_IOBUFSIZE;
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin ps->io_buffer_size_set = 0;
35c9e4d2c0a6465746a98958ef756114834461e6minfrin ps->maxfwd = DEFAULT_MAX_FORWARDS;
35c9e4d2c0a6465746a98958ef756114834461e6minfrin ps->maxfwd_set = 0;
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim ps->timeout = 0;
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim ps->timeout_set = 0;
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim ps->badopt = bad_error;
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim ps->badopt_set = 0;
b2b9b7f0644773b50aee41956a841ac884086250niq ps->source_address = NULL;
b2b9b7f0644773b50aee41956a841ac884086250niq ps->source_address_set = 0;
afbccb5d9eef1a37d07bff56872d3da17c41a275jim apr_pool_create_ex(&ps->pool, p, NULL, NULL);
c9147f126b25a20d45e5b39ea14efe6191628c41minfrin
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return ps;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluzastatic apr_array_header_t *merge_balancers(apr_pool_t *p,
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza apr_array_header_t *base,
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza apr_array_header_t *overrides)
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza{
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza proxy_balancer *b1;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza proxy_balancer *b2;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza proxy_balancer tmp;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza int x, y, found;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza apr_array_header_t *tocopy = apr_array_make(p, 1, sizeof(proxy_balancer));
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza
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 */
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b1 = (proxy_balancer *) base->elts;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza for (y = 0; y < base->nelts; y++) {
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2 = (proxy_balancer *) overrides->elts;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza for (x = 0, found = 0; x < overrides->nelts; x++) {
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza if (b1->hash.def == b2->hash.def && b1->hash.fnv == b2->hash.fnv) {
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza tmp = *b2;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza *b2 = *b1;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2->s = tmp.s;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza
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 if (*b2->s->sticky == 0 && *b1->s->sticky) {
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza PROXY_STRNCPY(b2->s->sticky_path, b1->s->sticky_path);
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza PROXY_STRNCPY(b2->s->sticky, b1->s->sticky);
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza }
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza if (!b2->s->sticky_separator_set
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza && b1->s->sticky_separator_set) {
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2->s->sticky_separator_set = b1->s->sticky_separator_set;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2->s->sticky_separator = b1->s->sticky_separator;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza }
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza if (!b2->s->timeout && b1->s->timeout) {
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2->s->timeout = b1->s->timeout;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza }
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza if (!b2->s->max_attempts_set && b1->s->max_attempts_set) {
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2->s->max_attempts_set = b1->s->max_attempts_set;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2->s->max_attempts = b1->s->max_attempts;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza }
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza if (!b2->s->nonce_set && b1->s->nonce_set) {
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2->s->nonce_set = b1->s->nonce_set;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza PROXY_STRNCPY(b2->s->nonce, b1->s->nonce);
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza }
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza if (!b2->s->sticky_force_set && b1->s->sticky_force_set) {
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2->s->sticky_force_set = b1->s->sticky_force_set;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2->s->sticky_force = b1->s->sticky_force;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza }
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza if (!b2->s->scolonsep_set && b1->s->scolonsep_set) {
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2->s->scolonsep_set = b1->s->scolonsep_set;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2->s->scolonsep = b1->s->scolonsep;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza }
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza if (!b2->s->forcerecovery_set && b1->s->forcerecovery_set) {
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2->s->forcerecovery_set = b1->s->forcerecovery_set;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2->s->forcerecovery = b1->s->forcerecovery;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza }
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza
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. */
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza if (tmp.lbmethod_set) {
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2->lbmethod_set = tmp.lbmethod_set;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2->lbmethod = tmp.lbmethod;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza }
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza if (tmp.growth_set) {
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2->growth_set = tmp.growth_set;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2->growth = tmp.growth;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza }
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza if (tmp.failontimeout_set) {
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2->failontimeout_set = tmp.failontimeout_set;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2->failontimeout = tmp.failontimeout;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza }
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza if (!apr_is_empty_array(tmp.errstatuses)) {
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza apr_array_cat(tmp.errstatuses, b2->errstatuses);
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2->errstatuses = tmp.errstatuses;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza }
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza found = 1;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza break;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza }
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b2++;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza }
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza if (!found) {
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza *(proxy_balancer *)apr_array_push(tocopy) = *b1;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza }
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza b1++;
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza }
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza return apr_array_append(p, tocopy, overrides);
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza}
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza
af952917c05e56874069e1e5f64e6473bb478b68minfrinstatic void * merge_proxy_config(apr_pool_t *p, void *basev, void *overridesv)
af952917c05e56874069e1e5f64e6473bb478b68minfrin{
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;
af952917c05e56874069e1e5f64e6473bb478b68minfrin
f4c820be3237778985b10dabd420c6301f65ee04rjung ps->inherit = (overrides->inherit_set == 0) ? base->inherit : overrides->inherit;
f4c820be3237778985b10dabd420c6301f65ee04rjung ps->inherit_set = overrides->inherit_set || base->inherit_set;
f4c820be3237778985b10dabd420c6301f65ee04rjung
8ad2333769563eadfe4944407c32666160b641a0jim ps->ppinherit = (overrides->ppinherit_set == 0) ? base->ppinherit : overrides->ppinherit;
8ad2333769563eadfe4944407c32666160b641a0jim ps->ppinherit_set = overrides->ppinherit_set || base->ppinherit_set;
8ad2333769563eadfe4944407c32666160b641a0jim
8ad2333769563eadfe4944407c32666160b641a0jim if (ps->ppinherit) {
8ad2333769563eadfe4944407c32666160b641a0jim ps->proxies = apr_array_append(p, base->proxies, overrides->proxies);
8ad2333769563eadfe4944407c32666160b641a0jim }
8ad2333769563eadfe4944407c32666160b641a0jim else {
8ad2333769563eadfe4944407c32666160b641a0jim ps->proxies = overrides->proxies;
8ad2333769563eadfe4944407c32666160b641a0jim }
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);
48b5093323ff20ad74f6fd198e2fa7528d162663jim if (ps->inherit || ps->ppinherit) {
1e9c19df8bde7cbced53210a99eb0216ce79e1fbjim ps->workers = apr_array_append(p, base->workers, overrides->workers);
8b1e99bce759689078370bcfb2d9f98c668baba2jkaluza ps->balancers = merge_balancers(p, base->balancers, overrides->balancers);
1e9c19df8bde7cbced53210a99eb0216ce79e1fbjim }
1e9c19df8bde7cbced53210a99eb0216ce79e1fbjim else {
1e9c19df8bde7cbced53210a99eb0216ce79e1fbjim ps->workers = overrides->workers;
1e9c19df8bde7cbced53210a99eb0216ce79e1fbjim ps->balancers = overrides->balancers;
1e9c19df8bde7cbced53210a99eb0216ce79e1fbjim }
609ecc54ccbd06a9286e1aaf891f80f62450b1aamturk ps->forward = overrides->forward ? overrides->forward : base->forward;
a865e849a3b00dc8524ecdda09a1699452876219mturk ps->reverse = overrides->reverse ? overrides->reverse : base->reverse;
af952917c05e56874069e1e5f64e6473bb478b68minfrin
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;
82b8e88fd2a266002f6504d8fc4313ec7b5630c0niq ps->req_set = overrides->req_set || base->req_set;
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;
c5f0334e27d00897c1842cf05e5b2dbf056a8bcbjim ps->bal_persist = overrides->bal_persist;
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;
afbccb5d9eef1a37d07bff56872d3da17c41a275jim ps->pool = base->pool;
af952917c05e56874069e1e5f64e6473bb478b68minfrin return ps;
af952917c05e56874069e1e5f64e6473bb478b68minfrin}
b2b9b7f0644773b50aee41956a841ac884086250niqstatic const char *set_source_address(cmd_parms *parms, void *dummy,
b2b9b7f0644773b50aee41956a841ac884086250niq const char *arg)
b2b9b7f0644773b50aee41956a841ac884086250niq{
b2b9b7f0644773b50aee41956a841ac884086250niq proxy_server_conf *psf =
b2b9b7f0644773b50aee41956a841ac884086250niq ap_get_module_config(parms->server->module_config, &proxy_module);
b2b9b7f0644773b50aee41956a841ac884086250niq struct apr_sockaddr_t *addr;
b2b9b7f0644773b50aee41956a841ac884086250niq
b2b9b7f0644773b50aee41956a841ac884086250niq if (APR_SUCCESS == apr_sockaddr_info_get(&addr, arg, APR_UNSPEC, 0, 0,
b2b9b7f0644773b50aee41956a841ac884086250niq psf->pool)) {
b2b9b7f0644773b50aee41956a841ac884086250niq psf->source_address = addr;
b2b9b7f0644773b50aee41956a841ac884086250niq psf->source_address_set = 1;
b2b9b7f0644773b50aee41956a841ac884086250niq }
b2b9b7f0644773b50aee41956a841ac884086250niq else {
b2b9b7f0644773b50aee41956a841ac884086250niq return "ProxySourceAddress invalid value";
b2b9b7f0644773b50aee41956a841ac884086250niq }
b2b9b7f0644773b50aee41956a841ac884086250niq
b2b9b7f0644773b50aee41956a841ac884086250niq return NULL;
b2b9b7f0644773b50aee41956a841ac884086250niq}
af952917c05e56874069e1e5f64e6473bb478b68minfrin
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowestatic void *create_proxy_dir_config(apr_pool_t *p, char *dummy)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe{
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe proxy_dir_conf *new =
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe (proxy_dir_conf *) apr_pcalloc(p, sizeof(proxy_dir_conf));
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe /* Filled in by proxysection, when applicable */
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
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));
3709b26f3370ae89c5324a3c03fab56a93b09ecdsf new->preserve_host_set = 0;
3709b26f3370ae89c5324a3c03fab56a93b09ecdsf new->preserve_host = 0;
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq new->interpolate_env = -1; /* unset */
40b22d3b20454959fe51fdc89907908d77701078minfrin new->error_override = 0;
40b22d3b20454959fe51fdc89907908d77701078minfrin new->error_override_set = 0;
93cf7fc650197b941ae31a7c7e51e901b129e954igalic new->add_forwarded_headers = 1;
f86b4df17588d404f3da535a8054f43b0642f92aniq
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return (void *) new;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe}
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowestatic void *merge_proxy_dir_config(apr_pool_t *p, void *basev, void *addv)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe{
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe proxy_dir_conf *new = (proxy_dir_conf *) apr_pcalloc(p, sizeof(proxy_dir_conf));
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe proxy_dir_conf *add = (proxy_dir_conf *) addv;
0b4d5285b176f443fd6c0fb07bef76f6b5eb81c7niq proxy_dir_conf *base = (proxy_dir_conf *) basev;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe new->p = add->p;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe new->p_is_fnmatch = add->p_is_fnmatch;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe new->r = add->r;
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin new->refs = add->refs;
f86b4df17588d404f3da535a8054f43b0642f92aniq
f86b4df17588d404f3da535a8054f43b0642f92aniq /* Put these in the dir config so they work inside <Location> */
0b4d5285b176f443fd6c0fb07bef76f6b5eb81c7niq new->raliases = apr_array_append(p, base->raliases, add->raliases);
f86b4df17588d404f3da535a8054f43b0642f92aniq new->cookie_paths
0b4d5285b176f443fd6c0fb07bef76f6b5eb81c7niq = apr_array_append(p, base->cookie_paths, add->cookie_paths);
f86b4df17588d404f3da535a8054f43b0642f92aniq new->cookie_domains
0b4d5285b176f443fd6c0fb07bef76f6b5eb81c7niq = apr_array_append(p, base->cookie_domains, add->cookie_domains);
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq new->interpolate_env = (add->interpolate_env == -1) ? base->interpolate_env
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq : add->interpolate_env;
3709b26f3370ae89c5324a3c03fab56a93b09ecdsf new->preserve_host = (add->preserve_host_set == 0) ? base->preserve_host
3709b26f3370ae89c5324a3c03fab56a93b09ecdsf : add->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 : add->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;
df419be6d7d4b68823efa05722375552af49c2b6minfrin new->alias_set = add->alias_set || base->alias_set;
93cf7fc650197b941ae31a7c7e51e901b129e954igalic new->add_forwarded_headers = add->add_forwarded_headers;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return new;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe}
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic const char *
9379749d811388a7d0e3410940ddd6743a33d330jim add_proxy(cmd_parms *cmd, void *dummy, const char *f1, const char *r1, int regex)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding server_rec *s = cmd->server;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding proxy_server_conf *conf =
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding struct proxy_remote *new;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding char *p, *q;
3c59b18ce62f97468aaa5951d4e21a5478ef36ecminfrin char *r, *f, *scheme;
ef5650b61a8e35f3cc93ec07e73efc17ea329894jorton ap_regex_t *reg = NULL;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding int port;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb r = apr_pstrdup(cmd->pool, r1);
3c59b18ce62f97468aaa5951d4e21a5478ef36ecminfrin scheme = apr_pstrdup(cmd->pool, r1);
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb f = apr_pstrdup(cmd->pool, f1);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding p = strchr(r, ':');
3c59b18ce62f97468aaa5951d4e21a5478ef36ecminfrin if (p == NULL || p[1] != '/' || p[2] != '/' || p[3] == '\0') {
9379749d811388a7d0e3410940ddd6743a33d330jim if (regex)
9379749d811388a7d0e3410940ddd6743a33d330jim return "ProxyRemoteMatch: Bad syntax for a remote proxy server";
9379749d811388a7d0e3410940ddd6743a33d330jim else
9379749d811388a7d0e3410940ddd6743a33d330jim return "ProxyRemote: Bad syntax for a remote proxy server";
3c59b18ce62f97468aaa5951d4e21a5478ef36ecminfrin }
3c59b18ce62f97468aaa5951d4e21a5478ef36ecminfrin else {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard scheme[p-r] = 0;
3c59b18ce62f97468aaa5951d4e21a5478ef36ecminfrin }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding q = strchr(p + 3, ':');
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (q != NULL) {
9379749d811388a7d0e3410940ddd6743a33d330jim if (sscanf(q + 1, "%u", &port) != 1 || port > 65535) {
9379749d811388a7d0e3410940ddd6743a33d330jim if (regex)
9379749d811388a7d0e3410940ddd6743a33d330jim return "ProxyRemoteMatch: Bad syntax for a remote proxy server (bad port number)";
9379749d811388a7d0e3410940ddd6743a33d330jim else
9379749d811388a7d0e3410940ddd6743a33d330jim return "ProxyRemote: Bad syntax for a remote proxy server (bad port number)";
9379749d811388a7d0e3410940ddd6743a33d330jim }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard *q = '\0';
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding else
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard port = -1;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *p = '\0';
9379749d811388a7d0e3410940ddd6743a33d330jim if (regex) {
ef5650b61a8e35f3cc93ec07e73efc17ea329894jorton reg = ap_pregcomp(cmd->pool, f, AP_REG_EXTENDED);
9379749d811388a7d0e3410940ddd6743a33d330jim if (!reg)
9379749d811388a7d0e3410940ddd6743a33d330jim return "Regular expression for ProxyRemoteMatch could not be compiled.";
9379749d811388a7d0e3410940ddd6743a33d330jim }
9379749d811388a7d0e3410940ddd6743a33d330jim else
9379749d811388a7d0e3410940ddd6743a33d330jim if (strchr(f, ':') == NULL)
65efbf0826de766a90d745cc44427bfa4e2447b6mturk ap_str_tolower(f); /* lowercase scheme */
65efbf0826de766a90d745cc44427bfa4e2447b6mturk ap_str_tolower(p + 3); /* lowercase hostname */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (port == -1) {
24efed0910118b762a4eb84830875d4714b8d315ianh port = apr_uri_port_of_scheme(scheme);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
066877f1a045103acfdd376d48cdd473c33f409bdougm new = apr_array_push(conf->proxies);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding new->scheme = f;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding new->protocol = r;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding new->hostname = p + 3;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding new->port = port;
9379749d811388a7d0e3410940ddd6743a33d330jim new->regexp = reg;
9379749d811388a7d0e3410940ddd6743a33d330jim new->use_regex = regex;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return NULL;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
9379749d811388a7d0e3410940ddd6743a33d330jimstatic const char *
9379749d811388a7d0e3410940ddd6743a33d330jim add_proxy_noregex(cmd_parms *cmd, void *dummy, const char *f1, const char *r1)
9379749d811388a7d0e3410940ddd6743a33d330jim{
9379749d811388a7d0e3410940ddd6743a33d330jim return add_proxy(cmd, dummy, f1, r1, 0);
9379749d811388a7d0e3410940ddd6743a33d330jim}
9379749d811388a7d0e3410940ddd6743a33d330jim
9379749d811388a7d0e3410940ddd6743a33d330jimstatic const char *
9379749d811388a7d0e3410940ddd6743a33d330jim add_proxy_regex(cmd_parms *cmd, void *dummy, const char *f1, const char *r1)
9379749d811388a7d0e3410940ddd6743a33d330jim{
9379749d811388a7d0e3410940ddd6743a33d330jim return add_proxy(cmd, dummy, f1, r1, 1);
9379749d811388a7d0e3410940ddd6743a33d330jim}
9379749d811388a7d0e3410940ddd6743a33d330jim
8ef23ef065afb74b96b94ad7d58212bce634e7cecovenerPROXY_DECLARE(const char *) ap_proxy_de_socketfy(apr_pool_t *p, const char *url)
38161f83959979bc9916ece8ab84410ca72a9230jim{
8ef23ef065afb74b96b94ad7d58212bce634e7cecovener const char *ptr;
38161f83959979bc9916ece8ab84410ca72a9230jim /*
38161f83959979bc9916ece8ab84410ca72a9230jim * We could be passed a URL during the config stage that contains
38161f83959979bc9916ece8ab84410ca72a9230jim * the UDS path... ignore it
38161f83959979bc9916ece8ab84410ca72a9230jim */
38161f83959979bc9916ece8ab84410ca72a9230jim if (!strncasecmp(url, "unix:", 5) &&
8ef23ef065afb74b96b94ad7d58212bce634e7cecovener ((ptr = ap_strchr_c(url, '|')) != NULL)) {
38161f83959979bc9916ece8ab84410ca72a9230jim /* move past the 'unix:...|' UDS path info */
8ef23ef065afb74b96b94ad7d58212bce634e7cecovener const char *ret, *c;
38161f83959979bc9916ece8ab84410ca72a9230jim
38161f83959979bc9916ece8ab84410ca72a9230jim ret = ptr + 1;
38161f83959979bc9916ece8ab84410ca72a9230jim /* special case: "unix:....|scheme:" is OK, expand
38161f83959979bc9916ece8ab84410ca72a9230jim * to "unix:....|scheme://localhost"
38161f83959979bc9916ece8ab84410ca72a9230jim * */
8ef23ef065afb74b96b94ad7d58212bce634e7cecovener c = ap_strchr_c(ret, ':');
38161f83959979bc9916ece8ab84410ca72a9230jim if (c == NULL) {
38161f83959979bc9916ece8ab84410ca72a9230jim return NULL;
38161f83959979bc9916ece8ab84410ca72a9230jim }
38161f83959979bc9916ece8ab84410ca72a9230jim if (c[1] == '\0') {
ea8e3350cface61eda0d549bfba28755e09fc322jim return apr_pstrcat(p, ret, "//localhost", NULL);
ea8e3350cface61eda0d549bfba28755e09fc322jim }
ea8e3350cface61eda0d549bfba28755e09fc322jim else {
ea8e3350cface61eda0d549bfba28755e09fc322jim return ret;
38161f83959979bc9916ece8ab84410ca72a9230jim }
38161f83959979bc9916ece8ab84410ca72a9230jim }
8ef23ef065afb74b96b94ad7d58212bce634e7cecovener return url;
38161f83959979bc9916ece8ab84410ca72a9230jim}
38161f83959979bc9916ece8ab84410ca72a9230jim
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic const char *
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim add_pass(cmd_parms *cmd, void *dummy, const char *arg, int is_regex)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
df419be6d7d4b68823efa05722375552af49c2b6minfrin proxy_dir_conf *dconf = (proxy_dir_conf *)dummy;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding server_rec *s = cmd->server;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding proxy_server_conf *conf =
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding struct proxy_alias *new;
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe char *f = cmd->path;
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe char *r = NULL;
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe char *word;
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe apr_table_t *params = apr_table_make(cmd->pool, 5);
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe const apr_array_header_t *arr;
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe const apr_table_entry_t *elts;
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe int i;
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim int use_regex = is_regex;
28fe44817329b1183f64e878c258962f90423a8dniq unsigned int flags = 0;
b588214d6e6fe09abe709e83e894921fbc7e25c8covener const char *err;
b588214d6e6fe09abe709e83e894921fbc7e25c8covener
b588214d6e6fe09abe709e83e894921fbc7e25c8covener err = ap_check_cmd_context(cmd, NOT_IN_DIRECTORY|NOT_IN_FILES);
14c8c18e6caab1bdeb0f26b2b031e000fef58ef9jim if (err) {
b588214d6e6fe09abe709e83e894921fbc7e25c8covener return err;
b588214d6e6fe09abe709e83e894921fbc7e25c8covener }
e8f95a682820a599fe41b22977010636be5c2717jim
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe while (*arg) {
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe word = ap_getword_conf(cmd->pool, &arg);
dcda744296f197717c5105fd197e94ceba7880d7jim if (!f) {
dcda744296f197717c5105fd197e94ceba7880d7jim if (!strcmp(word, "~")) {
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim if (is_regex) {
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim return "ProxyPassMatch invalid syntax ('~' usage).";
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim }
dcda744296f197717c5105fd197e94ceba7880d7jim use_regex = 1;
dcda744296f197717c5105fd197e94ceba7880d7jim continue;
dcda744296f197717c5105fd197e94ceba7880d7jim }
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe f = word;
dcda744296f197717c5105fd197e94ceba7880d7jim }
28fe44817329b1183f64e878c258962f90423a8dniq else if (!r) {
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe r = word;
28fe44817329b1183f64e878c258962f90423a8dniq }
28fe44817329b1183f64e878c258962f90423a8dniq else if (!strcasecmp(word,"nocanon")) {
28fe44817329b1183f64e878c258962f90423a8dniq flags |= PROXYPASS_NOCANON;
28fe44817329b1183f64e878c258962f90423a8dniq }
997023faa943892aae20d092044aa983c2936982niq else if (!strcasecmp(word,"interpolate")) {
997023faa943892aae20d092044aa983c2936982niq flags |= PROXYPASS_INTERPOLATE;
997023faa943892aae20d092044aa983c2936982niq }
63f0a4cce2c24181e97940eb9d61b75591ee6ed8jim else if (!strcasecmp(word,"noquery")) {
63f0a4cce2c24181e97940eb9d61b75591ee6ed8jim flags |= PROXYPASS_NOQUERY;
63f0a4cce2c24181e97940eb9d61b75591ee6ed8jim }
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe else {
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe char *val = strchr(word, '=');
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe if (!val) {
c7eeb0a294d58c75aee6ed86f73c6e1e8cf600a3rpluem if (cmd->path) {
c7eeb0a294d58c75aee6ed86f73c6e1e8cf600a3rpluem if (*r == '/') {
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim return "ProxyPass|ProxyPassMatch can not have a path when defined in "
c7eeb0a294d58c75aee6ed86f73c6e1e8cf600a3rpluem "a location.";
c7eeb0a294d58c75aee6ed86f73c6e1e8cf600a3rpluem }
c7eeb0a294d58c75aee6ed86f73c6e1e8cf600a3rpluem else {
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim return "Invalid ProxyPass|ProxyPassMatch parameter. Parameter must "
c7eeb0a294d58c75aee6ed86f73c6e1e8cf600a3rpluem "be in the form 'key=value'.";
c7eeb0a294d58c75aee6ed86f73c6e1e8cf600a3rpluem }
c7eeb0a294d58c75aee6ed86f73c6e1e8cf600a3rpluem }
c7eeb0a294d58c75aee6ed86f73c6e1e8cf600a3rpluem else {
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim return "Invalid ProxyPass|ProxyPassMatch parameter. Parameter must be "
c7eeb0a294d58c75aee6ed86f73c6e1e8cf600a3rpluem "in the form 'key=value'.";
c7eeb0a294d58c75aee6ed86f73c6e1e8cf600a3rpluem }
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe }
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe else
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe *val++ = '\0';
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe apr_table_setn(params, word, val);
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe }
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe };
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe
df419be6d7d4b68823efa05722375552af49c2b6minfrin if (r == NULL) {
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim return "ProxyPass|ProxyPassMatch needs a path when not defined in a location";
df419be6d7d4b68823efa05722375552af49c2b6minfrin }
df419be6d7d4b68823efa05722375552af49c2b6minfrin
df419be6d7d4b68823efa05722375552af49c2b6minfrin /* if per directory, save away the single alias */
df419be6d7d4b68823efa05722375552af49c2b6minfrin if (cmd->path) {
df419be6d7d4b68823efa05722375552af49c2b6minfrin dconf->alias = apr_pcalloc(cmd->pool, sizeof(struct proxy_alias));
df419be6d7d4b68823efa05722375552af49c2b6minfrin dconf->alias_set = 1;
df419be6d7d4b68823efa05722375552af49c2b6minfrin new = dconf->alias;
df419be6d7d4b68823efa05722375552af49c2b6minfrin if (apr_fnmatch_test(f)) {
df419be6d7d4b68823efa05722375552af49c2b6minfrin use_regex = 1;
df419be6d7d4b68823efa05722375552af49c2b6minfrin }
df419be6d7d4b68823efa05722375552af49c2b6minfrin }
df419be6d7d4b68823efa05722375552af49c2b6minfrin /* if per server, add to the alias array */
df419be6d7d4b68823efa05722375552af49c2b6minfrin else {
df419be6d7d4b68823efa05722375552af49c2b6minfrin new = apr_array_push(conf->aliases);
df419be6d7d4b68823efa05722375552af49c2b6minfrin }
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe
75b0a6a06ca1f4de80e3dd2a09c9f0c7d0a56089wrowe new->fake = apr_pstrdup(cmd->pool, f);
44b664206cee887b8b69862def5dd1832afc97ddcovener new->real = apr_pstrdup(cmd->pool, ap_proxy_de_socketfy(cmd->pool, r));
28fe44817329b1183f64e878c258962f90423a8dniq new->flags = flags;
dcda744296f197717c5105fd197e94ceba7880d7jim if (use_regex) {
dcda744296f197717c5105fd197e94ceba7880d7jim new->regex = ap_pregcomp(cmd->pool, f, AP_REG_EXTENDED);
dcda744296f197717c5105fd197e94ceba7880d7jim if (new->regex == NULL)
dcda744296f197717c5105fd197e94ceba7880d7jim return "Regular expression could not be compiled.";
dcda744296f197717c5105fd197e94ceba7880d7jim }
dcda744296f197717c5105fd197e94ceba7880d7jim else {
dcda744296f197717c5105fd197e94ceba7880d7jim new->regex = NULL;
dcda744296f197717c5105fd197e94ceba7880d7jim }
dcda744296f197717c5105fd197e94ceba7880d7jim
efddae96ddb58b8604704137a9221d7dc61868b0mturk if (r[0] == '!' && r[1] == '\0')
efddae96ddb58b8604704137a9221d7dc61868b0mturk return NULL;
e8f95a682820a599fe41b22977010636be5c2717jim
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe arr = apr_table_elts(params);
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe elts = (const apr_table_entry_t *)arr->elts;
e99dfd55d29a7b4209b814efc7270d0b74ccee74niq /* Distinguish the balancer from worker */
748859d4eeb90f2a64b8b8318bc45c3a61dcd968jim if (ap_proxy_valid_balancer_name(r, 9)) {
f66d52ac5f701eed7986e23d12960344f8bf6b61jim proxy_balancer *balancer = ap_proxy_get_balancer(cmd->pool, conf, r, 0);
e1f43cac62f6960a6945e1fb6e3288ef7082ac53rpluem char *fake_copy;
e1f43cac62f6960a6945e1fb6e3288ef7082ac53rpluem
e1f43cac62f6960a6945e1fb6e3288ef7082ac53rpluem /*
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 */
e1f43cac62f6960a6945e1fb6e3288ef7082ac53rpluem if (use_regex) {
e1f43cac62f6960a6945e1fb6e3288ef7082ac53rpluem fake_copy = NULL;
e1f43cac62f6960a6945e1fb6e3288ef7082ac53rpluem }
e1f43cac62f6960a6945e1fb6e3288ef7082ac53rpluem else {
e1f43cac62f6960a6945e1fb6e3288ef7082ac53rpluem fake_copy = f;
e1f43cac62f6960a6945e1fb6e3288ef7082ac53rpluem }
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe if (!balancer) {
e1f43cac62f6960a6945e1fb6e3288ef7082ac53rpluem const char *err = ap_proxy_define_balancer(cmd->pool, &balancer, conf, r, fake_copy, 0);
4415d997ac73262e513c0a571bd5be4f609040bawrowe if (err)
de274dca1be855ebb66bb7857951aae26fcb54c7wrowe return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL);
e8f95a682820a599fe41b22977010636be5c2717jim }
eb4a5f5f8aa7d48b2a2f24498e4886fc8ce28f4bjim else {
e1f43cac62f6960a6945e1fb6e3288ef7082ac53rpluem ap_proxy_update_balancer(cmd->pool, balancer, fake_copy);
eb4a5f5f8aa7d48b2a2f24498e4886fc8ce28f4bjim }
4415d997ac73262e513c0a571bd5be4f609040bawrowe for (i = 0; i < arr->nelts; i++) {
1febae173a82bc2a71c3c0ba4105cf674000791bjim const char *err = set_balancer_param(conf, cmd->pool, balancer, elts[i].key,
eee895b02dd7867622afd0a8a94f2efc7de9c618wrowe elts[i].val);
4415d997ac73262e513c0a571bd5be4f609040bawrowe if (err)
de274dca1be855ebb66bb7857951aae26fcb54c7wrowe return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL);
4415d997ac73262e513c0a571bd5be4f609040bawrowe }
f405815d4da148cdd3608dc2f46eed6000161663jim new->balancer = balancer;
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe }
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe else {
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza proxy_worker *worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, new->real);
06cdc8d205f0982074ab9b032d0b6d74c58f54carjung int reuse = 0;
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe if (!worker) {
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza const char *err;
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza if (use_regex) {
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza err = ap_proxy_define_match_worker(cmd->pool, &worker, NULL,
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza conf, r, 0);
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza }
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza else {
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza err = ap_proxy_define_worker(cmd->pool, &worker, NULL,
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza conf, r, 0);
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza }
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe if (err)
de274dca1be855ebb66bb7857951aae26fcb54c7wrowe return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL);
0c4b0ffd3db7ae8e34662826098b5e46dadc1e88jim
06cdc8d205f0982074ab9b032d0b6d74c58f54carjung PROXY_COPY_CONF_PARAMS(worker, conf);
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza }
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 ",
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza "(", worker->s->name, ")", NULL);
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza }
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza else {
06cdc8d205f0982074ab9b032d0b6d74c58f54carjung reuse = 1;
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_INFO, 0, cmd->server, APLOGNO(01145)
9acdc6e89570bd3d79206c6d2ca2b5ccf85b20c7jim "Sharing worker '%s' instead of creating new worker '%s'",
9acdc6e89570bd3d79206c6d2ca2b5ccf85b20c7jim ap_proxy_worker_name(cmd->pool, worker), new->real);
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe }
1dac466bcc84f8ebf410016dcf2a4cd4312e8611wrowe
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe for (i = 0; i < arr->nelts; i++) {
06cdc8d205f0982074ab9b032d0b6d74c58f54carjung if (reuse) {
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 } else {
06cdc8d205f0982074ab9b032d0b6d74c58f54carjung const char *err = set_worker_param(cmd->pool, worker, elts[i].key,
06cdc8d205f0982074ab9b032d0b6d74c58f54carjung elts[i].val);
06cdc8d205f0982074ab9b032d0b6d74c58f54carjung if (err)
06cdc8d205f0982074ab9b032d0b6d74c58f54carjung return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL);
06cdc8d205f0982074ab9b032d0b6d74c58f54carjung }
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe }
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe }
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe return NULL;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jimstatic const char *
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim add_pass_noregex(cmd_parms *cmd, void *dummy, const char *arg)
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim{
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim return add_pass(cmd, dummy, arg, 0);
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim}
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jimstatic const char *
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim add_pass_regex(cmd_parms *cmd, void *dummy, const char *arg)
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim{
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim return add_pass(cmd, dummy, arg, 1);
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim}
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim
d27b1ee5dae8f52cdde42e0ac1939cc2397c1be5jim
997023faa943892aae20d092044aa983c2936982niqstatic const char * add_pass_reverse(cmd_parms *cmd, void *dconf, const char *f,
997023faa943892aae20d092044aa983c2936982niq const char *r, const char *i)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
f86b4df17588d404f3da535a8054f43b0642f92aniq proxy_dir_conf *conf = dconf;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding struct proxy_alias *new;
997023faa943892aae20d092044aa983c2936982niq const char *fake;
997023faa943892aae20d092044aa983c2936982niq const char *real;
997023faa943892aae20d092044aa983c2936982niq const char *interp;
b588214d6e6fe09abe709e83e894921fbc7e25c8covener const char *err;
b588214d6e6fe09abe709e83e894921fbc7e25c8covener
b588214d6e6fe09abe709e83e894921fbc7e25c8covener err = ap_check_cmd_context(cmd, NOT_IN_DIRECTORY|NOT_IN_FILES);
14c8c18e6caab1bdeb0f26b2b031e000fef58ef9jim if (err) {
b588214d6e6fe09abe709e83e894921fbc7e25c8covener return err;
b588214d6e6fe09abe709e83e894921fbc7e25c8covener }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
997023faa943892aae20d092044aa983c2936982niq if (cmd->path == NULL) {
997023faa943892aae20d092044aa983c2936982niq if (r == NULL || !strcasecmp(r, "interpolate")) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return "ProxyPassReverse needs a path when not defined in a location";
997023faa943892aae20d092044aa983c2936982niq }
ea64665b1de60d55641104e018f696c4a310d2f1jim fake = f;
ea64665b1de60d55641104e018f696c4a310d2f1jim real = r;
ea64665b1de60d55641104e018f696c4a310d2f1jim interp = i;
997023faa943892aae20d092044aa983c2936982niq }
997023faa943892aae20d092044aa983c2936982niq else {
997023faa943892aae20d092044aa983c2936982niq if (r && strcasecmp(r, "interpolate")) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return "ProxyPassReverse can not have a path when defined in a location";
997023faa943892aae20d092044aa983c2936982niq }
ea64665b1de60d55641104e018f696c4a310d2f1jim fake = cmd->path;
ea64665b1de60d55641104e018f696c4a310d2f1jim real = f;
997023faa943892aae20d092044aa983c2936982niq interp = r;
529005244758297d4415aa912c67a67f805349bcianh }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard
997023faa943892aae20d092044aa983c2936982niq new = apr_array_push(conf->raliases);
997023faa943892aae20d092044aa983c2936982niq new->fake = fake;
997023faa943892aae20d092044aa983c2936982niq new->real = real;
997023faa943892aae20d092044aa983c2936982niq new->flags = interp ? PROXYPASS_INTERPOLATE : 0;
997023faa943892aae20d092044aa983c2936982niq
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return NULL;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
997023faa943892aae20d092044aa983c2936982niqstatic const char* cookie_path(cmd_parms *cmd, void *dconf, const char *f,
997023faa943892aae20d092044aa983c2936982niq const char *r, const char *interp)
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq{
f86b4df17588d404f3da535a8054f43b0642f92aniq proxy_dir_conf *conf = dconf;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq struct proxy_alias *new;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq
a812b025d139f465a31c76fc02ed162ed5271b03nd new = apr_array_push(conf->cookie_paths);
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq new->fake = f;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq new->real = r;
997023faa943892aae20d092044aa983c2936982niq new->flags = interp ? PROXYPASS_INTERPOLATE : 0;
a812b025d139f465a31c76fc02ed162ed5271b03nd
a812b025d139f465a31c76fc02ed162ed5271b03nd return NULL;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq}
997023faa943892aae20d092044aa983c2936982niqstatic const char* cookie_domain(cmd_parms *cmd, void *dconf, const char *f,
997023faa943892aae20d092044aa983c2936982niq const char *r, const char *interp)
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq{
f86b4df17588d404f3da535a8054f43b0642f92aniq proxy_dir_conf *conf = dconf;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq struct proxy_alias *new;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq
a812b025d139f465a31c76fc02ed162ed5271b03nd new = apr_array_push(conf->cookie_domains);
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq new->fake = f;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq new->real = r;
997023faa943892aae20d092044aa983c2936982niq new->flags = interp ? PROXYPASS_INTERPOLATE : 0;
a812b025d139f465a31c76fc02ed162ed5271b03nd return NULL;
33cb45dc8c5106018b7c2f6ae42478b109423e0eniq}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
11c3b5180e1de6776035320b012a28bb146e7b46chuckstatic const char *
11c3b5180e1de6776035320b012a28bb146e7b46chuck set_proxy_exclude(cmd_parms *parms, void *dummy, const char *arg)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding server_rec *s = parms->server;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding proxy_server_conf *conf =
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_get_module_config(s->module_config, &proxy_module);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding struct noproxy_entry *new;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding struct noproxy_entry *list = (struct noproxy_entry *) conf->noproxies->elts;
a6314dfa8dd8a0d69db16288581e4950a2dd3955minfrin struct apr_sockaddr_t *addr;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding int found = 0;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding int i;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* Don't duplicate entries */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding for (i = 0; i < conf->noproxies->nelts; i++) {
edc346c3223efd41e6a2057c37cea69744b73dccwrowe if (strcasecmp(arg, list[i].name) == 0) { /* ignore case for host names */
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard found = 1;
5e61924579cd46039f24cad3071e22fc9d07bac7jailletc break;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (!found) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard new = apr_array_push(conf->noproxies);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard new->name = arg;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard if (APR_SUCCESS == apr_sockaddr_info_get(&addr, new->name, APR_UNSPEC, 0, 0, parms->pool)) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard new->addr = addr;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard else {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard new->addr = NULL;
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return NULL;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* Similar to set_proxy_exclude(), but defining directly connected hosts,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * which should never be accessed via the configured ProxyRemote servers
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic const char *
11c3b5180e1de6776035320b012a28bb146e7b46chuck set_proxy_dirconn(cmd_parms *parms, void *dummy, const char *arg)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding server_rec *s = parms->server;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding proxy_server_conf *conf =
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_get_module_config(s->module_config, &proxy_module);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding struct dirconn_entry *New;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding struct dirconn_entry *list = (struct dirconn_entry *) conf->dirconn->elts;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding int found = 0;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding int i;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* Don't duplicate entries */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding for (i = 0; i < conf->dirconn->nelts; i++) {
c9606e488d7576c86010e607a7b2d8fd1526930ejailletc if (strcasecmp(arg, list[i].name) == 0) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard found = 1;
5e61924579cd46039f24cad3071e22fc9d07bac7jailletc break;
c9606e488d7576c86010e607a7b2d8fd1526930ejailletc }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (!found) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard New = apr_array_push(conf->dirconn);
11c3b5180e1de6776035320b012a28bb146e7b46chuck New->name = apr_pstrdup(parms->pool, arg);
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard New->hostaddr = NULL;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
2ee708a3c186643c065c486f851e1dd78f0a4adajailletc if (ap_proxy_is_ipaddr(New, parms->pool)) {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#if DEBUGGING
2ee708a3c186643c065c486f851e1dd78f0a4adajailletc ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
2ee708a3c186643c065c486f851e1dd78f0a4adajailletc "Parsed addr %s", inet_ntoa(New->addr));
2ee708a3c186643c065c486f851e1dd78f0a4adajailletc ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
2ee708a3c186643c065c486f851e1dd78f0a4adajailletc "Parsed mask %s", inet_ntoa(New->mask));
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif
2ee708a3c186643c065c486f851e1dd78f0a4adajailletc }
2ee708a3c186643c065c486f851e1dd78f0a4adajailletc else if (ap_proxy_is_domainname(New, parms->pool)) {
2ee708a3c186643c065c486f851e1dd78f0a4adajailletc ap_str_tolower(New->name);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#if DEBUGGING
2ee708a3c186643c065c486f851e1dd78f0a4adajailletc ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
2ee708a3c186643c065c486f851e1dd78f0a4adajailletc "Parsed domain %s", New->name);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard else if (ap_proxy_is_hostname(New, parms->pool)) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard ap_str_tolower(New->name);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#if DEBUGGING
1cde33c7e2019830f8fb3224e01649305583916etrawick ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
407cde44becba3694e7c3d81ac99b5d86f4b03a9rbb "Parsed host %s", New->name);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard else {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard ap_proxy_is_word(New, parms->pool);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#if DEBUGGING
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard fprintf(stderr, "Parsed word %s\n", New->name);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#endif
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return NULL;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic const char *
11c3b5180e1de6776035320b012a28bb146e7b46chuck set_proxy_domain(cmd_parms *parms, void *dummy, const char *arg)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding proxy_server_conf *psf =
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_get_module_config(parms->server->module_config, &proxy_module);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (arg[0] != '.')
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return "ProxyDomain: domain name must start with a dot.";
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding psf->domain = arg;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return NULL;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic const char *
11c3b5180e1de6776035320b012a28bb146e7b46chuck set_proxy_req(cmd_parms *parms, void *dummy, int flag)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding proxy_server_conf *psf =
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_get_module_config(parms->server->module_config, &proxy_module);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding psf->req = flag;
af952917c05e56874069e1e5f64e6473bb478b68minfrin psf->req_set = 1;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return NULL;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
609ecc54ccbd06a9286e1aaf891f80f62450b1aamturk
ff1234e45aca1b8171d711ecb87f58b9d9100a99ianhstatic const char *
40b22d3b20454959fe51fdc89907908d77701078minfrin set_proxy_error_override(cmd_parms *parms, void *dconf, int flag)
ff1234e45aca1b8171d711ecb87f58b9d9100a99ianh{
40b22d3b20454959fe51fdc89907908d77701078minfrin proxy_dir_conf *conf = dconf;
ff1234e45aca1b8171d711ecb87f58b9d9100a99ianh
40b22d3b20454959fe51fdc89907908d77701078minfrin conf->error_override = flag;
40b22d3b20454959fe51fdc89907908d77701078minfrin conf->error_override_set = 1;
ff1234e45aca1b8171d711ecb87f58b9d9100a99ianh return NULL;
ff1234e45aca1b8171d711ecb87f58b9d9100a99ianh}
93cf7fc650197b941ae31a7c7e51e901b129e954igalicstatic const char *
93cf7fc650197b941ae31a7c7e51e901b129e954igalic add_proxy_http_headers(cmd_parms *parms, void *dconf, int flag)
93cf7fc650197b941ae31a7c7e51e901b129e954igalic{
93cf7fc650197b941ae31a7c7e51e901b129e954igalic proxy_dir_conf *conf = dconf;
93cf7fc650197b941ae31a7c7e51e901b129e954igalic conf->add_forwarded_headers = flag;
93cf7fc650197b941ae31a7c7e51e901b129e954igalic return NULL;
93cf7fc650197b941ae31a7c7e51e901b129e954igalic}
fd3fa792f04fc9c4e8f5f83dceb0fc34e71f8570ianhstatic const char *
3709b26f3370ae89c5324a3c03fab56a93b09ecdsf set_preserve_host(cmd_parms *parms, void *dconf, int flag)
fd3fa792f04fc9c4e8f5f83dceb0fc34e71f8570ianh{
3709b26f3370ae89c5324a3c03fab56a93b09ecdsf proxy_dir_conf *conf = dconf;
fd3fa792f04fc9c4e8f5f83dceb0fc34e71f8570ianh
3709b26f3370ae89c5324a3c03fab56a93b09ecdsf conf->preserve_host = flag;
3709b26f3370ae89c5324a3c03fab56a93b09ecdsf conf->preserve_host_set = 1;
fd3fa792f04fc9c4e8f5f83dceb0fc34e71f8570ianh return NULL;
fd3fa792f04fc9c4e8f5f83dceb0fc34e71f8570ianh}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic const char *
11c3b5180e1de6776035320b012a28bb146e7b46chuck set_recv_buffer_size(cmd_parms *parms, void *dummy, const char *arg)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding proxy_server_conf *psf =
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding ap_get_module_config(parms->server->module_config, &proxy_module);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding int s = atoi(arg);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (s < 512 && s != 0) {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return "ProxyReceiveBufferSize must be >= 512 bytes, or 0 for system default.";
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding psf->recv_buffer_size = s;
af952917c05e56874069e1e5f64e6473bb478b68minfrin psf->recv_buffer_size_set = 1;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding return NULL;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrinstatic const char *
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin set_io_buffer_size(cmd_parms *parms, void *dummy, const char *arg)
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin{
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin proxy_server_conf *psf =
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin ap_get_module_config(parms->server->module_config, &proxy_module);
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin long s = atol(arg);
5eb56df4054a0bca4d740eedd7ef277355a2c0adjim if (s < 512 && s) {
5eb56df4054a0bca4d740eedd7ef277355a2c0adjim return "ProxyIOBufferSize must be >= 512 bytes, or 0 for system default.";
5eb56df4054a0bca4d740eedd7ef277355a2c0adjim }
5eb56df4054a0bca4d740eedd7ef277355a2c0adjim psf->io_buffer_size = (s ? s : AP_IOBUFSIZE);
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin psf->io_buffer_size_set = 1;
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin return NULL;
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin}
afef080e47ef499a5cbceb7ad7fadbb3abca0b48minfrin
35c9e4d2c0a6465746a98958ef756114834461e6minfrinstatic const char *
35c9e4d2c0a6465746a98958ef756114834461e6minfrin set_max_forwards(cmd_parms *parms, void *dummy, const char *arg)
35c9e4d2c0a6465746a98958ef756114834461e6minfrin{
35c9e4d2c0a6465746a98958ef756114834461e6minfrin proxy_server_conf *psf =
35c9e4d2c0a6465746a98958ef756114834461e6minfrin ap_get_module_config(parms->server->module_config, &proxy_module);
35c9e4d2c0a6465746a98958ef756114834461e6minfrin long s = atol(arg);
35c9e4d2c0a6465746a98958ef756114834461e6minfrin
35c9e4d2c0a6465746a98958ef756114834461e6minfrin psf->maxfwd = s;
35c9e4d2c0a6465746a98958ef756114834461e6minfrin psf->maxfwd_set = 1;
35c9e4d2c0a6465746a98958ef756114834461e6minfrin return NULL;
35c9e4d2c0a6465746a98958ef756114834461e6minfrin}
4224d5789080ea5586d49420da1e1996f5653bb5ianhstatic const char*
4224d5789080ea5586d49420da1e1996f5653bb5ianh set_proxy_timeout(cmd_parms *parms, void *dummy, const char *arg)
4224d5789080ea5586d49420da1e1996f5653bb5ianh{
4224d5789080ea5586d49420da1e1996f5653bb5ianh proxy_server_conf *psf =
4224d5789080ea5586d49420da1e1996f5653bb5ianh ap_get_module_config(parms->server->module_config, &proxy_module);
4224d5789080ea5586d49420da1e1996f5653bb5ianh int timeout;
4224d5789080ea5586d49420da1e1996f5653bb5ianh
35630e8756729a29273ef1a5c879b90df3594d66rjung timeout = atoi(arg);
4224d5789080ea5586d49420da1e1996f5653bb5ianh if (timeout<1) {
4224d5789080ea5586d49420da1e1996f5653bb5ianh return "Proxy Timeout must be at least 1 second.";
4224d5789080ea5586d49420da1e1996f5653bb5ianh }
35630e8756729a29273ef1a5c879b90df3594d66rjung psf->timeout_set = 1;
35630e8756729a29273ef1a5c879b90df3594d66rjung psf->timeout = apr_time_from_sec(timeout);
4224d5789080ea5586d49420da1e1996f5653bb5ianh
e8f95a682820a599fe41b22977010636be5c2717jim return NULL;
4224d5789080ea5586d49420da1e1996f5653bb5ianh}
35c9e4d2c0a6465746a98958ef756114834461e6minfrin
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic const char*
a2f9f38db0931e6edf7b71378dd680c3c5fa5841rbb set_via_opt(cmd_parms *parms, void *dummy, const char *arg)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
11c3b5180e1de6776035320b012a28bb146e7b46chuck proxy_server_conf *psf =
11c3b5180e1de6776035320b012a28bb146e7b46chuck ap_get_module_config(parms->server->module_config, &proxy_module);
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding if (strcasecmp(arg, "Off") == 0)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding psf->viaopt = via_off;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding else if (strcasecmp(arg, "On") == 0)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding psf->viaopt = via_on;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding else if (strcasecmp(arg, "Block") == 0)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding psf->viaopt = via_block;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding else if (strcasecmp(arg, "Full") == 0)
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding psf->viaopt = via_full;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding else {
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return "ProxyVia must be one of: "
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard "off | on | full | block";
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding }
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
af952917c05e56874069e1e5f64e6473bb478b68minfrin psf->viaopt_set = 1;
e8f95a682820a599fe41b22977010636be5c2717jim return NULL;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jimstatic const char*
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim set_bad_opt(cmd_parms *parms, void *dummy, const char *arg)
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim{
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim proxy_server_conf *psf =
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim ap_get_module_config(parms->server->module_config, &proxy_module);
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim if (strcasecmp(arg, "IsError") == 0)
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim psf->badopt = bad_error;
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim else if (strcasecmp(arg, "Ignore") == 0)
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim psf->badopt = bad_ignore;
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim else if (strcasecmp(arg, "StartBody") == 0)
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim psf->badopt = bad_body;
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim else {
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim return "ProxyBadHeader must be one of: "
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim "IsError | Ignore | StartBody";
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim }
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim psf->badopt_set = 1;
e8f95a682820a599fe41b22977010636be5c2717jim return NULL;
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim}
db8ac7cbb1fa6cdd6abcc4bb797d4deed32dd269jim
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowestatic const char*
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe set_status_opt(cmd_parms *parms, void *dummy, const char *arg)
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe{
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe proxy_server_conf *psf =
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe ap_get_module_config(parms->server->module_config, &proxy_module);
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe if (strcasecmp(arg, "Off") == 0)
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe psf->proxy_status = status_off;
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe else if (strcasecmp(arg, "On") == 0)
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe psf->proxy_status = status_on;
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe else if (strcasecmp(arg, "Full") == 0)
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe psf->proxy_status = status_full;
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe else {
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe return "ProxyStatus must be one of: "
6c05afd314b4ddd545d63b4ff5de822cc30eec79trawick "off | on | full";
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe }
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe psf->proxy_status_set = 1;
e8f95a682820a599fe41b22977010636be5c2717jim return NULL;
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe}
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe
7ce40500bfead8781bab964eb6e01944acbf3915jimstatic const char *set_bgrowth(cmd_parms *parms, void *dummy, const char *arg)
7ce40500bfead8781bab964eb6e01944acbf3915jim{
7ce40500bfead8781bab964eb6e01944acbf3915jim proxy_server_conf *psf =
7ce40500bfead8781bab964eb6e01944acbf3915jim ap_get_module_config(parms->server->module_config, &proxy_module);
7ce40500bfead8781bab964eb6e01944acbf3915jim
7ce40500bfead8781bab964eb6e01944acbf3915jim int growth = atoi(arg);
7ce40500bfead8781bab964eb6e01944acbf3915jim if (growth < 0 || growth > 1000) {
7ce40500bfead8781bab964eb6e01944acbf3915jim return "BalancerGrowth must be between 0 and 1000";
7ce40500bfead8781bab964eb6e01944acbf3915jim }
7ce40500bfead8781bab964eb6e01944acbf3915jim psf->bgrowth = growth;
7ce40500bfead8781bab964eb6e01944acbf3915jim psf->bgrowth_set = 1;
7ce40500bfead8781bab964eb6e01944acbf3915jim
7ce40500bfead8781bab964eb6e01944acbf3915jim return NULL;
7ce40500bfead8781bab964eb6e01944acbf3915jim}
7ce40500bfead8781bab964eb6e01944acbf3915jim
57db302f0875a6c93a79333b8941cea4c1827272jimstatic const char *set_persist(cmd_parms *parms, void *dummy, int flag)
57db302f0875a6c93a79333b8941cea4c1827272jim{
57db302f0875a6c93a79333b8941cea4c1827272jim proxy_server_conf *psf =
57db302f0875a6c93a79333b8941cea4c1827272jim ap_get_module_config(parms->server->module_config, &proxy_module);
57db302f0875a6c93a79333b8941cea4c1827272jim
57db302f0875a6c93a79333b8941cea4c1827272jim psf->bal_persist = flag;
57db302f0875a6c93a79333b8941cea4c1827272jim return NULL;
57db302f0875a6c93a79333b8941cea4c1827272jim}
57db302f0875a6c93a79333b8941cea4c1827272jim
1e9c19df8bde7cbced53210a99eb0216ce79e1fbjimstatic const char *set_inherit(cmd_parms *parms, void *dummy, int flag)
1e9c19df8bde7cbced53210a99eb0216ce79e1fbjim{
1e9c19df8bde7cbced53210a99eb0216ce79e1fbjim proxy_server_conf *psf =
1e9c19df8bde7cbced53210a99eb0216ce79e1fbjim ap_get_module_config(parms->server->module_config, &proxy_module);
1e9c19df8bde7cbced53210a99eb0216ce79e1fbjim
1e9c19df8bde7cbced53210a99eb0216ce79e1fbjim psf->inherit = flag;
f4c820be3237778985b10dabd420c6301f65ee04rjung psf->inherit_set = 1;
1e9c19df8bde7cbced53210a99eb0216ce79e1fbjim return NULL;
1e9c19df8bde7cbced53210a99eb0216ce79e1fbjim}
1e9c19df8bde7cbced53210a99eb0216ce79e1fbjim
8ad2333769563eadfe4944407c32666160b641a0jimstatic const char *set_ppinherit(cmd_parms *parms, void *dummy, int flag)
8ad2333769563eadfe4944407c32666160b641a0jim{
8ad2333769563eadfe4944407c32666160b641a0jim proxy_server_conf *psf =
8ad2333769563eadfe4944407c32666160b641a0jim ap_get_module_config(parms->server->module_config, &proxy_module);
8ad2333769563eadfe4944407c32666160b641a0jim
8ad2333769563eadfe4944407c32666160b641a0jim psf->ppinherit = flag;
8ad2333769563eadfe4944407c32666160b641a0jim psf->ppinherit_set = 1;
8ad2333769563eadfe4944407c32666160b641a0jim return NULL;
8ad2333769563eadfe4944407c32666160b641a0jim}
8ad2333769563eadfe4944407c32666160b641a0jim
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowestatic const char *add_member(cmd_parms *cmd, void *dummy, const char *arg)
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe{
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe server_rec *s = cmd->server;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe proxy_server_conf *conf =
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe ap_get_module_config(s->module_config, &proxy_module);
5a5a6c22260854843c973e2ea9a14bec64362ab5wrowe proxy_balancer *balancer;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe proxy_worker *worker;
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe char *path = cmd->path;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe char *name = NULL;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe char *word;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe apr_table_t *params = apr_table_make(cmd->pool, 5);
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe const apr_array_header_t *arr;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe const apr_table_entry_t *elts;
06cdc8d205f0982074ab9b032d0b6d74c58f54carjung int reuse = 0;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe int i;
7c2df38555e33d4c30de9973722128cc9646a1b3sf /* XXX: Should this be NOT_IN_DIRECTORY|NOT_IN_FILES? */
7c2df38555e33d4c30de9973722128cc9646a1b3sf const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS);
7c2df38555e33d4c30de9973722128cc9646a1b3sf if (err)
7c2df38555e33d4c30de9973722128cc9646a1b3sf return err;
e8f95a682820a599fe41b22977010636be5c2717jim
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe if (cmd->path)
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe path = apr_pstrdup(cmd->pool, cmd->path);
a2d1780b346e147ca4d5c1cdeb0fd8a57fd93899jfclere
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe while (*arg) {
a2d1780b346e147ca4d5c1cdeb0fd8a57fd93899jfclere char *val;
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe word = ap_getword_conf(cmd->pool, &arg);
a2d1780b346e147ca4d5c1cdeb0fd8a57fd93899jfclere val = strchr(word, '=');
a2d1780b346e147ca4d5c1cdeb0fd8a57fd93899jfclere
a2d1780b346e147ca4d5c1cdeb0fd8a57fd93899jfclere if (!val) {
a2d1780b346e147ca4d5c1cdeb0fd8a57fd93899jfclere if (!path)
a2d1780b346e147ca4d5c1cdeb0fd8a57fd93899jfclere path = word;
a2d1780b346e147ca4d5c1cdeb0fd8a57fd93899jfclere else if (!name)
a2d1780b346e147ca4d5c1cdeb0fd8a57fd93899jfclere name = word;
a2d1780b346e147ca4d5c1cdeb0fd8a57fd93899jfclere else {
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe if (cmd->path)
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe return "BalancerMember can not have a balancer name when defined in a location";
5d5c9e862c3d4e7f15c12d293de4111f52404760wrowe else
433dc2d5dae74ed067db6175010ff973d02511e9jerenkrantz return "Invalid BalancerMember parameter. Parameter must "
433dc2d5dae74ed067db6175010ff973d02511e9jerenkrantz "be in the form 'key=value'";
a2d1780b346e147ca4d5c1cdeb0fd8a57fd93899jfclere }
a2d1780b346e147ca4d5c1cdeb0fd8a57fd93899jfclere } else {
a2d1780b346e147ca4d5c1cdeb0fd8a57fd93899jfclere *val++ = '\0';
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe apr_table_setn(params, word, val);
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe }
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe }
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe if (!path)
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe return "BalancerMember must define balancer name when outside <Proxy > section";
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe if (!name)
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe return "BalancerMember must define remote proxy server";
e8f95a682820a599fe41b22977010636be5c2717jim
65efbf0826de766a90d745cc44427bfa4e2447b6mturk ap_str_tolower(path); /* lowercase scheme://hostname */
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim /* Try to find the balancer */
f66d52ac5f701eed7986e23d12960344f8bf6b61jim balancer = ap_proxy_get_balancer(cmd->temp_pool, conf, path, 0);
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim if (!balancer) {
aee938da5530729ca29b60015120c487d5e1bcacjim err = ap_proxy_define_balancer(cmd->pool, &balancer, conf, path, "/", 0);
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim if (err)
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim return apr_pstrcat(cmd->temp_pool, "BalancerMember ", err, NULL);
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim }
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim
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));
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe if (!worker) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01147)
0c4b0ffd3db7ae8e34662826098b5e46dadc1e88jim "Defining worker '%s' for balancer '%s'",
aee938da5530729ca29b60015120c487d5e1bcacjim name, balancer->s->name);
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);
06cdc8d205f0982074ab9b032d0b6d74c58f54carjung PROXY_COPY_CONF_PARAMS(worker, conf);
7ba381d8371d632d25ba1256a9047fe601cb984djfclere } else {
06cdc8d205f0982074ab9b032d0b6d74c58f54carjung reuse = 1;
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_INFO, 0, cmd->server, APLOGNO(01149)
9acdc6e89570bd3d79206c6d2ca2b5ccf85b20c7jim "Sharing worker '%s' instead of creating new worker '%s'",
9acdc6e89570bd3d79206c6d2ca2b5ccf85b20c7jim ap_proxy_worker_name(cmd->pool, worker), name);
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe }
e8f95a682820a599fe41b22977010636be5c2717jim
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe arr = apr_table_elts(params);
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe elts = (const apr_table_entry_t *)arr->elts;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe for (i = 0; i < arr->nelts; i++) {
06cdc8d205f0982074ab9b032d0b6d74c58f54carjung if (reuse) {
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 } else {
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim err = set_worker_param(cmd->pool, worker, elts[i].key,
06cdc8d205f0982074ab9b032d0b6d74c58f54carjung elts[i].val);
06cdc8d205f0982074ab9b032d0b6d74c58f54carjung if (err)
06cdc8d205f0982074ab9b032d0b6d74c58f54carjung return apr_pstrcat(cmd->temp_pool, "BalancerMember ", err, NULL);
06cdc8d205f0982074ab9b032d0b6d74c58f54carjung }
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe }
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe return NULL;
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe}
d52b01101efdd3a37493d1090f20eb23c4dd1521wrowe
65efbf0826de766a90d745cc44427bfa4e2447b6mturkstatic const char *
65efbf0826de766a90d745cc44427bfa4e2447b6mturk set_proxy_param(cmd_parms *cmd, void *dummy, const char *arg)
65efbf0826de766a90d745cc44427bfa4e2447b6mturk{
65efbf0826de766a90d745cc44427bfa4e2447b6mturk server_rec *s = cmd->server;
65efbf0826de766a90d745cc44427bfa4e2447b6mturk proxy_server_conf *conf =
65efbf0826de766a90d745cc44427bfa4e2447b6mturk (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module);
65efbf0826de766a90d745cc44427bfa4e2447b6mturk char *name = NULL;
65efbf0826de766a90d745cc44427bfa4e2447b6mturk char *word, *val;
65efbf0826de766a90d745cc44427bfa4e2447b6mturk proxy_balancer *balancer = NULL;
65efbf0826de766a90d745cc44427bfa4e2447b6mturk proxy_worker *worker = NULL;
fef95ce9cdb638443693c21f181dd2494b467469mturk int in_proxy_section = 0;
7c2df38555e33d4c30de9973722128cc9646a1b3sf /* XXX: Should this be NOT_IN_DIRECTORY|NOT_IN_FILES? */
7c2df38555e33d4c30de9973722128cc9646a1b3sf const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS);
7c2df38555e33d4c30de9973722128cc9646a1b3sf if (err)
7c2df38555e33d4c30de9973722128cc9646a1b3sf return err;
65efbf0826de766a90d745cc44427bfa4e2447b6mturk
65efbf0826de766a90d745cc44427bfa4e2447b6mturk if (cmd->directive->parent &&
65efbf0826de766a90d745cc44427bfa4e2447b6mturk strncasecmp(cmd->directive->parent->directive,
65efbf0826de766a90d745cc44427bfa4e2447b6mturk "<Proxy", 6) == 0) {
65efbf0826de766a90d745cc44427bfa4e2447b6mturk const char *pargs = cmd->directive->parent->args;
65efbf0826de766a90d745cc44427bfa4e2447b6mturk /* Directive inside <Proxy section
65efbf0826de766a90d745cc44427bfa4e2447b6mturk * Parent directive arg is the worker/balancer name.
65efbf0826de766a90d745cc44427bfa4e2447b6mturk */
65efbf0826de766a90d745cc44427bfa4e2447b6mturk name = ap_getword_conf(cmd->temp_pool, &pargs);
9738b63e3d24b2856b1b6a12fcddcbf325f26d4bnd if ((word = ap_strchr(name, '>')))
65efbf0826de766a90d745cc44427bfa4e2447b6mturk *word = '\0';
fef95ce9cdb638443693c21f181dd2494b467469mturk in_proxy_section = 1;
65efbf0826de766a90d745cc44427bfa4e2447b6mturk }
65efbf0826de766a90d745cc44427bfa4e2447b6mturk else {
65efbf0826de766a90d745cc44427bfa4e2447b6mturk /* Standard set directive with worker/balancer
65efbf0826de766a90d745cc44427bfa4e2447b6mturk * name as first param.
65efbf0826de766a90d745cc44427bfa4e2447b6mturk */
65efbf0826de766a90d745cc44427bfa4e2447b6mturk name = ap_getword_conf(cmd->temp_pool, &arg);
65efbf0826de766a90d745cc44427bfa4e2447b6mturk }
e8f95a682820a599fe41b22977010636be5c2717jim
748859d4eeb90f2a64b8b8318bc45c3a61dcd968jim if (ap_proxy_valid_balancer_name(name, 9)) {
f66d52ac5f701eed7986e23d12960344f8bf6b61jim balancer = ap_proxy_get_balancer(cmd->pool, conf, name, 0);
65efbf0826de766a90d745cc44427bfa4e2447b6mturk if (!balancer) {
fef95ce9cdb638443693c21f181dd2494b467469mturk if (in_proxy_section) {
aee938da5530729ca29b60015120c487d5e1bcacjim err = ap_proxy_define_balancer(cmd->pool, &balancer, conf, name, "/", 0);
fef95ce9cdb638443693c21f181dd2494b467469mturk if (err)
fef95ce9cdb638443693c21f181dd2494b467469mturk return apr_pstrcat(cmd->temp_pool, "ProxySet ",
fef95ce9cdb638443693c21f181dd2494b467469mturk err, NULL);
fef95ce9cdb638443693c21f181dd2494b467469mturk }
fef95ce9cdb638443693c21f181dd2494b467469mturk else
fef95ce9cdb638443693c21f181dd2494b467469mturk return apr_pstrcat(cmd->temp_pool, "ProxySet can not find '",
fef95ce9cdb638443693c21f181dd2494b467469mturk name, "' Balancer.", NULL);
e8f95a682820a599fe41b22977010636be5c2717jim }
65efbf0826de766a90d745cc44427bfa4e2447b6mturk }
65efbf0826de766a90d745cc44427bfa4e2447b6mturk else {
44b664206cee887b8b69862def5dd1832afc97ddcovener worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, ap_proxy_de_socketfy(cmd->temp_pool, name));
65efbf0826de766a90d745cc44427bfa4e2447b6mturk if (!worker) {
fef95ce9cdb638443693c21f181dd2494b467469mturk if (in_proxy_section) {
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim err = ap_proxy_define_worker(cmd->pool, &worker, NULL,
cb7cf74a315df272e2ec329ce2ef1d50b82b8384jim conf, name, 0);
fef95ce9cdb638443693c21f181dd2494b467469mturk if (err)
fef95ce9cdb638443693c21f181dd2494b467469mturk return apr_pstrcat(cmd->temp_pool, "ProxySet ",
fef95ce9cdb638443693c21f181dd2494b467469mturk err, NULL);
fef95ce9cdb638443693c21f181dd2494b467469mturk }
fef95ce9cdb638443693c21f181dd2494b467469mturk else
fef95ce9cdb638443693c21f181dd2494b467469mturk return apr_pstrcat(cmd->temp_pool, "ProxySet can not find '",
fef95ce9cdb638443693c21f181dd2494b467469mturk name, "' Worker.", NULL);
65efbf0826de766a90d745cc44427bfa4e2447b6mturk }
65efbf0826de766a90d745cc44427bfa4e2447b6mturk }
65efbf0826de766a90d745cc44427bfa4e2447b6mturk
65efbf0826de766a90d745cc44427bfa4e2447b6mturk while (*arg) {
65efbf0826de766a90d745cc44427bfa4e2447b6mturk word = ap_getword_conf(cmd->pool, &arg);
65efbf0826de766a90d745cc44427bfa4e2447b6mturk val = strchr(word, '=');
65efbf0826de766a90d745cc44427bfa4e2447b6mturk if (!val) {
65efbf0826de766a90d745cc44427bfa4e2447b6mturk return "Invalid ProxySet parameter. Parameter must be "
65efbf0826de766a90d745cc44427bfa4e2447b6mturk "in the form 'key=value'";
65efbf0826de766a90d745cc44427bfa4e2447b6mturk }
65efbf0826de766a90d745cc44427bfa4e2447b6mturk else
65efbf0826de766a90d745cc44427bfa4e2447b6mturk *val++ = '\0';
65efbf0826de766a90d745cc44427bfa4e2447b6mturk if (worker)
65efbf0826de766a90d745cc44427bfa4e2447b6mturk err = set_worker_param(cmd->pool, worker, word, val);
65efbf0826de766a90d745cc44427bfa4e2447b6mturk else
1febae173a82bc2a71c3c0ba4105cf674000791bjim err = set_balancer_param(conf, cmd->pool, balancer, word, val);
65efbf0826de766a90d745cc44427bfa4e2447b6mturk
65efbf0826de766a90d745cc44427bfa4e2447b6mturk if (err)
c332befc1519a1016d8de07608f0b859e6fab580jim return apr_pstrcat(cmd->temp_pool, "ProxySet: ", err, " ", word, "=", val, "; ", name, NULL);
65efbf0826de766a90d745cc44427bfa4e2447b6mturk }
65efbf0826de766a90d745cc44427bfa4e2447b6mturk
65efbf0826de766a90d745cc44427bfa4e2447b6mturk return NULL;
65efbf0826de766a90d745cc44427bfa4e2447b6mturk}
65efbf0826de766a90d745cc44427bfa4e2447b6mturk
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowestatic void ap_add_per_proxy_conf(server_rec *s, ap_conf_vector_t *dir_config)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe{
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe proxy_server_conf *sconf = ap_get_module_config(s->module_config,
b9b3cd7661ec354e0eee71116faa1e4afdf3fcdcmturk &proxy_module);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe void **new_space = (void **)apr_array_push(sconf->sec_proxy);
e8f95a682820a599fe41b22977010636be5c2717jim
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe *new_space = dir_config;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe}
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowestatic const char *proxysection(cmd_parms *cmd, void *mconfig, const char *arg)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe{
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe const char *errmsg;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe const char *endp = ap_strrchr_c(arg, '>');
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe int old_overrides = cmd->override;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe char *old_path = cmd->path;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe proxy_dir_conf *conf;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_conf_vector_t *new_dir_conf = ap_create_per_dir_config(cmd->pool);
ef5650b61a8e35f3cc93ec07e73efc17ea329894jorton ap_regex_t *r = NULL;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe const command_rec *thiscmd = cmd->cmd;
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk char *word, *val;
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk proxy_balancer *balancer = NULL;
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk proxy_worker *worker = NULL;
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza int use_regex = 0;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
bdf8801c51d958b1d3ff40f60ab16ccfd999b0fawrowe const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk proxy_server_conf *sconf =
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk (proxy_server_conf *) ap_get_module_config(cmd->server->module_config, &proxy_module);
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (err != NULL) {
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return err;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (endp == NULL) {
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return apr_pstrcat(cmd->pool, cmd->cmd->name,
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard "> directive missing closing '>'", NULL);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
35630e8756729a29273ef1a5c879b90df3594d66rjung arg = apr_pstrndup(cmd->pool, arg, endp-arg);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (!arg) {
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (thiscmd->cmd_data)
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return "<ProxyMatch > block must specify a path";
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe else
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return "<Proxy > block must specify a path";
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe cmd->path = ap_getword_conf(cmd->pool, &arg);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe cmd->override = OR_ALL|ACCESS_CONF;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
52489511342e4ff3fe399e57f29d38e5c4227bc8trawick if (!strncasecmp(cmd->path, "proxy:", 6))
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe cmd->path += 6;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
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()
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe */
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (thiscmd->cmd_data) { /* <ProxyMatch> */
ef5650b61a8e35f3cc93ec07e73efc17ea329894jorton r = ap_pregcomp(cmd->pool, cmd->path, AP_REG_EXTENDED);
e6c244ee56578707b20a86e0e938498299a93b6cnd if (!r) {
e6c244ee56578707b20a86e0e938498299a93b6cnd return "Regex could not be compiled";
e6c244ee56578707b20a86e0e938498299a93b6cnd }
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza use_regex = 1;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe /* initialize our config and fetch it */
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe conf = ap_set_config_vectors(cmd->server, new_dir_conf, cmd->path,
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe &proxy_module, cmd->pool);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_dir_conf);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (errmsg != NULL)
e6366481b8fe06a24337f0b30b7da66cf64d6062stoddard return errmsg;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe conf->r = r;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe conf->p = cmd->path;
9a806b671337b22acf6418e60a83f6bbeabdf771wrowe conf->p_is_fnmatch = apr_fnmatch_test(conf->p);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin if (r) {
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin conf->refs = apr_array_make(cmd->pool, 8, sizeof(char *));
eab364dc817e6d2f9179d0ecbd269d02df6f383cminfrin ap_regname(r, conf->refs, AP_REG_MATCH, 1);
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin }
a370a774825bc89fc6b0d8e45035a590e39b0bd6minfrin
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe ap_add_per_proxy_conf(cmd->server, new_dir_conf);
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe if (*arg != '\0') {
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk if (thiscmd->cmd_data)
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk return "Multiple <ProxyMatch> arguments not (yet) supported.";
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk if (conf->p_is_fnmatch)
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk return apr_pstrcat(cmd->pool, thiscmd->name,
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk "> arguments are not supported for wildchar url.",
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk NULL);
7033ee56ea894e9b3fdf573ab9960149a4e88a11jorton if (!ap_strchr_c(conf->p, ':'))
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk return apr_pstrcat(cmd->pool, thiscmd->name,
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk "> arguments are not supported for non url.",
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk NULL);
748859d4eeb90f2a64b8b8318bc45c3a61dcd968jim if (ap_proxy_valid_balancer_name((char *)conf->p, 9)) {
f66d52ac5f701eed7986e23d12960344f8bf6b61jim balancer = ap_proxy_get_balancer(cmd->pool, sconf, conf->p, 0);
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk if (!balancer) {
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim err = ap_proxy_define_balancer(cmd->pool, &balancer,
aee938da5530729ca29b60015120c487d5e1bcacjim sconf, conf->p, "/", 0);
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk if (err)
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk return apr_pstrcat(cmd->temp_pool, thiscmd->name,
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk " ", err, NULL);
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk }
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk }
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk else {
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim worker = ap_proxy_get_worker(cmd->temp_pool, NULL, sconf,
44b664206cee887b8b69862def5dd1832afc97ddcovener ap_proxy_de_socketfy(cmd->temp_pool, (char*)conf->p));
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk if (!worker) {
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza if (use_regex) {
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza err = ap_proxy_define_match_worker(cmd->pool, &worker, NULL,
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza sconf, conf->p, 0);
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza }
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza else {
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza err = ap_proxy_define_worker(cmd->pool, &worker, NULL,
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza sconf, conf->p, 0);
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza }
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk if (err)
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk return apr_pstrcat(cmd->temp_pool, thiscmd->name,
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk " ", err, NULL);
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk }
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 ",
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza "(", worker->s->name, ")", NULL);
8598609b666f19b7948b3f1ef24fe9ddc504ce72jkaluza }
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk }
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk if (worker == NULL && balancer == NULL) {
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk return apr_pstrcat(cmd->pool, thiscmd->name,
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk "> arguments are supported only for workers.",
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk NULL);
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk }
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk while (*arg) {
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk word = ap_getword_conf(cmd->pool, &arg);
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk val = strchr(word, '=');
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk if (!val) {
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk return "Invalid Proxy parameter. Parameter must be "
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk "in the form 'key=value'";
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk }
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk else
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk *val++ = '\0';
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk if (worker)
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk err = set_worker_param(cmd->pool, worker, word, val);
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk else
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk err = set_balancer_param(sconf, cmd->pool, balancer,
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk word, val);
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk if (err)
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk return apr_pstrcat(cmd->temp_pool, thiscmd->name, " ", err, " ",
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk word, "=", val, "; ", conf->p, NULL);
144f8db798e3b92e4e4a3f51904e8f21ad160680mturk }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe }
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe cmd->path = old_path;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe cmd->override = old_overrides;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe return NULL;
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe}
2ceedfca3a2fdfdb5ff60ca17f030ce91f6331cbwrowe
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic const command_rec proxy_cmds[] =
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
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 (void*)APR_OFFSETOF(proxy_dir_conf, interpolate_env),
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 AP_INIT_TAKE1("ProxyVia", set_via_opt, NULL, RSRC_CONF,
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"),
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding {NULL}
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding};
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
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
de8799b6a9e8221681873ab5a81b6af6596faaafwrowePROXY_DECLARE(int) ap_proxy_ssl_enable(conn_rec *c)
1723d9ccdd3b647f5b7bae44cab9ab3eca7a4874dougm{
e8f95a682820a599fe41b22977010636be5c2717jim /*
1723d9ccdd3b647f5b7bae44cab9ab3eca7a4874dougm * if c == NULL just check if the optional function was imported
1723d9ccdd3b647f5b7bae44cab9ab3eca7a4874dougm * else run the optional function so ssl filters are inserted
1723d9ccdd3b647f5b7bae44cab9ab3eca7a4874dougm */
1723d9ccdd3b647f5b7bae44cab9ab3eca7a4874dougm if (proxy_ssl_enable) {
1723d9ccdd3b647f5b7bae44cab9ab3eca7a4874dougm return c ? proxy_ssl_enable(c) : 1;
1723d9ccdd3b647f5b7bae44cab9ab3eca7a4874dougm }
1723d9ccdd3b647f5b7bae44cab9ab3eca7a4874dougm
1723d9ccdd3b647f5b7bae44cab9ab3eca7a4874dougm return 0;
1723d9ccdd3b647f5b7bae44cab9ab3eca7a4874dougm}
1723d9ccdd3b647f5b7bae44cab9ab3eca7a4874dougm
621bd763d2e4d32f19013ac8b76b375b5a01851fdougmPROXY_DECLARE(int) ap_proxy_ssl_disable(conn_rec *c)
621bd763d2e4d32f19013ac8b76b375b5a01851fdougm{
621bd763d2e4d32f19013ac8b76b375b5a01851fdougm if (proxy_ssl_disable) {
621bd763d2e4d32f19013ac8b76b375b5a01851fdougm return proxy_ssl_disable(c);
621bd763d2e4d32f19013ac8b76b375b5a01851fdougm }
621bd763d2e4d32f19013ac8b76b375b5a01851fdougm
621bd763d2e4d32f19013ac8b76b375b5a01851fdougm return 0;
621bd763d2e4d32f19013ac8b76b375b5a01851fdougm}
621bd763d2e4d32f19013ac8b76b375b5a01851fdougm
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturkPROXY_DECLARE(int) ap_proxy_conn_is_https(conn_rec *c)
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk{
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk if (proxy_is_https) {
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk return proxy_is_https(c);
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk }
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk else
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk return 0;
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk}
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturkPROXY_DECLARE(const char *) ap_proxy_ssl_val(apr_pool_t *p, server_rec *s,
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk conn_rec *c, request_rec *r,
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk const char *var)
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk{
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk if (proxy_ssl_val) {
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk /* XXX Perhaps the casting useless */
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk return (const char *)proxy_ssl_val(p, s, c, r, (char *)var);
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk }
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk else
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk return NULL;
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk}
79d97c2c5e2d3f8bb2a92cd21b3b4900d7bf04d6mturk
e1d00c81dc34e2c644cc936b9dea75ec9ccfca2adougmstatic int proxy_post_config(apr_pool_t *pconf, apr_pool_t *plog,
e1d00c81dc34e2c644cc936b9dea75ec9ccfca2adougm apr_pool_t *ptemp, server_rec *s)
e1d00c81dc34e2c644cc936b9dea75ec9ccfca2adougm{
c9147f126b25a20d45e5b39ea14efe6191628c41minfrin apr_status_t rv = ap_global_mutex_create(&proxy_mutex, NULL,
c9147f126b25a20d45e5b39ea14efe6191628c41minfrin proxy_id, NULL, s, pconf, 0);
c9147f126b25a20d45e5b39ea14efe6191628c41minfrin if (rv != APR_SUCCESS) {
8441484e251cc256d4cef5ff4ba88c37aaa3dde6jim ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, plog, APLOGNO(02478)
c9147f126b25a20d45e5b39ea14efe6191628c41minfrin "failed to create %s mutex", proxy_id);
c9147f126b25a20d45e5b39ea14efe6191628c41minfrin return rv;
c9147f126b25a20d45e5b39ea14efe6191628c41minfrin }
655b45ecbcfe204749cddff73f149dc0ec278905mturk
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);
e1d00c81dc34e2c644cc936b9dea75ec9ccfca2adougm
e1d00c81dc34e2c644cc936b9dea75ec9ccfca2adougm return OK;
e1d00c81dc34e2c644cc936b9dea75ec9ccfca2adougm}
e1d00c81dc34e2c644cc936b9dea75ec9ccfca2adougm
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe/*
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe * proxy Extension to mod_status
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe */
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowestatic int proxy_status_hook(request_rec *r, int flags)
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe{
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe int i, n;
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe void *sconf = r->server->module_config;
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe proxy_server_conf *conf = (proxy_server_conf *)
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe ap_get_module_config(sconf, &proxy_module);
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe proxy_balancer *balancer = NULL;
834fc281be8e0f7f2614961f12d8bbf603382a17jfclere proxy_worker **worker = NULL;
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung if (conf->balancers->nelts == 0 ||
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe conf->proxy_status == status_off)
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe return OK;
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe balancer = (proxy_balancer *)conf->balancers->elts;
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe for (i = 0; i < conf->balancers->nelts; i++) {
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung if (!(flags & AP_STATUS_SHORT)) {
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rputs("<hr />\n<h1>Proxy LoadBalancer Status for ", r);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rvputs(r, balancer->s->name, "</h1>\n\n", NULL);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rputs("\n\n<table border=\"0\"><tr>"
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung "<th>SSes</th><th>Timeout</th><th>Method</th>"
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung "</tr>\n<tr>", r);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung if (*balancer->s->sticky) {
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung if (strcmp(balancer->s->sticky, balancer->s->sticky_path)) {
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rvputs(r, "<td>", balancer->s->sticky, " | ",
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung balancer->s->sticky_path, NULL);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung }
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung else {
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rvputs(r, "<td>", balancer->s->sticky, NULL);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung }
c64fb33e0c4634fd352c4a6c143cd1a087c09b13nd }
c64fb33e0c4634fd352c4a6c143cd1a087c09b13nd else {
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rputs("<td> - ", r);
c64fb33e0c4634fd352c4a6c143cd1a087c09b13nd }
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rprintf(r, "</td><td>%" APR_TIME_T_FMT "</td>",
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung apr_time_sec(balancer->s->timeout));
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rprintf(r, "<td>%s</td>\n",
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung balancer->lbmethod->name);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rputs("</table>\n", r);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rputs("\n\n<table border=\"0\"><tr>"
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);
cd42921af450e87bc797da0ff899348b75732645jfclere }
cd42921af450e87bc797da0ff899348b75732645jfclere else {
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rprintf(r, "ProxyBalancer[%d]Name: %s\n", i, balancer->s->name);
cd42921af450e87bc797da0ff899348b75732645jfclere }
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe
834fc281be8e0f7f2614961f12d8bbf603382a17jfclere worker = (proxy_worker **)balancer->workers->elts;
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe for (n = 0; n < balancer->workers->nelts; n++) {
166a9c7964cffc8193764d877edce5bb9b509551mturk char fbuf[50];
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung if (!(flags & AP_STATUS_SHORT)) {
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->route, NULL);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rvputs(r, "</td><td>", (*worker)->s->redirect, NULL);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rprintf(r, "</td><td>%d</td>", (*worker)->s->lbfactor);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rprintf(r, "<td>%d</td>", (*worker)->s->lbset);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rprintf(r, "<td>%" APR_SIZE_T_FMT "</td><td>",
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung (*worker)->s->elected);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rputs(apr_strfsize((*worker)->s->transferred, fbuf), r);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rputs("</td><td>", r);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rputs(apr_strfsize((*worker)->s->read, fbuf), r);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rputs("</td>\n", r);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung /* TODO: Add the rest of dynamic worker data */
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rputs("</tr>\n", r);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung }
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung else {
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rprintf(r, "ProxyBalancer[%d]Worker[%d]Name: %s\n",
b37601f1ea5db01521378c0a08939a44000a54b1rjung i, n, (*worker)->s->name);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rprintf(r, "ProxyBalancer[%d]Worker[%d]Status: %s\n",
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung i, n, ap_proxy_parse_wstatus(r->pool, *worker));
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rprintf(r, "ProxyBalancer[%d]Worker[%d]Elected: %"
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung APR_SIZE_T_FMT "\n",
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung i, n, (*worker)->s->elected);
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rprintf(r, "ProxyBalancer[%d]Worker[%d]Sent: %s\n",
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung i, n, apr_strfsize((*worker)->s->transferred, fbuf));
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung ap_rprintf(r, "ProxyBalancer[%d]Worker[%d]Rcvd: %s\n",
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung i, n, apr_strfsize((*worker)->s->read, fbuf));
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung /* TODO: Add the rest of dynamic worker data */
d2fcf1d01ba9f36b78eb7b66fa5af8237b79ac70rjung }
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe ++worker;
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe }
f7dd2aaa55f30439e6c8512e84f18eb5c9ba2684rjung if (!(flags & AP_STATUS_SHORT)) {
f7dd2aaa55f30439e6c8512e84f18eb5c9ba2684rjung ap_rputs("</table>\n", r);
f7dd2aaa55f30439e6c8512e84f18eb5c9ba2684rjung }
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe ++balancer;
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe }
b37601f1ea5db01521378c0a08939a44000a54b1rjung if (!(flags & AP_STATUS_SHORT)) {
b37601f1ea5db01521378c0a08939a44000a54b1rjung ap_rputs("<hr /><table>\n"
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);
b37601f1ea5db01521378c0a08939a44000a54b1rjung }
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe return OK;
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe}
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe
1d2ff7570139286b0f0d16f92187a16ed5932291mturkstatic void child_init(apr_pool_t *p, server_rec *s)
1d2ff7570139286b0f0d16f92187a16ed5932291mturk{
a865e849a3b00dc8524ecdda09a1699452876219mturk proxy_worker *reverse = NULL;
e8f95a682820a599fe41b22977010636be5c2717jim
c3ffef98b00967c14c55056152a9411314b6f4bbjim apr_status_t rv = apr_global_mutex_child_init(&proxy_mutex,
c3ffef98b00967c14c55056152a9411314b6f4bbjim apr_global_mutex_lockfile(proxy_mutex),
c3ffef98b00967c14c55056152a9411314b6f4bbjim p);
c3ffef98b00967c14c55056152a9411314b6f4bbjim if (rv != APR_SUCCESS) {
8441484e251cc256d4cef5ff4ba88c37aaa3dde6jim ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(02479)
c3ffef98b00967c14c55056152a9411314b6f4bbjim "could not init proxy_mutex in child");
c3ffef98b00967c14c55056152a9411314b6f4bbjim exit(1); /* Ugly, but what else? */
c3ffef98b00967c14c55056152a9411314b6f4bbjim }
c3ffef98b00967c14c55056152a9411314b6f4bbjim
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim /* TODO */
888c31d26ec2735b6e744697dcaec1ab12877b01mturk while (s) {
888c31d26ec2735b6e744697dcaec1ab12877b01mturk void *sconf = s->module_config;
888c31d26ec2735b6e744697dcaec1ab12877b01mturk proxy_server_conf *conf;
888c31d26ec2735b6e744697dcaec1ab12877b01mturk proxy_worker *worker;
748859d4eeb90f2a64b8b8318bc45c3a61dcd968jim int i;
888c31d26ec2735b6e744697dcaec1ab12877b01mturk
888c31d26ec2735b6e744697dcaec1ab12877b01mturk conf = (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module);
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim /*
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim * NOTE: non-balancer members don't use shm at all...
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim * after all, why should they?
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim */
748859d4eeb90f2a64b8b8318bc45c3a61dcd968jim worker = (proxy_worker *)conf->workers->elts;
748859d4eeb90f2a64b8b8318bc45c3a61dcd968jim for (i = 0; i < conf->workers->nelts; i++, worker++) {
748859d4eeb90f2a64b8b8318bc45c3a61dcd968jim ap_proxy_initialize_worker(worker, s, conf->pool);
748859d4eeb90f2a64b8b8318bc45c3a61dcd968jim }
834fc281be8e0f7f2614961f12d8bbf603382a17jfclere /* Create and initialize forward worker if defined */
834fc281be8e0f7f2614961f12d8bbf603382a17jfclere if (conf->req_set && conf->req) {
748859d4eeb90f2a64b8b8318bc45c3a61dcd968jim proxy_worker *forward;
cb7cf74a315df272e2ec329ce2ef1d50b82b8384jim ap_proxy_define_worker(p, &forward, NULL, NULL, "http://www.apache.org", 0);
748859d4eeb90f2a64b8b8318bc45c3a61dcd968jim conf->forward = forward;
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim PROXY_STRNCPY(conf->forward->s->name, "proxy:forward");
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim PROXY_STRNCPY(conf->forward->s->hostname, "*");
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim PROXY_STRNCPY(conf->forward->s->scheme, "*");
14ce718783c7835d3bc89f3bb99ccb02dfb4058ajim conf->forward->hash.def = conf->forward->s->hash.def =
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim ap_proxy_hashfunc(conf->forward->s->name, PROXY_HASHFUNC_DEFAULT);
14ce718783c7835d3bc89f3bb99ccb02dfb4058ajim conf->forward->hash.fnv = conf->forward->s->hash.fnv =
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 */
4ff6259a3db2f4e365f3681df5145dc46d071e6fjim conf->forward->s->status |= PROXY_WORKER_GENERIC;
5c24acdc757b7557d33c389fafdb7cc455ce3740covener ap_proxy_initialize_worker(conf->forward, s, conf->pool);
e8f95a682820a599fe41b22977010636be5c2717jim /* Disable address cache for generic forward worker */
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim conf->forward->s->is_address_reusable = 0;
888c31d26ec2735b6e744697dcaec1ab12877b01mturk }
a865e849a3b00dc8524ecdda09a1699452876219mturk if (!reverse) {
cb7cf74a315df272e2ec329ce2ef1d50b82b8384jim ap_proxy_define_worker(p, &reverse, NULL, NULL, "http://www.apache.org", 0);
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim PROXY_STRNCPY(reverse->s->name, "proxy:reverse");
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim PROXY_STRNCPY(reverse->s->hostname, "*");
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim PROXY_STRNCPY(reverse->s->scheme, "*");
14ce718783c7835d3bc89f3bb99ccb02dfb4058ajim reverse->hash.def = reverse->s->hash.def =
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim ap_proxy_hashfunc(reverse->s->name, PROXY_HASHFUNC_DEFAULT);
14ce718783c7835d3bc89f3bb99ccb02dfb4058ajim reverse->hash.fnv = reverse->s->hash.fnv =
14ce718783c7835d3bc89f3bb99ccb02dfb4058ajim ap_proxy_hashfunc(reverse->s->name, PROXY_HASHFUNC_FNV);
a865e849a3b00dc8524ecdda09a1699452876219mturk /* Do not disable worker in case of errors */
a865e849a3b00dc8524ecdda09a1699452876219mturk reverse->s->status |= PROXY_WORKER_IGNORE_ERRORS;
4ff6259a3db2f4e365f3681df5145dc46d071e6fjim /* Mark as the "generic" worker */
4ff6259a3db2f4e365f3681df5145dc46d071e6fjim reverse->s->status |= PROXY_WORKER_GENERIC;
b24f2f0c00ea55efd834ea4a704f788d78fe7877rpluem conf->reverse = reverse;
5c24acdc757b7557d33c389fafdb7cc455ce3740covener ap_proxy_initialize_worker(conf->reverse, s, conf->pool);
e8f95a682820a599fe41b22977010636be5c2717jim /* Disable address cache for generic reverse worker */
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim reverse->s->is_address_reusable = 0;
a865e849a3b00dc8524ecdda09a1699452876219mturk }
6135cc8178d75a52828ad225b1d568cd1e97799erpluem conf->reverse = reverse;
888c31d26ec2735b6e744697dcaec1ab12877b01mturk s = s->next;
1d2ff7570139286b0f0d16f92187a16ed5932291mturk }
1d2ff7570139286b0f0d16f92187a16ed5932291mturk}
1d2ff7570139286b0f0d16f92187a16ed5932291mturk
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe/*
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe * This routine is called before the server processes the configuration
c9147f126b25a20d45e5b39ea14efe6191628c41minfrin * files.
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe */
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowestatic int proxy_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe apr_pool_t *ptemp)
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe{
c9147f126b25a20d45e5b39ea14efe6191628c41minfrin apr_status_t rv = ap_mutex_register(pconf, proxy_id, NULL,
c9147f126b25a20d45e5b39ea14efe6191628c41minfrin APR_LOCK_DEFAULT, 0);
c9147f126b25a20d45e5b39ea14efe6191628c41minfrin if (rv != APR_SUCCESS) {
8441484e251cc256d4cef5ff4ba88c37aaa3dde6jim ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, plog, APLOGNO(02480)
c9147f126b25a20d45e5b39ea14efe6191628c41minfrin "failed to register %s mutex", proxy_id);
c9147f126b25a20d45e5b39ea14efe6191628c41minfrin return 500; /* An HTTP status would be a misnomer! */
c9147f126b25a20d45e5b39ea14efe6191628c41minfrin }
c9147f126b25a20d45e5b39ea14efe6191628c41minfrin
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe APR_OPTIONAL_HOOK(ap, status_hook, proxy_status_hook, NULL, NULL,
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe APR_HOOK_MIDDLE);
e8f95a682820a599fe41b22977010636be5c2717jim /* Reset workers count on gracefull restart */
559db7681c06b49d8b57de9edb97b430c3b4d676mturk proxy_lb_workers = 0;
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe return OK;
c0a549c3f6e8edc87e921cf76fac95d04feba72bwrowe}
73e8b26287de5c06fa470d36162e103dbac9c7e5wrowestatic void register_hooks(apr_pool_t *p)
5babe00918c88eda487771fa6d6d4a1a19c0ced0chuck{
65aeb4185d6a108b19c27b89f311dc57dab62239nd /* fixup before mod_rewrite, so that the proxied url will not
65aeb4185d6a108b19c27b89f311dc57dab62239nd * escaped accidentally by our fixup.
65aeb4185d6a108b19c27b89f311dc57dab62239nd */
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.
1d2ff7570139286b0f0d16f92187a16ed5932291mturk */
4b155326ef6781820619c10e518dce1a44df7f91rjung static const char *const aszPred[] = { "mpm_winnt.c", "mod_proxy_balancer.c", NULL};
e8f95a682820a599fe41b22977010636be5c2717jim
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);
1d2ff7570139286b0f0d16f92187a16ed5932291mturk
4ab0fd1b54ce76f0fb6812b89b0b4dc7541014d6minfrin /* register optional functions within proxy_util.c */
4ab0fd1b54ce76f0fb6812b89b0b4dc7541014d6minfrin proxy_util_register_hooks(p);
5babe00918c88eda487771fa6d6d4a1a19c0ced0chuck}
5babe00918c88eda487771fa6d6d4a1a19c0ced0chuck
36ef8f77bffe75d1aa327882be1b5bdbe2ff567asfAP_DECLARE_MODULE(proxy) =
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding{
5babe00918c88eda487771fa6d6d4a1a19c0ced0chuck STANDARD20_MODULE_STUFF,
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 */
b9b3cd7661ec354e0eee71116faa1e4afdf3fcdcmturk proxy_cmds, /* command table */
5babe00918c88eda487771fa6d6d4a1a19c0ced0chuck register_hooks
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding};
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin
2e41eca72bcc4167d1871b0941ee79845540d58eminfrinAPR_HOOK_STRUCT(
65efbf0826de766a90d745cc44427bfa4e2447b6mturk APR_HOOK_LINK(scheme_handler)
65efbf0826de766a90d745cc44427bfa4e2447b6mturk APR_HOOK_LINK(canon_handler)
65efbf0826de766a90d745cc44427bfa4e2447b6mturk APR_HOOK_LINK(pre_request)
65efbf0826de766a90d745cc44427bfa4e2447b6mturk APR_HOOK_LINK(post_request)
bda7a7d57377f45932c237d5aba00b189d85c2a9ianh APR_HOOK_LINK(request_status)
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin)
2e41eca72bcc4167d1871b0941ee79845540d58eminfrin
e8f95a682820a599fe41b22977010636be5c2717jimAPR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(proxy, PROXY, int, scheme_handler,
446c6a9a1e1073798258f1237f8c848b5f917b66wrowe (request_rec *r, proxy_worker *worker,
e8f95a682820a599fe41b22977010636be5c2717jim proxy_server_conf *conf,
e8f95a682820a599fe41b22977010636be5c2717jim char *url, const char *proxyhost,
446c6a9a1e1073798258f1237f8c848b5f917b66wrowe apr_port_t proxyport),(r,worker,conf,
446c6a9a1e1073798258f1237f8c848b5f917b66wrowe url,proxyhost,proxyport),DECLINED)
e8f95a682820a599fe41b22977010636be5c2717jimAPR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(proxy, PROXY, int, canon_handler,
446c6a9a1e1073798258f1237f8c848b5f917b66wrowe (request_rec *r, char *url),(r,
446c6a9a1e1073798258f1237f8c848b5f917b66wrowe url),DECLINED)
d75bc22ab2702fa770f6935f07107efff16a76f0wroweAPR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(proxy, PROXY, int, pre_request, (
d75bc22ab2702fa770f6935f07107efff16a76f0wrowe proxy_worker **worker,
5a5a6c22260854843c973e2ea9a14bec64362ab5wrowe proxy_balancer **balancer,
e8f95a682820a599fe41b22977010636be5c2717jim request_rec *r,
d75bc22ab2702fa770f6935f07107efff16a76f0wrowe proxy_server_conf *conf,
d75bc22ab2702fa770f6935f07107efff16a76f0wrowe char **url),(worker,balancer,
d75bc22ab2702fa770f6935f07107efff16a76f0wrowe r,conf,url),DECLINED)
d75bc22ab2702fa770f6935f07107efff16a76f0wroweAPR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(proxy, PROXY, int, post_request,
d75bc22ab2702fa770f6935f07107efff16a76f0wrowe (proxy_worker *worker,
5a5a6c22260854843c973e2ea9a14bec64362ab5wrowe proxy_balancer *balancer,
d75bc22ab2702fa770f6935f07107efff16a76f0wrowe request_rec *r,
d75bc22ab2702fa770f6935f07107efff16a76f0wrowe proxy_server_conf *conf),(worker,
d75bc22ab2702fa770f6935f07107efff16a76f0wrowe balancer,r,conf),DECLINED)
67f62b7a48ff9eb8d9f31898dceaf9f89280a723dougmAPR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(proxy, PROXY, int, fixups,
b9b3cd7661ec354e0eee71116faa1e4afdf3fcdcmturk (request_rec *r), (r),
b9b3cd7661ec354e0eee71116faa1e4afdf3fcdcmturk OK, DECLINED)
bda7a7d57377f45932c237d5aba00b189d85c2a9ianhAPR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(proxy, PROXY, int, request_status,
e8f95a682820a599fe41b22977010636be5c2717jim (int *status, request_rec *r),
bda7a7d57377f45932c237d5aba00b189d85c2a9ianh (status, r),
bda7a7d57377f45932c237d5aba00b189d85c2a9ianh OK, DECLINED)
5f066f496cd9f20a2a701255bc67d44e7cb46daetrawickAPR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(proxy, PROXY, int, detach_backend,
5f066f496cd9f20a2a701255bc67d44e7cb46daetrawick (request_rec *r, proxy_conn_rec *backend),
5f066f496cd9f20a2a701255bc67d44e7cb46daetrawick (r, backend), OK, DECLINED)
5f066f496cd9f20a2a701255bc67d44e7cb46daetrawick