mod_proxy.h revision 41727a53c70d500138e14af00afc3d49455ecced
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* Licensed to the Apache Software Foundation (ASF) under one or more
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * contributor license agreements. See the NOTICE file distributed with
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * this work for additional information regarding copyright ownership.
b99dbaab171d91e1b664397cc40e039d0c087c65fielding * The ASF licenses this file to You under the Apache License, Version 2.0
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * (the "License"); you may not use this file except in compliance with
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * the License. You may obtain a copy of the License at
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * http://www.apache.org/licenses/LICENSE-2.0
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding *
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * Unless required by applicable law or agreed to in writing, software
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * distributed under the License is distributed on an "AS IS" BASIS,
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * See the License for the specific language governing permissions and
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * limitations under the License.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#ifndef MOD_PROXY_H
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#define MOD_PROXY_H
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding/**
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * @file mod_proxy.h
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * @brief Proxy Extension Module for Apache
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding *
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * @defgroup MOD_PROXY mod_proxy
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * @ingroup APACHE_MODS
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * @{
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding */
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding/*
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding Also note numerous FIXMEs and CHECKMEs which should be eliminated.
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
64185f9824e42f21ca7b9ae6c004484215c031a7rbb This code is once again experimental!
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding Things to do:
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding 1. Make it completely work (for FTP too)
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding 2. HTTP/1.1
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding Chuck Murcko <chuck@topsail.org> 02-06-01
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding */
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#define CORE_PRIVATE
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#include "apr_hooks.h"
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#include "apr.h"
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#include "apr_lib.h"
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#include "apr_strings.h"
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#include "apr_buckets.h"
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#include "apr_md5.h"
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#include "apr_network_io.h"
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#include "apr_pools.h"
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#include "apr_strings.h"
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#include "apr_uri.h"
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#include "apr_date.h"
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#include "apr_strmatch.h"
3568de757bac0b47256647504c186d17ca272f85rbb#include "apr_fnmatch.h"
3568de757bac0b47256647504c186d17ca272f85rbb#include "apr_reslist.h"
3568de757bac0b47256647504c186d17ca272f85rbb#define APR_WANT_STRFUNC
3568de757bac0b47256647504c186d17ca272f85rbb#include "apr_want.h"
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb#include "httpd.h"
3568de757bac0b47256647504c186d17ca272f85rbb#include "http_config.h"
3568de757bac0b47256647504c186d17ca272f85rbb#include "ap_config.h"
3568de757bac0b47256647504c186d17ca272f85rbb#include "http_core.h"
3568de757bac0b47256647504c186d17ca272f85rbb#include "http_protocol.h"
3568de757bac0b47256647504c186d17ca272f85rbb#include "http_request.h"
3568de757bac0b47256647504c186d17ca272f85rbb#include "http_vhost.h"
3568de757bac0b47256647504c186d17ca272f85rbb#include "http_main.h"
3568de757bac0b47256647504c186d17ca272f85rbb#include "http_log.h"
3568de757bac0b47256647504c186d17ca272f85rbb#include "http_connection.h"
3568de757bac0b47256647504c186d17ca272f85rbb#include "util_filter.h"
3568de757bac0b47256647504c186d17ca272f85rbb#include "util_ebcdic.h"
3568de757bac0b47256647504c186d17ca272f85rbb#include "ap_provider.h"
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb#if APR_HAVE_NETINET_IN_H
3568de757bac0b47256647504c186d17ca272f85rbb#include <netinet/in.h>
3568de757bac0b47256647504c186d17ca272f85rbb#endif
3568de757bac0b47256647504c186d17ca272f85rbb#if APR_HAVE_ARPA_INET_H
3568de757bac0b47256647504c186d17ca272f85rbb#include <arpa/inet.h>
3568de757bac0b47256647504c186d17ca272f85rbb#endif
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb/* for proxy_canonenc() */
3568de757bac0b47256647504c186d17ca272f85rbbenum enctype {
3568de757bac0b47256647504c186d17ca272f85rbb enc_path, enc_search, enc_user, enc_fpath, enc_parm
3568de757bac0b47256647504c186d17ca272f85rbb};
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb#if APR_CHARSET_EBCDIC
3568de757bac0b47256647504c186d17ca272f85rbb#define CRLF "\r\n"
3568de757bac0b47256647504c186d17ca272f85rbb#else /*APR_CHARSET_EBCDIC*/
3568de757bac0b47256647504c186d17ca272f85rbb#define CRLF "\015\012"
3568de757bac0b47256647504c186d17ca272f85rbb#endif /*APR_CHARSET_EBCDIC*/
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb/* default Max-Forwards header setting */
3568de757bac0b47256647504c186d17ca272f85rbb#define DEFAULT_MAX_FORWARDS 10
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb/* static information about a remote proxy */
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstruct proxy_remote {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *scheme; /* the schemes handled by this proxy, or '*' */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *protocol; /* the scheme used to talk to this proxy */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding const char *hostname; /* the hostname of this proxy */
3568de757bac0b47256647504c186d17ca272f85rbb apr_port_t port; /* the port for this proxy */
3568de757bac0b47256647504c186d17ca272f85rbb ap_regex_t *regexp; /* compiled regex (if any) for the remote */
3568de757bac0b47256647504c186d17ca272f85rbb int use_regex; /* simple boolean. True if we have a regex pattern */
3568de757bac0b47256647504c186d17ca272f85rbb};
3568de757bac0b47256647504c186d17ca272f85rbb
db12cd62083041bf90945eeb90cc40fbd2340797trawickstruct proxy_alias {
db12cd62083041bf90945eeb90cc40fbd2340797trawick const char *real;
db12cd62083041bf90945eeb90cc40fbd2340797trawick const char *fake;
333eac96e4fb7d6901cb75e6ca7bb22b2ccb84cetrawick};
333eac96e4fb7d6901cb75e6ca7bb22b2ccb84cetrawick
3568de757bac0b47256647504c186d17ca272f85rbbstruct dirconn_entry {
3568de757bac0b47256647504c186d17ca272f85rbb char *name;
3568de757bac0b47256647504c186d17ca272f85rbb struct in_addr addr, mask;
3568de757bac0b47256647504c186d17ca272f85rbb struct apr_sockaddr_t *hostaddr;
3568de757bac0b47256647504c186d17ca272f85rbb int (*matcher) (struct dirconn_entry * This, request_rec *r);
3568de757bac0b47256647504c186d17ca272f85rbb};
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbbstruct noproxy_entry {
3568de757bac0b47256647504c186d17ca272f85rbb const char *name;
3568de757bac0b47256647504c186d17ca272f85rbb struct apr_sockaddr_t *addr;
3568de757bac0b47256647504c186d17ca272f85rbb};
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbbtypedef struct proxy_balancer proxy_balancer;
3568de757bac0b47256647504c186d17ca272f85rbbtypedef struct proxy_worker proxy_worker;
3568de757bac0b47256647504c186d17ca272f85rbbtypedef struct proxy_conn_pool proxy_conn_pool;
3568de757bac0b47256647504c186d17ca272f85rbbtypedef struct proxy_balancer_method proxy_balancer_method;
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbbtypedef struct {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_array_header_t *proxies;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_array_header_t *sec_proxy;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_array_header_t *aliases;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_array_header_t *noproxies;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_array_header_t *dirconn;
8f3ec4772d2aeb347cf40e87c77627bb784dd018rbb apr_array_header_t *allowed_connect_ports;
8f3ec4772d2aeb347cf40e87c77627bb784dd018rbb apr_array_header_t *workers;
3d96ee83babeec32482c9082c9426340cee8c44dwrowe apr_array_header_t *balancers;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding proxy_worker *forward; /* forward proxy worker */
3568de757bac0b47256647504c186d17ca272f85rbb proxy_worker *reverse; /* reverse "module-driven" proxy worker */
3568de757bac0b47256647504c186d17ca272f85rbb const char *domain; /* domain name to use in absence of a domain name in the request */
3568de757bac0b47256647504c186d17ca272f85rbb int req; /* true if proxy requests are enabled */
3568de757bac0b47256647504c186d17ca272f85rbb char req_set;
3568de757bac0b47256647504c186d17ca272f85rbb enum {
3568de757bac0b47256647504c186d17ca272f85rbb via_off,
3568de757bac0b47256647504c186d17ca272f85rbb via_on,
3568de757bac0b47256647504c186d17ca272f85rbb via_block,
3568de757bac0b47256647504c186d17ca272f85rbb via_full
3568de757bac0b47256647504c186d17ca272f85rbb } viaopt; /* how to deal with proxy Via: headers */
3568de757bac0b47256647504c186d17ca272f85rbb char viaopt_set;
3568de757bac0b47256647504c186d17ca272f85rbb apr_size_t recv_buffer_size;
3568de757bac0b47256647504c186d17ca272f85rbb char recv_buffer_size_set;
3568de757bac0b47256647504c186d17ca272f85rbb apr_size_t io_buffer_size;
3568de757bac0b47256647504c186d17ca272f85rbb char io_buffer_size_set;
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding long maxfwd;
3568de757bac0b47256647504c186d17ca272f85rbb char maxfwd_set;
3568de757bac0b47256647504c186d17ca272f85rbb /**
3568de757bac0b47256647504c186d17ca272f85rbb * the following setting masks the error page
3568de757bac0b47256647504c186d17ca272f85rbb * returned from the 'proxied server' and just
3568de757bac0b47256647504c186d17ca272f85rbb * forwards the status code upwards.
3568de757bac0b47256647504c186d17ca272f85rbb * This allows the main server (us) to generate
41634f717c623556a16b27b25d7d909a66fe20f8wrowe * the error page, (so it will look like a error
3568de757bac0b47256647504c186d17ca272f85rbb * returned from the rest of the system
3568de757bac0b47256647504c186d17ca272f85rbb */
3568de757bac0b47256647504c186d17ca272f85rbb int error_override;
3568de757bac0b47256647504c186d17ca272f85rbb int error_override_set;
3568de757bac0b47256647504c186d17ca272f85rbb int preserve_host;
3568de757bac0b47256647504c186d17ca272f85rbb int preserve_host_set;
3568de757bac0b47256647504c186d17ca272f85rbb apr_interval_time_t timeout;
3568de757bac0b47256647504c186d17ca272f85rbb char timeout_set;
3568de757bac0b47256647504c186d17ca272f85rbb enum {
3568de757bac0b47256647504c186d17ca272f85rbb bad_error,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding bad_ignore,
41634f717c623556a16b27b25d7d909a66fe20f8wrowe bad_body
3568de757bac0b47256647504c186d17ca272f85rbb } badopt; /* how to deal with bad headers */
3568de757bac0b47256647504c186d17ca272f85rbb char badopt_set;
3568de757bac0b47256647504c186d17ca272f85rbb/* putting new stuff on the end maximises binary back-compatibility.
3568de757bac0b47256647504c186d17ca272f85rbb * the strmatch_patterns are really a const just to have a
3568de757bac0b47256647504c186d17ca272f85rbb * case-independent strstr.
3568de757bac0b47256647504c186d17ca272f85rbb */
3568de757bac0b47256647504c186d17ca272f85rbb enum {
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding status_off,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding status_on,
78ae889ffe0fdfab72f56c6993b0f302cb48da55rbb status_full
3568de757bac0b47256647504c186d17ca272f85rbb } proxy_status; /* Status display options */
fc1efab92032301e317f07e1b3a00082d9d71f3frbb char proxy_status_set;
0375f54d32af9c27de0006956d9f85d01b020351stoddard apr_pool_t *pool; /* Pool used for allocating this struct */
24b534291150023e6b68eca89ddd33e475ccddc0wrowe} proxy_server_conf;
3568de757bac0b47256647504c186d17ca272f85rbb
24b534291150023e6b68eca89ddd33e475ccddc0wrowe
3568de757bac0b47256647504c186d17ca272f85rbbtypedef struct {
24b534291150023e6b68eca89ddd33e475ccddc0wrowe const char *p; /* The path */
24b534291150023e6b68eca89ddd33e475ccddc0wrowe int p_is_fnmatch; /* Is this path an fnmatch candidate? */
3568de757bac0b47256647504c186d17ca272f85rbb ap_regex_t *r; /* Is this a regex? */
fc1efab92032301e317f07e1b3a00082d9d71f3frbb
3568de757bac0b47256647504c186d17ca272f85rbb/* ProxyPassReverse and friends are documented as working inside
fc1efab92032301e317f07e1b3a00082d9d71f3frbb * <Location>. But in fact they never have done in the case of
3568de757bac0b47256647504c186d17ca272f85rbb * more than one <Location>, because the server_conf can't see it.
fc1efab92032301e317f07e1b3a00082d9d71f3frbb * We need to move them to the per-dir config.
3568de757bac0b47256647504c186d17ca272f85rbb * Discussed in February:
fc1efab92032301e317f07e1b3a00082d9d71f3frbb * http://marc.theaimsgroup.com/?l=apache-httpd-dev&m=110726027118798&w=2
3568de757bac0b47256647504c186d17ca272f85rbb */
3568de757bac0b47256647504c186d17ca272f85rbb apr_array_header_t *raliases;
3568de757bac0b47256647504c186d17ca272f85rbb apr_array_header_t* cookie_paths;
3568de757bac0b47256647504c186d17ca272f85rbb apr_array_header_t* cookie_domains;
3568de757bac0b47256647504c186d17ca272f85rbb const apr_strmatch_pattern* cookie_path_str;
3568de757bac0b47256647504c186d17ca272f85rbb const apr_strmatch_pattern* cookie_domain_str;
3568de757bac0b47256647504c186d17ca272f85rbb int interpolate_env;
3568de757bac0b47256647504c186d17ca272f85rbb} proxy_dir_conf;
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb/* if we interpolate env vars per-request, we'll need a per-request
3568de757bac0b47256647504c186d17ca272f85rbb * copy of the reverse proxy config
3568de757bac0b47256647504c186d17ca272f85rbb */
3568de757bac0b47256647504c186d17ca272f85rbbtypedef struct {
3568de757bac0b47256647504c186d17ca272f85rbb apr_array_header_t *raliases;
3568de757bac0b47256647504c186d17ca272f85rbb apr_array_header_t* cookie_paths;
3568de757bac0b47256647504c186d17ca272f85rbb apr_array_header_t* cookie_domains;
3568de757bac0b47256647504c186d17ca272f85rbb} proxy_req_conf;
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbbtypedef struct {
3568de757bac0b47256647504c186d17ca272f85rbb conn_rec *connection;
3568de757bac0b47256647504c186d17ca272f85rbb const char *hostname;
3568de757bac0b47256647504c186d17ca272f85rbb apr_port_t port;
3568de757bac0b47256647504c186d17ca272f85rbb int is_ssl;
3568de757bac0b47256647504c186d17ca272f85rbb apr_pool_t *pool; /* Subpool used for creating socket */
3568de757bac0b47256647504c186d17ca272f85rbb apr_socket_t *sock; /* Connection socket */
3568de757bac0b47256647504c186d17ca272f85rbb apr_sockaddr_t *addr; /* Preparsed remote address info */
3568de757bac0b47256647504c186d17ca272f85rbb apr_uint32_t flags; /* Conection flags */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding int close; /* Close 'this' connection */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding proxy_worker *worker; /* Connection pool this connection belogns to */
3568de757bac0b47256647504c186d17ca272f85rbb void *data; /* per scheme connection data */
239f998fbee5ac5b114b965bb76e217cce0003edstoddard#if APR_HAS_THREADS
78ae889ffe0fdfab72f56c6993b0f302cb48da55rbb int inreslist; /* connection in apr_reslist? */
3568de757bac0b47256647504c186d17ca272f85rbb#endif
3568de757bac0b47256647504c186d17ca272f85rbb} proxy_conn_rec;
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbbtypedef struct {
41634f717c623556a16b27b25d7d909a66fe20f8wrowe float cache_completion; /* completion percentage */
41634f717c623556a16b27b25d7d909a66fe20f8wrowe int content_length; /* length of the content */
41634f717c623556a16b27b25d7d909a66fe20f8wrowe} proxy_completion;
3568de757bac0b47256647504c186d17ca272f85rbb
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard/* Connection pool */
3568de757bac0b47256647504c186d17ca272f85rbbstruct proxy_conn_pool {
3568de757bac0b47256647504c186d17ca272f85rbb apr_pool_t *pool; /* The pool used in constructor and destructor calls */
3568de757bac0b47256647504c186d17ca272f85rbb apr_sockaddr_t *addr; /* Preparsed remote address info */
3568de757bac0b47256647504c186d17ca272f85rbb#if APR_HAS_THREADS
3568de757bac0b47256647504c186d17ca272f85rbb apr_reslist_t *res; /* Connection resource list */
3568de757bac0b47256647504c186d17ca272f85rbb#endif
3568de757bac0b47256647504c186d17ca272f85rbb proxy_conn_rec *conn; /* Single connection for prefork mpm's */
3568de757bac0b47256647504c186d17ca272f85rbb};
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj/* worker status flags */
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_WORKER_INITIALIZED 0x0001
42b95445a3e9b563e716503b91df6b433f9fb29agregames#define PROXY_WORKER_IGNORE_ERRORS 0x0002
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_WORKER_IN_SHUTDOWN 0x0010
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_WORKER_DISABLED 0x0020
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#define PROXY_WORKER_STOPPED 0x0040
ca53a74f4012a45cbad48e940eddf27d866981f9dougm#define PROXY_WORKER_IN_ERROR 0x0080
ca53a74f4012a45cbad48e940eddf27d866981f9dougm#define PROXY_WORKER_HOT_STANDBY 0x0100
ca53a74f4012a45cbad48e940eddf27d866981f9dougm
ca53a74f4012a45cbad48e940eddf27d866981f9dougm#define PROXY_WORKER_NOT_USABLE_BITMAP ( PROXY_WORKER_IN_SHUTDOWN | \
239f998fbee5ac5b114b965bb76e217cce0003edstoddardPROXY_WORKER_DISABLED | PROXY_WORKER_STOPPED | PROXY_WORKER_IN_ERROR )
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_WORKER_IS_INITIALIZED(f) ( (f)->s->status & \
3568de757bac0b47256647504c186d17ca272f85rbb PROXY_WORKER_INITIALIZED )
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_WORKER_IS_STANDBY(f) ( (f)->s->status & \
3568de757bac0b47256647504c186d17ca272f85rbb PROXY_WORKER_HOT_STANDBY )
3568de757bac0b47256647504c186d17ca272f85rbb
48d2edbfb84e5559b5da0f8d614ccab805cc67a8rbb#define PROXY_WORKER_IS_USABLE(f) ( !((f)->s->status & \
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding (PROXY_WORKER_NOT_USABLE_BITMAP)) && PROXY_WORKER_IS_INITIALIZED(f) )
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* default worker retry timeout in seconds */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#define PROXY_WORKER_DEFAULT_RETRY 60
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding#define PROXY_WORKER_MAX_ROUTE_SIZ 63
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb/* Runtime worker status informations. Shared in scoreboard */
3568de757bac0b47256647504c186d17ca272f85rbbtypedef struct {
3568de757bac0b47256647504c186d17ca272f85rbb int status;
3568de757bac0b47256647504c186d17ca272f85rbb apr_time_t error_time; /* time of the last error */
3568de757bac0b47256647504c186d17ca272f85rbb int retries; /* number of retries on this worker */
3568de757bac0b47256647504c186d17ca272f85rbb int lbstatus; /* Current lbstatus */
3568de757bac0b47256647504c186d17ca272f85rbb int lbfactor; /* dynamic lbfactor */
3568de757bac0b47256647504c186d17ca272f85rbb apr_off_t transferred;/* Number of bytes transferred to remote */
3568de757bac0b47256647504c186d17ca272f85rbb apr_off_t read; /* Number of bytes read from remote */
3568de757bac0b47256647504c186d17ca272f85rbb apr_size_t elected; /* Number of times the worker was elected */
3568de757bac0b47256647504c186d17ca272f85rbb char route[PROXY_WORKER_MAX_ROUTE_SIZ+1];
3568de757bac0b47256647504c186d17ca272f85rbb char redirect[PROXY_WORKER_MAX_ROUTE_SIZ+1];
3568de757bac0b47256647504c186d17ca272f85rbb void *context; /* general purpose storage */
3568de757bac0b47256647504c186d17ca272f85rbb apr_size_t busy; /* busyness factor */
3568de757bac0b47256647504c186d17ca272f85rbb int lbset; /* load balancer cluster set */
3568de757bac0b47256647504c186d17ca272f85rbb} proxy_worker_stat;
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb/* Worker configuration */
3568de757bac0b47256647504c186d17ca272f85rbbstruct proxy_worker {
3568de757bac0b47256647504c186d17ca272f85rbb int id; /* scoreboard id */
3568de757bac0b47256647504c186d17ca272f85rbb apr_interval_time_t retry; /* retry interval */
3568de757bac0b47256647504c186d17ca272f85rbb int lbfactor; /* initial load balancing factor */
3568de757bac0b47256647504c186d17ca272f85rbb const char *name;
3568de757bac0b47256647504c186d17ca272f85rbb const char *scheme; /* scheme to use ajp|http|https */
3568de757bac0b47256647504c186d17ca272f85rbb const char *hostname; /* remote backend address */
3568de757bac0b47256647504c186d17ca272f85rbb const char *route; /* balancing route */
3568de757bac0b47256647504c186d17ca272f85rbb const char *redirect; /* temporary balancing redirection route */
3568de757bac0b47256647504c186d17ca272f85rbb int status; /* temporary worker status */
3568de757bac0b47256647504c186d17ca272f85rbb apr_port_t port;
3568de757bac0b47256647504c186d17ca272f85rbb int min; /* Desired minimum number of available connections */
3568de757bac0b47256647504c186d17ca272f85rbb int smax; /* Soft maximum on the total number of connections */
3568de757bac0b47256647504c186d17ca272f85rbb int hmax; /* Hard maximum on the total number of connections */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_interval_time_t ttl; /* maximum amount of time in seconds a connection
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * may be available while exceeding the soft limit */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding apr_interval_time_t timeout; /* connection timeout */
5a58a10705b7b154b53294e0c0283d64eabdcb7fstoddard char timeout_set;
3568de757bac0b47256647504c186d17ca272f85rbb apr_interval_time_t acquire; /* acquire timeout when the maximum number of connections is exceeded */
3568de757bac0b47256647504c186d17ca272f85rbb char acquire_set;
3568de757bac0b47256647504c186d17ca272f85rbb apr_size_t recv_buffer_size;
3568de757bac0b47256647504c186d17ca272f85rbb char recv_buffer_size_set;
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj apr_size_t io_buffer_size;
3568de757bac0b47256647504c186d17ca272f85rbb char io_buffer_size_set;
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj char keepalive;
3568de757bac0b47256647504c186d17ca272f85rbb char keepalive_set;
f8b7801ea5717ef22cc0d02bffacfd5f9e48f898gregames proxy_conn_pool *cp; /* Connection pool to use */
f8b7801ea5717ef22cc0d02bffacfd5f9e48f898gregames proxy_worker_stat *s; /* Shared data */
f8b7801ea5717ef22cc0d02bffacfd5f9e48f898gregames void *opaque; /* per scheme worker data */
5a0f707b48da7703cbe6bc087f13a6735b1c742dgregames int is_address_reusable;
5a0f707b48da7703cbe6bc087f13a6735b1c742dgregames#if APR_HAS_THREADS
5a0f707b48da7703cbe6bc087f13a6735b1c742dgregames apr_thread_mutex_t *mutex; /* Thread lock for updating address cache */
5a0f707b48da7703cbe6bc087f13a6735b1c742dgregames#endif
5a0f707b48da7703cbe6bc087f13a6735b1c742dgregames void *context; /* general purpose storage */
5a0f707b48da7703cbe6bc087f13a6735b1c742dgregames enum {
5a0f707b48da7703cbe6bc087f13a6735b1c742dgregames flush_off,
5a0f707b48da7703cbe6bc087f13a6735b1c742dgregames flush_on,
3568de757bac0b47256647504c186d17ca272f85rbb flush_auto
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj } flush_packets; /* control AJP flushing */
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj int flush_wait; /* poll wait time in microseconds if flush_auto */
3568de757bac0b47256647504c186d17ca272f85rbb apr_interval_time_t ping_timeout;
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard char ping_timeout_set;
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj int lbset; /* load balancer cluster set */
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj char retry_set;
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj};
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard/*
3568de757bac0b47256647504c186d17ca272f85rbb * Wait 10000 microseconds to find out if more data is currently
3568de757bac0b47256647504c186d17ca272f85rbb * available at the backend. Just an arbitrary choose.
3568de757bac0b47256647504c186d17ca272f85rbb */
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_FLUSH_WAIT 10000
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbbstruct proxy_balancer {
3568de757bac0b47256647504c186d17ca272f85rbb apr_array_header_t *workers; /* array of proxy_workers */
3568de757bac0b47256647504c186d17ca272f85rbb const char *name; /* name of the load balancer */
3568de757bac0b47256647504c186d17ca272f85rbb const char *sticky; /* sticky session identifier */
42b95445a3e9b563e716503b91df6b433f9fb29agregames int sticky_force; /* Disable failover for sticky sessions */
3568de757bac0b47256647504c186d17ca272f85rbb apr_interval_time_t timeout; /* Timeout for waiting on free connection */
3568de757bac0b47256647504c186d17ca272f85rbb int max_attempts; /* Number of attempts before failing */
74fd6d9aeadb9022086259c5c1ae00bc0dda9c9astoddard char max_attempts_set;
0f113d7123e8bd3e3e2e9b6373461a1a773bfccatrawick proxy_balancer_method *lbmethod;
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb /* XXX: Perhaps we will need the proc mutex too.
3568de757bac0b47256647504c186d17ca272f85rbb * Altrough we are only using arithmetic operations
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe * it may lead to a incorrect calculations.
3568de757bac0b47256647504c186d17ca272f85rbb * For now use only the thread mutex.
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe */
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe#if APR_HAS_THREADS
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe apr_thread_mutex_t *mutex; /* Thread lock for updating lb params */
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe#endif
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe void *context; /* general purpose storage */
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe};
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowestruct proxy_balancer_method {
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe const char *name; /* name of the load balancer method*/
3568de757bac0b47256647504c186d17ca272f85rbb proxy_worker *(*finder)(proxy_balancer *balancer,
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe request_rec *r);
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe void *context; /* general purpose storage */
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe};
3568de757bac0b47256647504c186d17ca272f85rbb
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe#if APR_HAS_THREADS
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_THREAD_LOCK(x) apr_thread_mutex_lock((x)->mutex)
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_THREAD_UNLOCK(x) apr_thread_mutex_unlock((x)->mutex)
3568de757bac0b47256647504c186d17ca272f85rbb#else
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_THREAD_LOCK(x) APR_SUCCESS
f714f1a7002928d785e53e70349700a7f595fee3trawick#define PROXY_THREAD_UNLOCK(x) APR_SUCCESS
f714f1a7002928d785e53e70349700a7f595fee3trawick#endif
f714f1a7002928d785e53e70349700a7f595fee3trawick
3568de757bac0b47256647504c186d17ca272f85rbb/* hooks */
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard
3568de757bac0b47256647504c186d17ca272f85rbb/* Create a set of PROXY_DECLARE(type), PROXY_DECLARE_NONSTD(type) and
3568de757bac0b47256647504c186d17ca272f85rbb * PROXY_DECLARE_DATA with appropriate export and import tags for the platform
3568de757bac0b47256647504c186d17ca272f85rbb */
3568de757bac0b47256647504c186d17ca272f85rbb#if !defined(WIN32)
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_DECLARE(type) type
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_DECLARE_NONSTD(type) type
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_DECLARE_DATA
3568de757bac0b47256647504c186d17ca272f85rbb#elif defined(PROXY_DECLARE_STATIC)
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_DECLARE(type) type __stdcall
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_DECLARE_NONSTD(type) type
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_DECLARE_DATA
3568de757bac0b47256647504c186d17ca272f85rbb#elif defined(PROXY_DECLARE_EXPORT)
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_DECLARE(type) __declspec(dllexport) type __stdcall
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_DECLARE_NONSTD(type) __declspec(dllexport) type
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_DECLARE_DATA __declspec(dllexport)
3568de757bac0b47256647504c186d17ca272f85rbb#else
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_DECLARE(type) __declspec(dllimport) type __stdcall
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_DECLARE_NONSTD(type) __declspec(dllimport) type
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_DECLARE_DATA __declspec(dllimport)
3568de757bac0b47256647504c186d17ca272f85rbb#endif
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe
3568de757bac0b47256647504c186d17ca272f85rbb/**
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe * Hook an optional proxy hook. Unlike static hooks, this uses a macro
3568de757bac0b47256647504c186d17ca272f85rbb * instead of a function.
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard */
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_OPTIONAL_HOOK(name,fn,pre,succ,order) \
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe APR_OPTIONAL_HOOK(proxy,name,fn,pre,succ,order)
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbbAPR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, scheme_handler, (request_rec *r,
3568de757bac0b47256647504c186d17ca272f85rbb proxy_worker *worker, proxy_server_conf *conf, char *url,
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe const char *proxyhost, apr_port_t proxyport))
3568de757bac0b47256647504c186d17ca272f85rbbAPR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, canon_handler, (request_rec *r,
3568de757bac0b47256647504c186d17ca272f85rbb char *url))
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbbAPR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, create_req, (request_rec *r, request_rec *pr))
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wroweAPR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, fixups, (request_rec *r))
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb/**
3568de757bac0b47256647504c186d17ca272f85rbb * pre request hook.
24b534291150023e6b68eca89ddd33e475ccddc0wrowe * It will return the most suitable worker at the moment
24b534291150023e6b68eca89ddd33e475ccddc0wrowe * and coresponding balancer.
3568de757bac0b47256647504c186d17ca272f85rbb * The url is rewritten from balancer://cluster/uri to scheme://host:port/uri
3568de757bac0b47256647504c186d17ca272f85rbb * and then the scheme_handler is called.
3568de757bac0b47256647504c186d17ca272f85rbb *
3568de757bac0b47256647504c186d17ca272f85rbb */
24b534291150023e6b68eca89ddd33e475ccddc0wroweAPR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, pre_request, (proxy_worker **worker,
24b534291150023e6b68eca89ddd33e475ccddc0wrowe proxy_balancer **balancer,
3568de757bac0b47256647504c186d17ca272f85rbb request_rec *r,
3568de757bac0b47256647504c186d17ca272f85rbb proxy_server_conf *conf, char **url))
3568de757bac0b47256647504c186d17ca272f85rbb/**
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe * post request hook.
3568de757bac0b47256647504c186d17ca272f85rbb * It is called after request for updating runtime balancer status.
3568de757bac0b47256647504c186d17ca272f85rbb */
3568de757bac0b47256647504c186d17ca272f85rbbAPR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, post_request, (proxy_worker *worker,
3568de757bac0b47256647504c186d17ca272f85rbb proxy_balancer *balancer, request_rec *r,
5a0f707b48da7703cbe6bc087f13a6735b1c742dgregames proxy_server_conf *conf))
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb/**
5a0f707b48da7703cbe6bc087f13a6735b1c742dgregames * request status hook
3568de757bac0b47256647504c186d17ca272f85rbb * It is called after all proxy processing has been done. This gives other
3568de757bac0b47256647504c186d17ca272f85rbb * modules a chance to create default content on failure, for example
3568de757bac0b47256647504c186d17ca272f85rbb */
3568de757bac0b47256647504c186d17ca272f85rbbAPR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, request_status,
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe (int *status, request_rec *r))
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb/* proxy_util.c */
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbbPROXY_DECLARE(request_rec *)ap_proxy_make_fake_req(conn_rec *c, request_rec *r);
3568de757bac0b47256647504c186d17ca272f85rbbPROXY_DECLARE(int) ap_proxy_hex2c(const char *x);
3568de757bac0b47256647504c186d17ca272f85rbbPROXY_DECLARE(void) ap_proxy_c2hex(int ch, char *x);
3568de757bac0b47256647504c186d17ca272f85rbbPROXY_DECLARE(char *)ap_proxy_canonenc(apr_pool_t *p, const char *x, int len, enum enctype t,
3568de757bac0b47256647504c186d17ca272f85rbb int forcedec, int proxyreq);
3568de757bac0b47256647504c186d17ca272f85rbbPROXY_DECLARE(char *)ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, char **userp,
beb70d51e435dc36c56a72b6cd83556c04db9283wrowe char **passwordp, char **hostp, apr_port_t *port);
fe6baec9bbcd36f932b71a355120cd7b5a685d6cfieldingPROXY_DECLARE(const char *)ap_proxy_date_canon(apr_pool_t *p, const char *x);
3568de757bac0b47256647504c186d17ca272f85rbbPROXY_DECLARE(int) ap_proxy_liststr(const char *list, const char *val);
3568de757bac0b47256647504c186d17ca272f85rbbPROXY_DECLARE(char *)ap_proxy_removestr(apr_pool_t *pool, const char *list, const char *val);
3568de757bac0b47256647504c186d17ca272f85rbbPROXY_DECLARE(int) ap_proxy_hex2sec(const char *x);
3568de757bac0b47256647504c186d17ca272f85rbbPROXY_DECLARE(void) ap_proxy_sec2hex(int t, char *y);
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowePROXY_DECLARE(int) ap_proxyerror(request_rec *r, int statuscode, const char *message);
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowePROXY_DECLARE(int) ap_proxy_is_ipaddr(struct dirconn_entry *This, apr_pool_t *p);
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowePROXY_DECLARE(int) ap_proxy_is_domainname(struct dirconn_entry *This, apr_pool_t *p);
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowePROXY_DECLARE(int) ap_proxy_is_hostname(struct dirconn_entry *This, apr_pool_t *p);
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowePROXY_DECLARE(int) ap_proxy_is_word(struct dirconn_entry *This, apr_pool_t *p);
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowePROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf, apr_sockaddr_t *uri_addr);
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowePROXY_DECLARE(int) ap_proxy_pre_http_request(conn_rec *c, request_rec *r);
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowePROXY_DECLARE(apr_status_t) ap_proxy_string_read(conn_rec *c, apr_bucket_brigade *bb, char *buff, size_t bufflen, int *eos);
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowePROXY_DECLARE(void) ap_proxy_table_unmerge(apr_pool_t *p, apr_table_t *t, char *key);
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe/* DEPRECATED (will be replaced with ap_proxy_connect_backend */
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowePROXY_DECLARE(int) ap_proxy_connect_to_backend(apr_socket_t **, const char *, apr_sockaddr_t *, const char *, proxy_server_conf *, server_rec *, apr_pool_t *);
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowePROXY_DECLARE(int) ap_proxy_ssl_enable(conn_rec *c);
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowePROXY_DECLARE(int) ap_proxy_ssl_disable(conn_rec *c);
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowePROXY_DECLARE(int) ap_proxy_conn_is_https(conn_rec *c);
3568de757bac0b47256647504c186d17ca272f85rbbPROXY_DECLARE(const char *) ap_proxy_ssl_val(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, const char *var);
8e9734d1a4af74c141e2a0f880bb51bb061fa03atrawick
8e9734d1a4af74c141e2a0f880bb51bb061fa03atrawick/* Header mapping functions, and a typedef of their signature */
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowePROXY_DECLARE(const char *) ap_proxy_location_reverse_map(request_rec *r, proxy_dir_conf *conf, const char *url);
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowePROXY_DECLARE(const char *) ap_proxy_cookie_reverse_map(request_rec *r, proxy_dir_conf *conf, const char *str);
3568de757bac0b47256647504c186d17ca272f85rbb
8e9734d1a4af74c141e2a0f880bb51bb061fa03atrawick#if !defined(WIN32)
3568de757bac0b47256647504c186d17ca272f85rbbtypedef const char *(*ap_proxy_header_reverse_map_fn)(request_rec *,
3568de757bac0b47256647504c186d17ca272f85rbb proxy_dir_conf *, const char *);
3568de757bac0b47256647504c186d17ca272f85rbb#elif defined(PROXY_DECLARE_STATIC)
0f113d7123e8bd3e3e2e9b6373461a1a773bfccatrawicktypedef const char *(__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *,
0f113d7123e8bd3e3e2e9b6373461a1a773bfccatrawick proxy_dir_conf *, const char *);
0f113d7123e8bd3e3e2e9b6373461a1a773bfccatrawick#elif defined(PROXY_DECLARE_EXPORT)
8e9734d1a4af74c141e2a0f880bb51bb061fa03atrawicktypedef __declspec(dllexport) const char *
3568de757bac0b47256647504c186d17ca272f85rbb (__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *,
8e9734d1a4af74c141e2a0f880bb51bb061fa03atrawick proxy_dir_conf *, const char *);
3568de757bac0b47256647504c186d17ca272f85rbb#else
3568de757bac0b47256647504c186d17ca272f85rbbtypedef __declspec(dllimport) const char *
3568de757bac0b47256647504c186d17ca272f85rbb (__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *,
3568de757bac0b47256647504c186d17ca272f85rbb proxy_dir_conf *, const char *);
3568de757bac0b47256647504c186d17ca272f85rbb#endif
3568de757bac0b47256647504c186d17ca272f85rbb
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe
3568de757bac0b47256647504c186d17ca272f85rbb/* Connection pool API */
3568de757bac0b47256647504c186d17ca272f85rbb/**
3568de757bac0b47256647504c186d17ca272f85rbb * Get the worker from proxy configuration
3568de757bac0b47256647504c186d17ca272f85rbb * @param p memory pool used for finding worker
3568de757bac0b47256647504c186d17ca272f85rbb * @param conf current proxy server configuration
3568de757bac0b47256647504c186d17ca272f85rbb * @param url url to find the worker from
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe * @return proxy_worker or NULL if not found
3568de757bac0b47256647504c186d17ca272f85rbb */
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddardPROXY_DECLARE(proxy_worker *) ap_proxy_get_worker(apr_pool_t *p,
3568de757bac0b47256647504c186d17ca272f85rbb proxy_server_conf *conf,
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe const char *url);
3568de757bac0b47256647504c186d17ca272f85rbb/**
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe * Add the worker to proxy configuration
3568de757bac0b47256647504c186d17ca272f85rbb * @param worker the new worker
3568de757bac0b47256647504c186d17ca272f85rbb * @param p memory pool to allocate worker from
3568de757bac0b47256647504c186d17ca272f85rbb * @param conf current proxy server configuration
3568de757bac0b47256647504c186d17ca272f85rbb * @param url url containing worker name
3568de757bac0b47256647504c186d17ca272f85rbb * @return error message or NULL if successfull
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj */
3568de757bac0b47256647504c186d17ca272f85rbbPROXY_DECLARE(const char *) ap_proxy_add_worker(proxy_worker **worker,
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj apr_pool_t *p,
3568de757bac0b47256647504c186d17ca272f85rbb proxy_server_conf *conf,
3568de757bac0b47256647504c186d17ca272f85rbb const char *url);
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb/**
3568de757bac0b47256647504c186d17ca272f85rbb * Create new worker
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard * @param p memory pool to allocate worker from
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj * @return new worker
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard */
3568de757bac0b47256647504c186d17ca272f85rbbPROXY_DECLARE(proxy_worker *) ap_proxy_create_worker(apr_pool_t *p);
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard
3568de757bac0b47256647504c186d17ca272f85rbb/**
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj * Initize the worker's shared data
3568de757bac0b47256647504c186d17ca272f85rbb * @param conf current proxy server configuration
3568de757bac0b47256647504c186d17ca272f85rbb * @param worker worker to initialize
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard * @param s current server record
3568de757bac0b47256647504c186d17ca272f85rbb * @param worker worker to initialize
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj */
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpjPROXY_DECLARE(void) ap_proxy_initialize_worker_share(proxy_server_conf *conf,
3568de757bac0b47256647504c186d17ca272f85rbb proxy_worker *worker,
3568de757bac0b47256647504c186d17ca272f85rbb server_rec *s);
24b534291150023e6b68eca89ddd33e475ccddc0wrowe
24b534291150023e6b68eca89ddd33e475ccddc0wrowe
24b534291150023e6b68eca89ddd33e475ccddc0wrowe/**
3568de757bac0b47256647504c186d17ca272f85rbb * Initize the worker
3568de757bac0b47256647504c186d17ca272f85rbb * @param worker worker to initialize
3568de757bac0b47256647504c186d17ca272f85rbb * @param s current server record
3568de757bac0b47256647504c186d17ca272f85rbb * @return APR_SUCCESS or error code
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj */
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpjPROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker,
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj server_rec *s);
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj/**
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj * Get the balancer from proxy configuration
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj * @param p memory pool used for finding balancer
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj * @param conf current proxy server configuration
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj * @param url url to find the worker from. Has to have balancer:// prefix
3568de757bac0b47256647504c186d17ca272f85rbb * @return proxy_balancer or NULL if not found
3568de757bac0b47256647504c186d17ca272f85rbb */
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpjPROXY_DECLARE(proxy_balancer *) ap_proxy_get_balancer(apr_pool_t *p,
3568de757bac0b47256647504c186d17ca272f85rbb proxy_server_conf *conf,
3568de757bac0b47256647504c186d17ca272f85rbb const char *url);
3568de757bac0b47256647504c186d17ca272f85rbb/**
3568de757bac0b47256647504c186d17ca272f85rbb * Add the balancer to proxy configuration
3568de757bac0b47256647504c186d17ca272f85rbb * @param balancer the new balancer
3568de757bac0b47256647504c186d17ca272f85rbb * @param p memory pool to allocate balancer from
0f113d7123e8bd3e3e2e9b6373461a1a773bfccatrawick * @param conf current proxy server configuration
0f113d7123e8bd3e3e2e9b6373461a1a773bfccatrawick * @param url url containing balancer name
3568de757bac0b47256647504c186d17ca272f85rbb * @return error message or NULL if successfull
0f113d7123e8bd3e3e2e9b6373461a1a773bfccatrawick */
3568de757bac0b47256647504c186d17ca272f85rbbPROXY_DECLARE(const char *) ap_proxy_add_balancer(proxy_balancer **balancer,
3568de757bac0b47256647504c186d17ca272f85rbb apr_pool_t *p,
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj proxy_server_conf *conf,
3568de757bac0b47256647504c186d17ca272f85rbb const char *url);
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb/**
3568de757bac0b47256647504c186d17ca272f85rbb * Add the worker to the balancer
3568de757bac0b47256647504c186d17ca272f85rbb * @param pool memory pool for adding worker
3568de757bac0b47256647504c186d17ca272f85rbb * @param balancer balancer to add to
3568de757bac0b47256647504c186d17ca272f85rbb * @param balancer worker to add
3568de757bac0b47256647504c186d17ca272f85rbb * @note Single worker can be added to multiple balancers.
3568de757bac0b47256647504c186d17ca272f85rbb */
3568de757bac0b47256647504c186d17ca272f85rbbPROXY_DECLARE(void) ap_proxy_add_worker_to_balancer(apr_pool_t *pool,
3568de757bac0b47256647504c186d17ca272f85rbb proxy_balancer *balancer,
3568de757bac0b47256647504c186d17ca272f85rbb proxy_worker *worker);
3568de757bac0b47256647504c186d17ca272f85rbb/**
3568de757bac0b47256647504c186d17ca272f85rbb * Get the most suitable worker and(or) balancer for the request
3568de757bac0b47256647504c186d17ca272f85rbb * @param worker worker used for processing request
3568de757bac0b47256647504c186d17ca272f85rbb * @param balancer balancer used for processing request
3568de757bac0b47256647504c186d17ca272f85rbb * @param r current request
3568de757bac0b47256647504c186d17ca272f85rbb * @param conf current proxy server configuration
3568de757bac0b47256647504c186d17ca272f85rbb * @param url request url that balancer can rewrite.
3568de757bac0b47256647504c186d17ca272f85rbb * @return OK or HTTP_XXX error
3568de757bac0b47256647504c186d17ca272f85rbb * @note It calls balancer pre_request hook if the url starts with balancer://
ec020ca384efb30d501a5af796ddc3bb237d7b8fgregames * The balancer then rewrites the url to particular worker, like http://host:port
ec020ca384efb30d501a5af796ddc3bb237d7b8fgregames */
ec020ca384efb30d501a5af796ddc3bb237d7b8fgregamesPROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker,
3568de757bac0b47256647504c186d17ca272f85rbb proxy_balancer **balancer,
3568de757bac0b47256647504c186d17ca272f85rbb request_rec *r,
3568de757bac0b47256647504c186d17ca272f85rbb proxy_server_conf *conf,
3568de757bac0b47256647504c186d17ca272f85rbb char **url);
3568de757bac0b47256647504c186d17ca272f85rbb/**
3568de757bac0b47256647504c186d17ca272f85rbb * Post request worker and balancer cleanup
5f4e89b7e376d596fbf5167314a3781fd0889064trawick * @param worker worker used for processing request
5f4e89b7e376d596fbf5167314a3781fd0889064trawick * @param balancer balancer used for processing request
5f4e89b7e376d596fbf5167314a3781fd0889064trawick * @param r current request
3568de757bac0b47256647504c186d17ca272f85rbb * @param conf current proxy server configuration
3568de757bac0b47256647504c186d17ca272f85rbb * @return OK or HTTP_XXX error
3568de757bac0b47256647504c186d17ca272f85rbb * @note When ever the pre_request is called, the post_request has to be
3568de757bac0b47256647504c186d17ca272f85rbb * called too.
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard */
3568de757bac0b47256647504c186d17ca272f85rbbPROXY_DECLARE(int) ap_proxy_post_request(proxy_worker *worker,
3568de757bac0b47256647504c186d17ca272f85rbb proxy_balancer *balancer,
3568de757bac0b47256647504c186d17ca272f85rbb request_rec *r,
3568de757bac0b47256647504c186d17ca272f85rbb proxy_server_conf *conf);
0f113d7123e8bd3e3e2e9b6373461a1a773bfccatrawick
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj/**
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj * Request status function
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj * @param status status of proxy request
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj * @return OK or DECLINED
3568de757bac0b47256647504c186d17ca272f85rbb */
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj PROXY_DECLARE(int) ap_proxy_request_status(int *status, request_rec *r);
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb/**
3568de757bac0b47256647504c186d17ca272f85rbb * Deternime backend hostname and port
3568de757bac0b47256647504c186d17ca272f85rbb * @param p memory pool used for processing
3568de757bac0b47256647504c186d17ca272f85rbb * @param r current request
3568de757bac0b47256647504c186d17ca272f85rbb * @param conf current proxy server configuration
3568de757bac0b47256647504c186d17ca272f85rbb * @param worker worker used for processing request
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe * @param conn proxy connection struct
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj * @param uri processed uri
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj * @param url request url
3568de757bac0b47256647504c186d17ca272f85rbb * @param proxyname are we connecting directly or via s proxy
3568de757bac0b47256647504c186d17ca272f85rbb * @param proxyport proxy host port
3568de757bac0b47256647504c186d17ca272f85rbb * @param server_portstr Via headers server port
3568de757bac0b47256647504c186d17ca272f85rbb * @param server_portstr_size size of the server_portstr buffer
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj * @return OK or HTTP_XXX error
3568de757bac0b47256647504c186d17ca272f85rbb */
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowePROXY_DECLARE(int) ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
3568de757bac0b47256647504c186d17ca272f85rbb proxy_server_conf *conf,
3568de757bac0b47256647504c186d17ca272f85rbb proxy_worker *worker,
3568de757bac0b47256647504c186d17ca272f85rbb proxy_conn_rec *conn,
3568de757bac0b47256647504c186d17ca272f85rbb apr_uri_t *uri,
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe char **url,
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe const char *proxyname,
3568de757bac0b47256647504c186d17ca272f85rbb apr_port_t proxyport,
0f113d7123e8bd3e3e2e9b6373461a1a773bfccatrawick char *server_portstr,
3568de757bac0b47256647504c186d17ca272f85rbb int server_portstr_size);
3568de757bac0b47256647504c186d17ca272f85rbb/**
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj * Mark a worker for retry
3568de757bac0b47256647504c186d17ca272f85rbb * @param proxy_function calling proxy scheme (http, ajp, ...)
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe * @param conf current proxy server configuration
3568de757bac0b47256647504c186d17ca272f85rbb * @param worker worker used for retrying
3568de757bac0b47256647504c186d17ca272f85rbb * @param s current server record
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe * @return OK if marked for retry, DECLINED otherwise
3568de757bac0b47256647504c186d17ca272f85rbb * @note Worker will be marker for retry if the time of the last retry
3568de757bac0b47256647504c186d17ca272f85rbb * has been ellapsed. In case there is no retry option set, defaults to
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe * number_of_retries seconds.
3568de757bac0b47256647504c186d17ca272f85rbb */
3568de757bac0b47256647504c186d17ca272f85rbbPROXY_DECLARE(int) ap_proxy_retry_worker(const char *proxy_function,
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe proxy_worker *worker,
3568de757bac0b47256647504c186d17ca272f85rbb server_rec *s);
3568de757bac0b47256647504c186d17ca272f85rbb/**
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe * Acquire a connection from workers connection pool
3568de757bac0b47256647504c186d17ca272f85rbb * @param proxy_function calling proxy scheme (http, ajp, ...)
3568de757bac0b47256647504c186d17ca272f85rbb * @param conn acquired connection
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe * @param worker worker used for obtaining connection
3568de757bac0b47256647504c186d17ca272f85rbb * @param s current server record
3568de757bac0b47256647504c186d17ca272f85rbb * @return OK or HTTP_XXX error
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe * @note If the number of connections is exhaused the function will
3568de757bac0b47256647504c186d17ca272f85rbb * block untill the timeout is reached.
ec020ca384efb30d501a5af796ddc3bb237d7b8fgregames */
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowePROXY_DECLARE(int) ap_proxy_acquire_connection(const char *proxy_function,
ec020ca384efb30d501a5af796ddc3bb237d7b8fgregames proxy_conn_rec **conn,
3568de757bac0b47256647504c186d17ca272f85rbb proxy_worker *worker,
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe server_rec *s);
3568de757bac0b47256647504c186d17ca272f85rbb/**
3568de757bac0b47256647504c186d17ca272f85rbb * Release a connection back to worker connection pool
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe * @param proxy_function calling proxy scheme (http, ajp, ...)
3568de757bac0b47256647504c186d17ca272f85rbb * @param conn acquired connection
5f4e89b7e376d596fbf5167314a3781fd0889064trawick * @param s current server record
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe * @return OK or HTTP_XXX error
5f4e89b7e376d596fbf5167314a3781fd0889064trawick * @note The connection will be closed if conn->close_on_release is set
3568de757bac0b47256647504c186d17ca272f85rbb */
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowePROXY_DECLARE(int) ap_proxy_release_connection(const char *proxy_function,
3568de757bac0b47256647504c186d17ca272f85rbb proxy_conn_rec *conn,
3568de757bac0b47256647504c186d17ca272f85rbb server_rec *s);
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard/**
3568de757bac0b47256647504c186d17ca272f85rbb * Make a connection to the backend
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe * @param proxy_function calling proxy scheme (http, ajp, ...)
3568de757bac0b47256647504c186d17ca272f85rbb * @param conn acquired connection
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe * @param worker connection worker
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj * @param s current server record
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj * @return OK or HTTP_XXX error
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj * @note In case the socket already exists for conn, just check the link
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj * status.
3568de757bac0b47256647504c186d17ca272f85rbb */
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpjPROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
3568de757bac0b47256647504c186d17ca272f85rbb proxy_conn_rec *conn,
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe proxy_worker *worker,
3568de757bac0b47256647504c186d17ca272f85rbb server_rec *s);
3568de757bac0b47256647504c186d17ca272f85rbb/**
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj * Make a connection record for backend connection
3568de757bac0b47256647504c186d17ca272f85rbb * @param proxy_function calling proxy scheme (http, ajp, ...)
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe * @param conn acquired connection
3568de757bac0b47256647504c186d17ca272f85rbb * @param c client connection record
3568de757bac0b47256647504c186d17ca272f85rbb * @param s current server record
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe * @return OK or HTTP_XXX error
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj */
3568de757bac0b47256647504c186d17ca272f85rbbPROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function,
3568de757bac0b47256647504c186d17ca272f85rbb proxy_conn_rec *conn,
aa616c3b5a4aa59867472cddf7d8e63693808f0erederpj conn_rec *c, server_rec *s);
3568de757bac0b47256647504c186d17ca272f85rbb/**
3568de757bac0b47256647504c186d17ca272f85rbb * Signal the upstream chain that the connection to the backend broke in the
3568de757bac0b47256647504c186d17ca272f85rbb * middle of the response. This is done by sending an error bucket with
3568de757bac0b47256647504c186d17ca272f85rbb * status HTTP_BAD_GATEWAY and an EOS bucket up the filter chain.
3568de757bac0b47256647504c186d17ca272f85rbb * @param r current request record of client request
3568de757bac0b47256647504c186d17ca272f85rbb * @param brigade The brigade that is sent through the output filter chain
3568de757bac0b47256647504c186d17ca272f85rbb */
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddardPROXY_DECLARE(void) ap_proxy_backend_broke(request_rec *r,
3568de757bac0b47256647504c186d17ca272f85rbb apr_bucket_brigade *brigade);
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe
3568de757bac0b47256647504c186d17ca272f85rbb#define PROXY_LBMETHOD "proxylbmethod"
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe/* The number of dynamic workers that can be added when reconfiguring.
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe * If this limit is reached you must stop and restart the server.
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe */
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe#define PROXY_DYNAMIC_BALANCER_LIMIT 16
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe/**
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe * Calculate number of maximum number of workers in scoreboard.
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe * @return number of workers to allocate in the scoreboard
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe */
3568de757bac0b47256647504c186d17ca272f85rbbint ap_proxy_lb_workers(void);
3568de757bac0b47256647504c186d17ca272f85rbb
3568de757bac0b47256647504c186d17ca272f85rbb/* For proxy_util */
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wroweextern module PROXY_DECLARE_DATA proxy_module;
3568de757bac0b47256647504c186d17ca272f85rbb
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wroweextern int PROXY_DECLARE_DATA proxy_lb_workers;
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe#endif /*MOD_PROXY_H*/
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe/** @} */
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe