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

📄 proxy_util.c

📁 最新apache的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	     * MS IIS servers, so we need to determine just how to handle	     * them. We can either ignore them, assume that they mark the	     * start-of-body (eg: a missing CRLF) or (the default) mark	     * the headers as totally bogus and return a 500. The sole	     * exception is an extra "HTTP/1.0 200, OK" line sprinkled	     * in between the usual MIME headers, which is a favorite	     * IIS bug.	     */	     /* XXX: The mask check is buggy if we ever see an HTTP/1.10 */	    if (!apr_date_checkmask(buffer, "HTTP/#.# ###*")) {		if (psc->badopt == bad_error) {		    /* Nope, it wasn't even an extra HTTP header. Give up. */		    return NULL;		}		else if (psc->badopt == bad_body) {		    /* if we've already started loading headers_out, then		     * return what we've accumulated so far, in the hopes		     * that they are useful. Otherwise, we completely bail.		     */		    /* FIXME: We've already scarfed the supposed 1st line of		     * the body, so the actual content may end up being bogus		     * as well. If the content is HTML, we may be lucky.		     */		    if (saw_headers) {			ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server,			 "proxy: Starting body due to bogus non-header in headers "			 "returned by %s (%s)", r->uri, r->method);			return headers_out;		    } else {			 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server,			 "proxy: No HTTP headers "			 "returned by %s (%s)", r->uri, r->method);			return NULL;		    }		}	    }	    /* this is the psc->badopt == bad_ignore case */	    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server,			 "proxy: Ignoring bogus HTTP header "			 "returned by %s (%s)", r->uri, r->method);	    continue;	}        *value = '\0';        ++value;	/* XXX: RFC2068 defines only SP and HT as whitespace, this test is	 * wrong... and so are many others probably.	 */        while (apr_isspace(*value))            ++value;            /* Skip to start of value   */	/* should strip trailing whitespace as well */	for (end = &value[strlen(value)-1]; end > value && apr_isspace(*end); --end)	    *end = '\0';        /* make sure we add so as not to destroy duplicated headers */        apr_table_add(headers_out, buffer, value);        saw_headers = 1;	/* the header was too long; at the least we should skip extra data */	if (len >= size - 1) { 	    while ((len = ap_getline(field, MAX_STRING_LEN, rr, 1))		    >= MAX_STRING_LEN - 1) {		/* soak up the extra data */	    }	    if (len == 0) /* time to exit the larger loop as well */		break;	}    }    return headers_out;}/* * list is a comma-separated list of case-insensitive tokens, with * optional whitespace around the tokens. * The return returns 1 if the token val is found in the list, or 0 * otherwise. */PROXY_DECLARE(int) ap_proxy_liststr(const char *list, const char *val){    int len, i;    const char *p;    len = strlen(val);    while (list != NULL) {	p = ap_strchr_c(list, ',');	if (p != NULL) {	    i = p - list;	    do		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)	    return 1;	list = p;    }    return 0;}/* * list is a comma-separated list of case-insensitive tokens, with * optional whitespace around the tokens. * if val appears on the list of tokens, it is removed from the list, * and the new list is returned. */PROXY_DECLARE(char *)ap_proxy_removestr(apr_pool_t *pool, const char *list, const char *val){    int len, i;    const char *p;    char *new = NULL;    len = strlen(val);    while (list != NULL) {	p = ap_strchr_c(list, ',');	if (p != NULL) {	    i = p - list;	    do		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_uri(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)

⌨️ 快捷键说明

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