mod_proxy.c
来自「linux网络服务器工具」· C语言 代码 · 共 1,845 行 · 第 1/5 页
C
1,845 行
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); new->interpolate_env = -1; /* unset */ 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; new->interpolate_env = (add->interpolate_env == -1) ? base->interpolate_env : add->interpolate_env; new->ftp_directory_charset = add->ftp_directory_charset ? add->ftp_directory_charset : base->ftp_directory_charset; 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, int is_regex){ 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; int use_regex = is_regex; unsigned int flags = 0; while (*arg) { word = ap_getword_conf(cmd->pool, &arg); if (!f) { if (!strcmp(word, "~")) { if (is_regex) { return "ProxyPassMatch invalid syntax ('~' usage)."; } use_regex = 1; continue; } f = word; } else if (!r) { r = word; } else if (!strcasecmp(word,"nocanon")) { flags |= PROXYPASS_NOCANON; } else if (!strcasecmp(word,"interpolate")) { flags |= PROXYPASS_INTERPOLATE; } else { char *val = strchr(word, '='); if (!val) { if (cmd->path) { if (*r == '/') { return "ProxyPass|ProxyPassMatch can not have a path when defined in " "a location."; } else { return "Invalid ProxyPass|ProxyPassMatch parameter. Parameter must " "be in the form 'key=value'."; } } else { return "Invalid ProxyPass|ProxyPassMatch parameter. Parameter must be " "in the form 'key=value'."; } } else *val++ = '\0'; apr_table_setn(params, word, val); } }; if (r == NULL) return "ProxyPass|ProxyPassMatch 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); new->flags = flags; if (use_regex) { new->regex = ap_pregcomp(cmd->pool, f, AP_REG_EXTENDED); if (new->regex == NULL) return "Regular expression could not be compiled."; } else { new->regex = NULL; } 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 worker */ 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); } else { ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, "worker %s already used by another worker", worker->name); } 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_noregex(cmd_parms *cmd, void *dummy, const char *arg){ return add_pass(cmd, dummy, arg, 0);}static const char * add_pass_regex(cmd_parms *cmd, void *dummy, const char *arg){ return add_pass(cmd, dummy, arg, 1);}static const char * add_pass_reverse(cmd_parms *cmd, void *dconf, const char *f, const char *r, const char *i){ proxy_dir_conf *conf = dconf; struct proxy_alias *new; const char *fake; const char *real; const char *interp; if (cmd->path == NULL) { fake = f; real = r; interp = i; if (r == NULL || !strcasecmp(r, "interpolate")) { return "ProxyPassReverse needs a path when not defined in a location"; } } else { fake = cmd->path; real = f; if (r && strcasecmp(r, "interpolate")) { return "ProxyPassReverse can not have a path when defined in a location"; } interp = r; } new = apr_array_push(conf->raliases); new->fake = fake; new->real = real; new->flags = interp ? PROXYPASS_INTERPOLATE : 0; return NULL;}static const char* cookie_path(cmd_parms *cmd, void *dconf, const char *f, const char *r, const char *interp){ proxy_dir_conf *conf = dconf; struct proxy_alias *new; new = apr_array_push(conf->cookie_paths); new->fake = f; new->real = r; new->flags = interp ? PROXYPASS_INTERPOLATE : 0; return NULL;}static const char* cookie_domain(cmd_parms *cmd, void *dconf, const char *f, const char *r, const char *interp){ proxy_dir_conf *conf = dconf; struct proxy_alias *new; new = apr_array_push(conf->cookie_domains); new->fake = f; new->real = r; new->flags = interp ? PROXYPASS_INTERPOLATE : 0; 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 (strcasecmp(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 *
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?