📄 proxy_util.c
字号:
x = (digest[i] << 16) | (digest[i + 1] << 8) | digest[i + 2]; tmp[k++] = enc_table[x >> 18]; tmp[k++] = enc_table[(x >> 12) & 0x3f]; tmp[k++] = enc_table[(x >> 6) & 0x3f]; tmp[k++] = enc_table[x & 0x3f]; }/* one byte left */ x = digest[15]; tmp[k++] = enc_table[x >> 2]; /* use up 6 bits */ tmp[k++] = enc_table[(x << 4) & 0x3f]; /* now split into directory levels */ for (i = k = d = 0; d < ndepth; ++d) { memcpy(&val[i], &tmp[k], nlength); k += nlength; val[i + nlength] = '/'; i += nlength + 1; } memcpy(&val[i], &tmp[k], 22 - k); val[i + 22 - k] = '\0';}#endif /* CASE_BLIND_FILESYSTEM *//* * Converts 16 hex digits to a time integer */int ap_proxy_hex2sec(const char *x){ int i, ch; unsigned int j; for (i = 0, j = 0; i < 16; i++) { ch = x[i]; j <<= 4; if (ap_isdigit(ch)) j |= ch - '0'; else if (ap_isupper(ch)) j |= ch - ('A' - 10); else j |= ch - ('a' - 10); }/* no longer necessary, as the source hex is 8-byte int *//* if (j == 0xffffffff)*/ /* return -1;*//* so that it works with 8-byte ints *//* else */ return j;}/* * Converts a time integer to 16 hex digits */void ap_proxy_sec2hex(int t, char *y){ int i, ch; unsigned int j = t; if (-1 == t) { strcpy(y, "FFFFFFFFFFFFFFFF"); return; } for (i = 15; i >= 0; i--) { ch = j & 0xF; j >>= 4; if (ch >= 10) y[i] = ch + ('A' - 10); else y[i] = ch + '0'; } y[16] = '\0';}cache_req *ap_proxy_cache_error(cache_req *c){ if (c != NULL) { if (c->fp != NULL) { ap_pclosef(c->req->pool, ap_bfileno(c->fp, B_WR)); c->fp = NULL; } if (c->origfp != NULL) { ap_pclosef(c->req->pool, ap_bfileno(c->origfp, B_WR)); c->origfp = NULL; } if (c->tempfile) unlink(c->tempfile); } return NULL;}int ap_proxyerror(request_rec *r, int statuscode, const char *message){ ap_table_setn(r->notes, "error-notes", ap_pstrcat(r->pool, "The proxy server could not handle the request " "<EM><A HREF=\"", ap_escape_uri(r->pool, r->uri), "\">", ap_escape_html(r->pool, r->method), " ", ap_escape_html(r->pool, r->uri), "</A></EM>.<P>\n" "Reason: <STRONG>", ap_escape_html(r->pool, message), "</STRONG>", NULL)); /* Allow "error-notes" string to be printed by ap_send_error_response() */ ap_table_setn(r->notes, "verbose-error-to", ap_pstrdup(r->pool, "*")); r->status_line = ap_psprintf(r->pool, "%3.3u Proxy Error", statuscode); return statuscode;}/* * This routine returns its own error message */const char * ap_proxy_host2addr(const char *host, struct hostent * reqhp){ int i; struct hostent *hp; struct per_thread_data *ptd = get_per_thread_data(); for (i = 0; host[i] != '\0'; i++) if (!ap_isdigit(host[i]) && host[i] != '.') break; if (host[i] != '\0') { hp = gethostbyname(host); if (hp == NULL) return "Host not found"; } else { ptd->ipaddr = ap_inet_addr(host); hp = gethostbyaddr((char *)&ptd->ipaddr, sizeof(ptd->ipaddr), AF_INET); if (hp == NULL) { memset(&ptd->hpbuf, 0, sizeof(ptd->hpbuf)); ptd->hpbuf.h_name = 0; ptd->hpbuf.h_addrtype = AF_INET; ptd->hpbuf.h_length = sizeof(ptd->ipaddr); ptd->hpbuf.h_addr_list = ptd->charpbuf; ptd->hpbuf.h_addr_list[0] = (char *)&ptd->ipaddr; ptd->hpbuf.h_addr_list[1] = 0; hp = &ptd->hpbuf; } } *reqhp = *hp; return NULL;}static const char * proxy_get_host_of_request(request_rec *r){ char *url, *user = NULL, *password = NULL, *err, *host; int port = -1; if (r->hostname != NULL) return r->hostname; /* Set url to the first char after "scheme://" */ if ((url = strchr(r->uri, ':')) == NULL || url[1] != '/' || url[2] != '/') return NULL; url = ap_pstrdup(r->pool, &url[1]); /* make it point to "//", which is * what proxy_canon_netloc expects */ err = ap_proxy_canon_netloc(r->pool, &url, &user, &password, &host, &port); if (err != NULL) ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, r, "%s", err); r->hostname = host; return host; /* ought to return the port, too */}/* Return TRUE if addr represents an IP address (or an IP network address) */int ap_proxy_is_ipaddr(struct dirconn_entry *This, pool *p){ const char *addr = This->name; long ip_addr[4]; int i, quads; long bits; /* if the address is given with an explicit netmask, use that */ /* Due to a deficiency in ap_inet_addr(), it is impossible to parse */ /* "partial" addresses (with less than 4 quads) correctly, i.e. */ /* 192.168.123 is parsed as 192.168.0.123, which is not what I want. */ /* I therefore have to parse the IP address manually: */ /* * if (proxy_readmask(This->name, &This->addr.s_addr, &This->mask.s_addr) * == 0) */ /* addr and mask were set by proxy_readmask() */ /* return 1; */ /* Parse IP addr manually, optionally allowing */ /* abbreviated net addresses like 192.168. */ /* Iterate over up to 4 (dotted) quads. */ for (quads = 0; quads < 4 && *addr != '\0'; ++quads) { char *tmp; if (*addr == '/' && quads > 0) /* netmask starts here. */ break; if (!ap_isdigit(*addr)) return 0; /* no digit at start of quad */ ip_addr[quads] = ap_strtol(addr, &tmp, 0); if (tmp == addr) /* expected a digit, found something else */ return 0; if (ip_addr[quads] < 0 || ip_addr[quads] > 255) { /* invalid octet */ return 0; } addr = tmp; if (*addr == '.' && quads != 3) ++addr; /* after the 4th quad, a dot would be illegal */ } for (This->addr.s_addr = 0, i = 0; i < quads; ++i) This->addr.s_addr |= htonl(ip_addr[i] << (24 - 8 * i)); if (addr[0] == '/' && ap_isdigit(addr[1])) { /* net mask follows: */ char *tmp; ++addr; bits = ap_strtol(addr, &tmp, 0); if (tmp == addr) /* expected a digit, found something else */ return 0; addr = tmp; if (bits < 0 || bits > 32) /* netmask must be between 0 and 32 */ return 0; } else { /* Determine (i.e., "guess") netmask by counting the */ /* number of trailing .0's; reduce #quads appropriately */ /* (so that 192.168.0.0 is equivalent to 192.168.) */ while (quads > 0 && ip_addr[quads - 1] == 0) --quads; /* * "IP Address should be given in dotted-quad form, optionally * followed by a netmask (e.g., 192.168.111.0/24)"; */ if (quads < 1) return 0; /* every zero-byte counts as 8 zero-bits */ bits = 8 * quads; if (bits != 32) /* no warning for fully qualified IP address */ fprintf(stderr, "Warning: NetMask not supplied with IP-Addr; guessing: %s/%ld\n", inet_ntoa(This->addr), bits); } This->mask.s_addr = htonl(INADDR_NONE << (32 - bits)); if (*addr == '\0' && (This->addr.s_addr & ~This->mask.s_addr) != 0) { fprintf(stderr, "Warning: NetMask and IP-Addr disagree in %s/%ld\n", inet_ntoa(This->addr), bits); This->addr.s_addr &= This->mask.s_addr; fprintf(stderr, " Set to %s/%ld\n", inet_ntoa(This->addr), bits); } if (*addr == '\0') { This->matcher = proxy_match_ipaddr; return 1; } else return (*addr == '\0'); /* okay iff we've parsed the whole string */}/* Return TRUE if addr represents an IP address (or an IP network address) */static int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r){ int i; int ip_addr[4]; struct in_addr addr; struct in_addr *ip_list; char **ip_listptr; const char *found; const char *host = proxy_get_host_of_request(r); if (host == NULL) /* oops! */ return 0; memset(&addr, '\0', sizeof addr); memset(ip_addr, '\0', sizeof ip_addr); if (4 == sscanf(host, "%d.%d.%d.%d", &ip_addr[0], &ip_addr[1], &ip_addr[2], &ip_addr[3])) { for (addr.s_addr = 0, i = 0; i < 4; ++i) addr.s_addr |= htonl(ip_addr[i] << (24 - 8 * i)); if (This->addr.s_addr == (addr.s_addr & This->mask.s_addr)) {#if DEBUGGING fprintf(stderr, "1)IP-Match: %s[%s] <-> ", host, inet_ntoa(addr)); fprintf(stderr, "%s/", inet_ntoa(This->addr)); fprintf(stderr, "%s\n", inet_ntoa(This->mask));#endif return 1; }#if DEBUGGING else { fprintf(stderr, "1)IP-NoMatch: %s[%s] <-> ", host, inet_ntoa(addr)); fprintf(stderr, "%s/", inet_ntoa(This->addr)); fprintf(stderr, "%s\n", inet_ntoa(This->mask)); }#endif } else { struct hostent the_host; memset(&the_host, '\0', sizeof the_host); found = ap_proxy_host2addr(host, &the_host); if (found != NULL) {#if DEBUGGING fprintf(stderr, "2)IP-NoMatch: hostname=%s msg=%s\n", host, found);#endif return 0; } if (the_host.h_name != NULL) found = the_host.h_name; else found = host; /* Try to deal with multiple IP addr's for a host */ for (ip_listptr = the_host.h_addr_list; *ip_listptr; ++ip_listptr) { ip_list = (struct in_addr *)*ip_listptr; if (This->addr.s_addr == (ip_list->s_addr & This->mask.s_addr)) {#if DEBUGGING fprintf(stderr, "3)IP-Match: %s[%s] <-> ", found, inet_ntoa(*ip_list)); fprintf(stderr, "%s/", inet_ntoa(This->addr)); fprintf(stderr, "%s\n", inet_ntoa(This->mask));#endif return 1; }#if DEBUGGING else { fprintf(stderr, "3)IP-NoMatch: %s[%s] <-> ", found, inet_ntoa(*ip_list)); fprintf(stderr, "%s/", inet_ntoa(This->addr)); fprintf(stderr, "%s\n", inet_ntoa(This->mask)); }#endif } } return 0;}/* Return TRUE if addr represents a domain name */int ap_proxy_is_domainname(struct dirconn_entry *This, pool *p){ char *addr = This->name; int i; /* Domain name must start with a '.' */ if (addr[0] != '.') return 0; /* rfc1035 says DNS names must consist of "[-a-zA-Z0-9]" and '.' */ for (i = 0; ap_isalnum(addr[i]) || addr[i] == '-' || addr[i] == '.'; ++i) continue;#if 0 if (addr[i] == ':') { fprintf(stderr, "@@@@ handle optional port in proxy_is_domainname()\n"); /* @@@@ handle optional port */ }#endif if (addr[i] != '\0') return 0; /* Strip trailing dots */ for (i = strlen(addr) - 1; i > 0 && addr[i] == '.'; --i) addr[i] = '\0'; This->matcher = proxy_match_domainname; return 1;}/* Return TRUE if host "host" is in domain "domain" */static int proxy_match_domainname(struct dirconn_entry *This, request_rec *r){ const char *host = proxy_get_host_of_request(r); int d_len = strlen(This->name), h_len; if (host == NULL) /* some error was logged already */ return 0; h_len = strlen(host); /* @@@ do this within the setup? */ /* Ignore trailing dots in domain comparison: */ while (d_len > 0 && This->name[d_len - 1] == '.') --d_len;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -