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 */
115 struct dirconn_entry {
117 struct in_addr addr, mask;
118 struct apr_sockaddr_t *hostaddr;
119 int (*matcher) (struct dirconn_entry * This, request_rec *r);
122 struct noproxy_entry {
124 struct apr_sockaddr_t *addr;
127 typedef struct proxy_balancer proxy_balancer;
128 typedef struct proxy_worker proxy_worker;
129 typedef struct proxy_conn_pool proxy_conn_pool;
130 typedef struct proxy_balancer_method proxy_balancer_method;
133 apr_array_header_t *proxies;
134 apr_array_header_t *sec_proxy;
135 apr_array_header_t *aliases;
136 apr_array_header_t *noproxies;
137 apr_array_header_t *dirconn;
138 apr_array_header_t *allowed_connect_ports;
139 apr_array_header_t *workers;
140 apr_array_header_t *balancers;
141 proxy_worker *forward; /* forward proxy worker */
142 proxy_worker *reverse; /* reverse "module-driven" proxy worker */
143 const char *domain; /* domain name to use in absence of a domain name in the request */
144 int req; /* true if proxy requests are enabled */
151 } viaopt; /* how to deal with proxy Via: headers */
153 apr_size_t recv_buffer_size;
154 char recv_buffer_size_set;
155 apr_size_t io_buffer_size;
156 char io_buffer_size_set;
160 * the following setting masks the error page
161 * returned from the 'proxied server' and just
162 * forwards the status code upwards.
163 * This allows the main server (us) to generate
164 * the error page, (so it will look like a error
165 * returned from the rest of the system
168 int error_override_set;
170 int preserve_host_set;
171 apr_interval_time_t timeout;
177 } badopt; /* how to deal with bad headers */
179 /* putting new stuff on the end maximises binary back-compatibility.
180 * the strmatch_patterns are really a const just to have a
181 * case-independent strstr.
187 } proxy_status; /* Status display options */
188 char proxy_status_set;
189 apr_pool_t *pool; /* Pool used for allocating this struct */
194 const char *p; /* The path */
195 int p_is_fnmatch; /* Is this path an fnmatch candidate? */
196 ap_regex_t *r; /* Is this a regex? */
198 /* ProxyPassReverse and friends are documented as working inside
199 * <Location>. But in fact they never have done in the case of
200 * more than one <Location>, because the server_conf can't see it.
201 * We need to move them to the per-dir config.
202 * Discussed in February:
203 * http://marc.theaimsgroup.com/?l=apache-httpd-dev&m=110726027118798&w=2
205 apr_array_header_t *raliases;
206 apr_array_header_t* cookie_paths;
207 apr_array_header_t* cookie_domains;
208 const apr_strmatch_pattern* cookie_path_str;
209 const apr_strmatch_pattern* cookie_domain_str;
213 /* if we interpolate env vars per-request, we'll need a per-request
214 * copy of the reverse proxy config
217 apr_array_header_t *raliases;
218 apr_array_header_t* cookie_paths;
219 apr_array_header_t* cookie_domains;
223 conn_rec *connection;
224 const char *hostname;
227 apr_pool_t *pool; /* Subpool used for creating socket */
228 apr_socket_t *sock; /* Connection socket */
229 apr_sockaddr_t *addr; /* Preparsed remote address info */
230 apr_uint32_t flags; /* Conection flags */
231 int close; /* Close 'this' connection */
232 proxy_worker *worker; /* Connection pool this connection belongs to */
233 void *data; /* per scheme connection data */
235 int inreslist; /* connection in apr_reslist? */
240 float cache_completion; /* completion percentage */
241 int content_length; /* length of the content */
244 /* Connection pool */
245 struct proxy_conn_pool {
246 apr_pool_t *pool; /* The pool used in constructor and destructor calls */
247 apr_sockaddr_t *addr; /* Preparsed remote address info */
249 apr_reslist_t *res; /* Connection resource list */
251 proxy_conn_rec *conn; /* Single connection for prefork mpm's */
254 /* worker status flags */
255 #define PROXY_WORKER_INITIALIZED 0x0001
256 #define PROXY_WORKER_IGNORE_ERRORS 0x0002
257 #define PROXY_WORKER_IN_SHUTDOWN 0x0010
258 #define PROXY_WORKER_DISABLED 0x0020
259 #define PROXY_WORKER_STOPPED 0x0040
260 #define PROXY_WORKER_IN_ERROR 0x0080
261 #define PROXY_WORKER_HOT_STANDBY 0x0100
263 #define PROXY_WORKER_NOT_USABLE_BITMAP ( PROXY_WORKER_IN_SHUTDOWN | \
264 PROXY_WORKER_DISABLED | PROXY_WORKER_STOPPED | PROXY_WORKER_IN_ERROR )
266 /* NOTE: these check the shared status */
267 #define PROXY_WORKER_IS_INITIALIZED(f) ( (f)->s && \
268 ( (f)->s->status & PROXY_WORKER_INITIALIZED ) )
270 #define PROXY_WORKER_IS_STANDBY(f) ( (f)->s && \
271 ( (f)->s->status & PROXY_WORKER_HOT_STANDBY ) )
273 #define PROXY_WORKER_IS_USABLE(f) ( (f)->s && \
274 ( !( (f)->s->status & PROXY_WORKER_NOT_USABLE_BITMAP) ) && \
275 PROXY_WORKER_IS_INITIALIZED(f) )
277 /* default worker retry timeout in seconds */
278 #define PROXY_WORKER_DEFAULT_RETRY 60
279 #define PROXY_WORKER_MAX_ROUTE_SIZ 63
281 /* Runtime worker status informations. Shared in scoreboard */
284 apr_time_t error_time; /* time of the last error */
285 int retries; /* number of retries on this worker */
286 int lbstatus; /* Current lbstatus */
287 int lbfactor; /* dynamic lbfactor */
288 apr_off_t transferred;/* Number of bytes transferred to remote */
289 apr_off_t read; /* Number of bytes read from remote */
290 apr_size_t elected; /* Number of times the worker was elected */
291 char route[PROXY_WORKER_MAX_ROUTE_SIZ+1];
292 char redirect[PROXY_WORKER_MAX_ROUTE_SIZ+1];
293 void *context; /* general purpose storage */
294 apr_size_t busy; /* busyness factor */
295 int lbset; /* load balancer cluster set */
298 /* Worker configuration */
299 struct proxy_worker {
300 int id; /* scoreboard id */
301 apr_interval_time_t retry; /* retry interval */
302 int lbfactor; /* initial load balancing factor */
304 const char *scheme; /* scheme to use ajp|http|https */
305 const char *hostname; /* remote backend address */
306 const char *route; /* balancing route */
307 const char *redirect; /* temporary balancing redirection route */
308 int status; /* temporary worker status */
310 int min; /* Desired minimum number of available connections */
311 int smax; /* Soft maximum on the total number of connections */
312 int hmax; /* Hard maximum on the total number of connections */
313 apr_interval_time_t ttl; /* maximum amount of time in seconds a connection
314 * may be available while exceeding the soft limit */
315 apr_interval_time_t timeout; /* connection timeout */
317 apr_interval_time_t acquire; /* acquire timeout when the maximum number of connections is exceeded */
319 apr_size_t recv_buffer_size;
320 char recv_buffer_size_set;
321 apr_size_t io_buffer_size;
322 char io_buffer_size_set;
325 proxy_conn_pool *cp; /* Connection pool to use */
326 proxy_worker_stat *s; /* Shared data */
327 void *opaque; /* per scheme worker data */
328 int is_address_reusable;
330 apr_thread_mutex_t *mutex; /* Thread lock for updating address cache */
332 void *context; /* general purpose storage */
337 } flush_packets; /* control AJP flushing */
338 int flush_wait; /* poll wait time in microseconds if flush_auto */
339 apr_interval_time_t ping_timeout;
340 char ping_timeout_set;
341 int lbset; /* load balancer cluster set */
346 * Wait 10000 microseconds to find out if more data is currently
347 * available at the backend. Just an arbitrary choose.
349 #define PROXY_FLUSH_WAIT 10000
351 struct proxy_balancer {
352 apr_array_header_t *workers; /* array of proxy_workers */
353 const char *name; /* name of the load balancer */
354 const char *sticky; /* sticky session identifier */
355 int sticky_force; /* Disable failover for sticky sessions */
356 apr_interval_time_t timeout; /* Timeout for waiting on free connection */
357 int max_attempts; /* Number of attempts before failing */
358 char max_attempts_set;
359 proxy_balancer_method *lbmethod;
361 /* XXX: Perhaps we will need the proc mutex too.
362 * Altrough we are only using arithmetic operations
363 * it may lead to a incorrect calculations.
364 * For now use only the thread mutex.
367 apr_thread_mutex_t *mutex; /* Thread lock for updating lb params */
369 void *context; /* general purpose storage */
370 const char *sticky_path; /* URL sticky session identifier */
373 struct proxy_balancer_method {
374 const char *name; /* name of the load balancer method*/
375 proxy_worker *(*finder)(proxy_balancer *balancer,
377 void *context; /* general purpose storage */
381 #define PROXY_THREAD_LOCK(x) apr_thread_mutex_lock((x)->mutex)
382 #define PROXY_THREAD_UNLOCK(x) apr_thread_mutex_unlock((x)->mutex)
384 #define PROXY_THREAD_LOCK(x) APR_SUCCESS
385 #define PROXY_THREAD_UNLOCK(x) APR_SUCCESS
390 /* Create a set of PROXY_DECLARE(type), PROXY_DECLARE_NONSTD(type) and
391 * PROXY_DECLARE_DATA with appropriate export and import tags for the platform
394 #define PROXY_DECLARE(type) type
395 #define PROXY_DECLARE_NONSTD(type) type
396 #define PROXY_DECLARE_DATA
397 #elif defined(PROXY_DECLARE_STATIC)
398 #define PROXY_DECLARE(type) type __stdcall
399 #define PROXY_DECLARE_NONSTD(type) type
400 #define PROXY_DECLARE_DATA
401 #elif defined(PROXY_DECLARE_EXPORT)
402 #define PROXY_DECLARE(type) __declspec(dllexport) type __stdcall
403 #define PROXY_DECLARE_NONSTD(type) __declspec(dllexport) type
404 #define PROXY_DECLARE_DATA __declspec(dllexport)
406 #define PROXY_DECLARE(type) __declspec(dllimport) type __stdcall
407 #define PROXY_DECLARE_NONSTD(type) __declspec(dllimport) type
408 #define PROXY_DECLARE_DATA __declspec(dllimport)
412 * Hook an optional proxy hook. Unlike static hooks, this uses a macro
413 * instead of a function.
415 #define PROXY_OPTIONAL_HOOK(name,fn,pre,succ,order) \
416 APR_OPTIONAL_HOOK(proxy,name,fn,pre,succ,order)
418 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, scheme_handler, (request_rec *r,
419 proxy_worker *worker, proxy_server_conf *conf, char *url,
420 const char *proxyhost, apr_port_t proxyport))
421 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, canon_handler, (request_rec *r,
424 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, create_req, (request_rec *r, request_rec *pr))
425 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, fixups, (request_rec *r))
429 * It will return the most suitable worker at the moment
430 * and coresponding balancer.
431 * The url is rewritten from balancer://cluster/uri to scheme://host:port/uri
432 * and then the scheme_handler is called.
435 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, pre_request, (proxy_worker **worker,
436 proxy_balancer **balancer,
438 proxy_server_conf *conf, char **url))
441 * It is called after request for updating runtime balancer status.
443 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, post_request, (proxy_worker *worker,
444 proxy_balancer *balancer, request_rec *r,
445 proxy_server_conf *conf))
448 * request status hook
449 * It is called after all proxy processing has been done. This gives other
450 * modules a chance to create default content on failure, for example
452 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, request_status,
453 (int *status, request_rec *r))
457 PROXY_DECLARE(request_rec *)ap_proxy_make_fake_req(conn_rec *c, request_rec *r);
458 PROXY_DECLARE(int) ap_proxy_hex2c(const char *x);
459 PROXY_DECLARE(void) ap_proxy_c2hex(int ch, char *x);
460 PROXY_DECLARE(char *)ap_proxy_canonenc(apr_pool_t *p, const char *x, int len, enum enctype t,
461 int forcedec, int proxyreq);
462 PROXY_DECLARE(char *)ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, char **userp,
463 char **passwordp, char **hostp, apr_port_t *port);
464 PROXY_DECLARE(const char *)ap_proxy_date_canon(apr_pool_t *p, const char *x);
465 PROXY_DECLARE(int) ap_proxy_liststr(const char *list, const char *val);
466 PROXY_DECLARE(char *)ap_proxy_removestr(apr_pool_t *pool, const char *list, const char *val);
467 PROXY_DECLARE(int) ap_proxy_hex2sec(const char *x);
468 PROXY_DECLARE(void) ap_proxy_sec2hex(int t, char *y);
469 PROXY_DECLARE(int) ap_proxyerror(request_rec *r, int statuscode, const char *message);
470 PROXY_DECLARE(int) ap_proxy_is_ipaddr(struct dirconn_entry *This, apr_pool_t *p);
471 PROXY_DECLARE(int) ap_proxy_is_domainname(struct dirconn_entry *This, apr_pool_t *p);
472 PROXY_DECLARE(int) ap_proxy_is_hostname(struct dirconn_entry *This, apr_pool_t *p);
473 PROXY_DECLARE(int) ap_proxy_is_word(struct dirconn_entry *This, apr_pool_t *p);
474 PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf, apr_sockaddr_t *uri_addr);
475 PROXY_DECLARE(int) ap_proxy_pre_http_request(conn_rec *c, request_rec *r);
476 PROXY_DECLARE(apr_status_t) ap_proxy_string_read(conn_rec *c, apr_bucket_brigade *bb, char *buff, size_t bufflen, int *eos);
477 PROXY_DECLARE(void) ap_proxy_table_unmerge(apr_pool_t *p, apr_table_t *t, char *key);
478 /* DEPRECATED (will be replaced with ap_proxy_connect_backend */
479 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 *);
480 PROXY_DECLARE(int) ap_proxy_ssl_enable(conn_rec *c);
481 PROXY_DECLARE(int) ap_proxy_ssl_disable(conn_rec *c);
482 PROXY_DECLARE(int) ap_proxy_conn_is_https(conn_rec *c);
483 PROXY_DECLARE(const char *) ap_proxy_ssl_val(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, const char *var);
485 /* Header mapping functions, and a typedef of their signature */
486 PROXY_DECLARE(const char *) ap_proxy_location_reverse_map(request_rec *r, proxy_dir_conf *conf, const char *url);
487 PROXY_DECLARE(const char *) ap_proxy_cookie_reverse_map(request_rec *r, proxy_dir_conf *conf, const char *str);
490 typedef const char *(*ap_proxy_header_reverse_map_fn)(request_rec *,
491 proxy_dir_conf *, const char *);
492 #elif defined(PROXY_DECLARE_STATIC)
493 typedef const char *(__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *,
494 proxy_dir_conf *, const char *);
495 #elif defined(PROXY_DECLARE_EXPORT)
496 typedef __declspec(dllexport) const char *
497 (__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *,
498 proxy_dir_conf *, const char *);
500 typedef __declspec(dllimport) const char *
501 (__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *,
502 proxy_dir_conf *, const char *);
506 /* Connection pool API */
508 * Get the worker from proxy configuration
509 * @param p memory pool used for finding worker
510 * @param conf current proxy server configuration
511 * @param url url to find the worker from
512 * @return proxy_worker or NULL if not found
514 PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker(apr_pool_t *p,
515 proxy_server_conf *conf,
518 * Add the worker to proxy configuration
519 * @param worker the new worker
520 * @param p memory pool to allocate worker from
521 * @param conf current proxy server configuration
522 * @param url url containing worker name
523 * @return error message or NULL if successfull
525 PROXY_DECLARE(const char *) ap_proxy_add_worker(proxy_worker **worker,
527 proxy_server_conf *conf,
532 * @param p memory pool to allocate worker from
535 PROXY_DECLARE(proxy_worker *) ap_proxy_create_worker(apr_pool_t *p);
538 * Initize the worker's shared data
539 * @param conf current proxy server configuration
540 * @param worker worker to initialize
541 * @param s current server record
542 * @param worker worker to initialize
544 PROXY_DECLARE(void) ap_proxy_initialize_worker_share(proxy_server_conf *conf,
545 proxy_worker *worker,
551 * @param worker worker to initialize
552 * @param s current server record
553 * @return APR_SUCCESS or error code
555 PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker,
558 * Get the balancer from proxy configuration
559 * @param p memory pool used for finding balancer
560 * @param conf current proxy server configuration
561 * @param url url to find the worker from. Has to have balancer:// prefix
562 * @return proxy_balancer or NULL if not found
564 PROXY_DECLARE(proxy_balancer *) ap_proxy_get_balancer(apr_pool_t *p,
565 proxy_server_conf *conf,
568 * Add the balancer to proxy configuration
569 * @param balancer the new balancer
570 * @param p memory pool to allocate balancer from
571 * @param conf current proxy server configuration
572 * @param url url containing balancer name
573 * @return error message or NULL if successfull
575 PROXY_DECLARE(const char *) ap_proxy_add_balancer(proxy_balancer **balancer,
577 proxy_server_conf *conf,
581 * Add the worker to the balancer
582 * @param pool memory pool for adding worker
583 * @param balancer balancer to add to
584 * @param balancer worker to add
585 * @note Single worker can be added to multiple balancers.
587 PROXY_DECLARE(void) ap_proxy_add_worker_to_balancer(apr_pool_t *pool,
588 proxy_balancer *balancer,
589 proxy_worker *worker);
591 * Get the most suitable worker and(or) balancer for the request
592 * @param worker worker used for processing request
593 * @param balancer balancer used for processing request
594 * @param r current request
595 * @param conf current proxy server configuration
596 * @param url request url that balancer can rewrite.
597 * @return OK or HTTP_XXX error
598 * @note It calls balancer pre_request hook if the url starts with balancer://
599 * The balancer then rewrites the url to particular worker, like http://host:port
601 PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker,
602 proxy_balancer **balancer,
604 proxy_server_conf *conf,
607 * Post request worker and balancer cleanup
608 * @param worker worker used for processing request
609 * @param balancer balancer used for processing request
610 * @param r current request
611 * @param conf current proxy server configuration
612 * @return OK or HTTP_XXX error
613 * @note When ever the pre_request is called, the post_request has to be
616 PROXY_DECLARE(int) ap_proxy_post_request(proxy_worker *worker,
617 proxy_balancer *balancer,
619 proxy_server_conf *conf);
622 * Request status function
623 * @param status status of proxy request
624 * @return OK or DECLINED
626 PROXY_DECLARE(int) ap_proxy_request_status(int *status, request_rec *r);
629 * Deternime backend hostname and port
630 * @param p memory pool used for processing
631 * @param r current request
632 * @param conf current proxy server configuration
633 * @param worker worker used for processing request
634 * @param conn proxy connection struct
635 * @param uri processed uri
636 * @param url request url
637 * @param proxyname are we connecting directly or via s proxy
638 * @param proxyport proxy host port
639 * @param server_portstr Via headers server port
640 * @param server_portstr_size size of the server_portstr buffer
641 * @return OK or HTTP_XXX error
643 PROXY_DECLARE(int) ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
644 proxy_server_conf *conf,
645 proxy_worker *worker,
646 proxy_conn_rec *conn,
649 const char *proxyname,
650 apr_port_t proxyport,
651 char *server_portstr,
652 int server_portstr_size);
654 * Mark a worker for retry
655 * @param proxy_function calling proxy scheme (http, ajp, ...)
656 * @param conf current proxy server configuration
657 * @param worker worker used for retrying
658 * @param s current server record
659 * @return OK if marked for retry, DECLINED otherwise
660 * @note Worker will be marker for retry if the time of the last retry
661 * has been ellapsed. In case there is no retry option set, defaults to
662 * number_of_retries seconds.
664 PROXY_DECLARE(int) ap_proxy_retry_worker(const char *proxy_function,
665 proxy_worker *worker,
668 * Acquire a connection from workers connection pool
669 * @param proxy_function calling proxy scheme (http, ajp, ...)
670 * @param conn acquired connection
671 * @param worker worker used for obtaining connection
672 * @param s current server record
673 * @return OK or HTTP_XXX error
674 * @note If the number of connections is exhaused the function will
675 * block untill the timeout is reached.
677 PROXY_DECLARE(int) ap_proxy_acquire_connection(const char *proxy_function,
678 proxy_conn_rec **conn,
679 proxy_worker *worker,
682 * Release a connection back to worker connection pool
683 * @param proxy_function calling proxy scheme (http, ajp, ...)
684 * @param conn acquired connection
685 * @param s current server record
686 * @return OK or HTTP_XXX error
687 * @note The connection will be closed if conn->close_on_release is set
689 PROXY_DECLARE(int) ap_proxy_release_connection(const char *proxy_function,
690 proxy_conn_rec *conn,
693 * Make a connection to the backend
694 * @param proxy_function calling proxy scheme (http, ajp, ...)
695 * @param conn acquired connection
696 * @param worker connection worker
697 * @param s current server record
698 * @return OK or HTTP_XXX error
699 * @note In case the socket already exists for conn, just check the link
702 PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
703 proxy_conn_rec *conn,
704 proxy_worker *worker,
707 * Make a connection record for backend connection
708 * @param proxy_function calling proxy scheme (http, ajp, ...)
709 * @param conn acquired connection
710 * @param c client connection record
711 * @param s current server record
712 * @return OK or HTTP_XXX error
714 PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function,
715 proxy_conn_rec *conn,
716 conn_rec *c, server_rec *s);
718 * Signal the upstream chain that the connection to the backend broke in the
719 * middle of the response. This is done by sending an error bucket with
720 * status HTTP_BAD_GATEWAY and an EOS bucket up the filter chain.
721 * @param r current request record of client request
722 * @param brigade The brigade that is sent through the output filter chain
724 PROXY_DECLARE(void) ap_proxy_backend_broke(request_rec *r,
725 apr_bucket_brigade *brigade);
727 #define PROXY_LBMETHOD "proxylbmethod"
729 /* The number of dynamic workers that can be added when reconfiguring.
730 * If this limit is reached you must stop and restart the server.
732 #define PROXY_DYNAMIC_BALANCER_LIMIT 16
735 extern module PROXY_DECLARE_DATA proxy_module;
737 extern int PROXY_DECLARE_DATA proxy_lb_workers;
739 #endif /*MOD_PROXY_H*/