📄 mod_proxy.c
字号:
for (direct_connect = ii = 0; ii < conf->dirconn->nelts && !direct_connect; ii++) { direct_connect = list[ii].matcher(&list[ii], r); }#if DEBUGGING ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, (direct_connect) ? "NoProxy for %s" : "UseProxy for %s", r->uri);#endif } /* firstly, try a proxy, unless a NoProxy directive is active */ if (!direct_connect) { for (i = 0; i < proxies->nelts; i++) { p2 = ap_strchr_c(ents[i].scheme, ':'); /* is it a partial URL? */ if (strcmp(ents[i].scheme, "*") == 0 || (ents[i].use_regex && ap_regexec(ents[i].regexp, url, 0,NULL, 0) == 0) || (p2 == NULL && strcasecmp(scheme, ents[i].scheme) == 0) || (p2 != NULL && strncasecmp(url, ents[i].scheme, strlen(ents[i].scheme)) == 0)) { /* handle the scheme */ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Trying to run scheme_handler against proxy"); access_status = proxy_run_scheme_handler(r, conf, url, ents[i].hostname, ents[i].port); /* an error or success */ if (access_status != DECLINED && access_status != HTTP_BAD_GATEWAY) { return access_status; } /* we failed to talk to the upstream proxy */ } } } /* 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, "Trying to run scheme_handler"); access_status = proxy_run_scheme_handler(r, conf, url, NULL, 0); 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); return HTTP_FORBIDDEN; } 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->raliases = 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->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; 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->raliases = apr_array_append(p, base->raliases, overrides->raliases); 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->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; 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 */ 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; new->p = add->p; new->p_is_fnmatch = add->p_is_fnmatch; new->r = add->r; 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; 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, 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 *f, const char *r){ 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; if (r!=NULL && cmd->path == NULL ) { new = apr_array_push(conf->aliases); new->fake = f; new->real = r; } else if (r==NULL && cmd->path != NULL) { new = apr_array_push(conf->aliases); new->fake = cmd->path; new->real = f; } else { if ( r== NULL) return "ProxyPass needs a path when not defined in a location"; else return "ProxyPass can not have a path when defined in a location"; } return NULL;}static const char * add_pass_reverse(cmd_parms *cmd, void *dummy, const char *f, const char *r){ server_rec *s = cmd->server; proxy_server_conf *conf; struct proxy_alias *new; conf = (proxy_server_conf *)ap_get_module_config(s->module_config, &proxy_module); 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 * set_proxy_exclude(cmd_parms *parms, void *dummy, const char *arg){ server_rec *s = parms->server; proxy_server_conf *conf = ap_get_module_config(s->module_config, &proxy_module); struct noproxy_entry *new; struct noproxy_entry *list = (struct noproxy_entry *) conf->noproxies->elts; struct apr_sockaddr_t *addr; int found = 0; int i; /* Don't duplicate entries */ for (i = 0; i < conf->noproxies->nelts; i++) { if (apr_strnatcasecmp(arg, list[i].name) == 0) { /* ignore case for host names */ found = 1; } } if (!found) { new = apr_array_push(conf->noproxies); new->name = arg; if (APR_SUCCESS == apr_sockaddr_info_get(&addr, new->name, APR_UNSPEC, 0, 0, parms->pool)) { new->addr = addr; } else { new->addr = NULL; } } return NULL;}/* * Set the ports CONNECT can use */static const char * set_allowed_ports(cmd_parms *parms, void *dummy, const char *arg){ server_rec *s = parms->server; proxy_server_conf *conf = ap_get_module_config(s->module_config, &proxy_module); int *New; if (!apr_isdigit(arg[0])) return "AllowCONNECT: port number must be numeric"; New = apr_array_push(conf->allowed_connect_ports); *New = atoi(arg); return NULL;}/* Similar to set_proxy_exclude(), but defining directly connected hosts, * which should never be accessed via the configured ProxyRemote servers */static const char * set_proxy_dirconn(cmd_parms *parms, void *dummy, const char *arg){ server_rec *s = parms->server; proxy_server_conf *conf = ap_get_module_config(s->module_config, &proxy_module); struct dirconn_entry *New; struct dirconn_entry *list = (struct dirconn_entry *) conf->dirconn->elts; int found = 0; int i; /* Don't duplicate entries */ for (i = 0; i < conf->dirconn->nelts; i++) { if (strcasecmp(arg, list[i].name) == 0) found = 1; } if (!found) { New = apr_array_push(conf->dirconn); New->name = apr_pstrdup(parms->pool, arg); New->hostaddr = NULL; if (ap_proxy_is_ipaddr(New, parms->pool)) {#if DEBUGGING ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "Parsed addr %s", inet_ntoa(New->addr)); ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "Parsed mask %s", inet_ntoa(New->mask));#endif } else if (ap_proxy_is_domainname(New, parms->pool)) { ap_str_tolower(New->name);#if DEBUGGING ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "Parsed domain %s", New->name);#endif } else if (ap_proxy_is_hostname(New, parms->pool)) { ap_str_tolower(New->name);#if DEBUGGING ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "Parsed host %s", New->name);#endif } else { ap_proxy_is_word(New, parms->pool);#if DEBUGGING fprintf(stderr, "Parsed word %s\n", New->name);#endif } } return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -