github.com/krum110487/go-htaccess@v0.0.0-20240316004156-60641c8e7598/tests/data/apache_2_4_58/include/mod_proxy.h (about) 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 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 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. 15 */ 16 17 #ifndef MOD_PROXY_H 18 #define MOD_PROXY_H 19 20 /** 21 * @file mod_proxy.h 22 * @brief Proxy Extension Module for Apache 23 * 24 * @defgroup MOD_PROXY mod_proxy 25 * @ingroup APACHE_MODS 26 * @{ 27 */ 28 29 #include "apr_hooks.h" 30 #include "apr_optional.h" 31 #include "apr.h" 32 #include "apr_lib.h" 33 #include "apr_strings.h" 34 #include "apr_buckets.h" 35 #include "apr_md5.h" 36 #include "apr_network_io.h" 37 #include "apr_pools.h" 38 #include "apr_strings.h" 39 #include "apr_uri.h" 40 #include "apr_date.h" 41 #include "apr_strmatch.h" 42 #include "apr_fnmatch.h" 43 #include "apr_reslist.h" 44 #define APR_WANT_STRFUNC 45 #include "apr_want.h" 46 #include "apr_uuid.h" 47 #include "util_mutex.h" 48 #include "apr_global_mutex.h" 49 #include "apr_thread_mutex.h" 50 51 #include "httpd.h" 52 #include "http_config.h" 53 #include "ap_config.h" 54 #include "http_core.h" 55 #include "http_protocol.h" 56 #include "http_request.h" 57 #include "http_vhost.h" 58 #include "http_main.h" 59 #include "http_log.h" 60 #include "http_connection.h" 61 #include "http_ssl.h" 62 #include "util_filter.h" 63 #include "util_ebcdic.h" 64 #include "ap_provider.h" 65 #include "ap_slotmem.h" 66 67 #if APR_HAVE_NETINET_IN_H 68 #include <netinet/in.h> 69 #endif 70 #if APR_HAVE_ARPA_INET_H 71 #include <arpa/inet.h> 72 #endif 73 74 /* for proxy_canonenc() */ 75 enum enctype { 76 enc_path, enc_search, enc_user, enc_fpath, enc_parm 77 }; 78 79 /* Flags for ap_proxy_canonenc_ex */ 80 #define PROXY_CANONENC_FORCEDEC 0x01 81 #define PROXY_CANONENC_NOENCODEDSLASHENCODING 0x02 82 83 typedef enum { 84 NONE, TCP, OPTIONS, HEAD, GET, CPING, PROVIDER, OPTIONS11, HEAD11, GET11, EOT 85 } hcmethod_t; 86 87 typedef struct { 88 hcmethod_t method; 89 char *name; 90 int implemented; 91 } proxy_hcmethods_t; 92 93 typedef struct { 94 unsigned int bit; 95 char flag; 96 const char *name; 97 } proxy_wstat_t; 98 99 #define BALANCER_PREFIX "balancer://" 100 101 #if APR_CHARSET_EBCDIC 102 #define CRLF "\r\n" 103 #else /*APR_CHARSET_EBCDIC*/ 104 #define CRLF "\015\012" 105 #endif /*APR_CHARSET_EBCDIC*/ 106 107 /* default Max-Forwards header setting */ 108 /* Set this to -1, which complies with RFC2616 by not setting 109 * max-forwards if the client didn't send it to us. 110 */ 111 #define DEFAULT_MAX_FORWARDS -1 112 113 typedef struct proxy_balancer proxy_balancer; 114 typedef struct proxy_worker proxy_worker; 115 typedef struct proxy_conn_pool proxy_conn_pool; 116 typedef struct proxy_balancer_method proxy_balancer_method; 117 118 /* static information about a remote proxy */ 119 struct proxy_remote { 120 const char *scheme; /* the schemes handled by this proxy, or '*' */ 121 const char *protocol; /* the scheme used to talk to this proxy */ 122 const char *hostname; /* the hostname of this proxy */ 123 ap_regex_t *regexp; /* compiled regex (if any) for the remote */ 124 int use_regex; /* simple boolean. True if we have a regex pattern */ 125 apr_port_t port; /* the port for this proxy */ 126 }; 127 128 #define PROXYPASS_NOCANON 0x01 129 #define PROXYPASS_INTERPOLATE 0x02 130 #define PROXYPASS_NOQUERY 0x04 131 #define PROXYPASS_MAP_ENCODED 0x08 132 #define PROXYPASS_MAP_SERVLET 0x18 /* + MAP_ENCODED */ 133 struct proxy_alias { 134 const char *real; 135 const char *fake; 136 ap_regex_t *regex; 137 unsigned int flags; 138 proxy_balancer *balancer; /* only valid for reverse-proxys */ 139 }; 140 141 struct dirconn_entry { 142 char *name; 143 struct in_addr addr, mask; 144 struct apr_sockaddr_t *hostaddr; 145 int (*matcher) (struct dirconn_entry * This, request_rec *r); 146 }; 147 148 struct noproxy_entry { 149 const char *name; 150 struct apr_sockaddr_t *addr; 151 }; 152 153 typedef struct { 154 apr_array_header_t *proxies; 155 apr_array_header_t *sec_proxy; 156 apr_array_header_t *aliases; 157 apr_array_header_t *noproxies; 158 apr_array_header_t *dirconn; 159 apr_array_header_t *workers; /* non-balancer workers, eg ProxyPass http://example.com */ 160 apr_array_header_t *balancers; /* list of balancers @ config time */ 161 proxy_worker *forward; /* forward proxy worker */ 162 proxy_worker *reverse; /* reverse "module-driven" proxy worker */ 163 const char *domain; /* domain name to use in absence of a domain name in the request */ 164 const char *id; 165 apr_pool_t *pool; /* Pool used for allocating this struct's elements */ 166 int req; /* true if proxy requests are enabled */ 167 int max_balancers; /* maximum number of allowed balancers */ 168 int bgrowth; /* number of post-config balancers can added */ 169 enum { 170 via_off, 171 via_on, 172 via_block, 173 via_full 174 } viaopt; /* how to deal with proxy Via: headers */ 175 apr_size_t recv_buffer_size; 176 apr_size_t io_buffer_size; 177 long maxfwd; 178 apr_interval_time_t timeout; 179 enum { 180 bad_error, 181 bad_ignore, 182 bad_body 183 } badopt; /* how to deal with bad headers */ 184 enum { 185 status_off, 186 status_on, 187 status_full 188 } proxy_status; /* Status display options */ 189 apr_sockaddr_t *source_address; 190 apr_global_mutex_t *mutex; /* global lock, for pool, etc */ 191 ap_slotmem_instance_t *bslot; /* balancers shm data - runtime */ 192 ap_slotmem_provider_t *storage; 193 194 unsigned int req_set:1; 195 unsigned int viaopt_set:1; 196 unsigned int recv_buffer_size_set:1; 197 unsigned int io_buffer_size_set:1; 198 unsigned int maxfwd_set:1; 199 unsigned int timeout_set:1; 200 unsigned int badopt_set:1; 201 unsigned int proxy_status_set:1; 202 unsigned int source_address_set:1; 203 unsigned int bgrowth_set:1; 204 unsigned int bal_persist:1; 205 unsigned int inherit:1; 206 unsigned int inherit_set:1; 207 unsigned int ppinherit:1; 208 unsigned int ppinherit_set:1; 209 unsigned int map_encoded_one:1; 210 unsigned int map_encoded_all:1; 211 } proxy_server_conf; 212 213 typedef struct { 214 const char *p; /* The path */ 215 ap_regex_t *r; /* Is this a regex? */ 216 217 /* FIXME 218 * ProxyPassReverse and friends are documented as working inside 219 * <Location>. But in fact they never have done in the case of 220 * more than one <Location>, because the server_conf can't see it. 221 * We need to move them to the per-dir config. 222 * Discussed in February 2005: 223 * http://marc.theaimsgroup.com/?l=apache-httpd-dev&m=110726027118798&w=2 224 */ 225 apr_array_header_t *raliases; 226 apr_array_header_t* cookie_paths; 227 apr_array_header_t* cookie_domains; 228 signed char p_is_fnmatch; /* Is the path an fnmatch candidate? */ 229 signed char interpolate_env; 230 struct proxy_alias *alias; 231 232 /** 233 * the following setting masks the error page 234 * returned from the 'proxied server' and just 235 * forwards the status code upwards. 236 * This allows the main server (us) to generate 237 * the error page, (so it will look like a error 238 * returned from the rest of the system 239 */ 240 unsigned int error_override:1; 241 unsigned int preserve_host:1; 242 unsigned int preserve_host_set:1; 243 unsigned int error_override_set:1; 244 unsigned int alias_set:1; 245 unsigned int add_forwarded_headers:1; 246 unsigned int add_forwarded_headers_set:1; 247 248 /** Named back references */ 249 apr_array_header_t *refs; 250 251 unsigned int forward_100_continue:1; 252 unsigned int forward_100_continue_set:1; 253 254 apr_array_header_t *error_override_codes; 255 } proxy_dir_conf; 256 257 /* if we interpolate env vars per-request, we'll need a per-request 258 * copy of the reverse proxy config 259 */ 260 typedef struct { 261 apr_array_header_t *raliases; 262 apr_array_header_t* cookie_paths; 263 apr_array_header_t* cookie_domains; 264 } proxy_req_conf; 265 266 typedef struct { 267 conn_rec *connection; 268 request_rec *r; /* Request record of the backend request 269 * that is used over the backend connection. */ 270 proxy_worker *worker; /* Connection pool this connection belongs to */ 271 apr_pool_t *pool; /* Subpool for hostname and addr data */ 272 const char *hostname; 273 apr_sockaddr_t *addr; /* Preparsed remote address info */ 274 apr_pool_t *scpool; /* Subpool used for socket and connection data */ 275 apr_socket_t *sock; /* Connection socket */ 276 void *data; /* per scheme connection data */ 277 void *forward; /* opaque forward proxy data */ 278 apr_uint32_t flags; /* Connection flags */ 279 apr_port_t port; 280 unsigned int is_ssl:1; 281 unsigned int close:1; /* Close 'this' connection */ 282 unsigned int need_flush:1; /* Flag to decide whether we need to flush the 283 * filter chain or not */ 284 unsigned int inreslist:1; /* connection in apr_reslist? */ 285 const char *uds_path; /* Unix domain socket path */ 286 const char *ssl_hostname;/* Hostname (SNI) in use by SSL connection */ 287 apr_bucket_brigade *tmp_bb;/* Temporary brigade created with the connection 288 * and its scpool/bucket_alloc (NULL before), 289 * must be left cleaned when used (locally). 290 */ 291 } proxy_conn_rec; 292 293 typedef struct { 294 float cache_completion; /* completion percentage */ 295 int content_length; /* length of the content */ 296 } proxy_completion; 297 298 /* Connection pool */ 299 struct proxy_conn_pool { 300 apr_pool_t *pool; /* The pool used in constructor and destructor calls */ 301 apr_sockaddr_t *addr; /* Preparsed remote address info */ 302 apr_reslist_t *res; /* Connection resource list */ 303 proxy_conn_rec *conn; /* Single connection for prefork mpm */ 304 apr_pool_t *dns_pool; /* The pool used for worker scoped DNS resolutions */ 305 }; 306 307 #define AP_VOLATILIZE_T(T, x) (*(T volatile *)&(x)) 308 309 /* worker status bits */ 310 /* 311 * NOTE: Keep up-to-date w/ proxy_wstat_tbl[] 312 * in mod_proxy.c ! 313 */ 314 #define PROXY_WORKER_INITIALIZED 0x0001 315 #define PROXY_WORKER_IGNORE_ERRORS 0x0002 316 #define PROXY_WORKER_DRAIN 0x0004 317 #define PROXY_WORKER_GENERIC 0x0008 318 #define PROXY_WORKER_IN_SHUTDOWN 0x0010 319 #define PROXY_WORKER_DISABLED 0x0020 320 #define PROXY_WORKER_STOPPED 0x0040 321 #define PROXY_WORKER_IN_ERROR 0x0080 322 #define PROXY_WORKER_HOT_STANDBY 0x0100 323 #define PROXY_WORKER_FREE 0x0200 324 #define PROXY_WORKER_HC_FAIL 0x0400 325 #define PROXY_WORKER_HOT_SPARE 0x0800 326 327 /* worker status flags */ 328 #define PROXY_WORKER_INITIALIZED_FLAG 'O' 329 #define PROXY_WORKER_IGNORE_ERRORS_FLAG 'I' 330 #define PROXY_WORKER_DRAIN_FLAG 'N' 331 #define PROXY_WORKER_GENERIC_FLAG 'G' 332 #define PROXY_WORKER_IN_SHUTDOWN_FLAG 'U' 333 #define PROXY_WORKER_DISABLED_FLAG 'D' 334 #define PROXY_WORKER_STOPPED_FLAG 'S' 335 #define PROXY_WORKER_IN_ERROR_FLAG 'E' 336 #define PROXY_WORKER_HOT_STANDBY_FLAG 'H' 337 #define PROXY_WORKER_FREE_FLAG 'F' 338 #define PROXY_WORKER_HC_FAIL_FLAG 'C' 339 #define PROXY_WORKER_HOT_SPARE_FLAG 'R' 340 341 #define PROXY_WORKER_NOT_USABLE_BITMAP ( PROXY_WORKER_IN_SHUTDOWN | \ 342 PROXY_WORKER_DISABLED | PROXY_WORKER_STOPPED | PROXY_WORKER_IN_ERROR | \ 343 PROXY_WORKER_HC_FAIL ) 344 345 /* NOTE: these check the shared status */ 346 #define PROXY_WORKER_IS_INITIALIZED(f) ( (f)->s->status & PROXY_WORKER_INITIALIZED ) 347 348 #define PROXY_WORKER_IS_STANDBY(f) ( (f)->s->status & PROXY_WORKER_HOT_STANDBY ) 349 350 #define PROXY_WORKER_IS_SPARE(f) ( (f)->s->status & PROXY_WORKER_HOT_SPARE ) 351 352 #define PROXY_WORKER_IS_USABLE(f) ( ( !( (f)->s->status & PROXY_WORKER_NOT_USABLE_BITMAP) ) && \ 353 PROXY_WORKER_IS_INITIALIZED(f) ) 354 355 #define PROXY_WORKER_IS_DRAINING(f) ( (f)->s->status & PROXY_WORKER_DRAIN ) 356 357 #define PROXY_WORKER_IS_GENERIC(f) ( (f)->s->status & PROXY_WORKER_GENERIC ) 358 359 #define PROXY_WORKER_IS_HCFAILED(f) ( (f)->s->status & PROXY_WORKER_HC_FAIL ) 360 361 #define PROXY_WORKER_IS_ERROR(f) ( (f)->s->status & PROXY_WORKER_IN_ERROR ) 362 363 #define PROXY_WORKER_IS(f, b) ( (f)->s->status & (b) ) 364 365 /* default worker retry timeout in seconds */ 366 #define PROXY_WORKER_DEFAULT_RETRY 60 367 368 /* Some max char string sizes, for shm fields */ 369 #define PROXY_WORKER_MAX_SCHEME_SIZE 16 370 #define PROXY_WORKER_MAX_ROUTE_SIZE 64 371 #define PROXY_BALANCER_MAX_ROUTE_SIZE PROXY_WORKER_MAX_ROUTE_SIZE 372 #define PROXY_WORKER_MAX_NAME_SIZE 96 373 #define PROXY_BALANCER_MAX_NAME_SIZE PROXY_WORKER_MAX_NAME_SIZE 374 #define PROXY_WORKER_MAX_HOSTNAME_SIZE 64 375 #define PROXY_BALANCER_MAX_HOSTNAME_SIZE PROXY_WORKER_MAX_HOSTNAME_SIZE 376 #define PROXY_BALANCER_MAX_STICKY_SIZE 64 377 #define PROXY_WORKER_MAX_SECRET_SIZE 64 378 379 #define PROXY_RFC1035_HOSTNAME_SIZE 256 380 #define PROXY_WORKER_EXT_NAME_SIZE 384 381 382 /* RFC-1035 mentions limits of 255 for host-names and 253 for domain-names, 383 * dotted together(?) this would fit the below size (+ trailing NUL). 384 */ 385 #define PROXY_WORKER_RFC1035_NAME_SIZE 512 386 387 #define PROXY_MAX_PROVIDER_NAME_SIZE 16 388 389 #define PROXY_STRNCPY(dst, src) ap_proxy_strncpy((dst), (src), (sizeof(dst))) 390 391 #define PROXY_COPY_CONF_PARAMS(w, c) \ 392 do { \ 393 (w)->s->timeout = (c)->timeout; \ 394 (w)->s->timeout_set = (c)->timeout_set; \ 395 (w)->s->recv_buffer_size = (c)->recv_buffer_size; \ 396 (w)->s->recv_buffer_size_set = (c)->recv_buffer_size_set; \ 397 (w)->s->io_buffer_size = (c)->io_buffer_size; \ 398 (w)->s->io_buffer_size_set = (c)->io_buffer_size_set; \ 399 } while (0) 400 401 #define PROXY_SHOULD_PING_100_CONTINUE(w, r) \ 402 ((w)->s->ping_timeout_set \ 403 && (PROXYREQ_REVERSE == (r)->proxyreq) \ 404 && ap_request_has_body((r))) 405 406 #define PROXY_DO_100_CONTINUE(w, r) \ 407 (PROXY_SHOULD_PING_100_CONTINUE(w, r) \ 408 && !apr_table_get((r)->subprocess_env, "force-proxy-request-1.0")) 409 410 /* use 2 hashes */ 411 typedef struct { 412 unsigned int def; 413 unsigned int fnv; 414 } proxy_hashes ; 415 416 /* Runtime worker status information. Shared in scoreboard */ 417 /* The addition of member uds_path in 2.4.7 was an incompatible API change. */ 418 typedef struct { 419 char name[PROXY_WORKER_MAX_NAME_SIZE]; 420 char scheme[PROXY_WORKER_MAX_SCHEME_SIZE]; /* scheme to use ajp|http|https */ 421 char hostname[PROXY_WORKER_MAX_HOSTNAME_SIZE]; /* remote backend address (deprecated, use hostname_ex below) */ 422 char route[PROXY_WORKER_MAX_ROUTE_SIZE]; /* balancing route */ 423 char redirect[PROXY_WORKER_MAX_ROUTE_SIZE]; /* temporary balancing redirection route */ 424 char flusher[PROXY_WORKER_MAX_SCHEME_SIZE]; /* flush provider used by mod_proxy_fdpass */ 425 char uds_path[PROXY_WORKER_MAX_NAME_SIZE]; /* path to worker's unix domain socket if applicable */ 426 int lbset; /* load balancer cluster set */ 427 int retries; /* number of retries on this worker */ 428 int lbstatus; /* Current lbstatus */ 429 int lbfactor; /* dynamic lbfactor */ 430 int min; /* Desired minimum number of available connections */ 431 int smax; /* Soft maximum on the total number of connections */ 432 int hmax; /* Hard maximum on the total number of connections */ 433 int flush_wait; /* poll wait time in microseconds if flush_auto */ 434 int index; /* shm array index */ 435 proxy_hashes hash; /* hash of worker name */ 436 unsigned int status; /* worker status bitfield */ 437 enum { 438 flush_off, 439 flush_on, 440 flush_auto 441 } flush_packets; /* control AJP flushing */ 442 apr_time_t updated; /* timestamp of last update for dynamic workers, or queue-time of HC workers */ 443 apr_time_t error_time; /* time of the last error */ 444 apr_interval_time_t ttl; /* maximum amount of time in seconds a connection 445 * may be available while exceeding the soft limit */ 446 apr_interval_time_t retry; /* retry interval */ 447 apr_interval_time_t timeout; /* connection timeout */ 448 apr_interval_time_t acquire; /* acquire timeout when the maximum number of connections is exceeded */ 449 apr_interval_time_t ping_timeout; 450 apr_interval_time_t conn_timeout; 451 apr_size_t recv_buffer_size; 452 apr_size_t io_buffer_size; 453 apr_size_t elected; /* Number of times the worker was elected */ 454 apr_size_t busy; /* busyness factor */ 455 apr_port_t port; 456 apr_off_t transferred;/* Number of bytes transferred to remote */ 457 apr_off_t read; /* Number of bytes read from remote */ 458 void *context; /* general purpose storage */ 459 unsigned int keepalive:1; 460 unsigned int disablereuse:1; 461 unsigned int is_address_reusable:1; 462 unsigned int retry_set:1; 463 unsigned int timeout_set:1; 464 unsigned int acquire_set:1; 465 unsigned int ping_timeout_set:1; 466 unsigned int conn_timeout_set:1; 467 unsigned int recv_buffer_size_set:1; 468 unsigned int io_buffer_size_set:1; 469 unsigned int keepalive_set:1; 470 unsigned int disablereuse_set:1; 471 unsigned int was_malloced:1; 472 unsigned int is_name_matchable:1; 473 char hcuri[PROXY_WORKER_MAX_ROUTE_SIZE]; /* health check uri */ 474 char hcexpr[PROXY_WORKER_MAX_SCHEME_SIZE]; /* name of condition expr for health check */ 475 int passes; /* number of successes for check to pass */ 476 int pcount; /* current count of passes */ 477 int fails; /* number of failures for check to fail */ 478 int fcount; /* current count of failures */ 479 hcmethod_t method; /* method to use for health check */ 480 apr_interval_time_t interval; 481 char upgrade[PROXY_WORKER_MAX_SCHEME_SIZE];/* upgrade protocol used by mod_proxy_wstunnel */ 482 char hostname_ex[PROXY_RFC1035_HOSTNAME_SIZE]; /* RFC1035 compliant version of the remote backend address */ 483 apr_size_t response_field_size; /* Size of proxy response buffer in bytes. */ 484 unsigned int response_field_size_set:1; 485 char secret[PROXY_WORKER_MAX_SECRET_SIZE]; /* authentication secret (e.g. AJP13) */ 486 char name_ex[PROXY_WORKER_EXT_NAME_SIZE]; /* Extended name (>96 chars for 2.4.x) */ 487 } proxy_worker_shared; 488 489 #define ALIGNED_PROXY_WORKER_SHARED_SIZE (APR_ALIGN_DEFAULT(sizeof(proxy_worker_shared))) 490 491 /* Worker configuration */ 492 struct proxy_worker { 493 proxy_hashes hash; /* hash of worker name */ 494 unsigned int local_status; /* status of per-process worker */ 495 proxy_conn_pool *cp; /* Connection pool to use */ 496 proxy_worker_shared *s; /* Shared data */ 497 proxy_balancer *balancer; /* which balancer am I in? */ 498 #if APR_HAS_THREADS 499 apr_thread_mutex_t *tmutex; /* Thread lock for updating address cache */ 500 #endif 501 void *context; /* general purpose storage */ 502 ap_conf_vector_t *section_config; /* <Proxy>-section wherein defined */ 503 }; 504 505 /* default to health check every 30 seconds */ 506 #define HCHECK_WATHCHDOG_DEFAULT_INTERVAL (30) 507 /* The watchdog runs every 2 seconds, which is also the minimal check */ 508 #define HCHECK_WATHCHDOG_INTERVAL (2) 509 510 /* 511 * Time to wait (in microseconds) to find out if more data is currently 512 * available at the backend. 513 */ 514 #define PROXY_FLUSH_WAIT 10000 515 516 typedef struct { 517 char sticky_path[PROXY_BALANCER_MAX_STICKY_SIZE]; /* URL sticky session identifier */ 518 char sticky[PROXY_BALANCER_MAX_STICKY_SIZE]; /* sticky session identifier */ 519 char lbpname[PROXY_MAX_PROVIDER_NAME_SIZE]; /* lbmethod provider name */ 520 char nonce[APR_UUID_FORMATTED_LENGTH + 1]; 521 char name[PROXY_BALANCER_MAX_NAME_SIZE]; 522 char sname[PROXY_BALANCER_MAX_NAME_SIZE]; 523 char vpath[PROXY_BALANCER_MAX_ROUTE_SIZE]; 524 char vhost[PROXY_BALANCER_MAX_HOSTNAME_SIZE]; 525 apr_interval_time_t timeout; /* Timeout for waiting on free connection */ 526 apr_time_t wupdated; /* timestamp of last change to workers list */ 527 int max_attempts; /* Number of attempts before failing */ 528 int index; /* shm array index */ 529 proxy_hashes hash; 530 unsigned int sticky_force:1; /* Disable failover for sticky sessions */ 531 unsigned int scolonsep:1; /* true if ';' seps sticky session paths */ 532 unsigned int max_attempts_set:1; 533 unsigned int was_malloced:1; 534 unsigned int need_reset:1; 535 unsigned int vhosted:1; 536 unsigned int inactive:1; 537 unsigned int forcerecovery:1; 538 char sticky_separator; /* separator for sessionid/route */ 539 unsigned int forcerecovery_set:1; 540 unsigned int scolonsep_set:1; 541 unsigned int sticky_force_set:1; 542 unsigned int nonce_set:1; 543 unsigned int sticky_separator_set:1; 544 } proxy_balancer_shared; 545 546 #define ALIGNED_PROXY_BALANCER_SHARED_SIZE (APR_ALIGN_DEFAULT(sizeof(proxy_balancer_shared))) 547 548 struct proxy_balancer { 549 apr_array_header_t *workers; /* initially configured workers */ 550 apr_array_header_t *errstatuses; /* statuses to force members into error */ 551 ap_slotmem_instance_t *wslot; /* worker shm data - runtime */ 552 ap_slotmem_provider_t *storage; 553 int growth; /* number of post-config workers can added */ 554 int max_workers; /* maximum number of allowed workers */ 555 proxy_hashes hash; 556 apr_time_t wupdated; /* timestamp of last change to workers list */ 557 proxy_balancer_method *lbmethod; 558 apr_global_mutex_t *gmutex; /* global lock for updating list of workers */ 559 #if APR_HAS_THREADS 560 apr_thread_mutex_t *tmutex; /* Thread lock for updating shm */ 561 #endif 562 proxy_server_conf *sconf; 563 void *context; /* general purpose storage */ 564 proxy_balancer_shared *s; /* Shared data */ 565 int failontimeout; /* Whether to mark a member in Err if IO timeout occurs */ 566 unsigned int failontimeout_set:1; 567 unsigned int growth_set:1; 568 unsigned int lbmethod_set:1; 569 ap_conf_vector_t *section_config; /* <Proxy>-section wherein defined */ 570 }; 571 572 struct proxy_balancer_method { 573 const char *name; /* name of the load balancer method*/ 574 proxy_worker *(*finder)(proxy_balancer *balancer, 575 request_rec *r); 576 void *context; /* general purpose storage */ 577 apr_status_t (*reset)(proxy_balancer *balancer, server_rec *s); 578 apr_status_t (*age)(proxy_balancer *balancer, server_rec *s); 579 apr_status_t (*updatelbstatus)(proxy_balancer *balancer, proxy_worker *elected, server_rec *s); 580 }; 581 582 #define PROXY_THREAD_LOCK(x) ( (x) && (x)->tmutex ? apr_thread_mutex_lock((x)->tmutex) : APR_SUCCESS) 583 #define PROXY_THREAD_UNLOCK(x) ( (x) && (x)->tmutex ? apr_thread_mutex_unlock((x)->tmutex) : APR_SUCCESS) 584 585 #define PROXY_GLOBAL_LOCK(x) ( (x) && (x)->gmutex ? apr_global_mutex_lock((x)->gmutex) : APR_SUCCESS) 586 #define PROXY_GLOBAL_UNLOCK(x) ( (x) && (x)->gmutex ? apr_global_mutex_unlock((x)->gmutex) : APR_SUCCESS) 587 588 /* hooks */ 589 590 /* Create a set of PROXY_DECLARE(type), PROXY_DECLARE_NONSTD(type) and 591 * PROXY_DECLARE_DATA with appropriate export and import tags for the platform 592 */ 593 #if !defined(WIN32) 594 #define PROXY_DECLARE(type) type 595 #define PROXY_DECLARE_NONSTD(type) type 596 #define PROXY_DECLARE_DATA 597 #elif defined(PROXY_DECLARE_STATIC) 598 #define PROXY_DECLARE(type) type __stdcall 599 #define PROXY_DECLARE_NONSTD(type) type 600 #define PROXY_DECLARE_DATA 601 #elif defined(PROXY_DECLARE_EXPORT) 602 #define PROXY_DECLARE(type) __declspec(dllexport) type __stdcall 603 #define PROXY_DECLARE_NONSTD(type) __declspec(dllexport) type 604 #define PROXY_DECLARE_DATA __declspec(dllexport) 605 #else 606 #define PROXY_DECLARE(type) __declspec(dllimport) type __stdcall 607 #define PROXY_DECLARE_NONSTD(type) __declspec(dllimport) type 608 #define PROXY_DECLARE_DATA __declspec(dllimport) 609 #endif 610 611 /* Using PROXY_DECLARE_OPTIONAL_HOOK instead of 612 * APR_DECLARE_EXTERNAL_HOOK allows build/make_nw_export.awk 613 * to distinguish between hooks that implement 614 * proxy_hook_xx and proxy_hook_get_xx in mod_proxy.c and 615 * those which don't. 616 */ 617 #define PROXY_DECLARE_OPTIONAL_HOOK APR_DECLARE_EXTERNAL_HOOK 618 619 /* These 2 are in mod_proxy.c */ 620 extern PROXY_DECLARE_DATA proxy_hcmethods_t proxy_hcmethods[]; 621 extern PROXY_DECLARE_DATA proxy_wstat_t proxy_wstat_tbl[]; 622 623 /* Following 4 from health check */ 624 APR_DECLARE_OPTIONAL_FN(void, hc_show_exprs, (request_rec *)); 625 APR_DECLARE_OPTIONAL_FN(void, hc_select_exprs, (request_rec *, const char *)); 626 APR_DECLARE_OPTIONAL_FN(int, hc_valid_expr, (request_rec *, const char *)); 627 APR_DECLARE_OPTIONAL_FN(const char *, set_worker_hc_param, 628 (apr_pool_t *, server_rec *, proxy_worker *, 629 const char *, const char *, void *)); 630 631 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, section_post_config, 632 (apr_pool_t *p, apr_pool_t *plog, 633 apr_pool_t *ptemp, server_rec *s, 634 ap_conf_vector_t *section_config)) 635 636 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, scheme_handler, 637 (request_rec *r, proxy_worker *worker, 638 proxy_server_conf *conf, char *url, 639 const char *proxyhost, apr_port_t proxyport)) 640 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, check_trans, 641 (request_rec *r, const char *url)) 642 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, canon_handler, 643 (request_rec *r, char *url)) 644 645 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, create_req, (request_rec *r, request_rec *pr)) 646 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, fixups, (request_rec *r)) 647 648 649 /** 650 * pre request hook. 651 * It will return the most suitable worker at the moment 652 * and corresponding balancer. 653 * The url is rewritten from balancer://cluster/uri to scheme://host:port/uri 654 * and then the scheme_handler is called. 655 * 656 */ 657 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, pre_request, (proxy_worker **worker, 658 proxy_balancer **balancer, 659 request_rec *r, 660 proxy_server_conf *conf, char **url)) 661 /** 662 * post request hook. 663 * It is called after request for updating runtime balancer status. 664 */ 665 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, post_request, (proxy_worker *worker, 666 proxy_balancer *balancer, request_rec *r, 667 proxy_server_conf *conf)) 668 669 /** 670 * request status hook 671 * It is called after all proxy processing has been done. This gives other 672 * modules a chance to create default content on failure, for example 673 */ 674 APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, request_status, 675 (int *status, request_rec *r)) 676 677 /* proxy_util.c */ 678 679 PROXY_DECLARE(apr_status_t) ap_proxy_strncpy(char *dst, const char *src, 680 apr_size_t dlen); 681 PROXY_DECLARE(int) ap_proxy_hex2c(const char *x); 682 PROXY_DECLARE(void) ap_proxy_c2hex(int ch, char *x); 683 PROXY_DECLARE(char *)ap_proxy_canonenc_ex(apr_pool_t *p, const char *x, int len, enum enctype t, 684 int flags, int proxyreq); 685 PROXY_DECLARE(char *)ap_proxy_canonenc(apr_pool_t *p, const char *x, int len, enum enctype t, 686 int forcedec, int proxyreq); 687 PROXY_DECLARE(char *)ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, char **userp, 688 char **passwordp, char **hostp, apr_port_t *port); 689 PROXY_DECLARE(int) ap_proxyerror(request_rec *r, int statuscode, const char *message); 690 PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf, apr_sockaddr_t *uri_addr); 691 692 /** Test whether the hostname/address of the request are blocked by the ProxyBlock 693 * configuration. 694 * @param r request 695 * @param conf server configuration 696 * @param hostname hostname from request URI 697 * @param addr resolved address of hostname, or NULL if not known 698 * @return OK on success, or else an error 699 */ 700 PROXY_DECLARE(int) ap_proxy_checkproxyblock2(request_rec *r, proxy_server_conf *conf, 701 const char *hostname, apr_sockaddr_t *addr); 702 703 PROXY_DECLARE(int) ap_proxy_pre_http_request(conn_rec *c, request_rec *r); 704 /* DEPRECATED (will be replaced with ap_proxy_connect_backend */ 705 PROXY_DECLARE(int) ap_proxy_connect_to_backend(apr_socket_t **, const char *, apr_sockaddr_t *, const char *, proxy_server_conf *, request_rec *); 706 /* DEPRECATED (will be replaced with ap_proxy_check_connection */ 707 PROXY_DECLARE(apr_status_t) ap_proxy_ssl_connection_cleanup(proxy_conn_rec *conn, 708 request_rec *r); 709 PROXY_DECLARE(int) ap_proxy_ssl_enable(conn_rec *c); 710 PROXY_DECLARE(int) ap_proxy_ssl_disable(conn_rec *c); 711 PROXY_DECLARE(int) ap_proxy_ssl_engine(conn_rec *c, 712 ap_conf_vector_t *per_dir_config, 713 int enable); 714 PROXY_DECLARE(int) ap_proxy_conn_is_https(conn_rec *c); 715 PROXY_DECLARE(const char *) ap_proxy_ssl_val(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, const char *var); 716 717 /* Header mapping functions, and a typedef of their signature */ 718 PROXY_DECLARE(const char *) ap_proxy_location_reverse_map(request_rec *r, proxy_dir_conf *conf, const char *url); 719 PROXY_DECLARE(const char *) ap_proxy_cookie_reverse_map(request_rec *r, proxy_dir_conf *conf, const char *str); 720 721 #if !defined(WIN32) 722 typedef const char *(*ap_proxy_header_reverse_map_fn)(request_rec *, 723 proxy_dir_conf *, const char *); 724 #elif defined(PROXY_DECLARE_STATIC) 725 typedef const char *(__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *, 726 proxy_dir_conf *, const char *); 727 #elif defined(PROXY_DECLARE_EXPORT) 728 typedef __declspec(dllexport) const char * 729 (__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *, 730 proxy_dir_conf *, const char *); 731 #else 732 typedef __declspec(dllimport) const char * 733 (__stdcall *ap_proxy_header_reverse_map_fn)(request_rec *, 734 proxy_dir_conf *, const char *); 735 #endif 736 737 738 /* Connection pool API */ 739 /** 740 * Return the user-land, UDS aware worker name 741 * @param p memory pool used for displaying worker name 742 * @param worker the worker 743 * @return name 744 */ 745 746 PROXY_DECLARE(char *) ap_proxy_worker_name(apr_pool_t *p, 747 proxy_worker *worker); 748 749 /** 750 * Return whether a worker upgrade configuration matches Upgrade header 751 * @param p memory pool used for displaying worker name 752 * @param worker the worker 753 * @param upgrade the Upgrade header to match 754 * @param dflt default protocol (NULL for none) 755 * @return 1 (true) or 0 (false) 756 */ 757 PROXY_DECLARE(int) ap_proxy_worker_can_upgrade(apr_pool_t *p, 758 const proxy_worker *worker, 759 const char *upgrade, 760 const char *dflt); 761 762 /* Bitmask for ap_proxy_{define,get}_worker_ex(). */ 763 #define AP_PROXY_WORKER_IS_PREFIX (1u << 0) 764 #define AP_PROXY_WORKER_IS_MATCH (1u << 1) 765 #define AP_PROXY_WORKER_IS_MALLOCED (1u << 2) 766 #define AP_PROXY_WORKER_NO_UDS (1u << 3) 767 768 /** 769 * Get the worker from proxy configuration, looking for either PREFIXED or 770 * MATCHED or both types of workers according to given mask 771 * @param p memory pool used for finding worker 772 * @param balancer the balancer that the worker belongs to 773 * @param conf current proxy server configuration 774 * @param url url to find the worker from 775 * @param mask bitmask of AP_PROXY_WORKER_IS_* 776 * @return proxy_worker or NULL if not found 777 */ 778 PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker_ex(apr_pool_t *p, 779 proxy_balancer *balancer, 780 proxy_server_conf *conf, 781 const char *url, 782 unsigned int mask); 783 784 /** 785 * Get the worker from proxy configuration, both types 786 * @param p memory pool used for finding worker 787 * @param balancer the balancer that the worker belongs to 788 * @param conf current proxy server configuration 789 * @param url url to find the worker from 790 * @return proxy_worker or NULL if not found 791 */ 792 PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker(apr_pool_t *p, 793 proxy_balancer *balancer, 794 proxy_server_conf *conf, 795 const char *url); 796 797 /** 798 * Define and Allocate space for the worker to proxy configuration, of either 799 * PREFIXED or MATCHED type according to given mask 800 * @param p memory pool to allocate worker from 801 * @param worker the new worker 802 * @param balancer the balancer that the worker belongs to 803 * @param conf current proxy server configuration 804 * @param url url containing worker name 805 * @param mask bitmask of AP_PROXY_WORKER_IS_* 806 * @return error message or NULL if successful (*worker is new worker) 807 */ 808 PROXY_DECLARE(char *) ap_proxy_define_worker_ex(apr_pool_t *p, 809 proxy_worker **worker, 810 proxy_balancer *balancer, 811 proxy_server_conf *conf, 812 const char *url, 813 unsigned int mask); 814 815 /** 816 * Define and Allocate space for the worker to proxy configuration 817 * @param p memory pool to allocate worker from 818 * @param worker the new worker 819 * @param balancer the balancer that the worker belongs to 820 * @param conf current proxy server configuration 821 * @param url url containing worker name 822 * @param do_malloc true if shared struct should be malloced 823 * @return error message or NULL if successful (*worker is new worker) 824 */ 825 PROXY_DECLARE(char *) ap_proxy_define_worker(apr_pool_t *p, 826 proxy_worker **worker, 827 proxy_balancer *balancer, 828 proxy_server_conf *conf, 829 const char *url, 830 int do_malloc); 831 832 /** 833 * Define and Allocate space for the ap_strcmp_match()able worker to proxy 834 * configuration. 835 * @param p memory pool to allocate worker from 836 * @param worker the new worker 837 * @param balancer the balancer that the worker belongs to 838 * @param conf current proxy server configuration 839 * @param url url containing worker name (produces match pattern) 840 * @param do_malloc true if shared struct should be malloced 841 * @return error message or NULL if successful (*worker is new worker) 842 * @deprecated Replaced by ap_proxy_define_worker_ex() 843 */ 844 PROXY_DECLARE(char *) ap_proxy_define_match_worker(apr_pool_t *p, 845 proxy_worker **worker, 846 proxy_balancer *balancer, 847 proxy_server_conf *conf, 848 const char *url, 849 int do_malloc); 850 851 /** 852 * Share a defined proxy worker via shm 853 * @param worker worker to be shared 854 * @param shm location of shared info 855 * @param i index into shm 856 * @return APR_SUCCESS or error code 857 */ 858 PROXY_DECLARE(apr_status_t) ap_proxy_share_worker(proxy_worker *worker, 859 proxy_worker_shared *shm, 860 int i); 861 862 /** 863 * Initialize the worker by setting up worker connection pool and mutex 864 * @param worker worker to initialize 865 * @param s current server record 866 * @param p memory pool used for mutex and connection pool 867 * @return APR_SUCCESS or error code 868 */ 869 PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker, 870 server_rec *s, 871 apr_pool_t *p); 872 873 /** 874 * Verifies valid balancer name (eg: balancer://foo) 875 * @param name name to test 876 * @param i number of chars to test; 0 for all. 877 * @return true/false 878 */ 879 PROXY_DECLARE(int) ap_proxy_valid_balancer_name(char *name, int i); 880 881 882 /** 883 * Get the balancer from proxy configuration 884 * @param p memory pool used for temporary storage while finding balancer 885 * @param conf current proxy server configuration 886 * @param url url to find the worker from; must have balancer:// prefix 887 * @param careactive true if we care if the balancer is active or not 888 * @return proxy_balancer or NULL if not found 889 */ 890 PROXY_DECLARE(proxy_balancer *) ap_proxy_get_balancer(apr_pool_t *p, 891 proxy_server_conf *conf, 892 const char *url, 893 int careactive); 894 895 /** 896 * Update the balancer's vhost related fields 897 * @param p memory pool used for temporary storage while finding balancer 898 * @param balancer balancer to be updated 899 * @param url url to find vhost info 900 * @return error string or NULL if OK 901 */ 902 PROXY_DECLARE(char *) ap_proxy_update_balancer(apr_pool_t *p, 903 proxy_balancer *balancer, 904 const char *url); 905 906 /** 907 * Define and Allocate space for the balancer to proxy configuration 908 * @param p memory pool to allocate balancer from 909 * @param balancer the new balancer 910 * @param conf current proxy server configuration 911 * @param url url containing balancer name 912 * @param alias alias/fake-path to this balancer 913 * @param do_malloc true if shared struct should be malloced 914 * @return error message or NULL if successful 915 */ 916 PROXY_DECLARE(char *) ap_proxy_define_balancer(apr_pool_t *p, 917 proxy_balancer **balancer, 918 proxy_server_conf *conf, 919 const char *url, 920 const char *alias, 921 int do_malloc); 922 923 /** 924 * Share a defined proxy balancer via shm 925 * @param balancer balancer to be shared 926 * @param shm location of shared info 927 * @param i index into shm 928 * @return APR_SUCCESS or error code 929 */ 930 PROXY_DECLARE(apr_status_t) ap_proxy_share_balancer(proxy_balancer *balancer, 931 proxy_balancer_shared *shm, 932 int i); 933 934 /** 935 * Initialize the balancer as needed 936 * @param balancer balancer to initialize 937 * @param s current server record 938 * @param p memory pool used for mutex and connection pool 939 * @return APR_SUCCESS or error code 940 */ 941 PROXY_DECLARE(apr_status_t) ap_proxy_initialize_balancer(proxy_balancer *balancer, 942 server_rec *s, 943 apr_pool_t *p); 944 945 typedef int (proxy_is_best_callback_fn_t)(proxy_worker *current, proxy_worker *prev_best, void *baton); 946 947 /** 948 * Retrieve the best worker in a balancer for the current request 949 * @param balancer balancer for which to find the best worker 950 * @param r current request record 951 * @param is_best a callback function provide by the lbmethod 952 * that determines if the current worker is best 953 * @param baton an lbmethod-specific context pointer (baton) 954 * passed to the is_best callback 955 * @return the best worker to be used for the request 956 */ 957 PROXY_DECLARE(proxy_worker *) ap_proxy_balancer_get_best_worker(proxy_balancer *balancer, 958 request_rec *r, 959 proxy_is_best_callback_fn_t *is_best, 960 void *baton); 961 /* 962 * Needed by the lb modules. 963 */ 964 APR_DECLARE_OPTIONAL_FN(proxy_worker *, proxy_balancer_get_best_worker, 965 (proxy_balancer *balancer, 966 request_rec *r, 967 proxy_is_best_callback_fn_t *is_best, 968 void *baton)); 969 970 /** 971 * Find the shm of the worker as needed 972 * @param storage slotmem provider 973 * @param slot slotmem instance 974 * @param worker worker to find 975 * @param index pointer to index within slotmem of worker 976 * @return pointer to shm of worker, or NULL 977 */ 978 PROXY_DECLARE(proxy_worker_shared *) ap_proxy_find_workershm(ap_slotmem_provider_t *storage, 979 ap_slotmem_instance_t *slot, 980 proxy_worker *worker, 981 unsigned int *index); 982 983 /** 984 * Find the shm of the balancer as needed 985 * @param storage slotmem provider 986 * @param slot slotmem instance 987 * @param balancer balancer of shm to find 988 * @param index pointer to index within slotmem of balancer 989 * @return pointer to shm of balancer, or NULL 990 */ 991 PROXY_DECLARE(proxy_balancer_shared *) ap_proxy_find_balancershm(ap_slotmem_provider_t *storage, 992 ap_slotmem_instance_t *slot, 993 proxy_balancer *balancer, 994 unsigned int *index); 995 996 /** 997 * Get the most suitable worker and/or balancer for the request 998 * @param worker worker used for processing request 999 * @param balancer balancer used for processing request 1000 * @param r current request 1001 * @param conf current proxy server configuration 1002 * @param url request url that balancer can rewrite. 1003 * @return OK or HTTP_XXX error 1004 * @note It calls balancer pre_request hook if the url starts with balancer:// 1005 * The balancer then rewrites the url to particular worker, like http://host:port 1006 */ 1007 PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker, 1008 proxy_balancer **balancer, 1009 request_rec *r, 1010 proxy_server_conf *conf, 1011 char **url); 1012 /** 1013 * Post request worker and balancer cleanup 1014 * @param worker worker used for processing request 1015 * @param balancer balancer used for processing request 1016 * @param r current request 1017 * @param conf current proxy server configuration 1018 * @return OK or HTTP_XXX error 1019 * @note Whenever the pre_request is called, the post_request has to be 1020 * called too. 1021 */ 1022 PROXY_DECLARE(int) ap_proxy_post_request(proxy_worker *worker, 1023 proxy_balancer *balancer, 1024 request_rec *r, 1025 proxy_server_conf *conf); 1026 1027 /** 1028 * Determine backend hostname and port 1029 * @param p memory pool used for processing 1030 * @param r current request 1031 * @param conf current proxy server configuration 1032 * @param worker worker used for processing request 1033 * @param conn proxy connection struct 1034 * @param uri processed uri 1035 * @param url request url 1036 * @param proxyname are we connecting directly or via a proxy 1037 * @param proxyport proxy host port 1038 * @param server_portstr Via headers server port, must be non-NULL 1039 * @param server_portstr_size size of the server_portstr buffer; must 1040 * be at least one, even if the protocol doesn't use this 1041 * @return OK or HTTP_XXX error 1042 */ 1043 PROXY_DECLARE(int) ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, 1044 proxy_server_conf *conf, 1045 proxy_worker *worker, 1046 proxy_conn_rec *conn, 1047 apr_uri_t *uri, 1048 char **url, 1049 const char *proxyname, 1050 apr_port_t proxyport, 1051 char *server_portstr, 1052 int server_portstr_size); 1053 1054 /** 1055 * Mark a worker for retry 1056 * @param proxy_function calling proxy scheme (http, ajp, ...) 1057 * @param worker worker used for retrying 1058 * @param s current server record 1059 * @return OK if marked for retry, DECLINED otherwise 1060 * @note The error status of the worker will cleared if the retry interval has 1061 * elapsed since the last error. 1062 */ 1063 APR_DECLARE_OPTIONAL_FN(int, ap_proxy_retry_worker, 1064 (const char *proxy_function, proxy_worker *worker, server_rec *s)); 1065 1066 /** 1067 * Acquire a connection from worker connection pool 1068 * @param proxy_function calling proxy scheme (http, ajp, ...) 1069 * @param conn acquired connection 1070 * @param worker worker used for obtaining connection 1071 * @param s current server record 1072 * @return OK or HTTP_XXX error 1073 * @note If the connection limit has been reached, the function will 1074 * block until a connection becomes available or the timeout has 1075 * elapsed. 1076 */ 1077 PROXY_DECLARE(int) ap_proxy_acquire_connection(const char *proxy_function, 1078 proxy_conn_rec **conn, 1079 proxy_worker *worker, 1080 server_rec *s); 1081 /** 1082 * Release a connection back to worker connection pool 1083 * @param proxy_function calling proxy scheme (http, ajp, ...) 1084 * @param conn acquired connection 1085 * @param s current server record 1086 * @return OK or HTTP_XXX error 1087 * @note The connection will be closed if conn->close_on_release is set 1088 */ 1089 PROXY_DECLARE(int) ap_proxy_release_connection(const char *proxy_function, 1090 proxy_conn_rec *conn, 1091 server_rec *s); 1092 1093 #define PROXY_CHECK_CONN_EMPTY (1 << 0) 1094 /** 1095 * Check a connection to the backend 1096 * @param scheme calling proxy scheme (http, ajp, ...) 1097 * @param conn acquired connection 1098 * @param server current server record 1099 * @param max_blank_lines how many blank lines to consume, 1100 * or zero for none (considered data) 1101 * @param flags PROXY_CHECK_* bitmask 1102 * @return APR_SUCCESS: connection established, 1103 * APR_ENOTEMPTY: connection established with data, 1104 * APR_ENOSOCKET: not connected, 1105 * APR_EINVAL: worker in error state (unusable), 1106 * other: connection closed/aborted (remotely) 1107 */ 1108 PROXY_DECLARE(apr_status_t) ap_proxy_check_connection(const char *scheme, 1109 proxy_conn_rec *conn, 1110 server_rec *server, 1111 unsigned max_blank_lines, 1112 int flags); 1113 1114 /** 1115 * Make a connection to the backend 1116 * @param proxy_function calling proxy scheme (http, ajp, ...) 1117 * @param conn acquired connection 1118 * @param worker connection worker 1119 * @param s current server record 1120 * @return OK or HTTP_XXX error 1121 * @note In case the socket already exists for conn, just check the link 1122 * status. 1123 */ 1124 PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, 1125 proxy_conn_rec *conn, 1126 proxy_worker *worker, 1127 server_rec *s); 1128 1129 /** 1130 * Make a connection to a Unix Domain Socket (UDS) path 1131 * @param sock UDS to connect 1132 * @param uds_path UDS path to connect to 1133 * @param p pool to make the sock addr 1134 * @return APR_SUCCESS or error status 1135 */ 1136 PROXY_DECLARE(apr_status_t) ap_proxy_connect_uds(apr_socket_t *sock, 1137 const char *uds_path, 1138 apr_pool_t *p); 1139 /** 1140 * Make a connection record for backend connection 1141 * @param proxy_function calling proxy scheme (http, ajp, ...) 1142 * @param conn acquired connection 1143 * @param c client connection record (unused, deprecated) 1144 * @param s current server record 1145 * @return OK or HTTP_XXX error 1146 * @note The function will return immediately if conn->connection 1147 * is already set, 1148 */ 1149 PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function, 1150 proxy_conn_rec *conn, 1151 conn_rec *c, server_rec *s); 1152 1153 /** 1154 * Make a connection record for backend connection, using request dir config 1155 * @param proxy_function calling proxy scheme (http, ajp, ...) 1156 * @param conn acquired connection 1157 * @param r current request record 1158 * @return OK or HTTP_XXX error 1159 * @note The function will return immediately if conn->connection 1160 * is already set, 1161 */ 1162 PROXY_DECLARE(int) ap_proxy_connection_create_ex(const char *proxy_function, 1163 proxy_conn_rec *conn, 1164 request_rec *r); 1165 /** 1166 * Determine if proxy connection can potentially be reused at the 1167 * end of this request. 1168 * @param conn proxy connection 1169 * @return non-zero if reusable, 0 otherwise 1170 * @note Even if this function returns non-zero, the connection may 1171 * be subsequently marked for closure. 1172 */ 1173 PROXY_DECLARE(int) ap_proxy_connection_reusable(proxy_conn_rec *conn); 1174 1175 /** 1176 * Signal the upstream chain that the connection to the backend broke in the 1177 * middle of the response. This is done by sending an error bucket with 1178 * status HTTP_BAD_GATEWAY and an EOS bucket up the filter chain. 1179 * @param r current request record of client request 1180 * @param brigade The brigade that is sent through the output filter chain 1181 */ 1182 PROXY_DECLARE(void) ap_proxy_backend_broke(request_rec *r, 1183 apr_bucket_brigade *brigade); 1184 1185 /** 1186 * Return a hash based on the passed string 1187 * @param str string to produce hash from 1188 * @param method hashing method to use 1189 * @return hash as unsigned int 1190 */ 1191 1192 typedef enum { PROXY_HASHFUNC_DEFAULT, PROXY_HASHFUNC_APR, PROXY_HASHFUNC_FNV } proxy_hash_t; 1193 1194 PROXY_DECLARE(unsigned int) ap_proxy_hashfunc(const char *str, proxy_hash_t method); 1195 1196 1197 /** 1198 * Set/unset the worker status bitfield depending on flag 1199 * @param c flag 1200 * @param set set or unset bit 1201 * @param w worker to use 1202 * @return APR_SUCCESS if valid flag 1203 */ 1204 PROXY_DECLARE(apr_status_t) ap_proxy_set_wstatus(char c, int set, proxy_worker *w); 1205 1206 1207 /** 1208 * Create readable representation of worker status bitfield 1209 * @param p pool 1210 * @param w worker to use 1211 * @return string representation of status 1212 */ 1213 PROXY_DECLARE(char *) ap_proxy_parse_wstatus(apr_pool_t *p, proxy_worker *w); 1214 1215 1216 /** 1217 * Sync balancer and workers based on any updates w/i shm 1218 * @param b balancer to check/update member list of 1219 * @param s server rec 1220 * @param conf config 1221 * @return APR_SUCCESS if all goes well 1222 */ 1223 PROXY_DECLARE(apr_status_t) ap_proxy_sync_balancer(proxy_balancer *b, 1224 server_rec *s, 1225 proxy_server_conf *conf); 1226 1227 /** 1228 * Configure and create workers (and balancer) in mod_balancer. 1229 * @param r request 1230 * @param params table with the parameters like b=mycluster etc. 1231 * @return 404 when the worker/balancer doesn't exist, 1232 * 400 if something is invalid 1233 * 200 for success. 1234 */ 1235 APR_DECLARE_OPTIONAL_FN(apr_status_t, balancer_manage, 1236 (request_rec *, apr_table_t *params)); 1237 1238 /** 1239 * Find the matched alias for this request and setup for proxy handler 1240 * @param r request 1241 * @param ent proxy_alias record 1242 * @param dconf per-dir config or NULL 1243 * @return OK if the alias matched, 1244 * DONE if the alias matched and r->uri was normalized so 1245 * no further transformation should happen on it, 1246 * DECLINED if proxying is disabled for this alias, 1247 * HTTP_CONTINUE if the alias did not match 1248 */ 1249 PROXY_DECLARE(int) ap_proxy_trans_match(request_rec *r, 1250 struct proxy_alias *ent, 1251 proxy_dir_conf *dconf); 1252 1253 /** 1254 * Create a HTTP request header brigade, old_cl_val and old_te_val as required. 1255 * @param p pool 1256 * @param header_brigade header brigade to use/fill 1257 * @param r request 1258 * @param p_conn proxy connection rec 1259 * @param worker selected worker 1260 * @param conf per-server proxy config 1261 * @param uri uri 1262 * @param url url 1263 * @param server_portstr port as string 1264 * @param old_cl_val stored old content-len val 1265 * @param old_te_val stored old TE val 1266 * @return OK or HTTP_EXPECTATION_FAILED 1267 */ 1268 PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p, 1269 apr_bucket_brigade *header_brigade, 1270 request_rec *r, 1271 proxy_conn_rec *p_conn, 1272 proxy_worker *worker, 1273 proxy_server_conf *conf, 1274 apr_uri_t *uri, 1275 char *url, char *server_portstr, 1276 char **old_cl_val, 1277 char **old_te_val); 1278 1279 /** 1280 * Prefetch the client request body (in memory), up to a limit. 1281 * Read what's in the client pipe. If nonblocking is set and read is EAGAIN, 1282 * pass a FLUSH bucket to the backend and read again in blocking mode. 1283 * @param r client request 1284 * @param backend backend connection 1285 * @param input_brigade input brigade to use/fill 1286 * @param block blocking or non-blocking mode 1287 * @param bytes_read number of bytes read 1288 * @param max_read maximum number of bytes to read 1289 * @return OK or HTTP_* error code 1290 * @note max_read is rounded up to APR_BUCKET_BUFF_SIZE 1291 */ 1292 PROXY_DECLARE(int) ap_proxy_prefetch_input(request_rec *r, 1293 proxy_conn_rec *backend, 1294 apr_bucket_brigade *input_brigade, 1295 apr_read_type_e block, 1296 apr_off_t *bytes_read, 1297 apr_off_t max_read); 1298 1299 /** 1300 * Spool the client request body to memory, or disk above given limit. 1301 * @param r client request 1302 * @param backend backend connection 1303 * @param input_brigade input brigade to use/fill 1304 * @param bytes_spooled number of bytes spooled 1305 * @param max_mem_spool maximum number of in-memory bytes 1306 * @return OK or HTTP_* error code 1307 */ 1308 PROXY_DECLARE(int) ap_proxy_spool_input(request_rec *r, 1309 proxy_conn_rec *backend, 1310 apr_bucket_brigade *input_brigade, 1311 apr_off_t *bytes_spooled, 1312 apr_off_t max_mem_spool); 1313 1314 /** 1315 * Read what's in the client pipe. If the read would block (EAGAIN), 1316 * pass a FLUSH bucket to the backend and read again in blocking mode. 1317 * @param r client request 1318 * @param backend backend connection 1319 * @param input_brigade brigade to use/fill 1320 * @param max_read maximum number of bytes to read 1321 * @return OK or HTTP_* error code 1322 */ 1323 PROXY_DECLARE(int) ap_proxy_read_input(request_rec *r, 1324 proxy_conn_rec *backend, 1325 apr_bucket_brigade *input_brigade, 1326 apr_off_t max_read); 1327 1328 /** 1329 * @param bucket_alloc bucket allocator 1330 * @param r request 1331 * @param p_conn proxy connection 1332 * @param origin connection rec of origin 1333 * @param bb brigade to send to origin 1334 * @param flush flush 1335 * @return status (OK) 1336 */ 1337 PROXY_DECLARE(int) ap_proxy_pass_brigade(apr_bucket_alloc_t *bucket_alloc, 1338 request_rec *r, proxy_conn_rec *p_conn, 1339 conn_rec *origin, apr_bucket_brigade *bb, 1340 int flush); 1341 1342 struct proxy_tunnel_conn; /* opaque */ 1343 typedef struct { 1344 request_rec *r; 1345 const char *scheme; 1346 apr_pollset_t *pollset; 1347 apr_array_header_t *pfds; 1348 apr_interval_time_t timeout; 1349 struct proxy_tunnel_conn *client, 1350 *origin; 1351 apr_size_t read_buf_size; 1352 int replied; /* TODO 2.5+: one bit to merge in below bitmask */ 1353 unsigned int nohalfclose :1; 1354 } proxy_tunnel_rec; 1355 1356 /** 1357 * Create a tunnel, to be activated by ap_proxy_tunnel_run(). 1358 * @param tunnel tunnel created 1359 * @param r client request 1360 * @param c_o connection to origin 1361 * @param scheme caller proxy scheme (connect, ws(s), http(s), ...) 1362 * @return APR_SUCCESS or error status 1363 */ 1364 PROXY_DECLARE(apr_status_t) ap_proxy_tunnel_create(proxy_tunnel_rec **tunnel, 1365 request_rec *r, conn_rec *c_o, 1366 const char *scheme); 1367 1368 /** 1369 * Forward anything from either side of the tunnel to the other, 1370 * until one end aborts or a polling timeout/error occurs. 1371 * @param tunnel tunnel to run 1372 * @return OK if completion is full, HTTP_GATEWAY_TIME_OUT on timeout 1373 * or another HTTP_ error otherwise. 1374 */ 1375 PROXY_DECLARE(int) ap_proxy_tunnel_run(proxy_tunnel_rec *tunnel); 1376 1377 /** 1378 * Clear the headers referenced by the Connection header from the given 1379 * table, and remove the Connection header. 1380 * @param r request 1381 * @param headers table of headers to clear 1382 * @return 1 if "close" was present, 0 otherwise. 1383 */ 1384 APR_DECLARE_OPTIONAL_FN(int, ap_proxy_clear_connection, 1385 (request_rec *r, apr_table_t *headers)); 1386 1387 /** 1388 * Do a AJP CPING and wait for CPONG on the socket 1389 * 1390 */ 1391 APR_DECLARE_OPTIONAL_FN(apr_status_t, ajp_handle_cping_cpong, 1392 (apr_socket_t *sock, request_rec *r, 1393 apr_interval_time_t timeout)); 1394 1395 1396 /** 1397 * @param socket socket to test 1398 * @return TRUE if socket is connected/active 1399 */ 1400 PROXY_DECLARE(int) ap_proxy_is_socket_connected(apr_socket_t *socket); 1401 1402 #define PROXY_LBMETHOD "proxylbmethod" 1403 1404 /* The number of dynamic workers that can be added when reconfiguring. 1405 * If this limit is reached you must stop and restart the server. 1406 */ 1407 #define PROXY_DYNAMIC_BALANCER_LIMIT 16 1408 1409 /** 1410 * Calculate maximum number of workers in scoreboard. 1411 * @return number of workers to allocate in the scoreboard 1412 */ 1413 int ap_proxy_lb_workers(void); 1414 1415 /** 1416 * Returns 1 if a response with the given status should be overridden. 1417 * 1418 * @param conf proxy directory configuration 1419 * @param code http status code 1420 * @return 1 if code is considered an error-code, 0 otherwise 1421 */ 1422 PROXY_DECLARE(int) ap_proxy_should_override(proxy_dir_conf *conf, int code); 1423 1424 /** 1425 * Return the port number of a known scheme (eg: http -> 80). 1426 * @param scheme scheme to test 1427 * @return port number or 0 if unknown 1428 */ 1429 PROXY_DECLARE(apr_port_t) ap_proxy_port_of_scheme(const char *scheme); 1430 1431 /** 1432 * Return the name of the health check method (eg: "OPTIONS"). 1433 * @param method method enum 1434 * @return name of method 1435 */ 1436 PROXY_DECLARE (const char *) ap_proxy_show_hcmethod(hcmethod_t method); 1437 1438 /** 1439 * Strip a unix domain socket (UDS) prefix from the input URL 1440 * @param p pool to allocate result from 1441 * @param url a URL potentially prefixed with a UDS path 1442 * @return URL with the UDS prefix removed 1443 */ 1444 PROXY_DECLARE(const char *) ap_proxy_de_socketfy(apr_pool_t *p, const char *url); 1445 1446 /* 1447 * Transform buckets from one bucket allocator to another one by creating a 1448 * transient bucket for each data bucket and let it use the data read from 1449 * the old bucket. Metabuckets are transformed by just recreating them. 1450 * Attention: Currently only the following bucket types are handled: 1451 * 1452 * All data buckets 1453 * FLUSH 1454 * EOS 1455 * 1456 * If an other bucket type is found its type is logged as a debug message 1457 * and APR_EGENERAL is returned. 1458 * 1459 * @param r request_rec of the actual request. Used for logging purposes 1460 * @param from the bucket brigade to take the buckets from 1461 * @param to the bucket brigade to store the transformed buckets 1462 * @return apr_status_t of the operation. Either APR_SUCCESS or 1463 * APR_EGENERAL 1464 */ 1465 PROXY_DECLARE(apr_status_t) ap_proxy_buckets_lifetime_transform(request_rec *r, 1466 apr_bucket_brigade *from, 1467 apr_bucket_brigade *to); 1468 1469 /* 1470 * The flags for ap_proxy_transfer_between_connections(), where for legacy and 1471 * compatibility reasons FLUSH_EACH and FLUSH_AFTER are boolean values. 1472 */ 1473 #define AP_PROXY_TRANSFER_FLUSH_EACH (0x00) 1474 #define AP_PROXY_TRANSFER_FLUSH_AFTER (0x01) 1475 #define AP_PROXY_TRANSFER_YIELD_PENDING (0x02) 1476 #define AP_PROXY_TRANSFER_YIELD_MAX_READS (0x04) 1477 1478 /* 1479 * Sends all data that can be read non blocking from the input filter chain of 1480 * c_i and send it down the output filter chain of c_o. For reading it uses 1481 * the bucket brigade bb_i which should be created from the bucket allocator 1482 * associated with c_i. For sending through the output filter chain it uses 1483 * the bucket brigade bb_o which should be created from the bucket allocator 1484 * associated with c_o. In order to get the buckets from bb_i to bb_o 1485 * ap_proxy_buckets_lifetime_transform is used. 1486 * 1487 * @param r request_rec of the actual request. Used for logging purposes 1488 * @param c_i inbound connection conn_rec 1489 * @param c_o outbound connection conn_rec 1490 * @param bb_i bucket brigade for pulling data from the inbound connection 1491 * @param bb_o bucket brigade for sending data through the outbound connection 1492 * @param name string for logging from where data was pulled 1493 * @param sent if not NULL will be set to 1 if data was sent through c_o 1494 * @param bsize maximum amount of data pulled in one iteration from c_i 1495 * @param flags AP_PROXY_TRANSFER_* bitmask 1496 * @return apr_status_t of the operation. Could be any error returned from 1497 * either the input filter chain of c_i or the output filter chain 1498 * of c_o, APR_EPIPE if the outgoing connection was aborted, or 1499 * APR_INCOMPLETE if AP_PROXY_TRANSFER_YIELD_PENDING was set and 1500 * the output stack gets full before the input stack is exhausted. 1501 */ 1502 PROXY_DECLARE(apr_status_t) ap_proxy_transfer_between_connections( 1503 request_rec *r, 1504 conn_rec *c_i, 1505 conn_rec *c_o, 1506 apr_bucket_brigade *bb_i, 1507 apr_bucket_brigade *bb_o, 1508 const char *name, 1509 int *sent, 1510 apr_off_t bsize, 1511 int flags); 1512 1513 extern module PROXY_DECLARE_DATA proxy_module; 1514 1515 #endif /*MOD_PROXY_H*/ 1516 /** @} */