⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 proxy_util.c

📁 Apache官方在今天放出产品系列2.2的最新版本2.2.11的源码包 最流行的HTTP服务器软件之一
💻 C
📖 第 1 页 / 共 5 页
字号:
                p++;            } while (apr_isspace(*p));        }        else {            i = strlen(list);        }        while (i > 0 && apr_isspace(list[i - 1])) {            i--;        }        if (i == len && strncasecmp(list, val, len) == 0) {            /* do nothing */        }        else {            if (new) {                new = apr_pstrcat(pool, new, ",", apr_pstrndup(pool, list, i), NULL);            }            else {                new = apr_pstrndup(pool, list, i);            }        }        list = p;    }    return new;}/* * Converts 8 hex digits to a time integer */PROXY_DECLARE(int) ap_proxy_hex2sec(const char *x){    int i, ch;    unsigned int j;    for (i = 0, j = 0; i < 8; i++) {        ch = x[i];        j <<= 4;        if (apr_isdigit(ch)) {            j |= ch - '0';        }        else if (apr_isupper(ch)) {            j |= ch - ('A' - 10);        }        else {            j |= ch - ('a' - 10);        }    }    if (j == 0xffffffff) {        return -1;      /* so that it works with 8-byte ints */    }    else {        return j;    }}/* * Converts a time integer to 8 hex digits */PROXY_DECLARE(void) ap_proxy_sec2hex(int t, char *y){    int i, ch;    unsigned int j = t;    for (i = 7; i >= 0; i--) {        ch = j & 0xF;        j >>= 4;        if (ch >= 10) {            y[i] = ch + ('A' - 10);        }        else {            y[i] = ch + '0';        }    }    y[8] = '\0';}PROXY_DECLARE(int) ap_proxyerror(request_rec *r, int statuscode, const char *message){    apr_table_setn(r->notes, "error-notes",    apr_pstrcat(r->pool,        "The proxy server could not handle the request "        "<em><a href=\"", ap_escape_html(r->pool, r->uri),        "\">", ap_escape_html(r->pool, r->method),        "&nbsp;",        ap_escape_html(r->pool, r->uri), "</a></em>.<p>\n"        "Reason: <strong>",        ap_escape_html(r->pool, message),        "</strong></p>", NULL));    /* Allow "error-notes" string to be printed by ap_send_error_response() */    apr_table_setn(r->notes, "verbose-error-to", apr_pstrdup(r->pool, "*"));    r->status_line = apr_psprintf(r->pool, "%3.3u Proxy Error", statuscode);    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,             "proxy: %s returned by %s", message, r->uri);    return statuscode;}static const char *     proxy_get_host_of_request(request_rec *r){    char *url, *user = NULL, *password = NULL, *err, *host;    apr_port_t port;    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 = apr_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, 0, 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) */PROXY_DECLARE(int) ap_proxy_is_ipaddr(struct dirconn_entry *This, apr_pool_t *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 apr_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 (!apr_isdigit(*addr)) {            return 0;       /* no digit at start of quad */        }        ip_addr[quads] = 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] == '/' && apr_isdigit(addr[1])) {   /* net mask follows: */        char *tmp;        ++addr;        bits = 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 */            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                         "Warning: NetMask not supplied with IP-Addr; guessing: %s/%ld",                         inet_ntoa(This->addr), bits);        }    }    This->mask.s_addr = htonl(APR_INADDR_NONE << (32 - bits));    if (*addr == '\0' && (This->addr.s_addr & ~This->mask.s_addr) != 0) {        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                     "Warning: NetMask and IP-Addr disagree in %s/%ld",                     inet_ntoa(This->addr), bits);        This->addr.s_addr &= This->mask.s_addr;        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                     "         Set to %s/%ld", 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, ip_addr[4];    struct in_addr addr, *ip;    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            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                         "1)IP-Match: %s[%s] <-> ", host, inet_ntoa(addr));            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                         "%s/", inet_ntoa(This->addr));            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                         "%s", inet_ntoa(This->mask));#endif            return 1;        }#if DEBUGGING        else {            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                         "1)IP-NoMatch: %s[%s] <-> ", host, inet_ntoa(addr));            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                         "%s/", inet_ntoa(This->addr));            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                         "%s", inet_ntoa(This->mask));        }#endif    }    else {        struct apr_sockaddr_t *reqaddr;        if (apr_sockaddr_info_get(&reqaddr, host, APR_UNSPEC, 0, 0, r->pool)            != APR_SUCCESS) {#if DEBUGGING            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,             "2)IP-NoMatch: hostname=%s msg=Host not found", host);#endif            return 0;        }        /* Try to deal with multiple IP addr's for a host */        /* FIXME: This needs to be able to deal with IPv6 */        while (reqaddr) {            ip = (struct in_addr *) reqaddr->ipaddr_ptr;            if (This->addr.s_addr == (ip->s_addr & This->mask.s_addr)) {#if DEBUGGING                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                             "3)IP-Match: %s[%s] <-> ", host, inet_ntoa(*ip));                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                             "%s/", inet_ntoa(This->addr));                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                             "%s", inet_ntoa(This->mask));#endif                return 1;            }#if DEBUGGING            else {                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                             "3)IP-NoMatch: %s[%s] <-> ", host, inet_ntoa(*ip));                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                             "%s/", inet_ntoa(This->addr));                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                             "%s", inet_ntoa(This->mask));            }#endif            reqaddr = reqaddr->next;        }    }    return 0;}/* Return TRUE if addr represents a domain name */PROXY_DECLARE(int) ap_proxy_is_domainname(struct dirconn_entry *This, apr_pool_t *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; apr_isalnum(addr[i]) || addr[i] == '-' || addr[i] == '.'; ++i) {        continue;    }#if 0    if (addr[i] == ':') {    ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,                     "@@@@ handle optional port in proxy_is_domainname()");    /* @@@@ 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;    }    while (h_len > 0 && host[h_len - 1] == '.') {        --h_len;    }    return h_len > d_len        && strncasecmp(&host[h_len - d_len], This->name, d_len) == 0;}/* Return TRUE if host represents a host name */PROXY_DECLARE(int) ap_proxy_is_hostname(struct dirconn_entry *This, apr_pool_t *p){    struct apr_sockaddr_t *addr;    char *host = This->name;    int i;    /* Host names must not start with a '.' */    if (host[0] == '.') {        return 0;    }    /* rfc1035 says DNS names must consist of "[-a-zA-Z0-9]" and '.' */    for (i = 0; apr_isalnum(host[i]) || host[i] == '-' || host[i] == '.'; ++i);    if (host[i] != '\0' || apr_sockaddr_info_get(&addr, host, APR_UNSPEC, 0, 0, p) != APR_SUCCESS) {        return 0;    }    This->hostaddr = addr;    /* Strip trailing dots */    for (i = strlen(host) - 1; i > 0 && host[i] == '.'; --i) {        host[i] = '\0';

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -