1
/* Licensed to the Apache Software Foundation (ASF) under one or more
2
* contributor license agreements. See the NOTICE file distributed with
3
* this work for additional information regarding copyright ownership.
4
* The ASF licenses this file to You under the Apache License, Version 2.0
5
* (the "License"); you may not use this file except in compliance with
6
* the License. You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
22
* @brief Proxy Extension Module for Apache
24
* @defgroup MOD_PROXY mod_proxy
25
* @ingroup APACHE_MODS
31
Also note numerous FIXMEs and CHECKMEs which should be eliminated.
33
This code is once again experimental!
37
1. Make it completely work (for FTP too)
41
Chuck Murcko <chuck@topsail.org> 02-06-01
47
#include "apr_hooks.h"
50
#include "apr_strings.h"
51
#include "apr_buckets.h"
53
#include "apr_network_io.h"
54
#include "apr_pools.h"
55
#include "apr_strings.h"
58
#include "apr_strmatch.h"
59
#include "apr_fnmatch.h"
60
#include "apr_reslist.h"
61
#define APR_WANT_STRFUNC
65
#include "http_config.h"
66
#include "ap_config.h"
67
#include "http_core.h"
68
#include "http_protocol.h"
69
#include "http_request.h"
70
#include "http_vhost.h"
71
#include "http_main.h"
73
#include "http_connection.h"
74
#include "util_filter.h"
75
#include "util_ebcdic.h"
76
#include "ap_provider.h"
78
#if APR_HAVE_NETINET_IN_H
79
#include <netinet/in.h>
81
#if APR_HAVE_ARPA_INET_H
82
#include <arpa/inet.h>
85
/* for proxy_canonenc() */
87
enc_path, enc_search, enc_user, enc_fpath, enc_parm
90
#if APR_CHARSET_EBCDIC
92
#else /*APR_CHARSET_EBCDIC*/
93
#define CRLF "\015\012"
94
#endif /*APR_CHARSET_EBCDIC*/
96
/* default Max-Forwards header setting */
97
#define DEFAULT_MAX_FORWARDS 10
99
/* static information about a remote proxy */
100
struct proxy_remote {
101
const char *scheme; /* the schemes handled by this proxy, or '*' */
102
const char *protocol; /* the scheme used to talk to this proxy */
103
const char *hostname; /* the hostname of this proxy */
104
apr_port_t port; /* the port for this proxy */
105
ap_regex_t *regexp; /* compiled regex (if any) for the remote */
106
int use_regex; /* simple boolean. True if we have a regex pattern */
114
struct dirconn_entry {
116
struct in_addr addr, mask;
117
struct apr_sockaddr_t *hostaddr;
118
int (*matcher) (struct dirconn_entry * This, request_rec *r);
121
struct noproxy_entry {
123
struct apr_sockaddr_t *addr;
126
typedef struct proxy_balancer proxy_balancer;
127
typedef struct proxy_worker proxy_worker;
128
typedef struct proxy_conn_pool proxy_conn_pool;
129
typedef struct proxy_balancer_method proxy_balancer_method;
132
apr_array_header_t *proxies;
133
apr_array_header_t *sec_proxy;
134
apr_array_header_t *aliases;
135
apr_array_header_t *noproxies;
136
apr_array_header_t *dirconn;
137
apr_array_header_t *allowed_connect_ports;
138
apr_array_header_t *workers;
139
apr_array_header_t *balancers;
140
proxy_worker *forward; /* forward proxy worker */
141
proxy_worker *reverse; /* reverse "module-driven" proxy worker */
142
const char *domain; /* domain name to use in absence of a domain name in the request */
143
int req; /* true if proxy requests are enabled */
150
} viaopt; /* how to deal with proxy Via: headers */
152
apr_size_t recv_buffer_size;
153
char recv_buffer_size_set;
154
apr_size_t io_buffer_size;
155
char io_buffer_size_set;
159
* the following setting masks the error page
160
* returned from the 'proxied server' and just
161
* forwards the status code upwards.
162
* This allows the main server (us) to generate
163
* the error page, (so it will look like a error
164
* returned from the rest of the system
167
int error_override_set;
169
int preserve_host_set;
170
apr_interval_time_t timeout;
176
} badopt; /* how to deal with bad headers */
178
/* putting new stuff on the end maximises binary back-compatibility.
179
* the strmatch_patterns are really a const just to have a
180
* case-independent strstr.
186
} proxy_status; /* Status display options */
187
char proxy_status_set;
188
apr_pool_t *pool; /* Pool used for allocating this struct */
193
const char *p; /* The path */
194
int p_is_fnmatch; /* Is this path an fnmatch candidate? */
195
ap_regex_t *r; /* Is this a regex? */
197
/* ProxyPassReverse and friends are documented as working inside
198
* <Location>. But in fact they never have done in the case of
199
* more than one <Location>, because the server_conf can't see it.
200
* We need to move them to the per-dir config.
201
* Discussed in February:
202
* http://marc.theaimsgroup.com/?l=apache-httpd-dev&m=110726027118798&w=2
204
apr_array_header_t *raliases;
205
apr_array_header_t* cookie_paths;
206
apr_array_header_t* cookie_domains;
207
const apr_strmatch_pattern* cookie_path_str;
208
const apr_strmatch_pattern* cookie_domain_str;
212
conn_rec *connection;
213
const char *hostname;
216
apr_pool_t *pool; /* Subpool used for creating socket */
217
apr_socket_t *sock; /* Connection socket */
218
apr_sockaddr_t *addr; /* Preparsed remote address info */
219
apr_uint32_t flags; /* Conection flags */
220
int close; /* Close 'this' connection */
221
int close_on_recycle; /* Close the connection when returning to pool */
222
proxy_worker *worker; /* Connection pool this connection belogns to */
223
void *data; /* per scheme connection data */
225
int inreslist; /* connection in apr_reslist? */
230
float cache_completion; /* completion percentage */
231
int content_length; /* length of the content */
234
/* Connection pool */
235
struct proxy_conn_pool {
236
apr_pool_t *pool; /* The pool used in constructor and destructor calls */
237
apr_sockaddr_t *addr; /* Preparsed remote address info */
239
apr_reslist_t *res; /* Connection resource list */
241
proxy_conn_rec *conn; /* Single connection for prefork mpm's */
244
/* woker status flags */
245
#define PROXY_WORKER_INITIALIZED 0x0001
246
#define PROXY_WORKER_IGNORE_ERRORS 0x0002
247
#define PROXY_WORKER_IN_SHUTDOWN 0x0010
248
#define PROXY_WORKER_DISABLED 0x0020
249
#define PROXY_WORKER_STOPPED 0x0040
250
#define PROXY_WORKER_IN_ERROR 0x0080
252
#define PROXY_WORKER_IS_USABLE(f) (!((f)->s->status & 0x00F0))
254
/* default worker retry timeout in seconds */
255
#define PROXY_WORKER_DEFAULT_RETRY 60
256
#define PROXY_WORKER_MAX_ROUTE_SIZ 63
258
/* Runtime worker status informations. Shared in scoreboard */
261
apr_time_t error_time; /* time of the last error */
262
int retries; /* number of retries on this worker */
263
int lbstatus; /* Current lbstatus */
264
int lbfactor; /* dynamic lbfactor */
265
apr_off_t transferred;/* Number of bytes transferred to remote */
266
apr_off_t read; /* Number of bytes read from remote */
267
apr_size_t elected; /* Number of times the worker was elected */
268
char route[PROXY_WORKER_MAX_ROUTE_SIZ+1];
269
char redirect[PROXY_WORKER_MAX_ROUTE_SIZ+1];
270
void *context; /* general purpose storage */
273
/* Worker configuration */
274
struct proxy_worker {
275
int id; /* scoreboard id */
276
apr_interval_time_t retry; /* retry interval */
277
int lbfactor; /* initial load balancing factor */
279
const char *scheme; /* scheme to use ajp|http|https */
280
const char *hostname; /* remote backend address */
281
const char *route; /* balancing route */
282
const char *redirect; /* temporary balancing redirection route */
283
int status; /* temporary worker status */
285
int min; /* Desired minimum number of available connections */
286
int smax; /* Soft maximum on the total number of connections */
287
int hmax; /* Hard maximum on the total number of connections */
288
apr_interval_time_t ttl; /* maximum amount of time in seconds a connection
289
* may be available while exceeding the soft limit */
290
apr_interval_time_t timeout; /* connection timeout */
292
apr_interval_time_t acquire; /* acquire timeout when the maximum number of connections is exceeded */
294
apr_size_t recv_buffer_size;
295
char recv_buffer_size_set;
296
apr_size_t io_buffer_size;
297
char io_buffer_size_set;
300
proxy_conn_pool *cp; /* Connection pool to use */
301
proxy_worker_stat *s; /* Shared data */
302
void *opaque; /* per scheme worker data */
303
int is_address_reusable;
305
apr_thread_mutex_t *mutex; /* Thread lock for updating address cache */
307
void *context; /* general purpose storage */
312
} flush_packets; /* control AJP flushing */
313
int flush_wait; /* poll wait time in microseconds if flush_auto */
317
* Wait 10000 microseconds to find out if more data is currently
318
* available at the backend. Just an arbitrary choose.
320
#define PROXY_FLUSH_WAIT 10000
322
struct proxy_balancer {
323
apr_array_header_t *workers; /* array of proxy_workers */
324
const char *name; /* name of the load balancer */
325
const char *sticky; /* sticky session identifier */
326
int sticky_force; /* Disable failover for sticky sessions */
327
apr_interval_time_t timeout; /* Timeout for waiting on free connection */
328
int max_attempts; /* Number of attempts before failing */
329
char max_attempts_set;
330
proxy_balancer_method *lbmethod;
332
/* XXX: Perhaps we will need the proc mutex too.
333
* Altrough we are only using arithmetic operations
334
* it may lead to a incorrect calculations.
335
* For now use only the thread mutex.
338
apr_thread_mutex_t *mutex; /* Thread lock for updating lb params */
340
void *context; /* general purpose storage */
343
struct proxy_balancer_method {
344
const char *name; /* name of the load balancer method*/
345
proxy_worker *(*finder)(proxy_balancer *balancer,
347
void *context; /* general purpose storage */
351
#define PROXY_THREAD_LOCK(x) apr_thread_mutex_lock((x)->mutex)
352
#define PROXY_THREAD_UNLOCK(x) apr_thread_mutex_unlock((x)->mutex)
354
#define PROXY_THREAD_LOCK(x) APR_SUCCESS
355
#define PROXY_THREAD_UNLOCK(x) APR_SUCCESS
360
/* Create a set of PROXY_DECLARE(type), PROXY_DECLARE_NONSTD(type) and
361
* PROXY_DECLARE_DATA with appropriate export and import tags for the platform
364
#define PROXY_DECLARE(type) type
365
#define PROXY_DECLARE_NONSTD(type) type
366
#define PROXY_DECLARE_DATA
367
#elif defined(PROXY_DECLARE_STATIC)
368
#define PROXY_DECLARE(type) type __stdcall
369
#define PROXY_DECLARE_NONSTD(type) type
370
#define PROXY_DECLARE_DATA
371
#elif defined(PROXY_DECLARE_EXPORT)
372
#define PROXY_DECLARE(type) __declspec(dllexport) type __stdcall
373
#define PROXY_DECLARE_NONSTD(type) __declspec(dllexport) type
374
#define PROXY_DECLARE_DATA __declspec(dllexport)
376
#define PROXY_DECLARE(type) __declspec(dllimport) type __stdcall
377
#define PROXY_DECLARE_NONSTD(type) __declspec(dllimport) type
378
#define PROXY_DECLARE_DATA __declspec(dllimport)
382
* Hook an optional proxy hook. Unlike static hooks, this uses a macro
383
* instead of a function.
385
#define PROXY_OPTIONAL_HOOK(name,fn,pre,succ,order) \
386
APR_OPTIONAL_HOOK(proxy,name,fn,pre,succ,order)
388
APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, scheme_handler, (request_rec *r,
389
proxy_worker *worker, proxy_server_conf *conf, char *url,
390
const char *proxyhost, apr_port_t proxyport))
391
APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, canon_handler, (request_rec *r,
394
APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, create_req, (request_rec *r, request_rec *pr))
395
APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, fixups, (request_rec *r))
399
* It will return the most suitable worker at the moment
400
* and coresponding balancer.
401
* The url is rewritten from balancer://cluster/uri to scheme://host:port/uri
402
* and then the scheme_handler is called.
405
APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, pre_request, (proxy_worker **worker,
406
proxy_balancer **balancer,
408
proxy_server_conf *conf, char **url))
411
* It is called after request for updating runtime balancer status.
413
APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, post_request, (proxy_worker *worker,
414
proxy_balancer *balancer, request_rec *r,
415
proxy_server_conf *conf))
418
* request status hook
419
* It is called after all proxy processing has been done. This gives other
420
* modules a chance to create default content on failure, for example
422
APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, request_status,
423
(int *status, request_rec *r))
427
PROXY_DECLARE(request_rec *)ap_proxy_make_fake_req(conn_rec *c, request_rec *r);
428
PROXY_DECLARE(int) ap_proxy_hex2c(const char *x);
429
PROXY_DECLARE(void) ap_proxy_c2hex(int ch, char *x);
430
PROXY_DECLARE(char *)ap_proxy_canonenc(apr_pool_t *p, const char *x, int len, enum enctype t,
431
int forcedec, int proxyreq);
432
PROXY_DECLARE(char *)ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, char **userp,
433
char **passwordp, char **hostp, apr_port_t *port);
434
PROXY_DECLARE(const char *)ap_proxy_date_canon(apr_pool_t *p, const char *x);
435
PROXY_DECLARE(int) ap_proxy_liststr(const char *list, const char *val);
436
PROXY_DECLARE(char *)ap_proxy_removestr(apr_pool_t *pool, const char *list, const char *val);
437
PROXY_DECLARE(int) ap_proxy_hex2sec(const char *x);
438
PROXY_DECLARE(void) ap_proxy_sec2hex(int t, char *y);
439
PROXY_DECLARE(int) ap_proxyerror(request_rec *r, int statuscode, const char *message);
440
PROXY_DECLARE(int) ap_proxy_is_ipaddr(struct dirconn_entry *This, apr_pool_t *p);
441
PROXY_DECLARE(int) ap_proxy_is_domainname(struct dirconn_entry *This, apr_pool_t *p);
442
PROXY_DECLARE(int) ap_proxy_is_hostname(struct dirconn_entry *This, apr_pool_t *p);
443
PROXY_DECLARE(int) ap_proxy_is_word(struct dirconn_entry *This, apr_pool_t *p);
444
PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf, apr_sockaddr_t *uri_addr);
445
PROXY_DECLARE(int) ap_proxy_pre_http_request(conn_rec *c, request_rec *r);
446
PROXY_DECLARE(apr_status_t) ap_proxy_string_read(conn_rec *c, apr_bucket_brigade *bb, char *buff, size_t bufflen, int *eos);
447
PROXY_DECLARE(void) ap_proxy_table_unmerge(apr_pool_t *p, apr_table_t *t, char *key);
448
/* DEPRECATED (will be replaced with ap_proxy_connect_backend */
449
PROXY_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 *);
450
PROXY_DECLARE(int) ap_proxy_ssl_enable(conn_rec *c);
451
PROXY_DECLARE(int) ap_proxy_ssl_disable(conn_rec *c);
452
PROXY_DECLARE(int) ap_proxy_conn_is_https(conn_rec *c);
453
PROXY_DECLARE(const char *) ap_proxy_ssl_val(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, const char *var);
455
/* Header mapping functions, and a typedef of their signature */
456
PROXY_DECLARE(const char *) ap_proxy_location_reverse_map(request_rec *r, proxy_dir_conf *conf, const char *url);
457
PROXY_DECLARE(const char *) ap_proxy_cookie_reverse_map(request_rec *r, proxy_dir_conf *conf, const char *str);
460
typedef const char *(*ap_proxy_header_reverse_map_fn)(request_rec *,
461
proxy_dir_conf *, const char *);
462
#elif defined(PROXY_DECLARE_STATIC)
463
typedef const char *(__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *,
464
proxy_dir_conf *, const char *);
465
#elif defined(PROXY_DECLARE_EXPORT)
466
typedef __declspec(dllexport) const char *
467
(__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *,
468
proxy_dir_conf *, const char *);
470
typedef __declspec(dllimport) const char *
471
(__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *,
472
proxy_dir_conf *, const char *);
476
/* Connection pool API */
478
* Get the worker from proxy configuration
479
* @param p memory pool used for finding worker
480
* @param conf current proxy server configuration
481
* @param url url to find the worker from
482
* @return proxy_worker or NULL if not found
484
PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker(apr_pool_t *p,
485
proxy_server_conf *conf,
488
* Add the worker to proxy configuration
489
* @param worker the new worker
490
* @param p memory pool to allocate worker from
491
* @param conf current proxy server configuration
492
* @param url url containing worker name
493
* @return error message or NULL if successfull
495
PROXY_DECLARE(const char *) ap_proxy_add_worker(proxy_worker **worker,
497
proxy_server_conf *conf,
502
* @param p memory pool to allocate worker from
505
PROXY_DECLARE(proxy_worker *) ap_proxy_create_worker(apr_pool_t *p);
508
* Initize the worker's shared data
509
* @param conf current proxy server configuration
510
* @param worker worker to initialize
511
* @param s current server record
512
* @param worker worker to initialize
514
PROXY_DECLARE(void) ap_proxy_initialize_worker_share(proxy_server_conf *conf,
515
proxy_worker *worker,
521
* @param worker worker to initialize
522
* @param s current server record
523
* @return APR_SUCCESS or error code
525
PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker,
528
* Get the balancer from proxy configuration
529
* @param p memory pool used for finding balancer
530
* @param conf current proxy server configuration
531
* @param url url to find the worker from. Has to have balancer:// prefix
532
* @return proxy_balancer or NULL if not found
534
PROXY_DECLARE(proxy_balancer *) ap_proxy_get_balancer(apr_pool_t *p,
535
proxy_server_conf *conf,
538
* Add the balancer to proxy configuration
539
* @param balancer the new balancer
540
* @param p memory pool to allocate balancer from
541
* @param conf current proxy server configuration
542
* @param url url containing balancer name
543
* @return error message or NULL if successfull
545
PROXY_DECLARE(const char *) ap_proxy_add_balancer(proxy_balancer **balancer,
547
proxy_server_conf *conf,
551
* Add the worker to the balancer
552
* @param pool memory pool for adding worker
553
* @param balancer balancer to add to
554
* @param balancer worker to add
555
* @note Single worker can be added to multiple balancers.
557
PROXY_DECLARE(void) ap_proxy_add_worker_to_balancer(apr_pool_t *pool,
558
proxy_balancer *balancer,
559
proxy_worker *worker);
561
* Get the most suitable worker and(or) balancer for the request
562
* @param worker worker used for processing request
563
* @param balancer balancer used for processing request
564
* @param r current request
565
* @param conf current proxy server configuration
566
* @param url request url that balancer can rewrite.
567
* @return OK or HTTP_XXX error
568
* @note It calls balancer pre_request hook if the url starts with balancer://
569
* The balancer then rewrites the url to particular worker, like http://host:port
571
PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker,
572
proxy_balancer **balancer,
574
proxy_server_conf *conf,
577
* Post request worker and balancer cleanup
578
* @param worker worker used for processing request
579
* @param balancer balancer used for processing request
580
* @param r current request
581
* @param conf current proxy server configuration
582
* @return OK or HTTP_XXX error
583
* @note When ever the pre_request is called, the post_request has to be
586
PROXY_DECLARE(int) ap_proxy_post_request(proxy_worker *worker,
587
proxy_balancer *balancer,
589
proxy_server_conf *conf);
592
* Request status function
593
* @param status status of proxy request
594
* @return OK or DECLINED
596
PROXY_DECLARE(int) ap_proxy_request_status(int *status, request_rec *r);
599
* Deternime backend hostname and port
600
* @param p memory pool used for processing
601
* @param r current request
602
* @param conf current proxy server configuration
603
* @param worker worker used for processing request
604
* @param conn proxy connection struct
605
* @param uri processed uri
606
* @param url request url
607
* @param proxyname are we connecting directly or via s proxy
608
* @param proxyport proxy host port
609
* @param server_portstr Via headers server port
610
* @param server_portstr_size size of the server_portstr buffer
611
* @return OK or HTTP_XXX error
613
PROXY_DECLARE(int) ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
614
proxy_server_conf *conf,
615
proxy_worker *worker,
616
proxy_conn_rec *conn,
619
const char *proxyname,
620
apr_port_t proxyport,
621
char *server_portstr,
622
int server_portstr_size);
624
* Mark a worker for retry
625
* @param proxy_function calling proxy scheme (http, ajp, ...)
626
* @param conf current proxy server configuration
627
* @param worker worker used for retrying
628
* @param s current server record
629
* @return OK if marked for retry, DECLINED otherwise
630
* @note Worker will be marker for retry if the time of the last retry
631
* has been ellapsed. In case there is no retry option set, defaults to
632
* number_of_retries seconds.
634
PROXY_DECLARE(int) ap_proxy_retry_worker(const char *proxy_function,
635
proxy_worker *worker,
638
* Acquire a connection from workers connection pool
639
* @param proxy_function calling proxy scheme (http, ajp, ...)
640
* @param conn acquired connection
641
* @param worker worker used for obtaining connection
642
* @param s current server record
643
* @return OK or HTTP_XXX error
644
* @note If the number of connections is exhaused the function will
645
* block untill the timeout is reached.
647
PROXY_DECLARE(int) ap_proxy_acquire_connection(const char *proxy_function,
648
proxy_conn_rec **conn,
649
proxy_worker *worker,
652
* Release a connection back to worker connection pool
653
* @param proxy_function calling proxy scheme (http, ajp, ...)
654
* @param conn acquired connection
655
* @param s current server record
656
* @return OK or HTTP_XXX error
657
* @note The connection will be closed if conn->close_on_release is set
659
PROXY_DECLARE(int) ap_proxy_release_connection(const char *proxy_function,
660
proxy_conn_rec *conn,
663
* Make a connection to the backend
664
* @param proxy_function calling proxy scheme (http, ajp, ...)
665
* @param conn acquired connection
666
* @param worker connection worker
667
* @param s current server record
668
* @return OK or HTTP_XXX error
669
* @note In case the socket already exists for conn, just check the link
672
PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
673
proxy_conn_rec *conn,
674
proxy_worker *worker,
677
* Make a connection record for backend connection
678
* @param proxy_function calling proxy scheme (http, ajp, ...)
679
* @param conn acquired connection
680
* @param c client connection record
681
* @param s current server record
682
* @return OK or HTTP_XXX error
684
PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function,
685
proxy_conn_rec *conn,
686
conn_rec *c, server_rec *s);
688
* Signal the upstream chain that the connection to the backend broke in the
689
* middle of the response. This is done by sending an error bucket with
690
* status HTTP_BAD_GATEWAY and an EOS bucket up the filter chain.
691
* @param r current request record of client request
692
* @param brigade The brigade that is sent through the output filter chain
694
PROXY_DECLARE(void) ap_proxy_backend_broke(request_rec *r,
695
apr_bucket_brigade *brigade);
698
#if MODULE_MAGIC_NUMBER_MAJOR > 20020903
699
#define PROXY_HAS_SCOREBOARD 1
701
#define PROXY_HAS_SCOREBOARD 0
704
#define PROXY_LBMETHOD "proxylbmethod"
706
/* The number of dynamic workers that can be added when reconfiguring.
707
* If this limit is reached you must stop and restart the server.
709
#define PROXY_DYNAMIC_BALANCER_LIMIT 16
711
* Calculate number of maximum number of workers in scoreboard.
712
* @return number of workers to allocate in the scoreboard
714
int ap_proxy_lb_workers(void);
717
extern module PROXY_DECLARE_DATA proxy_module;
719
extern int PROXY_DECLARE_DATA proxy_lb_workers;
721
#endif /*MOD_PROXY_H*/