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 /* if we interpolate env vars per-request, we'll need a per-request
213 * copy of the reverse proxy config
216 apr_array_header_t *raliases;
217 apr_array_header_t* cookie_paths;
218 apr_array_header_t* cookie_domains;
222 conn_rec *connection;
223 const char *hostname;
226 apr_pool_t *pool; /* Subpool used for creating socket */
227 apr_socket_t *sock; /* Connection socket */
228 apr_sockaddr_t *addr; /* Preparsed remote address info */
229 apr_uint32_t flags; /* Conection flags */
230 int close; /* Close 'this' connection */
231 proxy_worker *worker; /* Connection pool this connection belogns to */
232 void *data; /* per scheme connection data */
234 int inreslist; /* connection in apr_reslist? */
239 float cache_completion; /* completion percentage */
240 int content_length; /* length of the content */
243 /* Connection pool */
244 struct proxy_conn_pool {
245 apr_pool_t *pool; /* The pool used in constructor and destructor calls */
246 apr_sockaddr_t *addr; /* Preparsed remote address info */
248 apr_reslist_t *res; /* Connection resource list */
250 proxy_conn_rec *conn; /* Single connection for prefork mpm's */
253 /* worker status flags */
254 #define PROXY_WORKER_INITIALIZED 0x0001
255 #define PROXY_WORKER_IGNORE_ERRORS 0x0002
256 #define PROXY_WORKER_IN_SHUTDOWN 0x0010
257 #define PROXY_WORKER_DISABLED 0x0020
258 #define PROXY_WORKER_STOPPED 0x0040
259 #define PROXY_WORKER_IN_ERROR 0x0080
260 #define PROXY_WORKER_HOT_STANDBY 0x0100
262 #define PROXY_WORKER_NOT_USABLE_BITMAP ( PROXY_WORKER_IN_SHUTDOWN | \
263 PROXY_WORKER_DISABLED | PROXY_WORKER_STOPPED | PROXY_WORKER_IN_ERROR )
265 #define PROXY_WORKER_IS_INITIALIZED(f) ( (f)->s->status & \
266 PROXY_WORKER_INITIALIZED )
268 #define PROXY_WORKER_IS_STANDBY(f) ( (f)->s->status & \
269 PROXY_WORKER_HOT_STANDBY )
271 #define PROXY_WORKER_IS_USABLE(f) ( !((f)->s->status & \
272 (PROXY_WORKER_NOT_USABLE_BITMAP)) && PROXY_WORKER_IS_INITIALIZED(f) )
274 /* default worker retry timeout in seconds */
275 #define PROXY_WORKER_DEFAULT_RETRY 60
276 #define PROXY_WORKER_MAX_ROUTE_SIZ 63
278 /* Runtime worker status informations. Shared in scoreboard */
281 apr_time_t error_time; /* time of the last error */
282 int retries; /* number of retries on this worker */
283 int lbstatus; /* Current lbstatus */
284 int lbfactor; /* dynamic lbfactor */
285 apr_off_t transferred;/* Number of bytes transferred to remote */
286 apr_off_t read; /* Number of bytes read from remote */
287 apr_size_t elected; /* Number of times the worker was elected */
288 char route[PROXY_WORKER_MAX_ROUTE_SIZ+1];
289 char redirect[PROXY_WORKER_MAX_ROUTE_SIZ+1];
290 void *context; /* general purpose storage */
291 apr_size_t busy; /* busyness factor */
292 int lbset; /* load balancer cluster set */
295 /* Worker configuration */
296 struct proxy_worker {
297 int id; /* scoreboard id */
298 apr_interval_time_t retry; /* retry interval */
299 int lbfactor; /* initial load balancing factor */
301 const char *scheme; /* scheme to use ajp|http|https */
302 const char *hostname; /* remote backend address */
303 const char *route; /* balancing route */
304 const char *redirect; /* temporary balancing redirection route */
305 int status; /* temporary worker status */
307 int min; /* Desired minimum number of available connections */
308 int smax; /* Soft maximum on the total number of connections */
309 int hmax; /* Hard maximum on the total number of connections */
310 apr_interval_time_t ttl; /* maximum amount of time in seconds a connection
311 * may be available while exceeding the soft limit */
312 apr_interval_time_t timeout; /* connection timeout */
314 apr_interval_time_t acquire; /* acquire timeout when the maximum number of connections is exceeded */
316 apr_size_t recv_buffer_size;
317 char recv_buffer_size_set;
318 apr_size_t io_buffer_size;
319 char io_buffer_size_set;
322 proxy_conn_pool *cp; /* Connection pool to use */
323 proxy_worker_stat *s; /* Shared data */
324 void *opaque; /* per scheme worker data */
325 int is_address_reusable;
327 apr_thread_mutex_t *mutex; /* Thread lock for updating address cache */
329 void *context; /* general purpose storage */
334 } flush_packets; /* control AJP flushing */
335 int flush_wait; /* poll wait time in microseconds if flush_auto */
336 apr_interval_time_t ping_timeout;
337 char ping_timeout_set;
338 int lbset; /* load balancer cluster set */
343 * Wait 10000 microseconds to find out if more data is currently
344 * available at the backend. Just an arbitrary choose.
346 #define PROXY_FLUSH_WAIT 10000
348 struct proxy_balancer {
349 apr_array_header_t *workers; /* array of proxy_workers */
350 const char *name; /* name of the load balancer */
351 const char *sticky; /* sticky session identifier */
352 int sticky_force; /* Disable failover for sticky sessions */
353 apr_interval_time_t timeout; /* Timeout for waiting on free connection */
354 int max_attempts; /* Number of attempts before failing */
355 char max_attempts_set;
356 proxy_balancer_method *lbmethod;
358 /* XXX: Perhaps we will need the proc mutex too.
359 * Altrough we are only using arithmetic operations
360 * it may lead to a incorrect calculations.
361 * For now use only the thread mutex.
364 apr_thread_mutex_t *mutex; /* Thread lock for updating lb params */
366 void *context; /* general purpose storage */
369 struct proxy_balancer_method {
370 const char *name; /* name of the load balancer method*/
371 proxy_worker *(*finder)(proxy_balancer *balancer,
373 void *context; /* general purpose storage */
377 #define PROXY_THREAD_LOCK(x) apr_thread_mutex_lock((x)->mutex)
378 #define PROXY_THREAD_UNLOCK(x) apr_thread_mutex_unlock((x)->mutex)
380 #define PROXY_THREAD_LOCK(x) APR_SUCCESS
381 #define PROXY_THREAD_UNLOCK(x) APR_SUCCESS
386 /* Create a set of PROXY_DECLARE(type), PROXY_DECLARE_NONSTD(type) and
387 * PROXY_DECLARE_DATA with appropriate export and import tags for the platform
390 #define PROXY_DECLARE(type) type
391 #define PROXY_DECLARE_NONSTD(type) type
392 #define PROXY_DECLARE_DATA
393 #elif defined(PROXY_DECLARE_STATIC)
394 #define PROXY_DECLARE(type) type __stdcall
395 #define PROXY_DECLARE_NONSTD(type) type
396 #define PROXY_DECLARE_DATA
397 #elif defined(PROXY_DECLARE_EXPORT)
398 #define PROXY_DECLARE(type) __declspec(dllexport) type __stdcall
399 #define PROXY_DECLARE_NONSTD(type) __declspec(dllexport) type
400 #define PROXY_DECLARE_DATA __declspec(dllexport)
402 #define PROXY_DECLARE(type) __declspec(dllimport) type __stdcall
403 #define PROXY_DECLARE_NONSTD(type) __declspec(dllimport) type
404 #define PROXY_DECLARE_DATA __declspec(dllimport)
408 * Hook an optional proxy hook. Unlike static hooks, this uses a macro
409 * instead of a function.
411 #define PROXY_OPTIONAL_HOOK(name,fn,pre,succ,order) \
412 APR_OPTIONAL_HOOK(proxy,name,fn,pre,succ,order)
414 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, scheme_handler, (request_rec *r,
415 proxy_worker *worker, proxy_server_conf *conf, char *url,
416 const char *proxyhost, apr_port_t proxyport))
417 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, canon_handler, (request_rec *r,
420 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, create_req, (request_rec *r, request_rec *pr))
421 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, fixups, (request_rec *r))
425 * It will return the most suitable worker at the moment
426 * and coresponding balancer.
427 * The url is rewritten from balancer://cluster/uri to scheme://host:port/uri
428 * and then the scheme_handler is called.
431 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, pre_request, (proxy_worker **worker,
432 proxy_balancer **balancer,
434 proxy_server_conf *conf, char **url))
437 * It is called after request for updating runtime balancer status.
439 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, post_request, (proxy_worker *worker,
440 proxy_balancer *balancer, request_rec *r,
441 proxy_server_conf *conf))
444 * request status hook
445 * It is called after all proxy processing has been done. This gives other
446 * modules a chance to create default content on failure, for example
448 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, request_status,
449 (int *status, request_rec *r))
453 PROXY_DECLARE(request_rec *)ap_proxy_make_fake_req(conn_rec *c, request_rec *r);
454 PROXY_DECLARE(int) ap_proxy_hex2c(const char *x);
455 PROXY_DECLARE(void) ap_proxy_c2hex(int ch, char *x);
456 PROXY_DECLARE(char *)ap_proxy_canonenc(apr_pool_t *p, const char *x, int len, enum enctype t,
457 int forcedec, int proxyreq);
458 PROXY_DECLARE(char *)ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, char **userp,
459 char **passwordp, char **hostp, apr_port_t *port);
460 PROXY_DECLARE(const char *)ap_proxy_date_canon(apr_pool_t *p, const char *x);
461 PROXY_DECLARE(int) ap_proxy_liststr(const char *list, const char *val);
462 PROXY_DECLARE(char *)ap_proxy_removestr(apr_pool_t *pool, const char *list, const char *val);
463 PROXY_DECLARE(int) ap_proxy_hex2sec(const char *x);
464 PROXY_DECLARE(void) ap_proxy_sec2hex(int t, char *y);
465 PROXY_DECLARE(int) ap_proxyerror(request_rec *r, int statuscode, const char *message);
466 PROXY_DECLARE(int) ap_proxy_is_ipaddr(struct dirconn_entry *This, apr_pool_t *p);
467 PROXY_DECLARE(int) ap_proxy_is_domainname(struct dirconn_entry *This, apr_pool_t *p);
468 PROXY_DECLARE(int) ap_proxy_is_hostname(struct dirconn_entry *This, apr_pool_t *p);
469 PROXY_DECLARE(int) ap_proxy_is_word(struct dirconn_entry *This, apr_pool_t *p);
470 PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf, apr_sockaddr_t *uri_addr);
471 PROXY_DECLARE(int) ap_proxy_pre_http_request(conn_rec *c, request_rec *r);
472 PROXY_DECLARE(apr_status_t) ap_proxy_string_read(conn_rec *c, apr_bucket_brigade *bb, char *buff, size_t bufflen, int *eos);
473 PROXY_DECLARE(void) ap_proxy_table_unmerge(apr_pool_t *p, apr_table_t *t, char *key);
474 /* DEPRECATED (will be replaced with ap_proxy_connect_backend */
475 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 *);
476 PROXY_DECLARE(int) ap_proxy_ssl_enable(conn_rec *c);
477 PROXY_DECLARE(int) ap_proxy_ssl_disable(conn_rec *c);
478 PROXY_DECLARE(int) ap_proxy_conn_is_https(conn_rec *c);
479 PROXY_DECLARE(const char *) ap_proxy_ssl_val(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, const char *var);
481 /* Header mapping functions, and a typedef of their signature */
482 PROXY_DECLARE(const char *) ap_proxy_location_reverse_map(request_rec *r, proxy_dir_conf *conf, const char *url);
483 PROXY_DECLARE(const char *) ap_proxy_cookie_reverse_map(request_rec *r, proxy_dir_conf *conf, const char *str);
486 typedef const char *(*ap_proxy_header_reverse_map_fn)(request_rec *,
487 proxy_dir_conf *, const char *);
488 #elif defined(PROXY_DECLARE_STATIC)
489 typedef const char *(__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *,
490 proxy_dir_conf *, const char *);
491 #elif defined(PROXY_DECLARE_EXPORT)
492 typedef __declspec(dllexport) const char *
493 (__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *,
494 proxy_dir_conf *, const char *);
496 typedef __declspec(dllimport) const char *
497 (__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *,
498 proxy_dir_conf *, const char *);
502 /* Connection pool API */
504 * Get the worker from proxy configuration
505 * @param p memory pool used for finding worker
506 * @param conf current proxy server configuration
507 * @param url url to find the worker from
508 * @return proxy_worker or NULL if not found
510 PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker(apr_pool_t *p,
511 proxy_server_conf *conf,
514 * Add the worker to proxy configuration
515 * @param worker the new worker
516 * @param p memory pool to allocate worker from
517 * @param conf current proxy server configuration
518 * @param url url containing worker name
519 * @return error message or NULL if successfull
521 PROXY_DECLARE(const char *) ap_proxy_add_worker(proxy_worker **worker,
523 proxy_server_conf *conf,
528 * @param p memory pool to allocate worker from
531 PROXY_DECLARE(proxy_worker *) ap_proxy_create_worker(apr_pool_t *p);
534 * Initize the worker's shared data
535 * @param conf current proxy server configuration
536 * @param worker worker to initialize
537 * @param s current server record
538 * @param worker worker to initialize
540 PROXY_DECLARE(void) ap_proxy_initialize_worker_share(proxy_server_conf *conf,
541 proxy_worker *worker,
547 * @param worker worker to initialize
548 * @param s current server record
549 * @return APR_SUCCESS or error code
551 PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker,
554 * Get the balancer from proxy configuration
555 * @param p memory pool used for finding balancer
556 * @param conf current proxy server configuration
557 * @param url url to find the worker from. Has to have balancer:// prefix
558 * @return proxy_balancer or NULL if not found
560 PROXY_DECLARE(proxy_balancer *) ap_proxy_get_balancer(apr_pool_t *p,
561 proxy_server_conf *conf,
564 * Add the balancer to proxy configuration
565 * @param balancer the new balancer
566 * @param p memory pool to allocate balancer from
567 * @param conf current proxy server configuration
568 * @param url url containing balancer name
569 * @return error message or NULL if successfull
571 PROXY_DECLARE(const char *) ap_proxy_add_balancer(proxy_balancer **balancer,
573 proxy_server_conf *conf,
577 * Add the worker to the balancer
578 * @param pool memory pool for adding worker
579 * @param balancer balancer to add to
580 * @param balancer worker to add
581 * @note Single worker can be added to multiple balancers.
583 PROXY_DECLARE(void) ap_proxy_add_worker_to_balancer(apr_pool_t *pool,
584 proxy_balancer *balancer,
585 proxy_worker *worker);
587 * Get the most suitable worker and(or) balancer for the request
588 * @param worker worker used for processing request
589 * @param balancer balancer used for processing request
590 * @param r current request
591 * @param conf current proxy server configuration
592 * @param url request url that balancer can rewrite.
593 * @return OK or HTTP_XXX error
594 * @note It calls balancer pre_request hook if the url starts with balancer://
595 * The balancer then rewrites the url to particular worker, like http://host:port
597 PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker,
598 proxy_balancer **balancer,
600 proxy_server_conf *conf,
603 * Post request worker and balancer cleanup
604 * @param worker worker used for processing request
605 * @param balancer balancer used for processing request
606 * @param r current request
607 * @param conf current proxy server configuration
608 * @return OK or HTTP_XXX error
609 * @note When ever the pre_request is called, the post_request has to be
612 PROXY_DECLARE(int) ap_proxy_post_request(proxy_worker *worker,
613 proxy_balancer *balancer,
615 proxy_server_conf *conf);
618 * Request status function
619 * @param status status of proxy request
620 * @return OK or DECLINED
622 PROXY_DECLARE(int) ap_proxy_request_status(int *status, request_rec *r);
625 * Deternime backend hostname and port
626 * @param p memory pool used for processing
627 * @param r current request
628 * @param conf current proxy server configuration
629 * @param worker worker used for processing request
630 * @param conn proxy connection struct
631 * @param uri processed uri
632 * @param url request url
633 * @param proxyname are we connecting directly or via s proxy
634 * @param proxyport proxy host port
635 * @param server_portstr Via headers server port
636 * @param server_portstr_size size of the server_portstr buffer
637 * @return OK or HTTP_XXX error
639 PROXY_DECLARE(int) ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
640 proxy_server_conf *conf,
641 proxy_worker *worker,
642 proxy_conn_rec *conn,
645 const char *proxyname,
646 apr_port_t proxyport,
647 char *server_portstr,
648 int server_portstr_size);
650 * Mark a worker for retry
651 * @param proxy_function calling proxy scheme (http, ajp, ...)
652 * @param conf current proxy server configuration
653 * @param worker worker used for retrying
654 * @param s current server record
655 * @return OK if marked for retry, DECLINED otherwise
656 * @note Worker will be marker for retry if the time of the last retry
657 * has been ellapsed. In case there is no retry option set, defaults to
658 * number_of_retries seconds.
660 PROXY_DECLARE(int) ap_proxy_retry_worker(const char *proxy_function,
661 proxy_worker *worker,
664 * Acquire a connection from workers connection pool
665 * @param proxy_function calling proxy scheme (http, ajp, ...)
666 * @param conn acquired connection
667 * @param worker worker used for obtaining connection
668 * @param s current server record
669 * @return OK or HTTP_XXX error
670 * @note If the number of connections is exhaused the function will
671 * block untill the timeout is reached.
673 PROXY_DECLARE(int) ap_proxy_acquire_connection(const char *proxy_function,
674 proxy_conn_rec **conn,
675 proxy_worker *worker,
678 * Release a connection back to worker connection pool
679 * @param proxy_function calling proxy scheme (http, ajp, ...)
680 * @param conn acquired connection
681 * @param s current server record
682 * @return OK or HTTP_XXX error
683 * @note The connection will be closed if conn->close_on_release is set
685 PROXY_DECLARE(int) ap_proxy_release_connection(const char *proxy_function,
686 proxy_conn_rec *conn,
689 * Make a connection to the backend
690 * @param proxy_function calling proxy scheme (http, ajp, ...)
691 * @param conn acquired connection
692 * @param worker connection worker
693 * @param s current server record
694 * @return OK or HTTP_XXX error
695 * @note In case the socket already exists for conn, just check the link
698 PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
699 proxy_conn_rec *conn,
700 proxy_worker *worker,
703 * Make a connection record for backend connection
704 * @param proxy_function calling proxy scheme (http, ajp, ...)
705 * @param conn acquired connection
706 * @param c client connection record
707 * @param s current server record
708 * @return OK or HTTP_XXX error
710 PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function,
711 proxy_conn_rec *conn,
712 conn_rec *c, server_rec *s);
714 * Signal the upstream chain that the connection to the backend broke in the
715 * middle of the response. This is done by sending an error bucket with
716 * status HTTP_BAD_GATEWAY and an EOS bucket up the filter chain.
717 * @param r current request record of client request
718 * @param brigade The brigade that is sent through the output filter chain
720 PROXY_DECLARE(void) ap_proxy_backend_broke(request_rec *r,
721 apr_bucket_brigade *brigade);
723 #define PROXY_LBMETHOD "proxylbmethod"
725 /* The number of dynamic workers that can be added when reconfiguring.
726 * If this limit is reached you must stop and restart the server.
728 #define PROXY_DYNAMIC_BALANCER_LIMIT 16
730 * Calculate number of maximum number of workers in scoreboard.
731 * @return number of workers to allocate in the scoreboard
733 int ap_proxy_lb_workers(void);
736 extern module PROXY_DECLARE_DATA proxy_module;
738 extern int PROXY_DECLARE_DATA proxy_lb_workers;
740 #endif /*MOD_PROXY_H*/