proxy_util.c revision db3fa7db7c7910f2f23c3e3ffe0cf9f41a1899b9
a530dde7009b0a808300c420def741354a4d13d2Martin Kühl/* ====================================================================
a530dde7009b0a808300c420def741354a4d13d2Martin Kühl * The Apache Software License, Version 1.1
a530dde7009b0a808300c420def741354a4d13d2Martin Kühl * Copyright (c) 2000 The Apache Software Foundation. All rights
a530dde7009b0a808300c420def741354a4d13d2Martin Kühl * Redistribution and use in source and binary forms, with or without
a530dde7009b0a808300c420def741354a4d13d2Martin Kühl * modification, are permitted provided that the following conditions
a530dde7009b0a808300c420def741354a4d13d2Martin Kühl * 1. Redistributions of source code must retain the above copyright
a530dde7009b0a808300c420def741354a4d13d2Martin Kühl * notice, this list of conditions and the following disclaimer.
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco * 2. Redistributions in binary form must reproduce the above copyright
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco * notice, this list of conditions and the following disclaimer in
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * the documentation and/or other materials provided with the
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * distribution.
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco * 3. The end-user documentation included with the redistribution,
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco * if any, must include the following acknowledgment:
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco * "This product includes software developed by the
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco * Apache Software Foundation (http://www.apache.org/)."
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco * Alternately, this acknowledgment may appear in the software itself,
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * if and wherever such third-party acknowledgments normally appear.
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * 4. The names "Apache" and "Apache Software Foundation" must
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco * not be used to endorse or promote products derived from this
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco * software without prior written permission. For written
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco * permission, please contact apache@apache.org.
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * 5. Products derived from this software may not be called "Apache",
223be434693e8c97e2522ac19155a284b3536035Adrián Riesco * nor may "Apache" appear in their name, without prior written
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco * permission of the Apache Software Foundation.
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
b9840e4ee6fda6e42fa4ee9f337482ccc4839a39Adrián Riesco * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
223be434693e8c97e2522ac19155a284b3536035Adrián Riesco * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223be434693e8c97e2522ac19155a284b3536035Adrián Riesco * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
223be434693e8c97e2522ac19155a284b3536035Adrián Riesco * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
223be434693e8c97e2522ac19155a284b3536035Adrián Riesco * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
223be434693e8c97e2522ac19155a284b3536035Adrián Riesco * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
223be434693e8c97e2522ac19155a284b3536035Adrián Riesco * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
223be434693e8c97e2522ac19155a284b3536035Adrián Riesco * SUCH DAMAGE.
223be434693e8c97e2522ac19155a284b3536035Adrián Riesco * ====================================================================
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * This software consists of voluntary contributions made by many
51c15129e8118fed5c33c334f8df82619ce98e7dAdrián Riesco * individuals on behalf of the Apache Software Foundation. For more
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco * information on the Apache Software Foundation, please see
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * Portions of this software are based upon public domain software
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * originally written at the National Center for Supercomputing Applications,
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * University of Illinois, Urbana-Champaign.
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco/* Utility routines for Apache proxy */
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco#include "util_date.h" /* get ap_checkmask() decl. */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riescostatic int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r);
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riescostatic int proxy_match_domainname(struct dirconn_entry *This, request_rec *r);
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riescostatic int proxy_match_hostname(struct dirconn_entry *This, request_rec *r);
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riescostatic int proxy_match_word(struct dirconn_entry *This, request_rec *r);
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riescostatic struct per_thread_data *get_per_thread_data(void);
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco/* already called in the knowledge that the characters are hex digits */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riescoint ap_proxy_hex2c(const char *x)
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco#else /*APR_CHARSET_EBCDIC*/
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco return (1 == sscanf(x, "%2x", &i)) ? os_toebcdic[i&0xFF] : 0;
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco#endif /*APR_CHARSET_EBCDIC*/
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco#else /*APR_CHARSET_EBCDIC*/
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco static const char ntoa[] = { "0123456789ABCDEF" };
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco#endif /*APR_CHARSET_EBCDIC*/
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * canonicalise a URL-encoded string
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * Convert a URL-encoded string to canonical form.
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * It decodes characters which need not be encoded,
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * and encodes those which must be encoded, and does not touch
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * those which must not be touched.
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riescochar *ap_proxy_canonenc(apr_pool_t *p, const char *x, int len, enum enctype t,
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco char *allowed; /* characters which should not be encoded */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco char *reserved; /* characters which much not be en/de-coded */
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco/* N.B. in addition to :@&=, this allows ';' in an http path
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * and '?' in an ftp path -- this may be revised
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * Also, it makes a '+' character in a search string reserved, as
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * it may be form-encoded. (Although RFC 1738 doesn't allow this -
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * it only permits ; / ? : @ = & as reserved chars.)
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco else if (t == enc_search)
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco else if (t == enc_user)
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco else if (t == enc_fpath)
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco else /* if (t == enc_parm) */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco else if (t == enc_search)
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco for (i = 0, j = 0; i < len; i++, j++) {
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco/* always handle '/' first */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco/* decode it if not already done */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco if (!ap_isxdigit(x[i + 1]) || !ap_isxdigit(x[i + 2]))
51c15129e8118fed5c33c334f8df82619ce98e7dAdrián Riesco if (ch != 0 && strchr(reserved, ch)) { /* keep it encoded */
223be434693e8c97e2522ac19155a284b3536035Adrián Riesco/* recode it, if necessary */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco if (!apr_isalnum(ch) && !strchr(allowed, ch)) {
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * Parses network-location.
51c15129e8118fed5c33c334f8df82619ce98e7dAdrián Riesco * urlp on input the URL; on output the path, after the leading /
fe5611d78ea0648e8719cb004a6a26e9a033429aAdrián Riesco * user NULL if no user/password permitted
6b2e3d60f2e2c230c9637bf0701d7024d289764dAdrián Riesco * password holder for password
51c15129e8118fed5c33c334f8df82619ce98e7dAdrián Riesco * host holder for host
51c15129e8118fed5c33c334f8df82619ce98e7dAdrián Riesco * port port number; only set if one is supplied.
8b389272b3312c6d3e3c0aee2e94bca6dbdade50Adrián Riesco * Returns an error string.
51c15129e8118fed5c33c334f8df82619ce98e7dAdrián Riesco ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, char **userp,
51c15129e8118fed5c33c334f8df82619ce98e7dAdrián Riesco return "Malformed URL";
8b389272b3312c6d3e3c0aee2e94bca6dbdade50Adrián Riesco /* find _last_ '@' since it might occur in user/password part */
6b2e3d60f2e2c230c9637bf0701d7024d289764dAdrián Riesco/* find password */
6b2e3d60f2e2c230c9637bf0701d7024d289764dAdrián Riesco password = ap_proxy_canonenc(p, strp + 1, strlen(strp + 1), enc_user, 1);
6b2e3d60f2e2c230c9637bf0701d7024d289764dAdrián Riesco return "Bad %-escape in URL (password)";
6b2e3d60f2e2c230c9637bf0701d7024d289764dAdrián Riesco user = ap_proxy_canonenc(p, user, strlen(user), enc_user, 1);
6b2e3d60f2e2c230c9637bf0701d7024d289764dAdrián Riesco return "Bad %-escape in URL (username)";
6b2e3d60f2e2c230c9637bf0701d7024d289764dAdrián Riesco /* if (i == 0) the no port was given; keep default */
6b2e3d60f2e2c230c9637bf0701d7024d289764dAdrián Riesco return "Bad port number in URL";
6b2e3d60f2e2c230c9637bf0701d7024d289764dAdrián Riesco } else if (i > 0) {
6b2e3d60f2e2c230c9637bf0701d7024d289764dAdrián Riesco return "Port number in URL > 65535";
6b2e3d60f2e2c230c9637bf0701d7024d289764dAdrián Riesco ap_str_tolower(host); /* DNS names are case-insensitive */
6b2e3d60f2e2c230c9637bf0701d7024d289764dAdrián Riesco return "Missing host in URL";
6b2e3d60f2e2c230c9637bf0701d7024d289764dAdrián Riesco/* check hostname syntax */
c1cf2f634a37116ff90e99ca710179a23115cbfbAdrián Riesco /* must be an IP address */
223be434693e8c97e2522ac19155a284b3536035Adrián Riesco#if defined(WIN32) || defined(NETWARE) || defined(TPF) || defined(BEOS)
223be434693e8c97e2522ac19155a284b3536035Adrián Riesco if (host[i] == '\0' && (inet_addr(host) == -1))
c1cf2f634a37116ff90e99ca710179a23115cbfbAdrián Riesco if (host[i] == '\0' && (ap_inet_addr(host) == -1 || inet_network(host) == -1))
c1cf2f634a37116ff90e99ca710179a23115cbfbAdrián Riesco return "Bad IP address in URL";
c1cf2f634a37116ff90e99ca710179a23115cbfbAdrián Riesco/* if (strchr(host,'.') == NULL && domain != NULL)
c1cf2f634a37116ff90e99ca710179a23115cbfbAdrián Riesco host = pstrcat(p, host, domain, NULL);
223be434693e8c97e2522ac19155a284b3536035Adrián Riesco{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
b9840e4ee6fda6e42fa4ee9f337482ccc4839a39Adrián Riesco * If the date is a valid RFC 850 date or asctime() date, then it
b9840e4ee6fda6e42fa4ee9f337482ccc4839a39Adrián Riesco * is converted to the RFC 1123 format, otherwise it is not modified.
b9840e4ee6fda6e42fa4ee9f337482ccc4839a39Adrián Riesco * This routine is not very fast at doing conversions, as it uses
c1cf2f634a37116ff90e99ca710179a23115cbfbAdrián Riesco * sscanf and sprintf. However, if the date is already correctly
223be434693e8c97e2522ac19155a284b3536035Adrián Riesco * formatted, then it exits very quickly.
0be63c5d4b5e66cc600a0003081ae2bf85be9615Adrián Riesco ap_proxy_date_canon(apr_pool_t *p, const char *x1)
fe5611d78ea0648e8719cb004a6a26e9a033429aAdrián Riesco /* check for RFC 850 date */
fe5611d78ea0648e8719cb004a6a26e9a033429aAdrián Riesco return x; /* not a valid date */
223be434693e8c97e2522ac19155a284b3536035Adrián Riesco if (q[4] != '-' || q[8] != '-' || q[11] != ' ' || q[14] != ':' ||
223be434693e8c97e2522ac19155a284b3536035Adrián Riesco if (sscanf(q + 2, "%u-%3s-%u %u:%u:%u %3s", &mday, month, &year,
223be434693e8c97e2522ac19155a284b3536035Adrián Riesco/* check for acstime() date */
223be434693e8c97e2522ac19155a284b3536035Adrián Riesco if (x[3] != ' ' || x[7] != ' ' || x[10] != ' ' || x[13] != ':' ||
223be434693e8c97e2522ac19155a284b3536035Adrián Riesco x[16] != ':' || x[19] != ' ' || x[24] != '\0')
c1cf2f634a37116ff90e99ca710179a23115cbfbAdrián Riesco if (sscanf(x, "%3s %3s %u %u:%u:%u %u", week, month, &mday, &hour,
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco/* check date */
223be434693e8c97e2522ac19155a284b3536035Adrián Riesco apr_snprintf(q, 30, "%s, %.2d %s %d %.2d:%.2d:%.2d GMT", ap_day_snames[wk],
223be434693e8c97e2522ac19155a284b3536035Adrián Riesco mday, ap_month_snames[mon], year, hour, min, sec);
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco request_rec *r = apr_pcalloc(c->pool, sizeof(*r));
27aad79faa0eec8d0e7dda32bca710db95bd2d0aAdrián Riesco r->subprocess_env = apr_make_table(r->pool, 50);
27aad79faa0eec8d0e7dda32bca710db95bd2d0aAdrián Riesco r->err_headers_out = apr_make_table(r->pool, 5);
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco r->request_config = ap_create_request_config(r->pool);
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco req_cfg = apr_pcalloc(r->pool, sizeof(core_request_config));
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco ap_set_module_config(r->request_config, &core_module, req_cfg);
c1cf2f634a37116ff90e99ca710179a23115cbfbAdrián Riesco * Reads headers from a buffer and returns an array of headers.
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco * Returns NULL on file error
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco * This routine tries to deal with too long lines and continuation lines.
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco * @@@: XXX: FIXME: currently the headers are passed thru un-merged.
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco * Is that okay, or should they be collapsed where possible?
27aad79faa0eec8d0e7dda32bca710db95bd2d0aAdrián Riescoapr_table_t *ap_proxy_read_headers(request_rec *r, char *buffer, int size, conn_rec *c)
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco * Read header lines until we get the empty separator line, a read error,
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco * the connection closes (EOF), or we timeout.
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco while ((len = ap_getline(buffer, size, rr, 1)) > 0) {
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco if (!(value = strchr(buffer, ':'))) { /* Find the colon separator */
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco /* Buggy MS IIS servers sometimes return invalid headers
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco * (an extra "HTTP/1.0 200, OK" line sprinkled in between
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco * the usual MIME headers). Try to deal with it in a sensible
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco * way, but log the fact.
c1cf2f634a37116ff90e99ca710179a23115cbfbAdrián Riesco * XXX: The mask check is buggy if we ever see an HTTP/1.10 */
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco /* Nope, it wasn't even an extra HTTP header. Give up. */
27aad79faa0eec8d0e7dda32bca710db95bd2d0aAdrián Riesco ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r->server,
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco "proxy: Ignoring duplicate HTTP header "
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco /* XXX: RFC2068 defines only SP and HT as whitespace, this test is
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco * wrong... and so are many others probably.
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco /* should strip trailing whitespace as well */
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco for (end = &value[strlen(value)-1]; end > value && apr_isspace(*end); --end)
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco /* the header was too long; at the least we should skip extra data */
c1cf2f634a37116ff90e99ca710179a23115cbfbAdrián Riesco while ((len = ap_getline(field, MAX_STRING_LEN, r, 1))
fecce42517d20490f893c4a9dee29b000e1653eaAdrián Riesco /* soak up the extra data */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco if (len == 0) /* time to exit the larger loop as well */
c1cf2f634a37116ff90e99ca710179a23115cbfbAdrián Riescolong int ap_proxy_send_fb(proxy_completion *completion, BUFF *f, request_rec *r, ap_cache_el *c)
51c15129e8118fed5c33c334f8df82619ce98e7dAdrián Riesco register int n, o;
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco int alternate_timeouts = 1; /* 1 if we alternate between soft & hard timeouts */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /* The cache copy is ASCII, not EBCDIC, even for text/html) */
51c15129e8118fed5c33c334f8df82619ce98e7dAdrián Riesco ap_bsetflag(f, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0);
7474965b2e6323002c96c0b39a59843cde201870Adrián Riesco ap_bsetflag(c->fp, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0);
51c15129e8118fed5c33c334f8df82619ce98e7dAdrián Riesco ap_bsetflag(con->client, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0);
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /* Since we are reading from one buffer and writing to another,
fecce42517d20490f893c4a9dee29b000e1653eaAdrián Riesco * it is unsafe to do a soft_timeout here, at least until the proxy
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * has its own timeout handler which can set both buffers to EOUT.
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco#if defined(WIN32) || defined(TPF) || defined(NETWARE)
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /* works fine under win32, so leave it */
172f4dfb4b858440fab545bac00d3ec4abd0cbe4Adrián Riesco /* CHECKME! Since hard_timeout won't work in unix on sends with partial
172f4dfb4b858440fab545bac00d3ec4abd0cbe4Adrián Riesco * cache completion, we have to alternate between hard_timeout
172f4dfb4b858440fab545bac00d3ec4abd0cbe4Adrián Riesco * for reads, and soft_timeout for send. This is because we need
fecce42517d20490f893c4a9dee29b000e1653eaAdrián Riesco * to get a return from ap_bwrite to be able to continue caching.
fecce42517d20490f893c4a9dee29b000e1653eaAdrián Riesco * BUT, if we *can't* continue anyway, just use hard_timeout.
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * (Also, if no cache file is written, use hard timeouts)
7474965b2e6323002c96c0b39a59843cde201870Adrián Riesco if (!completion || completion->content_length > 0
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /* Loop and ap_bread() while we can successfully read and write,
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * or (after the client aborted) while we can successfully
7474965b2e6323002c96c0b39a59843cde201870Adrián Riesco * read and finish the configured cache_completion.
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /* Read block from server */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco if (ap_bread(f, buf, IOBUFSIZE, &cntr) != APR_SUCCESS && !cntr)
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco else if(cntr == 0) break;
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /* Write to cache first. */
fecce42517d20490f893c4a9dee29b000e1653eaAdrián Riesco /*@@@ XXX FIXME: Assuming that writing the cache file won't time out?!!? */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco if (cachefp && apr_write(cachefp, &buf[0], &wrote_to_cache) != APR_SUCCESS) {
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco "proxy: error writing to cache");
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /* Write the block to the client, detect aborted transfers */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco if ((cntr = ap_rwrite(&buf[o], in_buffer, r))) {
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /* when a send failure occurs, we need to decide
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * whether to continue loading and caching the
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * document, or to abort the whole thing
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco (completion->content_length * completion->cache_completion < total_bytes_rcvd);
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco } /* while client alive and more data to send */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco } /* loop and ap_bread while "ok" */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * Sends response line and headers. Uses the client fd and the
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * headers_out array from the passed request_rec to talk to the client
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * and to properly set the headers it sends for things such as logging.
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * A timeout should be set before calling this routine.
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riescovoid ap_proxy_send_headers(request_rec *r, const char *respline, apr_table_t *t)
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco apr_socket_t *fp = r->connection->client_socket;
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco apr_table_entry_t *elts = (apr_table_entry_t *) apr_table_elts(t)->elts;
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco char *temp = apr_pstrcat(r->pool, respline, CRLF, NULL);
172f4dfb4b858440fab545bac00d3ec4abd0cbe4Adrián Riesco for (i = 0; i < ap_table_elts(t)->nelts; ++i) {
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco temp = apr_pstrcat(r->pool, elts[i].key, ": ", elts[i].val, CRLF, NULL);
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco apr_table_addn(r->headers_out, elts[i].key, elts[i].val);
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * list is a comma-separated list of case-insensitive tokens, with
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * optional whitespace around the tokens.
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * The return returns 1 if the token val is found in the list, or 0
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riescoint ap_proxy_liststr(const char *list, const char *val)
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco const char *p;
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco if (i == len && strncasecmp(list, val, len) == 0)
0f77efdcc159eee5682aabf2b9a3c178c467b466Adrián Riesco * Converts 8 hex digits to a time integer
0f77efdcc159eee5682aabf2b9a3c178c467b466Adrián Riescoint ap_proxy_hex2sec(const char *x)
0f77efdcc159eee5682aabf2b9a3c178c467b466Adrián Riesco unsigned int j;
0f77efdcc159eee5682aabf2b9a3c178c467b466Adrián Riesco for (i = 0, j = 0; i < 8; i++) {
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco if (j == 0xffffffff)
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco return -1; /* so that it works with 8-byte ints */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * Converts a time integer to 8 hex digits
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riescovoid ap_proxy_sec2hex(int t, char *y)
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco unsigned int j = t;
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco for (i = 7; i >= 0; i--) {
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco if (c && *c) {
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riescoint ap_proxyerror(request_rec *r, int statuscode, const char *message)
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco "The proxy server could not handle the request "
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco "<EM><A HREF=\"", ap_escape_uri(r->pool, r->uri),
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco ap_escape_html(r->pool, r->uri), "</A></EM>.<P>\n"
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco "Reason: <STRONG>",
fecce42517d20490f893c4a9dee29b000e1653eaAdrián Riesco /* Allow "error-notes" string to be printed by ap_send_error_response() */
fecce42517d20490f893c4a9dee29b000e1653eaAdrián Riesco apr_table_setn(r->notes, "verbose-error-to", apr_pstrdup(r->pool, "*"));
fecce42517d20490f893c4a9dee29b000e1653eaAdrián Riesco r->status_line = apr_psprintf(r->pool, "%3.3u Proxy Error", statuscode);
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * This routine returns its own error message
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riescoconst char *ap_proxy_host2addr(const char *host, struct hostent *reqhp)
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco struct per_thread_data *ptd = get_per_thread_data();
51c15129e8118fed5c33c334f8df82619ce98e7dAdrián Riesco return "Host not found";
51c15129e8118fed5c33c334f8df82619ce98e7dAdrián Riesco hp = gethostbyaddr((char *) &ptd->ipaddr, sizeof(ptd->ipaddr), AF_INET);
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco ptd->hpbuf.h_addr_list[0] = (char *) &ptd->ipaddr;
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riescostatic const char *
7474965b2e6323002c96c0b39a59843cde201870Adrián Riesco char *url, *user = NULL, *password = NULL, *err, *host;
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /* Set url to the first char after "scheme://" */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco url = apr_pstrdup(r->pool, &url[1]); /* make it point to "//", which is what proxy_canon_netloc expects */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco err = ap_proxy_canon_netloc(r->pool, &url, &user, &password, &host, &port);
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r,
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco return host; /* ought to return the port, too */
27aad79faa0eec8d0e7dda32bca710db95bd2d0aAdrián Riesco/* Return TRUE if addr represents an IP address (or an IP network address) */
7474965b2e6323002c96c0b39a59843cde201870Adrián Riescoint ap_proxy_is_ipaddr(struct dirconn_entry *This, apr_pool_t *p)
7474965b2e6323002c96c0b39a59843cde201870Adrián Riesco /* if the address is given with an explicit netmask, use that */
27aad79faa0eec8d0e7dda32bca710db95bd2d0aAdrián Riesco /* Due to a deficiency in ap_inet_addr(), it is impossible to parse */
27aad79faa0eec8d0e7dda32bca710db95bd2d0aAdrián Riesco /* "partial" addresses (with less than 4 quads) correctly, i.e. */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /* 192.168.123 is parsed as 192.168.0.123, which is not what I want. */
c1cf2f634a37116ff90e99ca710179a23115cbfbAdrián Riesco /* I therefore have to parse the IP address manually: */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /*if (proxy_readmask(This->name, &This->addr.s_addr, &This->mask.s_addr) == 0) */
51c15129e8118fed5c33c334f8df82619ce98e7dAdrián Riesco /* addr and mask were set by proxy_readmask() */
51c15129e8118fed5c33c334f8df82619ce98e7dAdrián Riesco /*return 1; */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /* Parse IP addr manually, optionally allowing */
51c15129e8118fed5c33c334f8df82619ce98e7dAdrián Riesco /* abbreviated net addresses like 192.168. */
27aad79faa0eec8d0e7dda32bca710db95bd2d0aAdrián Riesco /* Iterate over up to 4 (dotted) quads. */
27aad79faa0eec8d0e7dda32bca710db95bd2d0aAdrián Riesco for (quads = 0; quads < 4 && *addr != '\0'; ++quads) {
51c15129e8118fed5c33c334f8df82619ce98e7dAdrián Riesco if (*addr == '/' && quads > 0) /* netmask starts here. */
27aad79faa0eec8d0e7dda32bca710db95bd2d0aAdrián Riesco return 0; /* no digit at start of quad */
51c15129e8118fed5c33c334f8df82619ce98e7dAdrián Riesco if (tmp == addr) /* expected a digit, found something else */
51c15129e8118fed5c33c334f8df82619ce98e7dAdrián Riesco if (ip_addr[quads] < 0 || ip_addr[quads] > 255) {
51c15129e8118fed5c33c334f8df82619ce98e7dAdrián Riesco /* invalid octet */
27aad79faa0eec8d0e7dda32bca710db95bd2d0aAdrián Riesco ++addr; /* after the 4th quad, a dot would be illegal */
c1cf2f634a37116ff90e99ca710179a23115cbfbAdrián Riesco for (This->addr.s_addr = 0, i = 0; i < quads; ++i)
27aad79faa0eec8d0e7dda32bca710db95bd2d0aAdrián Riesco This->addr.s_addr |= htonl(ip_addr[i] << (24 - 8 * i));
27aad79faa0eec8d0e7dda32bca710db95bd2d0aAdrián Riesco if (addr[0] == '/' && apr_isdigit(addr[1])) { /* net mask follows: */
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco if (tmp == addr) /* expected a digit, found something else */
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco if (bits < 0 || bits > 32) /* netmask must be between 0 and 32 */
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco /* Determine (i.e., "guess") netmask by counting the */
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco /* number of trailing .0's; reduce #quads appropriately */
27aad79faa0eec8d0e7dda32bca710db95bd2d0aAdrián Riesco /* (so that 192.168.0.0 is equivalent to 192.168.) */
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco /* "IP Address should be given in dotted-quad form, optionally followed by a netmask (e.g., 192.168.111.0/24)"; */
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco /* every zero-byte counts as 8 zero-bits */
27aad79faa0eec8d0e7dda32bca710db95bd2d0aAdrián Riesco if (bits != 32) /* no warning for fully qualified IP address */
27aad79faa0eec8d0e7dda32bca710db95bd2d0aAdrián Riesco ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco "Warning: NetMask not supplied with IP-Addr; guessing: %s/%ld\n",
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco This->mask.s_addr = htonl(INADDR_NONE << (32 - bits));
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco if (*addr == '\0' && (This->addr.s_addr & ~This->mask.s_addr) != 0) {
aea9000fc94442cbfc92596f4264473c0fce51e4Adrián Riesco ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
51c15129e8118fed5c33c334f8df82619ce98e7dAdrián Riesco "Warning: NetMask and IP-Addr disagree in %s/%ld\n",
c1cf2f634a37116ff90e99ca710179a23115cbfbAdrián Riesco ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco " Set to %s/%ld\n",
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco return (*addr == '\0'); /* okay iff we've parsed the whole string */
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco/* Return TRUE if addr represents an IP address (or an IP network address) */
27aad79faa0eec8d0e7dda32bca710db95bd2d0aAdrián Riescostatic int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r)
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco const char *host = proxy_get_host_of_request(r);
8b389272b3312c6d3e3c0aee2e94bca6dbdade50Adrián Riesco if (4 == sscanf(host, "%d.%d.%d.%d", &ip_addr[0], &ip_addr[1], &ip_addr[2], &ip_addr[3])) {
8b389272b3312c6d3e3c0aee2e94bca6dbdade50Adrián Riesco addr.s_addr |= htonl(ip_addr[i] << (24 - 8 * i));
8b389272b3312c6d3e3c0aee2e94bca6dbdade50Adrián Riesco if (This->addr.s_addr == (addr.s_addr & This->mask.s_addr)) {
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco "1)IP-Match: %s[%s] <-> ", host, inet_ntoa(addr));
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
51c15129e8118fed5c33c334f8df82619ce98e7dAdrián Riesco ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco "1)IP-NoMatch: %s[%s] <-> ", host, inet_ntoa(addr));
8b389272b3312c6d3e3c0aee2e94bca6dbdade50Adrián Riesco ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco "2)IP-NoMatch: hostname=%s msg=%s", host, found);
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco /* Try to deal with multiple IP addr's for a host */
7fc57d0f02d0fec1192376ccebe2be0224cb9a55Adrián Riesco for (ip_listptr = the_host.h_addr_list; *ip_listptr; ++ip_listptr) {
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco if (This->addr.s_addr == (ip_list->s_addr & This->mask.s_addr)) {
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco "3)IP-Match: %s[%s] <-> ", found, inet_ntoa(*ip_list));
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
d72e314a1952b4418fb1c98b17dbab0d16bba585Adrián Riesco "3)IP-NoMatch: %s[%s] <-> ", found, inet_ntoa(*ip_list));
b9840e4ee6fda6e42fa4ee9f337482ccc4839a39Adrián Riesco ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco/* Return TRUE if addr represents a domain name */
b9840e4ee6fda6e42fa4ee9f337482ccc4839a39Adrián Riescoint ap_proxy_is_domainname(struct dirconn_entry *This, apr_pool_t *p)
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /* Domain name must start with a '.' */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /* rfc1035 says DNS names must consist of "[-a-zA-Z0-9]" and '.' */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco for (i = 0; apr_isalnum(addr[i]) || addr[i] == '-' || addr[i] == '.'; ++i)
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco "@@@@ handle optional port in proxy_is_domainname()");
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /* @@@@ handle optional port */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /* Strip trailing dots */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco for (i = strlen(addr) - 1; i > 0 && addr[i] == '.'; --i)
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco/* Return TRUE if host "host" is in domain "domain" */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riescostatic int proxy_match_domainname(struct dirconn_entry *This, request_rec *r)
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco const char *host = proxy_get_host_of_request(r);
c1cf2f634a37116ff90e99ca710179a23115cbfbAdrián Riesco if (host == NULL) /* some error was logged already */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /* @@@ do this within the setup? */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /* Ignore trailing dots in domain comparison: */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco while (d_len > 0 && This->name[d_len - 1] == '.')
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco && strncasecmp(&host[h_len - d_len], This->name, d_len) == 0;
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco/* Create a copy of a "struct hostent" record; it was presumably returned
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * from a call to gethostbyname() and lives in static storage.
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco * By creating a copy we can tuck it away for later use.
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riescostatic struct hostent * pduphostent(apr_pool_t *p, const struct hostent *hp)
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco int i = 0, j = 0;
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /* Count number of alias entries */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /* Count number of in_addr entries */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /* Allocate hostent structure, alias ptrs, addr ptrs, addrs */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco newent = (struct hostent *) apr_palloc(p, sizeof(*hp));
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco aliases = (char **) apr_palloc(p, (j+1) * sizeof(char*));
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco ptrs = (char **) apr_palloc(p, (i+1) * sizeof(char*));
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco addrs = (struct in_addr *) apr_palloc(p, (i+1) * sizeof(struct in_addr));
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /* Copy Alias Names: */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco aliases[j] = apr_pstrdup(p, hp->h_aliases[j]);
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco /* Copy address entries */
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco for (i = 0; hp->h_addr_list[i] != NULL; ++i) {
5318901bb69bf247e0f341312c800ba4ea87e46bAdrián Riesco addrs[i] = *(struct in_addr *) hp->h_addr_list[i];
fecce42517d20490f893c4a9dee29b000e1653eaAdrián Riesco/* Return TRUE if addr represents a host name */
fecce42517d20490f893c4a9dee29b000e1653eaAdrián Riescoint ap_proxy_is_hostname(struct dirconn_entry *This, apr_pool_t *p)
fecce42517d20490f893c4a9dee29b000e1653eaAdrián Riesco /* Host names must not start with a '.' */
fecce42517d20490f893c4a9dee29b000e1653eaAdrián Riesco /* rfc1035 says DNS names must consist of "[-a-zA-Z0-9]" and '.' */
fecce42517d20490f893c4a9dee29b000e1653eaAdrián Riesco for (i = 0; apr_isalnum(addr[i]) || addr[i] == '-' || addr[i] == '.'; ++i);
fecce42517d20490f893c4a9dee29b000e1653eaAdrián Riesco ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
fecce42517d20490f893c4a9dee29b000e1653eaAdrián Riesco "@@@@ handle optional port in proxy_is_hostname()");
fecce42517d20490f893c4a9dee29b000e1653eaAdrián Riesco /* @@@@ handle optional port */
b9840e4ee6fda6e42fa4ee9f337482ccc4839a39Adrián Riesco if (addr[i] != '\0' || ap_proxy_host2addr(addr, &host) != NULL)
b9840e4ee6fda6e42fa4ee9f337482ccc4839a39Adrián Riesco /* Strip trailing dots */
b9840e4ee6fda6e42fa4ee9f337482ccc4839a39Adrián Riesco for (i = strlen(addr) - 1; i > 0 && addr[i] == '.'; --i)
b9840e4ee6fda6e42fa4ee9f337482ccc4839a39Adrián Riesco/* Return TRUE if host "host" is equal to host2 "host2" */
b9840e4ee6fda6e42fa4ee9f337482ccc4839a39Adrián Riescostatic int proxy_match_hostname(struct dirconn_entry *This, request_rec *r)
b9840e4ee6fda6e42fa4ee9f337482ccc4839a39Adrián Riesco const char *host2 = proxy_get_host_of_request(r);
223be434693e8c97e2522ac19155a284b3536035Adrián Riesco return 0; /* oops! */
b3a8ae62887130fd41b91bf2ea1fd66360bd3c29Adrián Riesco unsigned long *ip_list;
b9840e4ee6fda6e42fa4ee9f337482ccc4839a39Adrián Riesco /* Try to deal with multiple IP addr's for a host */
b9840e4ee6fda6e42fa4ee9f337482ccc4839a39Adrián Riesco for (ip_list = *This->hostentry->h_addr_list; *ip_list != 0UL; ++ip_list)
b9840e4ee6fda6e42fa4ee9f337482ccc4839a39Adrián Riesco if (*ip_list == ? ? ? ? ? ? ? ? ? ? ? ? ?)
b9840e4ee6fda6e42fa4ee9f337482ccc4839a39Adrián Riesco /* Ignore trailing dots in host2 comparison: */
b9840e4ee6fda6e42fa4ee9f337482ccc4839a39Adrián Riesco while (h2_len > 0 && host2[h2_len - 1] == '.')
7474965b2e6323002c96c0b39a59843cde201870Adrián Riesco/* Return TRUE if addr is to be matched as a word */
7474965b2e6323002c96c0b39a59843cde201870Adrián Riescoint ap_proxy_is_word(struct dirconn_entry *This, apr_pool_t *p)
51c15129e8118fed5c33c334f8df82619ce98e7dAdrián Riesco/* Return TRUE if string "str2" occurs literally in "str1" */
return rv;
/* (from proxy_http.c and proxy_ftp.c) */
if (!r->assbackwards)
return len;
#if defined WIN32
switch (reason) {
case DLL_PROCESS_ATTACH:
case DLL_THREAD_DETACH:
if (memptr) {
return TRUE;
#if defined(WIN32)
return &sptd;
return NULL;
return HTTP_INTERNAL_SERVER_ERROR;
return HTTP_INTERNAL_SERVER_ERROR;
return OK;
if((r->status != HTTP_OK && r->status != HTTP_MOVED_PERMANENTLY && r->status != HTTP_NOT_MODIFIED) ||
r->header_only ||
if(!h) return DECLINED;
return DECLINED;