00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef MOD_PROXY_H
00018 #define MOD_PROXY_H
00019
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #define CORE_PRIVATE
00046
00047 #include "apr_hooks.h"
00048 #include "apr.h"
00049 #include "apr_lib.h"
00050 #include "apr_strings.h"
00051 #include "apr_buckets.h"
00052 #include "apr_md5.h"
00053 #include "apr_network_io.h"
00054 #include "apr_pools.h"
00055 #include "apr_strings.h"
00056 #include "apr_uri.h"
00057 #include "apr_date.h"
00058 #include "apr_strmatch.h"
00059 #include "apr_fnmatch.h"
00060 #include "apr_reslist.h"
00061 #define APR_WANT_STRFUNC
00062 #include "apr_want.h"
00063
00064 #include "httpd.h"
00065 #include "http_config.h"
00066 #include "ap_config.h"
00067 #include "http_core.h"
00068 #include "http_protocol.h"
00069 #include "http_request.h"
00070 #include "http_vhost.h"
00071 #include "http_main.h"
00072 #include "http_log.h"
00073 #include "http_connection.h"
00074 #include "util_filter.h"
00075 #include "util_ebcdic.h"
00076 #include "ap_provider.h"
00077
00078 #if APR_HAVE_NETINET_IN_H
00079 #include <netinet/in.h>
00080 #endif
00081 #if APR_HAVE_ARPA_INET_H
00082 #include <arpa/inet.h>
00083 #endif
00084
00085
00086 enum enctype {
00087 enc_path, enc_search, enc_user, enc_fpath, enc_parm
00088 };
00089
00090 #if APR_CHARSET_EBCDIC
00091 #define CRLF "\r\n"
00092 #else
00093 #define CRLF "\015\012"
00094 #endif
00095
00096
00097
00098
00099
00100 #define DEFAULT_MAX_FORWARDS -1
00101
00102
00103 struct proxy_remote {
00104 const char *scheme;
00105 const char *protocol;
00106 const char *hostname;
00107 apr_port_t port;
00108 ap_regex_t *regexp;
00109 int use_regex;
00110 };
00111
00112 #define PROXYPASS_NOCANON 0x01
00113 #define PROXYPASS_INTERPOLATE 0x02
00114 struct proxy_alias {
00115 const char *real;
00116 const char *fake;
00117 ap_regex_t *regex;
00118 unsigned int flags;
00119 };
00120
00121 struct dirconn_entry {
00122 char *name;
00123 struct in_addr addr, mask;
00124 struct apr_sockaddr_t *hostaddr;
00125 int (*matcher) (struct dirconn_entry * This, request_rec *r);
00126 };
00127
00128 struct noproxy_entry {
00129 const char *name;
00130 struct apr_sockaddr_t *addr;
00131 };
00132
00133 typedef struct proxy_balancer proxy_balancer;
00134 typedef struct proxy_worker proxy_worker;
00135 typedef struct proxy_conn_pool proxy_conn_pool;
00136 typedef struct proxy_balancer_method proxy_balancer_method;
00137
00138 typedef struct {
00139 apr_array_header_t *proxies;
00140 apr_array_header_t *sec_proxy;
00141 apr_array_header_t *aliases;
00142 apr_array_header_t *noproxies;
00143 apr_array_header_t *dirconn;
00144 apr_array_header_t *allowed_connect_ports;
00145 apr_array_header_t *workers;
00146 apr_array_header_t *balancers;
00147 proxy_worker *forward;
00148 proxy_worker *reverse;
00149 const char *domain;
00150 int req;
00151 char req_set;
00152 enum {
00153 via_off,
00154 via_on,
00155 via_block,
00156 via_full
00157 } viaopt;
00158 char viaopt_set;
00159 apr_size_t recv_buffer_size;
00160 char recv_buffer_size_set;
00161 apr_size_t io_buffer_size;
00162 char io_buffer_size_set;
00163 long maxfwd;
00164 char maxfwd_set;
00173 int error_override;
00174 int error_override_set;
00175 int preserve_host;
00176 int preserve_host_set;
00177 apr_interval_time_t timeout;
00178 char timeout_set;
00179 enum {
00180 bad_error,
00181 bad_ignore,
00182 bad_body
00183 } badopt;
00184 char badopt_set;
00185
00186
00187
00188
00189 enum {
00190 status_off,
00191 status_on,
00192 status_full
00193 } proxy_status;
00194 char proxy_status_set;
00195 apr_pool_t *pool;
00196 } proxy_server_conf;
00197
00198
00199 typedef struct {
00200 const char *p;
00201 int p_is_fnmatch;
00202 ap_regex_t *r;
00203
00204
00205
00206
00207
00208
00209
00210
00211 apr_array_header_t *raliases;
00212 apr_array_header_t* cookie_paths;
00213 apr_array_header_t* cookie_domains;
00214 const apr_strmatch_pattern* cookie_path_str;
00215 const apr_strmatch_pattern* cookie_domain_str;
00216 const char *ftp_directory_charset;
00217 int interpolate_env;
00218 } proxy_dir_conf;
00219
00220
00221
00222
00223 typedef struct {
00224 apr_array_header_t *raliases;
00225 apr_array_header_t* cookie_paths;
00226 apr_array_header_t* cookie_domains;
00227 } proxy_req_conf;
00228
00229 typedef struct {
00230 conn_rec *connection;
00231 const char *hostname;
00232 apr_port_t port;
00233 int is_ssl;
00234 apr_pool_t *pool;
00235 apr_socket_t *sock;
00236 apr_sockaddr_t *addr;
00237 apr_uint32_t flags;
00238 int close;
00239 int close_on_recycle;
00240 proxy_worker *worker;
00241 void *data;
00242 #if APR_HAS_THREADS
00243 int inreslist;
00244 #endif
00245 apr_pool_t *scpool;
00246 request_rec *r;
00247
00248 int need_flush;
00249
00250 } proxy_conn_rec;
00251
00252 typedef struct {
00253 float cache_completion;
00254 int content_length;
00255 } proxy_completion;
00256
00257
00258 struct proxy_conn_pool {
00259 apr_pool_t *pool;
00260 apr_sockaddr_t *addr;
00261 #if APR_HAS_THREADS
00262 apr_reslist_t *res;
00263 #endif
00264 proxy_conn_rec *conn;
00265 };
00266
00267
00268 #define PROXY_WORKER_INITIALIZED 0x0001
00269 #define PROXY_WORKER_IGNORE_ERRORS 0x0002
00270 #define PROXY_WORKER_IN_SHUTDOWN 0x0010
00271 #define PROXY_WORKER_DISABLED 0x0020
00272 #define PROXY_WORKER_STOPPED 0x0040
00273 #define PROXY_WORKER_IN_ERROR 0x0080
00274 #define PROXY_WORKER_HOT_STANDBY 0x0100
00275
00276 #define PROXY_WORKER_NOT_USABLE_BITMAP ( PROXY_WORKER_IN_SHUTDOWN | \
00277 PROXY_WORKER_DISABLED | PROXY_WORKER_STOPPED | PROXY_WORKER_IN_ERROR )
00278
00279
00280 #define PROXY_WORKER_IS_INITIALIZED(f) ( (f)->s && \
00281 ( (f)->s->status & PROXY_WORKER_INITIALIZED ) )
00282
00283 #define PROXY_WORKER_IS_STANDBY(f) ( (f)->s && \
00284 ( (f)->s->status & PROXY_WORKER_HOT_STANDBY ) )
00285
00286 #define PROXY_WORKER_IS_USABLE(f) ( (f)->s && \
00287 ( !( (f)->s->status & PROXY_WORKER_NOT_USABLE_BITMAP) ) && \
00288 PROXY_WORKER_IS_INITIALIZED(f) )
00289
00290
00291 #define PROXY_WORKER_DEFAULT_RETRY 60
00292 #define PROXY_WORKER_MAX_ROUTE_SIZ 63
00293
00294
00295 typedef struct {
00296 int status;
00297 apr_time_t error_time;
00298 int retries;
00299 int lbstatus;
00300 int lbfactor;
00301 apr_off_t transferred;
00302 apr_off_t read;
00303 apr_size_t elected;
00304 char route[PROXY_WORKER_MAX_ROUTE_SIZ+1];
00305 char redirect[PROXY_WORKER_MAX_ROUTE_SIZ+1];
00306 void *context;
00307 apr_size_t busy;
00308 int lbset;
00309 } proxy_worker_stat;
00310
00311
00312 struct proxy_worker {
00313 int id;
00314 apr_interval_time_t retry;
00315 int lbfactor;
00316 const char *name;
00317 const char *scheme;
00318 const char *hostname;
00319 const char *route;
00320 const char *redirect;
00321 int status;
00322 apr_port_t port;
00323 int min;
00324 int smax;
00325 int hmax;
00326 apr_interval_time_t ttl;
00327
00328 apr_interval_time_t timeout;
00329 char timeout_set;
00330 apr_interval_time_t acquire;
00331 char acquire_set;
00332 apr_size_t recv_buffer_size;
00333 char recv_buffer_size_set;
00334 apr_size_t io_buffer_size;
00335 char io_buffer_size_set;
00336 char keepalive;
00337 char keepalive_set;
00338 proxy_conn_pool *cp;
00339 proxy_worker_stat *s;
00340 void *opaque;
00341 int is_address_reusable;
00342 #if APR_HAS_THREADS
00343 apr_thread_mutex_t *mutex;
00344 #endif
00345 void *context;
00346 enum {
00347 flush_off,
00348 flush_on,
00349 flush_auto
00350 } flush_packets;
00351 int flush_wait;
00352 int lbset;
00353 apr_interval_time_t ping_timeout;
00354 char ping_timeout_set;
00355 char retry_set;
00356 char disablereuse;
00357 char disablereuse_set;
00358 };
00359
00360
00361
00362
00363
00364 #define PROXY_FLUSH_WAIT 10000
00365
00366 struct proxy_balancer {
00367 apr_array_header_t *workers;
00368 const char *name;
00369 const char *sticky;
00370 int sticky_force;
00371 apr_interval_time_t timeout;
00372 int max_attempts;
00373 char max_attempts_set;
00374 proxy_balancer_method *lbmethod;
00375
00376
00377
00378
00379
00380
00381 #if APR_HAS_THREADS
00382 apr_thread_mutex_t *mutex;
00383 #endif
00384 void *context;
00385 };
00386
00387 struct proxy_balancer_method {
00388 const char *name;
00389 proxy_worker *(*finder)(proxy_balancer *balancer,
00390 request_rec *r);
00391 void *context;
00392 };
00393
00394 #if APR_HAS_THREADS
00395 #define PROXY_THREAD_LOCK(x) apr_thread_mutex_lock((x)->mutex)
00396 #define PROXY_THREAD_UNLOCK(x) apr_thread_mutex_unlock((x)->mutex)
00397 #else
00398 #define PROXY_THREAD_LOCK(x) APR_SUCCESS
00399 #define PROXY_THREAD_UNLOCK(x) APR_SUCCESS
00400 #endif
00401
00402
00403
00404
00405
00406
00407 #if !defined(WIN32)
00408 #define PROXY_DECLARE(type) type
00409 #define PROXY_DECLARE_NONSTD(type) type
00410 #define PROXY_DECLARE_DATA
00411 #elif defined(PROXY_DECLARE_STATIC)
00412 #define PROXY_DECLARE(type) type __stdcall
00413 #define PROXY_DECLARE_NONSTD(type) type
00414 #define PROXY_DECLARE_DATA
00415 #elif defined(PROXY_DECLARE_EXPORT)
00416 #define PROXY_DECLARE(type) __declspec(dllexport) type __stdcall
00417 #define PROXY_DECLARE_NONSTD(type) __declspec(dllexport) type
00418 #define PROXY_DECLARE_DATA __declspec(dllexport)
00419 #else
00420 #define PROXY_DECLARE(type) __declspec(dllimport) type __stdcall
00421 #define PROXY_DECLARE_NONSTD(type) __declspec(dllimport) type
00422 #define PROXY_DECLARE_DATA __declspec(dllimport)
00423 #endif
00424
00429 #define PROXY_OPTIONAL_HOOK(name,fn,pre,succ,order) \
00430 APR_OPTIONAL_HOOK(proxy,name,fn,pre,succ,order)
00431
00432 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, scheme_handler, (request_rec *r,
00433 proxy_worker *worker, proxy_server_conf *conf, char *url,
00434 const char *proxyhost, apr_port_t proxyport))
00435 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, canon_handler, (request_rec *r,
00436 char *url))
00437
00438 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, create_req, (request_rec *r, request_rec *pr))
00439 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, fixups, (request_rec *r))
00440
00441
00449 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, pre_request, (proxy_worker **worker,
00450 proxy_balancer **balancer,
00451 request_rec *r,
00452 proxy_server_conf *conf, char **url))
00453
00457 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, post_request, (proxy_worker *worker,
00458 proxy_balancer *balancer, request_rec *r,
00459 proxy_server_conf *conf))
00460
00461
00466 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, request_status,
00467 (int *status, request_rec *r))
00468
00469
00470
00471 PROXY_DECLARE(request_rec *)ap_proxy_make_fake_req(conn_rec *c, request_rec *r);
00472 PROXY_DECLARE(int) ap_proxy_hex2c(const char *x);
00473 PROXY_DECLARE(void) ap_proxy_c2hex(int ch, char *x);
00474 PROXY_DECLARE(char *)ap_proxy_canonenc(apr_pool_t *p, const char *x, int len, enum enctype t,
00475 int forcedec, int proxyreq);
00476 PROXY_DECLARE(char *)ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, char **userp,
00477 char **passwordp, char **hostp, apr_port_t *port);
00478 PROXY_DECLARE(const char *)ap_proxy_date_canon(apr_pool_t *p, const char *x);
00479 PROXY_DECLARE(int) ap_proxy_liststr(const char *list, const char *val);
00480 PROXY_DECLARE(char *)ap_proxy_removestr(apr_pool_t *pool, const char *list, const char *val);
00481 PROXY_DECLARE(int) ap_proxy_hex2sec(const char *x);
00482 PROXY_DECLARE(void) ap_proxy_sec2hex(int t, char *y);
00483 PROXY_DECLARE(int) ap_proxyerror(request_rec *r, int statuscode, const char *message);
00484 PROXY_DECLARE(int) ap_proxy_is_ipaddr(struct dirconn_entry *This, apr_pool_t *p);
00485 PROXY_DECLARE(int) ap_proxy_is_domainname(struct dirconn_entry *This, apr_pool_t *p);
00486 PROXY_DECLARE(int) ap_proxy_is_hostname(struct dirconn_entry *This, apr_pool_t *p);
00487 PROXY_DECLARE(int) ap_proxy_is_word(struct dirconn_entry *This, apr_pool_t *p);
00488 PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf, apr_sockaddr_t *uri_addr);
00489 PROXY_DECLARE(int) ap_proxy_pre_http_request(conn_rec *c, request_rec *r);
00490 PROXY_DECLARE(apr_status_t) ap_proxy_string_read(conn_rec *c, apr_bucket_brigade *bb, char *buff, size_t bufflen, int *eos);
00491 PROXY_DECLARE(void) ap_proxy_table_unmerge(apr_pool_t *p, apr_table_t *t, char *key);
00492
00493 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 *);
00494 PROXY_DECLARE(apr_status_t) ap_proxy_ssl_connection_cleanup(proxy_conn_rec *conn,
00495 request_rec *r);
00496 PROXY_DECLARE(int) ap_proxy_ssl_enable(conn_rec *c);
00497 PROXY_DECLARE(int) ap_proxy_ssl_disable(conn_rec *c);
00498 PROXY_DECLARE(int) ap_proxy_conn_is_https(conn_rec *c);
00499 PROXY_DECLARE(const char *) ap_proxy_ssl_val(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, const char *var);
00500
00501
00502 PROXY_DECLARE(const char *) ap_proxy_location_reverse_map(request_rec *r, proxy_dir_conf *conf, const char *url);
00503 PROXY_DECLARE(const char *) ap_proxy_cookie_reverse_map(request_rec *r, proxy_dir_conf *conf, const char *str);
00504
00505 #if !defined(WIN32)
00506 typedef const char *(*ap_proxy_header_reverse_map_fn)(request_rec *,
00507 proxy_dir_conf *, const char *);
00508 #elif defined(PROXY_DECLARE_STATIC)
00509 typedef const char *(__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *,
00510 proxy_dir_conf *, const char *);
00511 #elif defined(PROXY_DECLARE_EXPORT)
00512 typedef __declspec(dllexport) const char *
00513 (__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *,
00514 proxy_dir_conf *, const char *);
00515 #else
00516 typedef __declspec(dllimport) const char *
00517 (__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *,
00518 proxy_dir_conf *, const char *);
00519 #endif
00520
00521
00522
00530 PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker(apr_pool_t *p,
00531 proxy_server_conf *conf,
00532 const char *url);
00541 PROXY_DECLARE(const char *) ap_proxy_add_worker(proxy_worker **worker,
00542 apr_pool_t *p,
00543 proxy_server_conf *conf,
00544 const char *url);
00545
00551 PROXY_DECLARE(proxy_worker *) ap_proxy_create_worker(apr_pool_t *p);
00552
00560 PROXY_DECLARE(void) ap_proxy_initialize_worker_share(proxy_server_conf *conf,
00561 proxy_worker *worker,
00562 server_rec *s);
00563
00564
00571 PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker,
00572 server_rec *s);
00580 PROXY_DECLARE(proxy_balancer *) ap_proxy_get_balancer(apr_pool_t *p,
00581 proxy_server_conf *conf,
00582 const char *url);
00591 PROXY_DECLARE(const char *) ap_proxy_add_balancer(proxy_balancer **balancer,
00592 apr_pool_t *p,
00593 proxy_server_conf *conf,
00594 const char *url);
00595
00603 PROXY_DECLARE(void) ap_proxy_add_worker_to_balancer(apr_pool_t *pool,
00604 proxy_balancer *balancer,
00605 proxy_worker *worker);
00617 PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker,
00618 proxy_balancer **balancer,
00619 request_rec *r,
00620 proxy_server_conf *conf,
00621 char **url);
00632 PROXY_DECLARE(int) ap_proxy_post_request(proxy_worker *worker,
00633 proxy_balancer *balancer,
00634 request_rec *r,
00635 proxy_server_conf *conf);
00636
00642 PROXY_DECLARE(int) ap_proxy_request_status(int *status, request_rec *r);
00643
00659 PROXY_DECLARE(int) ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
00660 proxy_server_conf *conf,
00661 proxy_worker *worker,
00662 proxy_conn_rec *conn,
00663 apr_uri_t *uri,
00664 char **url,
00665 const char *proxyname,
00666 apr_port_t proxyport,
00667 char *server_portstr,
00668 int server_portstr_size);
00680 PROXY_DECLARE(int) ap_proxy_retry_worker(const char *proxy_function,
00681 proxy_worker *worker,
00682 server_rec *s);
00693 PROXY_DECLARE(int) ap_proxy_acquire_connection(const char *proxy_function,
00694 proxy_conn_rec **conn,
00695 proxy_worker *worker,
00696 server_rec *s);
00705 PROXY_DECLARE(int) ap_proxy_release_connection(const char *proxy_function,
00706 proxy_conn_rec *conn,
00707 server_rec *s);
00718 PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
00719 proxy_conn_rec *conn,
00720 proxy_worker *worker,
00721 server_rec *s);
00730 PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function,
00731 proxy_conn_rec *conn,
00732 conn_rec *c, server_rec *s);
00740 PROXY_DECLARE(void) ap_proxy_backend_broke(request_rec *r,
00741 apr_bucket_brigade *brigade);
00742
00743
00744 #if MODULE_MAGIC_NUMBER_MAJOR > 20020903
00745 #define PROXY_HAS_SCOREBOARD 1
00746 #else
00747 #define PROXY_HAS_SCOREBOARD 0
00748 #endif
00749
00750 #define PROXY_LBMETHOD "proxylbmethod"
00751
00752
00753
00754
00755 #define PROXY_DYNAMIC_BALANCER_LIMIT 16
00756
00760 int ap_proxy_lb_workers(void);
00761
00762
00763 extern module PROXY_DECLARE_DATA proxy_module;
00764
00765 extern int PROXY_DECLARE_DATA proxy_lb_workers;
00766
00767 #endif
00768