mod_proxy.c
来自「apache服务器源代码(版本号:2.2.2)」· C语言 代码 · 共 1,862 行 · 第 1/5 页
C
1,862 行
} } /* otherwise, try it direct */ /* N.B. what if we're behind a firewall, where we must use a proxy or * give up?? */ /* handle the scheme */ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Running scheme %s handler (attempt %d)", scheme, attempts); access_status = proxy_run_scheme_handler(r, worker, conf, url, NULL, 0); if (access_status == OK) break; else if (access_status == HTTP_INTERNAL_SERVER_ERROR) { /* Unrecoverable server error. * We can not failover to another worker. * Mark the worker as unusable if member of load balancer */ if (balancer) worker->s->status |= PROXY_WORKER_IN_ERROR; break; } else if (access_status == HTTP_SERVICE_UNAVAILABLE) { /* Recoverable server error. * We can failover to another worker * Mark the worker as unusable if member of load balancer */ if (balancer) { worker->s->status |= PROXY_WORKER_IN_ERROR; } } else { /* Unrecoverable error. * Return the origin status code to the client. */ break; } /* Try again if the worker is unusable and the service is * unavailable. */ } while (!PROXY_WORKER_IS_USABLE(worker) && max_attempts > attempts++); if (DECLINED == access_status) { ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, "proxy: No protocol handler was valid for the URL %s. " "If you are using a DSO version of mod_proxy, make sure " "the proxy submodules are included in the configuration " "using LoadModule.", r->uri); access_status = HTTP_FORBIDDEN; goto cleanup; }cleanup: if (balancer) { int post_status = proxy_run_post_request(worker, balancer, r, conf); if (post_status == DECLINED) { post_status = OK; /* no post_request handler available */ /* TODO: recycle direct worker */ } } proxy_run_request_status(&access_status, r); return access_status;}/* -------------------------------------------------------------- *//* Setup configurable data */static void * create_proxy_config(apr_pool_t *p, server_rec *s){ proxy_server_conf *ps = apr_pcalloc(p, sizeof(proxy_server_conf)); ps->sec_proxy = apr_array_make(p, 10, sizeof(ap_conf_vector_t *)); ps->proxies = apr_array_make(p, 10, sizeof(struct proxy_remote)); ps->aliases = apr_array_make(p, 10, sizeof(struct proxy_alias)); ps->noproxies = apr_array_make(p, 10, sizeof(struct noproxy_entry)); ps->dirconn = apr_array_make(p, 10, sizeof(struct dirconn_entry)); ps->allowed_connect_ports = apr_array_make(p, 10, sizeof(int)); ps->workers = apr_array_make(p, 10, sizeof(proxy_worker)); ps->balancers = apr_array_make(p, 10, sizeof(proxy_balancer)); ps->forward = NULL; ps->reverse = NULL; ps->domain = NULL; ps->viaopt = via_off; /* initially backward compatible with 1.3.1 */ ps->viaopt_set = 0; /* 0 means default */ ps->req = 0; ps->req_set = 0; ps->recv_buffer_size = 0; /* this default was left unset for some reason */ ps->recv_buffer_size_set = 0; ps->io_buffer_size = AP_IOBUFSIZE; ps->io_buffer_size_set = 0; ps->maxfwd = DEFAULT_MAX_FORWARDS; ps->maxfwd_set = 0; ps->error_override = 0; ps->error_override_set = 0; ps->preserve_host_set = 0; ps->preserve_host = 0; ps->timeout = 0; ps->timeout_set = 0; ps->badopt = bad_error; ps->badopt_set = 0; ps->pool = p; return ps;}static void * merge_proxy_config(apr_pool_t *p, void *basev, void *overridesv){ proxy_server_conf *ps = apr_pcalloc(p, sizeof(proxy_server_conf)); proxy_server_conf *base = (proxy_server_conf *) basev; proxy_server_conf *overrides = (proxy_server_conf *) overridesv; ps->proxies = apr_array_append(p, base->proxies, overrides->proxies); ps->sec_proxy = apr_array_append(p, base->sec_proxy, overrides->sec_proxy); ps->aliases = apr_array_append(p, base->aliases, overrides->aliases); ps->noproxies = apr_array_append(p, base->noproxies, overrides->noproxies); ps->dirconn = apr_array_append(p, base->dirconn, overrides->dirconn); ps->allowed_connect_ports = apr_array_append(p, base->allowed_connect_ports, overrides->allowed_connect_ports); ps->workers = apr_array_append(p, base->workers, overrides->workers); ps->balancers = apr_array_append(p, base->balancers, overrides->balancers); ps->forward = overrides->forward ? overrides->forward : base->forward; ps->reverse = overrides->reverse ? overrides->reverse : base->reverse; ps->domain = (overrides->domain == NULL) ? base->domain : overrides->domain; ps->viaopt = (overrides->viaopt_set == 0) ? base->viaopt : overrides->viaopt; ps->req = (overrides->req_set == 0) ? base->req : overrides->req; ps->recv_buffer_size = (overrides->recv_buffer_size_set == 0) ? base->recv_buffer_size : overrides->recv_buffer_size; ps->io_buffer_size = (overrides->io_buffer_size_set == 0) ? base->io_buffer_size : overrides->io_buffer_size; ps->maxfwd = (overrides->maxfwd_set == 0) ? base->maxfwd : overrides->maxfwd; ps->error_override = (overrides->error_override_set == 0) ? base->error_override : overrides->error_override; ps->preserve_host = (overrides->preserve_host_set == 0) ? base->preserve_host : overrides->preserve_host; ps->timeout= (overrides->timeout_set == 0) ? base->timeout : overrides->timeout; ps->badopt = (overrides->badopt_set == 0) ? base->badopt : overrides->badopt; ps->proxy_status = (overrides->proxy_status_set == 0) ? base->proxy_status : overrides->proxy_status; ps->pool = p; return ps;}static void *create_proxy_dir_config(apr_pool_t *p, char *dummy){ proxy_dir_conf *new = (proxy_dir_conf *) apr_pcalloc(p, sizeof(proxy_dir_conf)); /* Filled in by proxysection, when applicable */ /* Put these in the dir config so they work inside <Location> */ new->raliases = apr_array_make(p, 10, sizeof(struct proxy_alias)); new->cookie_paths = apr_array_make(p, 10, sizeof(struct proxy_alias)); new->cookie_domains = apr_array_make(p, 10, sizeof(struct proxy_alias)); new->cookie_path_str = apr_strmatch_precompile(p, "path=", 0); new->cookie_domain_str = apr_strmatch_precompile(p, "domain=", 0); return (void *) new;}static void *merge_proxy_dir_config(apr_pool_t *p, void *basev, void *addv){ proxy_dir_conf *new = (proxy_dir_conf *) apr_pcalloc(p, sizeof(proxy_dir_conf)); proxy_dir_conf *add = (proxy_dir_conf *) addv; proxy_dir_conf *base = (proxy_dir_conf *) basev; new->p = add->p; new->p_is_fnmatch = add->p_is_fnmatch; new->r = add->r; /* Put these in the dir config so they work inside <Location> */ new->raliases = apr_array_append(p, base->raliases, add->raliases); new->cookie_paths = apr_array_append(p, base->cookie_paths, add->cookie_paths); new->cookie_domains = apr_array_append(p, base->cookie_domains, add->cookie_domains); new->cookie_path_str = base->cookie_path_str; new->cookie_domain_str = base->cookie_domain_str; return new;}static const char * add_proxy(cmd_parms *cmd, void *dummy, const char *f1, const char *r1, int regex){ server_rec *s = cmd->server; proxy_server_conf *conf = (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module); struct proxy_remote *new; char *p, *q; char *r, *f, *scheme; ap_regex_t *reg = NULL; int port; r = apr_pstrdup(cmd->pool, r1); scheme = apr_pstrdup(cmd->pool, r1); f = apr_pstrdup(cmd->pool, f1); p = strchr(r, ':'); if (p == NULL || p[1] != '/' || p[2] != '/' || p[3] == '\0') { if (regex) return "ProxyRemoteMatch: Bad syntax for a remote proxy server"; else return "ProxyRemote: Bad syntax for a remote proxy server"; } else { scheme[p-r] = 0; } q = strchr(p + 3, ':'); if (q != NULL) { if (sscanf(q + 1, "%u", &port) != 1 || port > 65535) { if (regex) return "ProxyRemoteMatch: Bad syntax for a remote proxy server (bad port number)"; else return "ProxyRemote: Bad syntax for a remote proxy server (bad port number)"; } *q = '\0'; } else port = -1; *p = '\0'; if (regex) { reg = ap_pregcomp(cmd->pool, f, AP_REG_EXTENDED); if (!reg) return "Regular expression for ProxyRemoteMatch could not be compiled."; } else if (strchr(f, ':') == NULL) ap_str_tolower(f); /* lowercase scheme */ ap_str_tolower(p + 3); /* lowercase hostname */ if (port == -1) { port = apr_uri_port_of_scheme(scheme); } new = apr_array_push(conf->proxies); new->scheme = f; new->protocol = r; new->hostname = p + 3; new->port = port; new->regexp = reg; new->use_regex = regex; return NULL;}static const char * add_proxy_noregex(cmd_parms *cmd, void *dummy, const char *f1, const char *r1){ return add_proxy(cmd, dummy, f1, r1, 0);}static const char * add_proxy_regex(cmd_parms *cmd, void *dummy, const char *f1, const char *r1){ return add_proxy(cmd, dummy, f1, r1, 1);}static const char * add_pass(cmd_parms *cmd, void *dummy, const char *arg){ server_rec *s = cmd->server; proxy_server_conf *conf = (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module); struct proxy_alias *new; char *f = cmd->path; char *r = NULL; char *word; apr_table_t *params = apr_table_make(cmd->pool, 5); const apr_array_header_t *arr; const apr_table_entry_t *elts; int i; while (*arg) { word = ap_getword_conf(cmd->pool, &arg); if (!f) f = word; else if (!r) r = word; else { char *val = strchr(word, '='); if (!val) { if (cmd->path) return "Invalid ProxyPass parameter. Parameter must be " "in the form 'key=value'"; else return "ProxyPass can not have a path when defined in a location"; } else *val++ = '\0'; apr_table_setn(params, word, val); } }; if (r == NULL) return "ProxyPass needs a path when not defined in a location"; new = apr_array_push(conf->aliases); new->fake = apr_pstrdup(cmd->pool, f); new->real = apr_pstrdup(cmd->pool, r); if (r[0] == '!' && r[1] == '\0') return NULL; arr = apr_table_elts(params); elts = (const apr_table_entry_t *)arr->elts; /* Distinguish the balancer from woker */ if (strncasecmp(r, "balancer:", 9) == 0) { proxy_balancer *balancer = ap_proxy_get_balancer(cmd->pool, conf, r); if (!balancer) { const char *err = ap_proxy_add_balancer(&balancer, cmd->pool, conf, r); if (err) return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL); } for (i = 0; i < arr->nelts; i++) { const char *err = set_balancer_param(conf, cmd->pool, balancer, elts[i].key, elts[i].val); if (err) return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL); } } else { proxy_worker *worker = ap_proxy_get_worker(cmd->temp_pool, conf, r); if (!worker) { const char *err = ap_proxy_add_worker(&worker, cmd->pool, conf, r); if (err) return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL); } PROXY_COPY_CONF_PARAMS(worker, conf); for (i = 0; i < arr->nelts; i++) { const char *err = set_worker_param(cmd->pool, worker, elts[i].key, elts[i].val); if (err) return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL); } } return NULL;}static const char * add_pass_reverse(cmd_parms *cmd, void *dconf, const char *f, const char *r){ proxy_dir_conf *conf = dconf; struct proxy_alias *new; if (r!=NULL && cmd->path == NULL ) { new = apr_array_push(conf->raliases); new->fake = f; new->real = r; } else if (r==NULL && cmd->path != NULL) { new = apr_array_push(conf->raliases); new->fake = cmd->path; new->real = f; } else { if ( r == NULL) return "ProxyPassReverse needs a path when not defined in a location"; else return "ProxyPassReverse can not have a path when defined in a location"; } return NULL;}static const char* cookie_path(cmd_parms *cmd, void *dconf, const char *f, const char *r){ proxy_dir_conf *conf = dconf; struct proxy_alias *new; new = apr_array_push(conf->cookie_paths); new->fake = f; new->real = r; return NULL;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?