📄 proxy_util.c
字号:
} This->matcher = proxy_match_hostname; return 1;}/* Return TRUE if host "host" is equal to host2 "host2" */static int proxy_match_hostname(struct dirconn_entry *This, request_rec *r){ char *host = This->name; const char *host2 = proxy_get_host_of_request(r); int h2_len; int h1_len; if (host == NULL || host2 == NULL) { return 0; /* oops! */ } h2_len = strlen(host2); h1_len = strlen(host);#if 0 struct apr_sockaddr_t *addr = *This->hostaddr; /* Try to deal with multiple IP addr's for a host */ while (addr) { if (addr->ipaddr_ptr == ? ? ? ? ? ? ? ? ? ? ? ? ?) return 1; addr = addr->next; }#endif /* Ignore trailing dots in host2 comparison: */ while (h2_len > 0 && host2[h2_len - 1] == '.') { --h2_len; } while (h1_len > 0 && host[h1_len - 1] == '.') { --h1_len; } return h1_len == h2_len && strncasecmp(host, host2, h1_len) == 0;}/* Return TRUE if addr is to be matched as a word */PROXY_DECLARE(int) ap_proxy_is_word(struct dirconn_entry *This, apr_pool_t *p){ This->matcher = proxy_match_word; return 1;}/* Return TRUE if string "str2" occurs literally in "str1" */static int proxy_match_word(struct dirconn_entry *This, request_rec *r){ const char *host = proxy_get_host_of_request(r); return host != NULL && ap_strstr_c(host, This->name) != NULL;}/* checks whether a host in uri_addr matches proxyblock */PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf, apr_sockaddr_t *uri_addr){ int j; apr_sockaddr_t * src_uri_addr = uri_addr; /* XXX FIXME: conf->noproxies->elts is part of an opaque structure */ for (j = 0; j < conf->noproxies->nelts; j++) { struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts; struct apr_sockaddr_t *conf_addr = npent[j].addr; uri_addr = src_uri_addr; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: checking remote machine [%s] against [%s]", uri_addr->hostname, npent[j].name); if ((npent[j].name && ap_strstr_c(uri_addr->hostname, npent[j].name)) || npent[j].name[0] == '*') { ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, "proxy: connect to remote machine %s blocked: name %s matched", uri_addr->hostname, npent[j].name); return HTTP_FORBIDDEN; } while (conf_addr) { uri_addr = src_uri_addr; while (uri_addr) { char *conf_ip; char *uri_ip; apr_sockaddr_ip_get(&conf_ip, conf_addr); apr_sockaddr_ip_get(&uri_ip, uri_addr); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: ProxyBlock comparing %s and %s", conf_ip, uri_ip); if (!apr_strnatcasecmp(conf_ip, uri_ip)) { ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, "proxy: connect to remote machine %s blocked: IP %s matched", uri_addr->hostname, conf_ip); return HTTP_FORBIDDEN; } uri_addr = uri_addr->next; } conf_addr = conf_addr->next; } } return OK;}/* set up the minimal filter set */PROXY_DECLARE(int) ap_proxy_pre_http_request(conn_rec *c, request_rec *r){ ap_add_input_filter("HTTP_IN", NULL, r, c); return OK;}/* * converts a series of buckets into a string * XXX: BillS says this function performs essentially the same function as * ap_rgetline() in protocol.c. Deprecate this function and use ap_rgetline() * instead? I think ap_proxy_string_read() will not work properly on non ASCII * (EBCDIC) machines either. */PROXY_DECLARE(apr_status_t) ap_proxy_string_read(conn_rec *c, apr_bucket_brigade *bb, char *buff, apr_size_t bufflen, int *eos){ apr_bucket *e; apr_status_t rv; char *pos = buff; char *response; int found = 0; apr_size_t len; /* start with an empty string */ buff[0] = 0; *eos = 0; /* loop through each brigade */ while (!found) { /* get brigade from network one line at a time */ if (APR_SUCCESS != (rv = ap_get_brigade(c->input_filters, bb, AP_MODE_GETLINE, APR_BLOCK_READ, 0))) { return rv; } /* loop through each bucket */ while (!found) { if (*eos || APR_BRIGADE_EMPTY(bb)) { /* The connection aborted or timed out */ return APR_ECONNABORTED; } e = APR_BRIGADE_FIRST(bb); if (APR_BUCKET_IS_EOS(e)) { *eos = 1; } else { if (APR_SUCCESS != (rv = apr_bucket_read(e, (const char **)&response, &len, APR_BLOCK_READ))) { return rv; } /* * is string LF terminated? * XXX: This check can be made more efficient by simply checking * if the last character in the 'response' buffer is an ASCII_LF. * See ap_rgetline() for an example. */ if (memchr(response, APR_ASCII_LF, len)) { found = 1; } /* concat strings until buff is full - then throw the data away */ if (len > ((bufflen-1)-(pos-buff))) { len = (bufflen-1)-(pos-buff); } if (len > 0) { memcpy(pos, response, len); pos += len; } } APR_BUCKET_REMOVE(e); apr_bucket_destroy(e); } *pos = '\0'; } return APR_SUCCESS;}/* unmerge an element in the table */PROXY_DECLARE(void) ap_proxy_table_unmerge(apr_pool_t *p, apr_table_t *t, char *key){ apr_off_t offset = 0; apr_off_t count = 0; char *value = NULL; /* get the value to unmerge */ const char *initial = apr_table_get(t, key); if (!initial) { return; } value = apr_pstrdup(p, initial); /* remove the value from the headers */ apr_table_unset(t, key); /* find each comma */ while (value[count]) { if (value[count] == ',') { value[count] = 0; apr_table_add(t, key, value + offset); offset = count + 1; } count++; } apr_table_add(t, key, value + offset);}PROXY_DECLARE(const char *) ap_proxy_location_reverse_map(request_rec *r, proxy_dir_conf *conf, const char *url){ proxy_req_conf *rconf; struct proxy_alias *ent; int i, l1, l2; char *u; /* * XXX FIXME: Make sure this handled the ambiguous case of the :<PORT> * after the hostname */ if (r->proxyreq != PROXYREQ_REVERSE) { return url; } l1 = strlen(url); if (conf->interpolate_env == 1) { rconf = ap_get_module_config(r->request_config, &proxy_module); ent = (struct proxy_alias *)rconf->raliases->elts; } else { ent = (struct proxy_alias *)conf->raliases->elts; } for (i = 0; i < conf->raliases->nelts; i++) { proxy_server_conf *sconf = (proxy_server_conf *) ap_get_module_config(r->server->module_config, &proxy_module); proxy_balancer *balancer; const char *real; real = ent[i].real; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "ppr: real: %s", real); /* * First check if mapping against a balancer and see * if we have such a entity. If so, then we need to * find the particulars of the actual worker which may * or may not be the right one... basically, we need * to find which member actually handled this request. */ if ((strncasecmp(real, "balancer:", 9) == 0) && (balancer = ap_proxy_get_balancer(r->pool, sconf, real))) { int n; proxy_worker *worker; worker = (proxy_worker *)balancer->workers->elts; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "ppr: checking balancer: %s", balancer->name); for (n = 0; n < balancer->workers->nelts; n++) { if (worker->port) { u = apr_psprintf(r->pool, "%s://%s:%d/", worker->scheme, worker->hostname, worker->port); } else { u = apr_psprintf(r->pool, "%s://%s/", worker->scheme, worker->hostname); } ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "ppr: matching member (%s) and URL (%s)", u, url); l2 = strlen(u); if (l1 >= l2 && strncasecmp(u, url, l2) == 0) { u = apr_pstrcat(r->pool, ent[i].fake, &url[l2], NULL); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "ppr: matched member (%s)", u); return ap_construct_url(r->pool, u, r); } worker++; } } l2 = strlen(real); if (l1 >= l2 && strncasecmp(real, url, l2) == 0) { u = apr_pstrcat(r->pool, ent[i].fake, &url[l2], NULL); return ap_construct_url(r->pool, u, r); } } return url;}/* * Cookies are a bit trickier to match: we've got two substrings to worry * about, and we can't just find them with strstr 'cos of case. Regexp * matching would be an easy fix, but for better consistency with all the * other matches we'll refrain and use apr_strmatch to find path=/domain= * and stick to plain strings for the config values. */PROXY_DECLARE(const char *) ap_proxy_cookie_reverse_map(request_rec *r, proxy_dir_conf *conf, const char *str){ proxy_req_conf *rconf = ap_get_module_config(r->request_config, &proxy_module); struct proxy_alias *ent; size_t len = strlen(str); const char *newpath = NULL; const char *newdomain = NULL; const char *pathp; const char *domainp; const char *pathe = NULL; const char *domaine = NULL; size_t l1, l2, poffs = 0, doffs = 0; int i; int ddiff = 0; int pdiff = 0; char *ret; if (r->proxyreq != PROXYREQ_REVERSE) { return str; } /* * Find the match and replacement, but save replacing until we've done * both path and domain so we know the new strlen */ if ((pathp = apr_strmatch(conf->cookie_path_str, str, len)) != NULL) { pathp += 5; poffs = pathp - str; pathe = ap_strchr_c(pathp, ';'); l1 = pathe ? (pathe - pathp) : strlen(pathp); pathe = pathp + l1 ; if (conf->interpolate_env == 1) { ent = (struct proxy_alias *)rconf->cookie_paths->elts; } else { ent = (struct proxy_alias *)conf->cookie_paths->elts; } for (i = 0; i < conf->cookie_paths->nelts; i++) { l2 = strlen(ent[i].fake); if (l1 >= l2 && strncmp(ent[i].fake, pathp, l2) == 0) { newpath = ent[i].real; pdiff = strlen(newpath) - l1; break; } } } if ((domainp = apr_strmatch(conf->cookie_domain_str, str, len)) != NULL) { domainp += 7; doffs = domainp - str; domaine = ap_strchr_c(domainp, ';'); l1 = domaine ? (domaine - domainp) : strlen(domainp); domaine = domainp + l1; if (conf->interpolate_env == 1) { ent = (struct proxy_alias *)rconf->cookie_domains->elts; } else { ent = (struct proxy_alias *)conf->cookie_domains->elts; } for (i = 0; i < conf->cookie_domains->nelts; i++) { l2 = strlen(ent[i].fake); if (l1 >= l2 && strncasecmp(ent[i].fake, domainp, l2) == 0) { newdomain = ent[i].real; ddiff = strlen(newdomain) - l1; break; } } } if (newpath) { ret = apr_palloc(r->pool, len + pdiff + ddiff + 1); l1 = strlen(newpath); if (newdomain) { l2 = strlen(newdomain); if (doffs > poffs) { memcpy(ret, str, poffs); memcpy(ret + poffs, newpath, l1); memcpy(ret + poffs + l1, pathe, domainp - pathe); memcpy(ret + doffs + pdiff, newdomain, l2); strcpy(ret + doffs + pdiff + l2, domaine); } else { memcpy(ret, str, doffs) ; memcpy(ret + doffs, newdomain, l2); memcpy(ret + doffs + l2, domaine, pathp - domaine); memcpy(ret + poffs + ddiff, newpath, l1); strcpy(ret + poffs + ddiff + l1, pathe); } } else { memcpy(ret, str, poffs); memcpy(ret + poffs, newpath, l1); strcpy(ret + poffs + l1, pathe); } } else { if (newdomain) { ret = apr_palloc(r->pool, len + pdiff + ddiff + 1); l2 = strlen(newdomain); memcpy(ret, str, doffs); memcpy(ret + doffs, newdomain, l2); strcpy(ret + doffs+l2, domaine); } else { ret = (char *)str; /* no change */ } } return ret;}PROXY_DECLARE(proxy_balancer *) ap_proxy_get_balancer(apr_pool_t *p, proxy_server_conf *conf, const char *url){ proxy_balancer *balancer; char *c, *uri = apr_pstrdup(p, url); int i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -