📄 mod_proxy.c
字号:
} *p = '\0'; scheme = ap_pstrdup(r->pool, url); *p = ':'; /* Check URI's destination host against NoProxy hosts */ /* Bypass ProxyRemote server lookup if configured as NoProxy */ /* we only know how to handle communication to a proxy via http */ /* if (strcasecmp(scheme, "http") == 0) */ { int ii; struct dirconn_entry *list = (struct dirconn_entry *)conf->dirconn->elts; 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 | APLOG_NOERRNO, 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++) { p = strchr(ents[i].scheme, ':'); /* is it a partial URL? */ if (strcmp(ents[i].scheme, "*") == 0 || (p == NULL && strcasecmp(scheme, ents[i].scheme) == 0) || (p != NULL && strncasecmp(url, ents[i].scheme, strlen(ents[i].scheme)) == 0)) { /* * CONNECT is a special method that bypasses the normal proxy * code. */ if (r->method_number == M_CONNECT) rc = ap_proxy_connect_handler(r, cr, url, ents[i].hostname, ents[i].port);/* we only know how to handle communication to a proxy via http */ else if (strcasecmp(ents[i].protocol, "http") == 0) rc = ap_proxy_http_handler(r, cr, url, ents[i].hostname, ents[i].port); else rc = DECLINED; /* an error or success */ if (rc != DECLINED && rc != HTTP_BAD_GATEWAY) return rc; /* 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 */ if (r->method_number == M_CONNECT) { return ap_proxy_connect_handler(r, cr, url, NULL, 0); } if (strcasecmp(scheme, "http") == 0) { return ap_proxy_http_handler(r, cr, url, NULL, 0); } if (strcasecmp(scheme, "ftp") == 0) { return ap_proxy_ftp_handler(r, cr, url); } else { ap_log_rerror(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, r, "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; }}/* -------------------------------------------------------------- *//* Setup configurable data */static void * create_proxy_config(pool *p, server_rec *s){ proxy_server_conf *ps = ap_pcalloc(p, sizeof(proxy_server_conf)); ps->proxies = ap_make_array(p, 10, sizeof(struct proxy_remote)); ps->aliases = ap_make_array(p, 10, sizeof(struct proxy_alias)); ps->raliases = ap_make_array(p, 10, sizeof(struct proxy_alias)); ps->noproxies = ap_make_array(p, 10, sizeof(struct noproxy_entry)); ps->dirconn = ap_make_array(p, 10, sizeof(struct dirconn_entry)); ps->nocaches = ap_make_array(p, 10, sizeof(struct nocache_entry)); ps->allowed_connect_ports = ap_make_array(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 = IOBUFSIZE; ps->io_buffer_size_set = 0; ps->cache.root = NULL; ps->cache.space = DEFAULT_CACHE_SPACE; ps->cache.space_set = 0; ps->cache.maxexpire = DEFAULT_CACHE_MAXEXPIRE; ps->cache.maxexpire_set = 0; ps->cache.defaultexpire = DEFAULT_CACHE_EXPIRE; ps->cache.defaultexpire_set = 0; ps->cache.lmfactor = DEFAULT_CACHE_LMFACTOR; ps->cache.lmfactor_set = 0; ps->cache.gcinterval = DEFAULT_CACHE_GCINTERVAL; ps->cache.gcinterval_set = 1; /* at these levels, the cache can have 2^18 directories (256,000) */ ps->cache.dirlevels = 3; ps->cache.dirlevels_set = 0; ps->cache.dirlength = 1; ps->cache.dirlength_set = 0; ps->cache.cache_completion = (float)DEFAULT_CACHE_COMPLETION; ps->cache.cache_completion_set = 0; return ps;}static void * merge_proxy_config(pool *p, void *basev, void *overridesv){ proxy_server_conf *ps = ap_pcalloc(p, sizeof(proxy_server_conf)); proxy_server_conf *base = (proxy_server_conf *)basev; proxy_server_conf *overrides = (proxy_server_conf *)overridesv; ps->proxies = ap_append_arrays(p, base->proxies, overrides->proxies); ps->aliases = ap_append_arrays(p, base->aliases, overrides->aliases); ps->raliases = ap_append_arrays(p, base->raliases, overrides->raliases); ps->noproxies = ap_append_arrays(p, base->noproxies, overrides->noproxies); ps->dirconn = ap_append_arrays(p, base->dirconn, overrides->dirconn); ps->nocaches = ap_append_arrays(p, base->nocaches, overrides->nocaches); ps->allowed_connect_ports = ap_append_arrays(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->cache.root = (overrides->cache.root == NULL) ? base->cache.root : overrides->cache.root; ps->cache.space = (overrides->cache.space_set == 0) ? base->cache.space : overrides->cache.space; ps->cache.maxexpire = (overrides->cache.maxexpire_set == 0) ? base->cache.maxexpire : overrides->cache.maxexpire; ps->cache.defaultexpire = (overrides->cache.defaultexpire_set == 0) ? base->cache.defaultexpire : overrides->cache.defaultexpire; ps->cache.lmfactor = (overrides->cache.lmfactor_set == 0) ? base->cache.lmfactor : overrides->cache.lmfactor; ps->cache.gcinterval = (overrides->cache.gcinterval_set == 0) ? base->cache.gcinterval : overrides->cache.gcinterval; /* at these levels, the cache can have 2^18 directories (256,000) */ ps->cache.dirlevels = (overrides->cache.dirlevels_set == 0) ? base->cache.dirlevels : overrides->cache.dirlevels; ps->cache.dirlength = (overrides->cache.dirlength_set == 0) ? base->cache.dirlength : overrides->cache.dirlength; ps->cache.cache_completion = (overrides->cache.cache_completion_set == 0) ? base->cache.cache_completion : overrides->cache.cache_completion; return ps;}static const char * add_proxy(cmd_parms *cmd, void *dummy, char *f, 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_remote *new; char *p, *q; int port; p = strchr(r, ':'); if (p == NULL || p[1] != '/' || p[2] != '/' || p[3] == '\0') return "ProxyRemote: Bad syntax for a remote proxy server"; q = strchr(p + 3, ':'); if (q != NULL) { if (sscanf(q + 1, "%u", &port) != 1 || port > 65535) return "ProxyRemote: Bad syntax for a remote proxy server (bad port number)"; *q = '\0'; } else port = -1; *p = '\0'; if (strchr(f, ':') == NULL) ap_str_tolower(f); /* lowercase scheme */ ap_str_tolower(p + 3); /* lowercase hostname */ if (port == -1) { int i; for (i = 0; defports[i].scheme != NULL; i++) if (strcasecmp(defports[i].scheme, r) == 0) break; port = defports[i].port; } new = ap_push_array(conf->proxies); new->scheme = f; new->protocol = r; new->hostname = p + 3; new->port = port; return NULL;}static const char * add_pass(cmd_parms *cmd, void *dummy, char *f, 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; new = ap_push_array(conf->aliases); new->fake = f; new->real = r; return NULL;}static const char * add_pass_reverse(cmd_parms *cmd, void *dummy, char *f, 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); new = ap_push_array(conf->raliases); new->fake = f; new->real = r; return NULL;}static const char * set_proxy_exclude(cmd_parms *parms, void *dummy, 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 hostent hp; 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 = ap_push_array(conf->noproxies); new->name = arg; /* Don't do name lookups on things that aren't dotted */ if (strchr(arg, '.') != NULL && ap_proxy_host2addr(new->name, &hp) == NULL) /* * @@@FIXME: This copies only the first of (possibly many) IP * addrs */ memcpy(&new->addr, hp.h_addr, sizeof(struct in_addr)); else new->addr.s_addr = 0; } return NULL;}/* * Set the ports CONNECT can use */static const char * set_allowed_ports(cmd_parms *parms, void *dummy, char *arg){ server_rec *s = parms->server; proxy_server_conf *conf = ap_get_module_config(s->module_config, &proxy_module); int *New; if (!ap_isdigit(arg[0])) return "AllowCONNECT: port number must be numeric"; New = ap_push_array(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, 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 = ap_push_array(conf->dirconn); New->name = arg; New->hostentry = NULL; if (ap_proxy_is_ipaddr(New, parms->pool)) {#if DEBUGGING fprintf(stderr, "Parsed addr %s\n", inet_ntoa(New->addr)); fprintf(stderr, "Parsed mask %s\n", inet_ntoa(New->mask));#endif } else if (ap_proxy_is_domainname(New, parms->pool)) { ap_str_tolower(New->name);#if DEBUGGING fprintf(stderr, "Parsed domain %s\n", New->name);#endif } else if (ap_proxy_is_hostname(New, parms->pool)) { ap_str_tolower(New->name);#if DEBUGGING fprintf(stderr, "Parsed host %s\n", New->name);#endif }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -