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

📄 proxy_util.c

📁 Apache官方在今天放出产品系列2.2的最新版本2.2.11的源码包 最流行的HTTP服务器软件之一
💻 C
📖 第 1 页 / 共 5 页
字号:
    }    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 + -