diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/proxy/.cvsignore | 9 | ||||
-rw-r--r-- | modules/proxy/.indent.pro | 55 | ||||
-rw-r--r-- | modules/proxy/Makefile.in | 3 | ||||
-rw-r--r-- | modules/proxy/config.m4 | 9 | ||||
-rw-r--r-- | modules/proxy/libproxy.exp | 1 | ||||
-rw-r--r-- | modules/proxy/mod_proxy.c | 766 | ||||
-rw-r--r-- | modules/proxy/mod_proxy.dsp | 123 | ||||
-rw-r--r-- | modules/proxy/mod_proxy.h | 261 | ||||
-rw-r--r-- | modules/proxy/mod_proxy.mak | 573 | ||||
-rw-r--r-- | modules/proxy/proxy_cache.c | 222 | ||||
-rw-r--r-- | modules/proxy/proxy_cache.h | 366 | ||||
-rw-r--r-- | modules/proxy/proxy_connect.c | 302 | ||||
-rw-r--r-- | modules/proxy/proxy_ftp.c | 1270 | ||||
-rw-r--r-- | modules/proxy/proxy_http.c | 532 | ||||
-rw-r--r-- | modules/proxy/proxy_util.c | 1323 | ||||
-rw-r--r-- | modules/test/mod_optional_fn_export.c | 86 | ||||
-rw-r--r-- | modules/test/mod_optional_fn_export.h | 3 | ||||
-rw-r--r-- | modules/test/mod_optional_fn_import.c | 93 |
18 files changed, 0 insertions, 5997 deletions
diff --git a/modules/proxy/.cvsignore b/modules/proxy/.cvsignore deleted file mode 100644 index 85c33e18d0..0000000000 --- a/modules/proxy/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -Debug -Release -Makefile -*.lo -*.la -*.so -modules.mk -.deps -.libs diff --git a/modules/proxy/.indent.pro b/modules/proxy/.indent.pro deleted file mode 100644 index 20c2d83371..0000000000 --- a/modules/proxy/.indent.pro +++ /dev/null @@ -1,55 +0,0 @@ --i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1 --TBUFF --TFILE --TTRANS --TUINT4 --T_trans --Tallow_options_t --Tapache_sfio --Tarray_header --Tbool_int --Tbuf_area --Tbuff_struct --Tbuffy --Tcmd_how --Tcmd_parms --Tcommand_rec --Tcommand_struct --Tconn_rec --Tcore_dir_config --Tcore_server_config --Tdir_maker_func --Tevent --Tglobals_s --Thandler_func --Thandler_rec --Tjoblist_s --Tlisten_rec --Tmerger_func --Tmode_t --Tmodule --Tmodule_struct --Tmutex --Tn_long --Tother_child_rec --Toverrides_t --Tparent_score --Tpid_t --Tpiped_log --Tpool --Trequest_rec --Trequire_line --Trlim_t --Tscoreboard --Tsemaphore --Tserver_addr_rec --Tserver_rec --Tserver_rec_chain --Tshort_score --Ttable --Ttable_entry --Tthread --Tu_wide_int --Tvtime_t --Twide_int --Tproxy_server_conf diff --git a/modules/proxy/Makefile.in b/modules/proxy/Makefile.in deleted file mode 100644 index 7c5c149d85..0000000000 --- a/modules/proxy/Makefile.in +++ /dev/null @@ -1,3 +0,0 @@ -# a modules Makefile has no explicit targets -- they will be defined by -# whatever modules are enabled. just grab special.mk to deal with this. -include $(top_srcdir)/build/special.mk diff --git a/modules/proxy/config.m4 b/modules/proxy/config.m4 deleted file mode 100644 index bea6a003bf..0000000000 --- a/modules/proxy/config.m4 +++ /dev/null @@ -1,9 +0,0 @@ -dnl modules enabled in this directory by default - -APACHE_MODPATH_INIT(proxy) - -proxy_objs="mod_proxy.lo proxy_connect.lo proxy_cache.lo proxy_http.lo proxy_util.lo" - -APACHE_MODULE(proxy, Apache proxy module, $proxy_objs, , no) - -APACHE_MODPATH_FINISH diff --git a/modules/proxy/libproxy.exp b/modules/proxy/libproxy.exp deleted file mode 100644 index a20f2378f5..0000000000 --- a/modules/proxy/libproxy.exp +++ /dev/null @@ -1 +0,0 @@ -proxy_module diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c deleted file mode 100644 index dbb47b9a29..0000000000 --- a/modules/proxy/mod_proxy.c +++ /dev/null @@ -1,766 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - * - * Portions of this software are based upon public domain software - * originally written at the National Center for Supercomputing Applications, - * University of Illinois, Urbana-Champaign. - */ - -#include "mod_proxy.h" - -#define CORE_PRIVATE - -#include "http_log.h" -#include "http_vhost.h" -#include "http_request.h" -#include "util_date.h" - -/* Some WWW schemes and their default ports; this is basically /etc/services */ -/* This will become global when the protocol abstraction comes */ -static struct proxy_services defports[] = -{ - {"http", DEFAULT_HTTP_PORT}, - {"ftp", DEFAULT_FTP_PORT}, - {"https", DEFAULT_HTTPS_PORT}, - {"gopher", DEFAULT_GOPHER_PORT}, - {"nntp", DEFAULT_NNTP_PORT}, - {"wais", DEFAULT_WAIS_PORT}, - {"snews", DEFAULT_SNEWS_PORT}, - {"prospero", DEFAULT_PROSPERO_PORT}, - {NULL, -1} /* unknown port */ -}; - -/* - * A Web proxy module. Stages: - * - * translate_name: set filename to proxy:<URL> - * type_checker: set type to PROXY_MAGIC_TYPE if filename begins proxy: - * fix_ups: convert the URL stored in the filename to the - * canonical form. - * handler: handle proxy requests - */ - -/* -------------------------------------------------------------- */ -/* Translate the URL into a 'filename' */ - -static int alias_match(const char *uri, const char *alias_fakename) -{ - const char *end_fakename = alias_fakename + strlen(alias_fakename); - const char *aliasp = alias_fakename, *urip = uri; - - while (aliasp < end_fakename) { - if (*aliasp == '/') { - /* any number of '/' in the alias matches any number in - * the supplied URI, but there must be at least one... - */ - if (*urip != '/') - return 0; - - while (*aliasp == '/') - ++aliasp; - while (*urip == '/') - ++urip; - } - else { - /* Other characters are compared literally */ - if (*urip++ != *aliasp++) - return 0; - } - } - - /* Check last alias path component matched all the way */ - - if (aliasp[-1] != '/' && *urip != '\0' && *urip != '/') - return 0; - - /* Return number of characters from URI which matched (may be - * greater than length of alias, since we may have matched - * doubled slashes) - */ - - return urip - uri; -} - -/* Detect if an absoluteURI should be proxied or not. Note that we - * have to do this during this phase because later phases are - * "short-circuiting"... i.e. translate_names will end when the first - * module returns OK. So for example, if the request is something like: - * - * GET http://othervhost/cgi-bin/printenv HTTP/1.0 - * - * mod_alias will notice the /cgi-bin part and ScriptAlias it and - * short-circuit the proxy... just because of the ordering in the - * configuration file. - */ -static int proxy_detect(request_rec *r) -{ - void *sconf = r->server->module_config; - proxy_server_conf *conf; - - conf = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); - - if (conf->req && r->parsed_uri.scheme) { - /* but it might be something vhosted */ - if (!(r->parsed_uri.hostname - && !strcasecmp(r->parsed_uri.scheme, ap_http_method(r)) - && ap_matches_request_vhost(r, r->parsed_uri.hostname, - r->parsed_uri.port_str ? r->parsed_uri.port : ap_default_port(r)))) { - r->proxyreq = 1; - r->uri = r->unparsed_uri; - r->filename = apr_pstrcat(r->pool, "proxy:", r->uri, NULL); - r->handler = "proxy-server"; - } - } - /* We need special treatment for CONNECT proxying: it has no scheme part */ - else if (conf->req && r->method_number == M_CONNECT - && r->parsed_uri.hostname - && r->parsed_uri.port_str) { - r->proxyreq = 1; - r->uri = r->unparsed_uri; - r->filename = apr_pstrcat(r->pool, "proxy:", r->uri, NULL); - r->handler = "proxy-server"; - } - return DECLINED; -} - -static int proxy_trans(request_rec *r) -{ - void *sconf = r->server->module_config; - proxy_server_conf *conf = - (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); - int i, len; - struct proxy_alias *ent = (struct proxy_alias *) conf->aliases->elts; - - if (r->proxyreq) { - /* someone has already set up the proxy, it was possibly ourselves - * in proxy_detect - */ - return OK; - } - - /* XXX: since r->uri has been manipulated already we're not really - * compliant with RFC1945 at this point. But this probably isn't - * an issue because this is a hybrid proxy/origin server. - */ - - for (i = 0; i < conf->aliases->nelts; i++) { - len = alias_match(r->uri, ent[i].fake); - - if (len > 0) { - r->filename = apr_pstrcat(r->pool, "proxy:", ent[i].real, - r->uri + len, NULL); - r->handler = "proxy-server"; - r->proxyreq = 1; - return OK; - } - } - return DECLINED; -} - -/* -------------------------------------------------------------- */ -/* Fixup the filename */ - -/* - * Canonicalise the URL - */ -static int proxy_fixup(request_rec *r) -{ - char *url, *p; - - if (!r->proxyreq || strncmp(r->filename, "proxy:", 6) != 0) - return DECLINED; - - url = &r->filename[6]; - -/* canonicalise each specific scheme */ - if (strncasecmp(url, "http:", 5) == 0) - return ap_proxy_http_canon(r, url + 5, "http", DEFAULT_HTTP_PORT); -#if FTP - else if (strncasecmp(url, "ftp:", 4) == 0) - return ap_proxy_ftp_canon(r, url + 4); -#endif - - p = strchr(url, ':'); - if (p == NULL || p == url) - return HTTP_BAD_REQUEST; - - return OK; /* otherwise; we've done the best we can */ -} - -/* Send a redirection if the request contains a hostname which is not */ -/* fully qualified, i.e. doesn't have a domain name appended. Some proxy */ -/* servers like Netscape's allow this and access hosts from the local */ -/* domain in this case. I think it is better to redirect to a FQDN, since */ -/* these will later be found in the bookmarks files. */ -/* The "ProxyDomain" directive determines what domain will be appended */ -static int proxy_needsdomain(request_rec *r, const char *url, const char *domain) -{ - char *nuri; - const char *ref; - - /* We only want to worry about GETs */ - if (!r->proxyreq || r->method_number != M_GET || !r->parsed_uri.hostname) - return DECLINED; - - /* If host does contain a dot already, or it is "localhost", decline */ - if (strchr(r->parsed_uri.hostname, '.') != NULL - || strcasecmp(r->parsed_uri.hostname, "localhost") == 0) - return DECLINED; /* host name has a dot already */ - - ref = apr_table_get(r->headers_in, "Referer"); - - /* Reassemble the request, but insert the domain after the host name */ - /* Note that the domain name always starts with a dot */ - r->parsed_uri.hostname = apr_pstrcat(r->pool, r->parsed_uri.hostname, - domain, NULL); - nuri = ap_unparse_uri_components(r->pool, - &r->parsed_uri, - UNP_REVEALPASSWORD); - - apr_table_set(r->headers_out, "Location", nuri); - ap_log_rerror(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, 0, r, - "Domain missing: %s sent to %s%s%s", r->uri, - ap_unparse_uri_components(r->pool, &r->parsed_uri, - UNP_OMITUSERINFO), - ref ? " from " : "", ref ? ref : ""); - - return HTTP_MOVED_PERMANENTLY; -} - -/* -------------------------------------------------------------- */ -/* Invoke handler */ - -static int proxy_handler(request_rec *r) -{ - char *url, *scheme, *p; - const char *p2; - void *sconf = r->server->module_config; - proxy_server_conf *conf = (proxy_server_conf *) - ap_get_module_config(sconf, &proxy_module); - apr_array_header_t *proxies = conf->proxies; - struct proxy_remote *ents = (struct proxy_remote *) proxies->elts; - int i, rc; - int direct_connect = 0; - const char *maxfwd_str; - const char *pragma, *auth, *imstr; - - if (!r->proxyreq || strncmp(r->filename, "proxy:", 6) != 0) - return DECLINED; - - if (r->method_number == M_TRACE && - (maxfwd_str = apr_table_get(r->headers_in, "Max-Forwards")) != NULL) { - long maxfwd = strtol(maxfwd_str, NULL, 10); - if (maxfwd < 1) { - int access_status; - r->proxyreq = 0; - if ((access_status = ap_send_http_trace(r))) - ap_die(access_status, r); - else - ap_finalize_request_protocol(r); - return OK; - } - apr_table_setn(r->headers_in, "Max-Forwards", - apr_psprintf(r->pool, "%ld", (maxfwd > 0) ? maxfwd-1 : 0)); - } - - if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) - return rc; - - url = r->filename + 6; - p = strchr(url, ':'); - if (p == NULL) - return HTTP_BAD_REQUEST; - - pragma = apr_table_get(r->headers_in, "Pragma"); - auth = apr_table_get(r->headers_in, "Authorization"); - imstr = apr_table_get(r->headers_in, "If-Modified-Since"); - - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "Request for %s, pragma=%s, auth=%s, imstr=%s", url, - pragma, auth, imstr); - - /* If the host doesn't have a domain name, add one and redirect. */ - if (conf->domain != NULL) { - rc = proxy_needsdomain(r, url, conf->domain); - if (ap_is_HTTP_REDIRECT(rc)) - return HTTP_MOVED_PERMANENTLY; - } - - *p = '\0'; - scheme = apr_pstrdup(r->pool, url); - *p = ':'; - - /* Check URI's destination host against NoProxy hosts */ - /* Bypass ProxyRemote server lookup if configured as NoProxy */ - /* we only know how to handle communication to a proxy via http */ - /*if (strcasecmp(scheme, "http") == 0) */ - { - int ii; - struct dirconn_entry *list = (struct dirconn_entry *) conf->dirconn->elts; - - for (direct_connect = ii = 0; ii < conf->dirconn->nelts && !direct_connect; ii++) { - direct_connect = list[ii].matcher(&list[ii], r); - } -#if DEBUGGING - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r, - (direct_connect) ? "NoProxy for %s" : "UseProxy for %s", - r->uri); -#endif - } - -/* firstly, try a proxy, unless a NoProxy directive is active */ - - if (!direct_connect) - for (i = 0; i < proxies->nelts; i++) { - p2 = ap_strchr_c(ents[i].scheme, ':'); /* is it a partial URL? */ - if (strcmp(ents[i].scheme, "*") == 0 || - (p2 == NULL && strcasecmp(scheme, ents[i].scheme) == 0) || - (p2 != NULL && - strncasecmp(url, ents[i].scheme, strlen(ents[i].scheme)) == 0)) { - /* CONNECT is a special method that bypasses the normal - * proxy code. - */ - if (r->method_number == M_CONNECT) - rc = ap_proxy_connect_handler(r, url, ents[i].hostname, - ents[i].port); -/* we only know how to handle communication to a proxy via http */ - else if (strcasecmp(ents[i].protocol, "http") == 0) - rc = ap_proxy_http_handler(r, url, ents[i].hostname, - ents[i].port); - else - rc = DECLINED; - - /* an error or success */ - if (rc != DECLINED && rc != HTTP_BAD_GATEWAY) - return rc; - /* we failed to talk to the upstream proxy */ - } - } - -/* otherwise, try it direct */ -/* N.B. what if we're behind a firewall, where we must use a proxy or - * give up?? - */ - /* handle the scheme */ - if (r->method_number == M_CONNECT) - return ap_proxy_connect_handler(r, url, NULL, 0); - if (strcasecmp(scheme, "http") == 0) - return ap_proxy_http_handler(r, url, NULL, 0); -#if FTP - if (strcasecmp(scheme, "ftp") == 0) - return ap_proxy_ftp_handler(r, NULL, url); -#endif - else - return HTTP_FORBIDDEN; -} - -/* -------------------------------------------------------------- */ -/* Setup configurable data */ - -static void * create_proxy_config(apr_pool_t *p, server_rec *s) -{ - proxy_server_conf *ps = ap_pcalloc(p, sizeof(proxy_server_conf)); - - ps->proxies = ap_make_array(p, 10, sizeof(struct proxy_remote)); - ps->aliases = ap_make_array(p, 10, sizeof(struct proxy_alias)); - ps->raliases = ap_make_array(p, 10, sizeof(struct proxy_alias)); - ps->noproxies = ap_make_array(p, 10, sizeof(struct noproxy_entry)); - ps->dirconn = ap_make_array(p, 10, sizeof(struct dirconn_entry)); - ps->nocaches = ap_make_array(p, 10, sizeof(struct nocache_entry)); - ps->allowed_connect_ports = ap_make_array(p, 10, sizeof(int)); - ps->cache_completion = DEFAULT_CACHE_COMPLETION; - ps->domain = NULL; - ps->viaopt = via_off; /* initially backward compatible with 1.3.1 */ - ps->req = 0; - - ap_cache_init(&ps->cache, "mod_proxy cache", s); - return ps; -} - -static const char * - add_proxy(cmd_parms *cmd, void *dummy, const char *f1, const char *r1) -{ - server_rec *s = cmd->server; - proxy_server_conf *conf = - (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module); - struct proxy_remote *new; - char *p, *q; - char *r, *f; - int port; - - r = apr_pstrdup(cmd->pool, r1); - f = apr_pstrdup(cmd->pool, f1); - p = strchr(r, ':'); - if (p == NULL || p[1] != '/' || p[2] != '/' || p[3] == '\0') - return "ProxyRemote: Bad syntax for a remote proxy server"; - q = strchr(p + 3, ':'); - if (q != NULL) { - if (sscanf(q + 1, "%u", &port) != 1 || port > 65535) - return "ProxyRemote: Bad syntax for a remote proxy server (bad port number)"; - *q = '\0'; - } - else - port = -1; - *p = '\0'; - if (strchr(f, ':') == NULL) - ap_str_tolower(f); /* lowercase scheme */ - ap_str_tolower(p + 3); /* lowercase hostname */ - - if (port == -1) { - int i; - for (i = 0; defports[i].scheme != NULL; i++) - if (strcasecmp(defports[i].scheme, r) == 0) - break; - port = defports[i].port; - } - - new = apr_array_push(conf->proxies); - new->scheme = f; - new->protocol = r; - new->hostname = p + 3; - new->port = port; - return NULL; -} - -static const char * - set_cache_exclude(cmd_parms *cmd, void *dummy, const char *arg) -{ - server_rec *s = cmd->server; - proxy_server_conf *psf = (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module); - struct nocache_entry *new; - struct nocache_entry *list = (struct nocache_entry *) psf->nocaches->elts; - struct hostent hp; - int found = 0; - int i; - - /* Don't duplicate entries */ - for (i = 0; i < psf->nocaches->nelts; i++) { - if (strcasecmp(arg, list[i].name) == 0) /* ignore case for host names */ - found = 1; - } - - if (!found) { - new = apr_array_push(psf->nocaches); - new->name = arg; - /* Don't do name lookups on things that aren't dotted */ - if (ap_strchr_c(arg, '.') != NULL && - ap_proxy_host2addr(new->name, &hp) == NULL) - /*@@@FIXME: This copies only the first of (possibly many) IP addrs */ memcpy(&new->addr, hp.h_addr, sizeof(struct in_addr)); - else - new->addr.s_addr = 0; - } - return NULL; -} - -static const char * - add_pass(cmd_parms *cmd, void *dummy, const char *f, const char *r) -{ - server_rec *s = cmd->server; - proxy_server_conf *conf = - (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module); - struct proxy_alias *new; - - new = apr_array_push(conf->aliases); - new->fake = f; - new->real = r; - return NULL; -} - -static const char * - add_pass_reverse(cmd_parms *cmd, void *dummy, const char *f, const char *r) -{ - server_rec *s = cmd->server; - proxy_server_conf *conf; - struct proxy_alias *new; - - conf = (proxy_server_conf *)ap_get_module_config(s->module_config, - &proxy_module); - new = apr_array_push(conf->raliases); - new->fake = f; - new->real = r; - return NULL; -} - -static const char * - set_proxy_exclude(cmd_parms *parms, void *dummy, const char *arg) -{ - server_rec *s = parms->server; - proxy_server_conf *conf = - ap_get_module_config(s->module_config, &proxy_module); - struct noproxy_entry *new; - struct noproxy_entry *list = (struct noproxy_entry *) conf->noproxies->elts; - struct hostent hp; - int found = 0; - int i; - - /* Don't duplicate entries */ - for (i = 0; i < conf->noproxies->nelts; i++) { - if (strcasecmp(arg, list[i].name) == 0) /* ignore case for host names */ - found = 1; - } - - if (!found) { - new = apr_array_push(conf->noproxies); - new->name = arg; - /* Don't do name lookups on things that aren't dotted */ - if (ap_strchr_c(arg, '.') != NULL && - ap_proxy_host2addr(new->name, &hp) == NULL) - /*@@@FIXME: This copies only the first of (possibly many) IP addrs */ - memcpy(&new->addr, hp.h_addr, sizeof(struct in_addr)); - else - new->addr.s_addr = 0; - } - return NULL; -} - -/* - * Set the ports CONNECT can use - */ -static const char * - set_allowed_ports(cmd_parms *parms, void *dummy, const char *arg) -{ - server_rec *s = parms->server; - proxy_server_conf *conf = - ap_get_module_config(s->module_config, &proxy_module); - int *New; - - if (!apr_isdigit(arg[0])) - return "AllowCONNECT: port number must be numeric"; - - New = apr_array_push(conf->allowed_connect_ports); - *New = atoi(arg); - return NULL; -} - -/* Similar to set_proxy_exclude(), but defining directly connected hosts, - * which should never be accessed via the configured ProxyRemote servers - */ -static const char * - set_proxy_dirconn(cmd_parms *parms, void *dummy, const char *arg) -{ - server_rec *s = parms->server; - proxy_server_conf *conf = - ap_get_module_config(s->module_config, &proxy_module); - struct dirconn_entry *New; - struct dirconn_entry *list = (struct dirconn_entry *) conf->dirconn->elts; - int found = 0; - int i; - - /* Don't duplicate entries */ - for (i = 0; i < conf->dirconn->nelts; i++) { - if (strcasecmp(arg, list[i].name) == 0) - found = 1; - } - - if (!found) { - New = apr_array_push(conf->dirconn); - New->name = apr_pstrdup(parms->pool, arg); - New->hostentry = NULL; - - if (ap_proxy_is_ipaddr(New, parms->pool)) { -#if DEBUGGING - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "Parsed addr %s", inet_ntoa(New->addr)); - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "Parsed mask %s", inet_ntoa(New->mask)); -#endif - } - else if (ap_proxy_is_domainname(New, parms->pool)) { - ap_str_tolower(New->name); -#if DEBUGGING - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "Parsed domain %s", New->name); -#endif - } - else if (ap_proxy_is_hostname(New, parms->pool)) { - ap_str_tolower(New->name); -#if DEBUGGING - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "Parsed host %s", New->name); -#endif - } - else { - ap_proxy_is_word(New, parms->pool); -#if DEBUGGING - fprintf(stderr, "Parsed word %s\n", New->name); -#endif - } - } - return NULL; -} - -static const char * - set_proxy_domain(cmd_parms *parms, void *dummy, const char *arg) -{ - proxy_server_conf *psf = - ap_get_module_config(parms->server->module_config, &proxy_module); - - if (arg[0] != '.') - return "ProxyDomain: domain name must start with a dot."; - - psf->domain = arg; - return NULL; -} - -static const char * - set_proxy_req(cmd_parms *parms, void *dummy, int flag) -{ - proxy_server_conf *psf = - ap_get_module_config(parms->server->module_config, &proxy_module); - - psf->req = flag; - return NULL; -} - -static const char * - set_recv_buffer_size(cmd_parms *parms, void *dummy, const char *arg) -{ - proxy_server_conf *psf = - ap_get_module_config(parms->server->module_config, &proxy_module); - int s = atoi(arg); - if (s < 512 && s != 0) { - return "ProxyReceiveBufferSize must be >= 512 bytes, or 0 for system default."; - } - - psf->recv_buffer_size = s; - return NULL; -} - -static const char* - set_via_opt(cmd_parms *parms, void *dummy, const char *arg) -{ - proxy_server_conf *psf = - ap_get_module_config(parms->server->module_config, &proxy_module); - - if (strcasecmp(arg, "Off") == 0) - psf->viaopt = via_off; - else if (strcasecmp(arg, "On") == 0) - psf->viaopt = via_on; - else if (strcasecmp(arg, "Block") == 0) - psf->viaopt = via_block; - else if (strcasecmp(arg, "Full") == 0) - psf->viaopt = via_full; - else { - return "ProxyVia must be one of: " - "off | on | full | block"; - } - - return NULL; -} - -static const char* - set_cache_completion(cmd_parms *parms, void *dummy, const char *arg) -{ - proxy_server_conf *psf = ap_get_module_config(parms->server->module_config, &proxy_module); - int s = atoi(arg); - if (s > 100 || s < 0) { - return "CacheForceCompletion must be <= 100 percent, " - "or 0 for system default."; - } - - if (s > 0) - psf->cache_completion = ((float)s / 100); - return NULL; -} - -static const command_rec proxy_cmds[] = -{ - AP_INIT_FLAG("ProxyRequests", set_proxy_req, NULL, RSRC_CONF, - "on if the true proxy requests should be accepted"), - AP_INIT_TAKE2("ProxyRemote", add_proxy, NULL, RSRC_CONF, - "a scheme, partial URL or '*' and a proxy server"), - AP_INIT_TAKE2("ProxyPass", add_pass, NULL, RSRC_CONF, - "a virtual path and a URL"), - AP_INIT_TAKE2("ProxyPassReverse", add_pass_reverse, NULL, RSRC_CONF, - "a virtual path and a URL for reverse proxy behaviour"), - AP_INIT_ITERATE("ProxyBlock", set_proxy_exclude, NULL, RSRC_CONF, - "A list of names, hosts or domains to which the proxy will not connect"), - AP_INIT_TAKE1("ProxyReceiveBufferSize", set_recv_buffer_size, NULL, RSRC_CONF, - "Receive buffer size for outgoing HTTP and FTP connections in bytes"), - AP_INIT_ITERATE("NoProxy", set_proxy_dirconn, NULL, RSRC_CONF, - "A list of domains, hosts, or subnets to which the proxy will connect directly"), - AP_INIT_TAKE1("ProxyDomain", set_proxy_domain, NULL, RSRC_CONF, - "The default intranet domain name (in absence of a domain in the URL)"), - AP_INIT_ITERATE("AllowCONNECT", set_allowed_ports, NULL, RSRC_CONF, - "A list of ports which CONNECT may connect to"), - AP_INIT_TAKE1("ProxyVia", set_via_opt, NULL, RSRC_CONF, - "Configure Via: proxy header header to one of: on | off | block | full"), - AP_INIT_ITERATE("ProxyNoCache", set_cache_exclude, NULL, RSRC_CONF, - "A list of names, hosts or domains for which caching is *not* provided"), - AP_INIT_TAKE1("ProxyCacheForceCompletion", set_cache_completion, NULL, RSRC_CONF, - "Force a http cache completion after this percentage is loaded"), - {NULL} -}; - -static void register_hooks(apr_pool_t *p) -{ - /* handler */ - ap_hook_handler(proxy_handler, NULL, NULL, APR_HOOK_FIRST); - /* filename-to-URI translation */ - ap_hook_translate_name(proxy_trans, NULL, NULL, APR_HOOK_FIRST); - /* fixups */ - ap_hook_fixups(proxy_fixup, NULL, NULL, APR_HOOK_FIRST); - /* post read_request handling */ - ap_hook_post_read_request(proxy_detect, NULL, NULL, APR_HOOK_FIRST); -} - -module AP_MODULE_DECLARE_DATA proxy_module = -{ - STANDARD20_MODULE_STUFF, - NULL, /* create per-directory config structure */ - NULL, /* merge per-directory config structures */ - create_proxy_config, /* create per-server config structure */ - NULL, /* merge per-server config structures */ - proxy_cmds, /* command table */ - register_hooks -}; diff --git a/modules/proxy/mod_proxy.dsp b/modules/proxy/mod_proxy.dsp deleted file mode 100644 index d57baaa0e5..0000000000 --- a/modules/proxy/mod_proxy.dsp +++ /dev/null @@ -1,123 +0,0 @@ -# Microsoft Developer Studio Project File - Name="mod_proxy" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=mod_proxy - Win32 Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "mod_proxy.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "mod_proxy.mak" CFG="mod_proxy - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "mod_proxy - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "mod_proxy - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "mod_proxy - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c -# ADD CPP /nologo /MD /W3 /O2 /I "..\..\srclib\apr\include" /I "../../srclib/apr-util/include" /I "..\..\include" /I "..\..\os\win32" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_proxy" /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x809 /d "NDEBUG" -# ADD RSC /l 0x809 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /map /out:"Release/mod_proxy.so" /machine:I386 /base:@..\..\os\win32\BaseAddr.ref,mod_proxy -# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /map /out:"Release/mod_proxy.so" /machine:I386 /base:@..\..\os\win32\BaseAddr.ref,mod_proxy - -!ELSEIF "$(CFG)" == "mod_proxy - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c -# ADD CPP /nologo /MDd /W3 /GX /ZI /Od /I "..\..\srclib\apr\include" /I "../../srclib/apr-util/include" /I "..\..\include" /I "..\..\os\win32" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_proxy" /FD /c -# ADD BASE MTL /nologo /D "_DEBUG" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x809 /d "_DEBUG" -# ADD RSC /l 0x809 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /map /debug /out:"Debug/mod_proxy.so" /machine:I386 /base:@..\..\os\win32\BaseAddr.ref,mod_proxy -# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /map /debug /out:"Debug/mod_proxy.so" /machine:I386 /base:@..\..\os\win32\BaseAddr.ref,mod_proxy - -!ENDIF - -# Begin Target - -# Name "mod_proxy - Win32 Release" -# Name "mod_proxy - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" -# Begin Source File - -SOURCE=.\mod_proxy.c -# End Source File -# Begin Source File - -SOURCE=.\proxy_connect.c -# End Source File -# Begin Source File - -SOURCE=.\proxy_ftp.c -# End Source File -# Begin Source File - -SOURCE=.\proxy_http.c -# End Source File -# Begin Source File - -SOURCE=.\proxy_util.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" -# Begin Source File - -SOURCE=.\mod_proxy.h -# End Source File -# End Group -# End Target -# End Project diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h deleted file mode 100644 index 1991c457ed..0000000000 --- a/modules/proxy/mod_proxy.h +++ /dev/null @@ -1,261 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - * - * Portions of this software are based upon public domain software - * originally written at the National Center for Supercomputing Applications, - * University of Illinois, Urbana-Champaign. - */ - -#ifndef MOD_PROXY_H -#define MOD_PROXY_H - -/* - * Main include file for the Apache proxy - */ - -/* - - Note that the Explain() stuff is not yet complete. - Also note numerous FIXMEs and CHECKMEs which should be eliminated. - - If TESTING is set, then garbage collection doesn't delete ... probably a good - idea when hacking. - - This code is once again experimental! - - Things to do: - - 1. Make it completely work (for FTP too) - - 2. HTTP/1.1 - - 3. Cache issues - - Chuck Murcko <chuck@topsail.org> 02-06-01 - - */ - -#define TESTING 0 -#undef EXPLAIN - -#include "apr_compat.h" -#include "apr_lib.h" -#include "apr_strings.h" - -#if APR_HAVE_NETDB_H -#include <netdb.h> -#endif -#if APR_HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#if APR_HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#if APR_HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif - -#include "httpd.h" -#include "http_config.h" -#include "http_protocol.h" -#include "proxy_cache.h" - - -extern module AP_MODULE_DECLARE_DATA proxy_module; - - -/* for proxy_canonenc() */ -enum enctype { - enc_path, enc_search, enc_user, enc_fpath, enc_parm -}; - -#define HDR_APP (0) /* append header, for proxy_add_header() */ -#define HDR_REP (1) /* replace header, for proxy_add_header() */ - -#if APR_CHARSET_EBCDIC -#define CRLF "\r\n" -#else /*APR_CHARSET_EBCDIC*/ -#define CRLF "\015\012" -#endif /*APR_CHARSET_EBCDIC*/ - -#define DEFAULT_FTP_DATA_PORT 20 -#define DEFAULT_FTP_PORT 21 -#define DEFAULT_GOPHER_PORT 70 -#define DEFAULT_NNTP_PORT 119 -#define DEFAULT_WAIS_PORT 210 -#define DEFAULT_HTTPS_PORT 443 -#define DEFAULT_SNEWS_PORT 563 -#define DEFAULT_PROSPERO_PORT 1525 /* WARNING: conflict w/Oracle */ - -#define DEFAULT_CACHE_COMPLETION (0.9) -/* Some WWW schemes and their default ports; this is basically /etc/services */ -struct proxy_services { - const char *scheme; - int port; -}; - -/* static information about a remote proxy */ -struct proxy_remote { - const char *scheme; /* the schemes handled by this proxy, or '*' */ - const char *protocol; /* the scheme used to talk to this proxy */ - const char *hostname; /* the hostname of this proxy */ - int port; /* the port for this proxy */ -}; - -struct proxy_alias { - const char *real; - const char *fake; -}; - -struct dirconn_entry { - char *name; - struct in_addr addr, mask; - struct hostent *hostentry; - int (*matcher) (struct dirconn_entry * This, request_rec *r); -}; - -struct noproxy_entry { - const char *name; - struct in_addr addr; -}; - -struct nocache_entry { - const char *name; - struct in_addr addr; -}; - -typedef struct { - apr_array_header_t *proxies; - apr_array_header_t *aliases; - apr_array_header_t *raliases; - apr_array_header_t *noproxies; - apr_array_header_t *dirconn; - apr_array_header_t *nocaches; - apr_array_header_t *allowed_connect_ports; - const char *domain; /* domain name to use in absence of a domain name in the request */ - int req; /* true if proxy requests are enabled */ - float cache_completion; /* Force cache completion after this point */ - enum { - via_off, - via_on, - via_block, - via_full - } viaopt; /* how to deal with proxy Via: headers */ - size_t recv_buffer_size; - ap_cache_handle_t *cache; -} proxy_server_conf; - -struct per_thread_data { - struct hostent hpbuf; - u_long ipaddr; - char *charpbuf[2]; -}; - -typedef struct { - float cache_completion; /* completion percentage */ - int content_length; /* length of the content */ -} proxy_completion; - - -/* Function prototypes */ - -/* proxy_connect.c */ - -int ap_proxy_connect_handler(request_rec *r, char *url, - const char *proxyhost, int proxyport); - -/* proxy_ftp.c */ - -int ap_proxy_ftp_canon(request_rec *r, char *url); -int ap_proxy_ftp_handler(request_rec *r, ap_cache_el *c, char *url); - -/* proxy_http.c */ - -int ap_proxy_http_canon(request_rec *r, char *url, const char *scheme, - int def_port); -int ap_proxy_http_handler(request_rec *r, char *url, - const char *proxyhost, int proxyport); - -/* proxy_util.c */ - -int ap_proxy_hex2c(const char *x); -void ap_proxy_c2hex(int ch, char *x); -char *ap_proxy_canonenc(apr_pool_t *p, const char *x, int len, enum enctype t, - int isenc); -char *ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, char **userp, - char **passwordp, char **hostp, int *port); -const char *ap_proxy_date_canon(apr_pool_t *p, const char *x); -apr_table_t *ap_proxy_read_headers(request_rec *r, char *buffer, int size, conn_rec *c); -void ap_proxy_send_headers(request_rec *r, const char *respline, apr_table_t *hdrs); -int ap_proxy_liststr(const char *list, const char *val); -void ap_proxy_hash(const char *it, char *val, int ndepth, int nlength); -int ap_proxy_hex2sec(const char *x); -void ap_proxy_sec2hex(int t, char *y); -const char *ap_proxy_host2addr(const char *host, struct hostent *reqhp); -int ap_proxy_cache_send(request_rec *r, ap_cache_el *c); -int ap_proxy_cache_should_cache(request_rec *r, apr_table_t *resp_hdrs, - const int is_HTTP1); -int ap_proxy_cache_update(ap_cache_el *c); -void ap_proxy_cache_error(ap_cache_el **r); -int ap_proxyerror(request_rec *r, int statuscode, const char *message); -int ap_proxy_is_ipaddr(struct dirconn_entry *This, apr_pool_t *p); -int ap_proxy_is_domainname(struct dirconn_entry *This, apr_pool_t *p); -int ap_proxy_is_hostname(struct dirconn_entry *This, apr_pool_t *p); -int ap_proxy_is_word(struct dirconn_entry *This, apr_pool_t *p); -apr_status_t ap_proxy_doconnect(apr_socket_t *sock, char *host, apr_uint32_t port, request_rec *r); -int ap_proxy_garbage_init(server_rec *, apr_pool_t *); -/* This function is called by ap_table_do() for all header lines */ -int ap_proxy_send_hdr_line(void *p, const char *key, const char *value); -unsigned ap_proxy_bputs2(const char *data, apr_socket_t *client, ap_cache_el *cache); - -#endif /*MOD_PROXY_H*/ diff --git a/modules/proxy/mod_proxy.mak b/modules/proxy/mod_proxy.mak deleted file mode 100644 index 3d13f3d1ac..0000000000 --- a/modules/proxy/mod_proxy.mak +++ /dev/null @@ -1,573 +0,0 @@ -# Microsoft Developer Studio Generated NMAKE File, Based on mod_proxy.dsp -!IF "$(CFG)" == "" -CFG=mod_proxy - Win32 Release -!MESSAGE No configuration specified. Defaulting to mod_proxy - Win32 Release. -!ENDIF - -!IF "$(CFG)" != "mod_proxy - Win32 Release" && "$(CFG)" !=\ - "mod_proxy - Win32 Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "mod_proxy.mak" CFG="mod_proxy - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "mod_proxy - Win32 Release" (based on\ - "Win32 (x86) Dynamic-Link Library") -!MESSAGE "mod_proxy - Win32 Debug" (based on\ - "Win32 (x86) Dynamic-Link Library") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -!IF "$(CFG)" == "mod_proxy - Win32 Release" - -OUTDIR=.\Release -INTDIR=.\Release -# Begin Custom Macros -OutDir=.\Release -# End Custom Macros - -!IF "$(RECURSE)" == "0" - -ALL : "$(OUTDIR)\mod_proxy.so" - -!ELSE - -ALL : "libaprutil - Win32 Release" "libhttpd - Win32 Release"\ - "libapr - Win32 Release" "$(OUTDIR)\mod_proxy.so" - -!ENDIF - -!IF "$(RECURSE)" == "1" -CLEAN :"libapr - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN"\ - "libaprutil - Win32 ReleaseCLEAN" -!ELSE -CLEAN : -!ENDIF - -@erase "$(INTDIR)\mod_proxy.idb" - -@erase "$(INTDIR)\mod_proxy.obj" - -@erase "$(INTDIR)\proxy_connect.obj" - -@erase "$(INTDIR)\proxy_ftp.obj" - -@erase "$(INTDIR)\proxy_http.obj" - -@erase "$(INTDIR)\proxy_util.obj" - -@erase "$(OUTDIR)\mod_proxy.exp" - -@erase "$(OUTDIR)\mod_proxy.lib" - -@erase "$(OUTDIR)\mod_proxy.map" - -@erase "$(OUTDIR)\mod_proxy.so" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MD /W3 /O2 /I "..\..\srclib\apr\include" /I\ - "../../srclib/apr-util/include" /I "..\..\include" /I "..\..\os\win32" /D\ - "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy" /FD\ - /c -CPP_OBJS=.\Release/ -CPP_SBRS=. - -.c{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 -RSC=rc.exe -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows\ - /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy.pdb"\ - /map:"$(INTDIR)\mod_proxy.map" /machine:I386 /out:"$(OUTDIR)\mod_proxy.so"\ - /implib:"$(OUTDIR)\mod_proxy.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy -LINK32_OBJS= \ - "$(INTDIR)\mod_proxy.obj" \ - "$(INTDIR)\proxy_connect.obj" \ - "$(INTDIR)\proxy_ftp.obj" \ - "$(INTDIR)\proxy_http.obj" \ - "$(INTDIR)\proxy_util.obj" \ - "..\..\Release\libhttpd.lib" \ - "..\..\srclib\apr-util\Release\libaprutil.lib" \ - "..\..\srclib\apr\Release\libapr.lib" - -"$(OUTDIR)\mod_proxy.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ELSEIF "$(CFG)" == "mod_proxy - Win32 Debug" - -OUTDIR=.\Debug -INTDIR=.\Debug -# Begin Custom Macros -OutDir=.\Debug -# End Custom Macros - -!IF "$(RECURSE)" == "0" - -ALL : "$(OUTDIR)\mod_proxy.so" - -!ELSE - -ALL : "libaprutil - Win32 Debug" "libhttpd - Win32 Debug"\ - "libapr - Win32 Debug" "$(OUTDIR)\mod_proxy.so" - -!ENDIF - -!IF "$(RECURSE)" == "1" -CLEAN :"libapr - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN"\ - "libaprutil - Win32 DebugCLEAN" -!ELSE -CLEAN : -!ENDIF - -@erase "$(INTDIR)\mod_proxy.idb" - -@erase "$(INTDIR)\mod_proxy.obj" - -@erase "$(INTDIR)\proxy_connect.obj" - -@erase "$(INTDIR)\proxy_ftp.obj" - -@erase "$(INTDIR)\proxy_http.obj" - -@erase "$(INTDIR)\proxy_util.obj" - -@erase "$(OUTDIR)\mod_proxy.exp" - -@erase "$(OUTDIR)\mod_proxy.lib" - -@erase "$(OUTDIR)\mod_proxy.map" - -@erase "$(OUTDIR)\mod_proxy.pdb" - -@erase "$(OUTDIR)\mod_proxy.so" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MDd /W3 /GX /Zi /Od /I "..\..\srclib\apr\include" /I\ - "../../srclib/apr-util/include" /I "..\..\include" /I "..\..\os\win32" /D\ - "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_proxy" /FD\ - /c -CPP_OBJS=.\Debug/ -CPP_SBRS=. - -.c{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 -RSC=rc.exe -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_proxy.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows\ - /dll /incremental:no /pdb:"$(OUTDIR)\mod_proxy.pdb"\ - /map:"$(INTDIR)\mod_proxy.map" /debug /machine:I386\ - /out:"$(OUTDIR)\mod_proxy.so" /implib:"$(OUTDIR)\mod_proxy.lib"\ - /base:@..\..\os\win32\BaseAddr.ref,mod_proxy -LINK32_OBJS= \ - "$(INTDIR)\mod_proxy.obj" \ - "$(INTDIR)\proxy_connect.obj" \ - "$(INTDIR)\proxy_ftp.obj" \ - "$(INTDIR)\proxy_http.obj" \ - "$(INTDIR)\proxy_util.obj" \ - "..\..\Debug\libhttpd.lib" \ - "..\..\srclib\apr-util\Debug\libaprutil.lib" \ - "..\..\srclib\apr\Debug\libapr.lib" - -"$(OUTDIR)\mod_proxy.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ENDIF - - -!IF "$(CFG)" == "mod_proxy - Win32 Release" || "$(CFG)" ==\ - "mod_proxy - Win32 Debug" -SOURCE=.\mod_proxy.c -DEP_CPP_MOD_P=\ - "..\..\include\ap_config.h"\ - "..\..\include\ap_mmn.h"\ - "..\..\include\http_config.h"\ - "..\..\include\http_log.h"\ - "..\..\include\http_protocol.h"\ - "..\..\include\http_request.h"\ - "..\..\include\http_vhost.h"\ - "..\..\include\httpd.h"\ - "..\..\include\pcreposix.h"\ - "..\..\include\util_cfgtree.h"\ - "..\..\include\util_date.h"\ - "..\..\include\util_filter.h"\ - "..\..\include\util_uri.h"\ - "..\..\os\win32\os.h"\ - "..\..\srclib\apr-util\include\ap_buckets.h"\ - "..\..\srclib\apr-util\include\ap_hooks.h"\ - "..\..\srclib\apr-util\include\ap_ring.h"\ - "..\..\srclib\apr\include\apr.h"\ - "..\..\srclib\apr\include\apr_compat.h"\ - "..\..\srclib\apr\include\apr_dso.h"\ - "..\..\srclib\apr\include\apr_errno.h"\ - "..\..\srclib\apr\include\apr_file_io.h"\ - "..\..\srclib\apr\include\apr_general.h"\ - "..\..\srclib\apr\include\apr_lib.h"\ - "..\..\srclib\apr\include\apr_lock.h"\ - "..\..\srclib\apr\include\apr_mmap.h"\ - "..\..\srclib\apr\include\apr_network_io.h"\ - "..\..\srclib\apr\include\apr_pools.h"\ - "..\..\srclib\apr\include\apr_portable.h"\ - "..\..\srclib\apr\include\apr_strings.h"\ - "..\..\srclib\apr\include\apr_tables.h"\ - "..\..\srclib\apr\include\apr_thread_proc.h"\ - "..\..\srclib\apr\include\apr_time.h"\ - "..\..\srclib\apr\network_io\os2\os2nerrno.h"\ - ".\mod_proxy.h"\ - -NODEP_CPP_MOD_P=\ - "..\..\include\ap_config_auto.h"\ - "..\..\include\ap_config_path.h"\ - ".\ap_cache.h"\ - ".\buff.h"\ - - -"$(INTDIR)\mod_proxy.obj" : $(SOURCE) $(DEP_CPP_MOD_P) "$(INTDIR)" - - -SOURCE=.\proxy_connect.c -DEP_CPP_PROXY=\ - "..\..\include\ap_config.h"\ - "..\..\include\ap_mmn.h"\ - "..\..\include\http_config.h"\ - "..\..\include\http_log.h"\ - "..\..\include\http_main.h"\ - "..\..\include\http_protocol.h"\ - "..\..\include\httpd.h"\ - "..\..\include\pcreposix.h"\ - "..\..\include\util_cfgtree.h"\ - "..\..\include\util_filter.h"\ - "..\..\include\util_uri.h"\ - "..\..\os\win32\os.h"\ - "..\..\srclib\apr-util\include\ap_buckets.h"\ - "..\..\srclib\apr-util\include\ap_hooks.h"\ - "..\..\srclib\apr-util\include\ap_ring.h"\ - "..\..\srclib\apr\include\apr.h"\ - "..\..\srclib\apr\include\apr_compat.h"\ - "..\..\srclib\apr\include\apr_dso.h"\ - "..\..\srclib\apr\include\apr_errno.h"\ - "..\..\srclib\apr\include\apr_file_io.h"\ - "..\..\srclib\apr\include\apr_general.h"\ - "..\..\srclib\apr\include\apr_lib.h"\ - "..\..\srclib\apr\include\apr_lock.h"\ - "..\..\srclib\apr\include\apr_mmap.h"\ - "..\..\srclib\apr\include\apr_network_io.h"\ - "..\..\srclib\apr\include\apr_pools.h"\ - "..\..\srclib\apr\include\apr_portable.h"\ - "..\..\srclib\apr\include\apr_strings.h"\ - "..\..\srclib\apr\include\apr_tables.h"\ - "..\..\srclib\apr\include\apr_thread_proc.h"\ - "..\..\srclib\apr\include\apr_time.h"\ - "..\..\srclib\apr\network_io\os2\os2nerrno.h"\ - ".\mod_proxy.h"\ - -NODEP_CPP_PROXY=\ - "..\..\include\ap_config_auto.h"\ - "..\..\include\ap_config_path.h"\ - ".\ap_cache.h"\ - ".\buff.h"\ - - -"$(INTDIR)\proxy_connect.obj" : $(SOURCE) $(DEP_CPP_PROXY) "$(INTDIR)" - - -SOURCE=.\proxy_ftp.c -DEP_CPP_PROXY_=\ - "..\..\include\ap_config.h"\ - "..\..\include\ap_mmn.h"\ - "..\..\include\http_config.h"\ - "..\..\include\http_core.h"\ - "..\..\include\http_log.h"\ - "..\..\include\http_main.h"\ - "..\..\include\http_protocol.h"\ - "..\..\include\httpd.h"\ - "..\..\include\pcreposix.h"\ - "..\..\include\util_cfgtree.h"\ - "..\..\include\util_filter.h"\ - "..\..\include\util_uri.h"\ - "..\..\os\win32\os.h"\ - "..\..\srclib\apr-util\include\ap_buckets.h"\ - "..\..\srclib\apr-util\include\ap_hooks.h"\ - "..\..\srclib\apr-util\include\ap_ring.h"\ - "..\..\srclib\apr\include\apr.h"\ - "..\..\srclib\apr\include\apr_compat.h"\ - "..\..\srclib\apr\include\apr_dso.h"\ - "..\..\srclib\apr\include\apr_errno.h"\ - "..\..\srclib\apr\include\apr_file_io.h"\ - "..\..\srclib\apr\include\apr_general.h"\ - "..\..\srclib\apr\include\apr_lib.h"\ - "..\..\srclib\apr\include\apr_lock.h"\ - "..\..\srclib\apr\include\apr_mmap.h"\ - "..\..\srclib\apr\include\apr_network_io.h"\ - "..\..\srclib\apr\include\apr_pools.h"\ - "..\..\srclib\apr\include\apr_portable.h"\ - "..\..\srclib\apr\include\apr_strings.h"\ - "..\..\srclib\apr\include\apr_tables.h"\ - "..\..\srclib\apr\include\apr_thread_proc.h"\ - "..\..\srclib\apr\include\apr_time.h"\ - "..\..\srclib\apr\network_io\os2\os2nerrno.h"\ - ".\mod_proxy.h"\ - -NODEP_CPP_PROXY_=\ - "..\..\include\ap_config_auto.h"\ - "..\..\include\ap_config_path.h"\ - ".\ap_cache.h"\ - ".\buff.h"\ - - -"$(INTDIR)\proxy_ftp.obj" : $(SOURCE) $(DEP_CPP_PROXY_) "$(INTDIR)" - - -SOURCE=.\proxy_http.c -DEP_CPP_PROXY_H=\ - "..\..\include\ap_config.h"\ - "..\..\include\ap_mmn.h"\ - "..\..\include\http_config.h"\ - "..\..\include\http_connection.h"\ - "..\..\include\http_core.h"\ - "..\..\include\http_log.h"\ - "..\..\include\http_main.h"\ - "..\..\include\http_protocol.h"\ - "..\..\include\httpd.h"\ - "..\..\include\pcreposix.h"\ - "..\..\include\util_cfgtree.h"\ - "..\..\include\util_date.h"\ - "..\..\include\util_filter.h"\ - "..\..\include\util_uri.h"\ - "..\..\os\win32\os.h"\ - "..\..\srclib\apr-util\include\ap_buckets.h"\ - "..\..\srclib\apr-util\include\ap_hooks.h"\ - "..\..\srclib\apr-util\include\ap_ring.h"\ - "..\..\srclib\apr\include\apr.h"\ - "..\..\srclib\apr\include\apr_compat.h"\ - "..\..\srclib\apr\include\apr_dso.h"\ - "..\..\srclib\apr\include\apr_errno.h"\ - "..\..\srclib\apr\include\apr_file_io.h"\ - "..\..\srclib\apr\include\apr_general.h"\ - "..\..\srclib\apr\include\apr_lib.h"\ - "..\..\srclib\apr\include\apr_lock.h"\ - "..\..\srclib\apr\include\apr_mmap.h"\ - "..\..\srclib\apr\include\apr_network_io.h"\ - "..\..\srclib\apr\include\apr_pools.h"\ - "..\..\srclib\apr\include\apr_portable.h"\ - "..\..\srclib\apr\include\apr_strings.h"\ - "..\..\srclib\apr\include\apr_tables.h"\ - "..\..\srclib\apr\include\apr_thread_proc.h"\ - "..\..\srclib\apr\include\apr_time.h"\ - "..\..\srclib\apr\network_io\os2\os2nerrno.h"\ - ".\mod_proxy.h"\ - -NODEP_CPP_PROXY_H=\ - "..\..\include\ap_config_auto.h"\ - "..\..\include\ap_config_path.h"\ - ".\ap_cache.h"\ - ".\buff.h"\ - - -"$(INTDIR)\proxy_http.obj" : $(SOURCE) $(DEP_CPP_PROXY_H) "$(INTDIR)" - - -SOURCE=.\proxy_util.c -DEP_CPP_PROXY_U=\ - "..\..\include\ap_config.h"\ - "..\..\include\ap_mmn.h"\ - "..\..\include\http_config.h"\ - "..\..\include\http_core.h"\ - "..\..\include\http_log.h"\ - "..\..\include\http_main.h"\ - "..\..\include\http_protocol.h"\ - "..\..\include\httpd.h"\ - "..\..\include\pcreposix.h"\ - "..\..\include\util_cfgtree.h"\ - "..\..\include\util_date.h"\ - "..\..\include\util_filter.h"\ - "..\..\include\util_uri.h"\ - "..\..\os\win32\os.h"\ - "..\..\srclib\apr-util\include\ap_buckets.h"\ - "..\..\srclib\apr-util\include\ap_hooks.h"\ - "..\..\srclib\apr-util\include\ap_ring.h"\ - "..\..\srclib\apr\include\apr.h"\ - "..\..\srclib\apr\include\apr_compat.h"\ - "..\..\srclib\apr\include\apr_dso.h"\ - "..\..\srclib\apr\include\apr_errno.h"\ - "..\..\srclib\apr\include\apr_file_io.h"\ - "..\..\srclib\apr\include\apr_general.h"\ - "..\..\srclib\apr\include\apr_lib.h"\ - "..\..\srclib\apr\include\apr_lock.h"\ - "..\..\srclib\apr\include\apr_md5.h"\ - "..\..\srclib\apr\include\apr_mmap.h"\ - "..\..\srclib\apr\include\apr_network_io.h"\ - "..\..\srclib\apr\include\apr_pools.h"\ - "..\..\srclib\apr\include\apr_portable.h"\ - "..\..\srclib\apr\include\apr_strings.h"\ - "..\..\srclib\apr\include\apr_tables.h"\ - "..\..\srclib\apr\include\apr_thread_proc.h"\ - "..\..\srclib\apr\include\apr_time.h"\ - "..\..\srclib\apr\include\apr_xlate.h"\ - "..\..\srclib\apr\network_io\os2\os2nerrno.h"\ - ".\mod_proxy.h"\ - -NODEP_CPP_PROXY_U=\ - "..\..\include\ap_config_auto.h"\ - "..\..\include\ap_config_path.h"\ - ".\ap_cache.h"\ - ".\buff.h"\ - - -"$(INTDIR)\proxy_util.obj" : $(SOURCE) $(DEP_CPP_PROXY_U) "$(INTDIR)" - - -!IF "$(CFG)" == "mod_proxy - Win32 Release" - -"libapr - Win32 Release" : - cd "\test\httpd-2.0\srclib\apr" - $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" - cd "..\..\modules\proxy" - -"libapr - Win32 ReleaseCLEAN" : - cd "\test\httpd-2.0\srclib\apr" - $(MAKE) /$(MAKEFLAGS) CLEAN /F ".\libapr.mak" CFG="libapr - Win32 Release"\ - RECURSE=1 - cd "..\..\modules\proxy" - -!ELSEIF "$(CFG)" == "mod_proxy - Win32 Debug" - -"libapr - Win32 Debug" : - cd "\test\httpd-2.0\srclib\apr" - $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" - cd "..\..\modules\proxy" - -"libapr - Win32 DebugCLEAN" : - cd "\test\httpd-2.0\srclib\apr" - $(MAKE) /$(MAKEFLAGS) CLEAN /F ".\libapr.mak" CFG="libapr - Win32 Debug"\ - RECURSE=1 - cd "..\..\modules\proxy" - -!ENDIF - -!IF "$(CFG)" == "mod_proxy - Win32 Release" - -"libhttpd - Win32 Release" : - cd "\test\httpd-2.0" - $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" - cd ".\modules\proxy" - -"libhttpd - Win32 ReleaseCLEAN" : - cd "\test\httpd-2.0" - $(MAKE) /$(MAKEFLAGS) CLEAN /F ".\libhttpd.mak"\ - CFG="libhttpd - Win32 Release" RECURSE=1 - cd ".\modules\proxy" - -!ELSEIF "$(CFG)" == "mod_proxy - Win32 Debug" - -"libhttpd - Win32 Debug" : - cd "\test\httpd-2.0" - $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" - cd ".\modules\proxy" - -"libhttpd - Win32 DebugCLEAN" : - cd "\test\httpd-2.0" - $(MAKE) /$(MAKEFLAGS) CLEAN /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"\ - RECURSE=1 - cd ".\modules\proxy" - -!ENDIF - -!IF "$(CFG)" == "mod_proxy - Win32 Release" - -"libaprutil - Win32 Release" : - cd "\test\httpd-2.0\srclib\apr-util" - $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"\ - - cd "..\..\modules\proxy" - -"libaprutil - Win32 ReleaseCLEAN" : - cd "\test\httpd-2.0\srclib\apr-util" - $(MAKE) /$(MAKEFLAGS) CLEAN /F ".\libaprutil.mak"\ - CFG="libaprutil - Win32 Release" RECURSE=1 - cd "..\..\modules\proxy" - -!ELSEIF "$(CFG)" == "mod_proxy - Win32 Debug" - -"libaprutil - Win32 Debug" : - cd "\test\httpd-2.0\srclib\apr-util" - $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" - cd "..\..\modules\proxy" - -"libaprutil - Win32 DebugCLEAN" : - cd "\test\httpd-2.0\srclib\apr-util" - $(MAKE) /$(MAKEFLAGS) CLEAN /F ".\libaprutil.mak"\ - CFG="libaprutil - Win32 Debug" RECURSE=1 - cd "..\..\modules\proxy" - -!ENDIF - - -!ENDIF - diff --git a/modules/proxy/proxy_cache.c b/modules/proxy/proxy_cache.c deleted file mode 100644 index 3f4ac25d37..0000000000 --- a/modules/proxy/proxy_cache.c +++ /dev/null @@ -1,222 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - */ - -#include "apr_strings.h" -#include "proxy_cache.h" -#include "httpd.h" -#include "http_log.h" -#ifdef HAVE_STDIO_H -#include <stdio.h> -#endif - -/* struct ap_cache_handle_t, some function pointer in the meth */ -#define VERIFY_IMPL(x, fun) if(!x || !x->meth.fun) return APR_ENOTIMPL - -APR_HOOK_STRUCT( - APR_HOOK_LINK(cache_init) -) - -apr_status_t ap_cache_init(ap_cache_handle_t **h, const char *desc, server_rec *server) -{ - return ap_run_cache_init(h, desc, server); -} -apr_status_t ap_cache_close(ap_cache_handle_t *h) -{ - VERIFY_IMPL(h, cache_close); - return h->meth.cache_close(h); -} -apr_status_t ap_cache_garbage_collect(ap_cache_handle_t *h) -{ - VERIFY_IMPL(h, cache_garbage_coll); - return h->meth.cache_garbage_coll(h); -} -apr_status_t ap_cache_seek(ap_cache_handle_t *h, const char *name, ap_cache_el **el) -{ - VERIFY_IMPL(h, cache_element); - *el = NULL; - return h->meth.cache_element(h, name, el, AP_CACHE_SEEK); -} -apr_status_t ap_cache_create(ap_cache_handle_t *h, const char *name, ap_cache_el **el) -{ - VERIFY_IMPL(h, cache_element); - *el = NULL; - return h->meth.cache_element(h, name, el, AP_CACHE_CREATE); -} -apr_status_t ap_cache_remove(ap_cache_handle_t *h, const char *name) -{ - VERIFY_IMPL(h, cache_element); - return h->meth.cache_element(h, name, NULL, AP_CACHE_REMOVE); -} -struct walk_struct { char **place; apr_pool_t *pool; }; -static int get_first_val(void *datum, const char *name, const char *val) -{ - struct walk_struct *ws = (struct walk_struct *)datum; - *(ws->place) = apr_pstrdup(ws->pool, val); - return 0; -} -apr_status_t ap_cache_el_header(ap_cache_el *el, const char *hdr, char **val) -{ - struct walk_struct ws; - if(!val || !el) return APR_BADARG; - *val = NULL; - ws.place = val; - ws.pool = el->cache->pool; - ap_cache_el_header_walk(el, get_first_val, &ws, hdr, NULL); - return *val ? APR_SUCCESS : APR_ENOENT; -} -apr_status_t ap_cache_el_header_walk(ap_cache_el *el, - int (*comp)(void *, const char *, const char *), void *rec, ...) -{ - va_list args; - apr_status_t ret; - - if(!el) return APR_BADARG; - VERIFY_IMPL(el->cache, cache_el_header_walk); - va_start(args, rec); - ret = el->cache->meth.cache_el_header_walk(el, comp, rec, args); - va_end(args); - return ret; -} -/* -static int merge_tables(void *datum, const char *name, const char *val) -{ - ap_cache_el *el = (ap_cache_el *)datum; - ap_cache_el_header_remove(el, name); - ap_cache_el_header_add(el, name, val); - return APR_SUCCESS; -} -*/ -apr_status_t ap_cache_el_header_merge(ap_cache_el *el, apr_table_t *tbl) -{ - apr_table_entry_t *elts = (apr_table_entry_t *) tbl->a.elts; - int i; -/* - const char *val; -*/ - - for (i = 0; i < tbl->a.nelts; ++i) - ap_cache_el_header_set(el, elts[i].key, elts[i].val); - return APR_SUCCESS; -} -apr_status_t ap_cache_el_header_set(ap_cache_el *el, const char *hdrname, - const char *hdrval) -{ - if(!el) return APR_BADARG; - VERIFY_IMPL(el->cache, cache_el_hdr); - return el->cache->meth.cache_el_hdr(el, hdrname, hdrval, AP_CACHE_CHANGE); -} -apr_status_t ap_cache_el_header_add(ap_cache_el *el, const char *hdrname, - const char *hdrval) -{ - if(!el) return APR_BADARG; - VERIFY_IMPL(el->cache, cache_el_hdr); - return el->cache->meth.cache_el_hdr(el, hdrname, hdrval, AP_CACHE_CREATE); -} -apr_status_t ap_cache_el_header_remove(ap_cache_el *el, const char *hdrname) -{ - if(!el) return APR_BADARG; - VERIFY_IMPL(el->cache, cache_el_hdr); - return el->cache->meth.cache_el_hdr(el, hdrname, NULL, AP_CACHE_REMOVE); -} -apr_status_t ap_cache_el_header_clear(ap_cache_el *el) -{ - if(!el) return APR_BADARG; - VERIFY_IMPL(el->cache, cache_el_reset); - return el->cache->meth.cache_el_reset(el, AP_CACHE_HEADER); -} -apr_status_t ap_cache_el_data(ap_cache_el *el, apr_file_t **b) -{ - if(!b || !el) return APR_BADARG; - *b = NULL; - VERIFY_IMPL(el->cache, cache_el_data); - return el->cache->meth.cache_el_data(el, b); -} -apr_status_t ap_cache_el_data_append(ap_cache_el *el, apr_file_t *data) -{ - apr_file_t *place; - char buffer[HUGE_STRING_LEN]; - apr_status_t ret = APR_SUCCESS; - apr_size_t nbytes, i, o; - - if((ret = ap_cache_el_data(el, &place)) != APR_SUCCESS) return ret; - nbytes = HUGE_STRING_LEN; - while(apr_file_read(data, buffer, &nbytes) == APR_SUCCESS && nbytes) { - o = 0; - while(nbytes) - { - i = nbytes; - apr_file_write(place, buffer + o, &i); - o += i; - nbytes -= i; - } - } - return ret; -} -apr_status_t ap_cache_el_data_clear(ap_cache_el *el) -{ - if(!el) return APR_BADARG; - VERIFY_IMPL(el->cache, cache_el_reset); - return el->cache->meth.cache_el_reset(el, AP_CACHE_DATA); -} -apr_status_t ap_cache_el_finalize(ap_cache_el *el) -{ - if(!el) return APR_BADARG; - VERIFY_IMPL(el->cache, cache_el_final); - return el->cache->meth.cache_el_final(el); -} - -/* hooks */ -AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, cache_init, (ap_cache_handle_t **h, const char *desc, server_rec *s), - (h, desc, s), APR_ENOTIMPL) - diff --git a/modules/proxy/proxy_cache.h b/modules/proxy/proxy_cache.h deleted file mode 100644 index e9cf4a7456..0000000000 --- a/modules/proxy/proxy_cache.h +++ /dev/null @@ -1,366 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - */ - -#ifndef __AP_CACHE_H__ -#define __AP_CACHE_H__ - -#include <stdarg.h> -#include "httpd.h" -#include "apr_file_io.h" -#include "apr_network_io.h" -#include "apr_pools.h" -#include "apr_hooks.h" -#include "httpd.h" - -/** - * @package Apache Caching Module API - */ - -/* Interface to caching modules - * This interface will allow access to special modules that will - * do actual caching calls and maintain elements appropriatly. - * - * To date there is only a file version and a shared memory of these caching - * backends. Clients of thie API need not know where their data will go, in - * general there are several calls (marked A) that will work on the database - * as a whole. From those points you will go onto (B) where you can seek, create - * and remove records. - * Upon seeking or creating records you will have an active ap_cache_el. You may - * continue down into (C) section. - * - * A cache element has two distinct parts, the header (D) and the data (E). - * One of the uses of the header section will, in fact, be internal to the - * cache backends to manage expiration. For example, ap_cache modules may - * use the "Cache-Control" header entry for ap_cache_garbage_collect(). - * All data portions or headers may be used for any purpose, and are not - * actually used by the API, though some headers may have special meanings - * to certain backends. - */ - -/* ********************* - * Example client usage: - * - * ap_cache_handle_t *my_cache; - * ap_cache_el *element; - * apr_file_t *element_buff; - * - * ap_cache_create(&my_cache, "Cache of Farm Animals"); - * - * ap_cache_push(my_cache, "Pig", &element); - * ap_cache_el_header_add(element, "Sound", "Oink"); - * ap_cache_el_data(element, &element_buff); - * ap_bputs("I smell bacon!\n", element_buff); - * ap_cache_el_finalize(element); - * - * ap_cache_seek(my_cache", "Cow", &element); - * ap_cache_el_header_walk(my_cache, some_func, NULL, "Sound", NULL); - * .... - * - * ap_cache_close(my_cache); - * - * A client can do anything it wants to an "active" cache_el however it - * must guarantee that when it is done with the cache element it will - * be finalized. In this way an element in a cache can only be active one - * time (and any cache_seek for this element will fail), for this reason - * one shouldn't stay open for long ammounts of time. The client is also - * responsible for calling garbage_collect periodically to give the cache a - * chance to clean up for itself if this is the behaviour it wants. - */ - -/* Types used by clients of this interface */ -typedef struct ap_cache_handle_t ap_cache_handle_t; -typedef struct ap_cache_el -{ - ap_cache_handle_t *cache; - const char *name; -} ap_cache_el; - -/* A) Works on the cache database as a whole */ -/** - * This will initialize a cache_handle. This is the main entry point into the - * caching API, from this point active caching modules will be asked to fill - * in the cache_handle. - * @param Where to put the handle - * @param A descriptive unique string for your client, this description could - * used by caching modules to determine if the their backend is suitable - * for this client. - * @param Current server_rec, this will be used for retreiving configuration, - * and various other necesar server pieces. - * @deffunc apr_status_t ap_cache_init(ap_cache_handle_t **h, const char *desc, server_rec *r) - */ -apr_status_t ap_cache_init(ap_cache_handle_t **h, const char *desc, server_rec *r); - -/** - * This function will finalize a cache_handle, after this call the handle will - * no longer be usable. - * @param The handle to close - * @deffunc apr_status_t ap_cache_close(ap_cache_handle_t *) - */ -apr_status_t ap_cache_close(ap_cache_handle_t *); - -/** - * Force a garbage collection of the cache_handle, the client should call this periodically, - * the caching module will not do this on its own, however it isn't required to actually - * garbage collect anything, and may defer the call until later. - * @param The handle to force a garbage collection. - * @deffunc apr_status_t ap_cache_garbage_collect(ap_cache_handle_t *h) - */ -apr_status_t ap_cache_garbage_collect(ap_cache_handle_t *h); - -/* B) insertion and query into database */ -/** - * Seek for a given element in an open cache. This call will fail if the requested element - * is already "in use" by previous call to ap_cache_seek or ap_cache_create. - * When finished with the element you must call ap_cache_el_finalize immediatly so the - * element is no longer locked. - * @param The cache to search in. - * @param The name of the record you are looking for - * @param Where to put the cache element if a seek succeeds. - * @deffunc apr_status_t ap_cache_seek(ap_cache_handle_t *h, const char *name, ap_cache_el **) - */ -apr_status_t ap_cache_seek(ap_cache_handle_t *h, const char *name, ap_cache_el **); - -/** - * Create a new element inside of a cache, you must call this first function to put - * something new into a cache; after calling you may use the cache_el passed in as - * you would use one retrieved from an ap_cache_seek. The element will be locked after - * this call. - * When finished with the element you must call ap_cache_el_finalize immediatly so the - * element is no longer locked. - * @param The cache to create this element in. - * @param The name to give this new record - * @param Where to put this new element. - * @deffunc apr_status_t ap_cache_create(ap_cache_handle_t *h, const char *name, ap_cache_el **) - */ -apr_status_t ap_cache_create(ap_cache_handle_t *h, const char *name, ap_cache_el **); - -/** - * Remove a record from a cache. This call will fail if the requested element - * is already "in use" by previous call to ap_cache_seek or ap_cache_create. - * When finished with the element you must call ap_cache_el_finalize immediatly so the - * element is no longer locked. - * @param The cache to remove this record from. - * @param The name of the record to remove from the cache. - * @deffunc apr_status_t ap_cache_remove(ap_cache_handle_t *h, const char *name) - */ -apr_status_t ap_cache_remove(ap_cache_handle_t *h, const char *name); - -/* (C) Works on an actual element */ - -/* (D) Works on the header section */ -/** - * This will retrieve a header value from the element. - * @param A previously ap-cache_seek()'d or ap_cache_create()'d element. - * @param Header name looking to retrieve, must be null terminated. - * @param Where to put the value - * @deffunc apr_status_t ap_cache_el_header(ap_cache_el *el, const char *hdr, char **val) - */ -apr_status_t ap_cache_el_header(ap_cache_el *el, const char *hdr, char **val); - -/** - * Walk through all the headers for given values. This function is synonymous with - * ap_table_walk. - * @param The element to walk through. - * @param The callback function to use for each element. The paramaters for this function: - * 1) Client defined data, as passed in by the next paramater to ap-cache_el_header_walk - * 2) The name of current header that forced this callback. - * 3) The value of the current header. - * @param User defined data passed back to the callback as argument 1. - * @param NULL terminated list of headers to walk through. If the first value - * of this list is NULL then ALL element will be walked over. - * @deffunc apr_status_t ap_cache_el_header_walk(ap_cache_el *el, - * int (*comp)(void *, const char *, const char *), void *rec, ...); - */ -apr_status_t ap_cache_el_header_walk(ap_cache_el *el, - int (*comp)(void *, const char *, const char *), void *rec, ...); - -/** - * This will merge an existing apr_table_t into a cache_el's header section. - * @param The cache element to merge onto. - * @param The filled in apr_table_t to merge in. - * @deffunc apr_status_t ap_cache_el_header_merge(ap_cache_el *el, apr_table_t *tbl) - */ -apr_status_t ap_cache_el_header_merge(ap_cache_el *el, apr_table_t *tbl); - -/** - * This will set the current value of a header name to a given value. Using this function - * the same as first ap_cache_el_header_remove, and then ap-cache_el_header_add. - * @param The cache element to modify - * @param The name of the header to change - * @param The value to assign to the given name. - * @deffunc apr_status_t ap_cache_el_header_set(ap_cache_el *el, const char *hdrname, const char *hdrval) - */ -apr_status_t ap_cache_el_header_set(ap_cache_el *el, const char *hdrname, const char *hdrval); - -/** - * Each header may have more than one value, you may call this function repeatedly and it will - * continue adding values onto a header element. If you want to assign a single value to a - * header you must use ap_cache_el_header_set instead. - * @param The cache element to add to - * @param The name of the header to append values to. - * @param The value to append to the given header name. - * @deffunc apr_status_t ap_cache_el_header_add(ap_cache_el *el, const char *hdrname, const char *hdrval) - */ -apr_status_t ap_cache_el_header_add(ap_cache_el *el, const char *hdrname, const char *hdrval); - -/** - * This will remove all headers of a given name. - * @param The cache element to remove headers from - * @param The name of the header to remove. This will remove ALL values assigned to this - * header (via the ap_cache_el_header_add call). - * @deffunc apr_status_t ap_cache_el_header_remove(ap_cache_el *el, const char *hdr) - */ -apr_status_t ap_cache_el_header_remove(ap_cache_el *el, const char *hdr); - -/** - * This will clear out an entire header section. You may use this if you are intending - * to change the entire value of the header section of a cache element. - * @param The element to clear - * @deffunc apr_status_t ap_cache_el_header_clear(ap_cache_el *el) - */ -apr_status_t ap_cache_el_header_clear(ap_cache_el *el); - -/* (E) Works on the data section */ -/** - * Retrieve a apr_file_t for a given cache element, where this data goes is opaque to all - * clients of this API. You can do all operations on the apr_file_t and trust the underlying - * caching module will accept the data and put it in the appropriate place. - * @param The element to retrieve data - * @param Where to put the apr_file_t structure when it comes back. In some cases this - * will be a normal buff that will either write to a network, or disk - but - * you should not rely on it going anywhere in a caching module as the destination - * for all data is opaque. - * @deffunc apr_status_t ap_cache_el_data(ap_cache_el *el, apr_file_t **) - */ -apr_status_t ap_cache_el_data(ap_cache_el *el, apr_file_t **); - -/** - * Convenience function to put an existing apr_file_t into a cache_el's data section. This - * function will probably not be fully optimal - and will actually just pipe one apr_file_t - * to another. - * @param The element to append to - * @param An existing apr_file_t to append onto the ap_cache_el's stream of data. - * @deffunc apr_status_t ap_cache_el_data_append(ap_cache_el *el, apr_file_t *data) - */ -apr_status_t ap_cache_el_data_append(ap_cache_el *el, apr_file_t *data); - -/** - * Clear the data section of an existing cache_el. You may use this if you are - * intending to change the entire value of the data section of a cache element. - * @param The element to clear - * @deffunc apr_status_t ap_cache_el_data_clear(ap_cache_el *el) - */ -apr_status_t ap_cache_el_data_clear(ap_cache_el *el); - -/** - * This will complete an open element. When you are done working on a caching - * element you must call this so the object will be unlocked and all data will - * be finalized, in some cases that means certain data won't make it into the - * destination backend until this call is made. Each module may decide how much - * this function actually does but you MUST call this function immediatly after - * completing a cache record. - * @param The element to finalize, after calling this function the caching - * element is no longer valid and you must ap_cache_seek for it again if - * you want to make any further changes to it. - * @deffunc apr_status_t ap_cache_el_finalize(ap_cache_el *el) - */ -apr_status_t ap_cache_el_finalize(ap_cache_el *el); - -/* ****************************************************************************/ -/* ****************************************************************************/ -/* This section is internal entirely, but it is exposed because - * implementors of caching modules will need to use some of this. Clients - * of the library are NEVER to use this interface however, and should use - * the above accessors to the cache. - */ - -/* This is how a cache module can grab control. This will be fired once the - * ap_cache_init call is made, each paramater will coorespond to the paramaters - * passed into ap_cache_init. If your cache wants to reject a hook call return - * APR_ENOTIMPL from your hook and the next caching module will be tried. - */ -AP_DECLARE_HOOK(apr_status_t, cache_init, (ap_cache_handle_t **, const char *desc, server_rec *t)) - -/* These are various enum's passed into call back functions (as defined below) */ -typedef enum { AP_CACHE_SEEK, AP_CACHE_CREATE, AP_CACHE_CHANGE, AP_CACHE_REMOVE } ap_cache_query; -typedef enum { AP_CACHE_DATA, AP_CACHE_HEADER } ap_cache_part; - -/* These are the callback functions filled in by handler of the cache_init hook. - * function may be NULL and will in turn return APR_ENOTIMPL by any of the various - * calls in the API. - */ -typedef struct ap_cache_methods -{ - apr_status_t (*cache_close)(ap_cache_handle_t *h); - apr_status_t (*cache_garbage_coll)(ap_cache_handle_t *h); - apr_status_t (*cache_element)(ap_cache_handle_t *h, const char *name, ap_cache_el **, - ap_cache_query flag); - apr_status_t (*cache_el_header_walk)(ap_cache_el *el, - int (*comp)(void *, const char *, const char *), void *rec, va_list); - apr_status_t (*cache_el_hdr)(ap_cache_el *el, const char *name, const char *val, ap_cache_query flag); - apr_status_t (*cache_el_data)(ap_cache_el *el, apr_file_t **); - apr_status_t (*cache_el_reset)(ap_cache_el *, ap_cache_part flag); - apr_status_t (*cache_el_final)(ap_cache_el *el); -} ap_cache_methods; -/* This is declared here because modules need to fill this in, however - * clients of the library should NEVER use this - */ -struct ap_cache_handle_t -{ - apr_pool_t *pool; /* pool for alloc's */ - server_rec *server; /* access to configurations, used on init */ - ap_cache_methods meth; -}; - -#endif /* __AP_CACHE_H__ */ diff --git a/modules/proxy/proxy_connect.c b/modules/proxy/proxy_connect.c deleted file mode 100644 index 9df39ee328..0000000000 --- a/modules/proxy/proxy_connect.c +++ /dev/null @@ -1,302 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - * - * Portions of this software are based upon public domain software - * originally written at the National Center for Supercomputing Applications, - * University of Illinois, Urbana-Champaign. - */ - -/* CONNECT method for Apache proxy */ - -#include "mod_proxy.h" -#include "http_log.h" -#include "http_main.h" -#include "apr_strings.h" - -#ifdef HAVE_BSTRING_H -#include <bstring.h> /* for IRIX, FD_SET calls bzero() */ -#endif - -/* - * This handles Netscape CONNECT method secure proxy requests. - * A connection is opened to the specified host and data is - * passed through between the WWW site and the browser. - * - * This code is based on the INTERNET-DRAFT document - * "Tunneling SSL Through a WWW Proxy" currently at - * http://www.mcom.com/newsref/std/tunneling_ssl.html. - * - * If proxyhost and proxyport are set, we send a CONNECT to - * the specified proxy.. - * - * FIXME: this is bad, because it does its own socket I/O - * instead of using the I/O in buff.c. However, - * the I/O in buff.c blocks on reads, and because - * this function doesn't know how much data will - * be sent either way (or when) it can't use blocking - * I/O. This may be very implementation-specific - * (to Linux). Any suggestions? - * FIXME: this doesn't log the number of bytes sent, but - * that may be okay, since the data is supposed to - * be transparent. In fact, this doesn't log at all - * yet. 8^) - * FIXME: doesn't check any headers initally sent from the - * client. - * FIXME: should allow authentication, but hopefully the - * generic proxy authentication is good enough. - * FIXME: no check for r->assbackwards, whatever that is. - */ - -static int -allowed_port(proxy_server_conf *conf, int port) -{ - int i; - int *list = (int *) conf->allowed_connect_ports->elts; - - for(i = 0; i < conf->allowed_connect_ports->nelts; i++) { - if(port == list[i]) - return 1; - } - return 0; -} - - -int ap_proxy_connect_handler(request_rec *r, char *url, - const char *proxyhost, int proxyport) -{ - struct in_addr destaddr; - const char *host; - char *p; - int port; - apr_socket_t *sock; - char buffer[HUGE_STRING_LEN]; - int nbytes, i; - - apr_socket_t *client_sock = NULL; - apr_pollfd_t *pollfd; - apr_int32_t pollcnt; - apr_int16_t pollevent; - - void *sconf = r->server->module_config; - proxy_server_conf *conf = - (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); - struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts; - - /* Break the URL into host:port pairs */ - host = url; - p = strchr(url, ':'); - if (p == NULL) - port = DEFAULT_HTTPS_PORT; - else { - port = atoi(p + 1); - *p = '\0'; - } - -/* check if ProxyBlock directive on this host */ - destaddr.s_addr = ap_inet_addr(host); - for (i = 0; i < conf->noproxies->nelts; i++) { - if ((npent[i].name != NULL && ap_strstr_c(host, npent[i].name) != NULL) - || destaddr.s_addr == npent[i].addr.s_addr || npent[i].name[0] == '*') - return ap_proxyerror(r, HTTP_FORBIDDEN, - "Connect to remote machine blocked"); - } - - /* Check if it is an allowed port */ - if (conf->allowed_connect_ports->nelts == 0) { - /* Default setting if not overridden by AllowCONNECT */ - switch (port) { - case DEFAULT_HTTPS_PORT: - case DEFAULT_SNEWS_PORT: - break; - default: - return HTTP_FORBIDDEN; - } - } else if(!allowed_port(conf, port)) - return HTTP_FORBIDDEN; - - if (proxyhost) { - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "CONNECT to remote proxy %s on port %d", proxyhost, proxyport); - } - else { - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "CONNECT to %s on port %d", host, port); - } - - if ((apr_socket_create(&sock, APR_INET, SOCK_STREAM, r->pool)) != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: error creating socket"); - return HTTP_INTERNAL_SERVER_ERROR; - } - - if (ap_proxy_doconnect(sock, (char *)(proxyhost ? proxyhost : host), - proxyport ? proxyport : port, r) != APR_SUCCESS) { - apr_socket_close(sock); - return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, - apr_pstrcat(r->pool, "Could not connect to remote machine:<br>", - proxyhost, NULL)); - } - - /* If we are connecting through a remote proxy, we need to pass - * the CONNECT request on to it. - */ - if (proxyport) { - /* FIXME: We should not be calling write() directly, but we currently - * have no alternative. Error checking ignored. Also, we force - * a HTTP/1.0 request to keep things simple. - */ - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "Sending the CONNECT request to the remote proxy"); - nbytes = apr_snprintf(buffer, sizeof(buffer), - "CONNECT %s HTTP/1.0" CRLF, r->uri); - apr_send(sock, buffer, &nbytes); - nbytes = apr_snprintf(buffer, sizeof(buffer), - "Proxy-agent: %s" CRLF CRLF, ap_get_server_version()); - apr_send(sock, buffer, &nbytes); - } - else { - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "Returning 200 OK Status"); - ap_rvputs(r, "HTTP/1.0 200 Connection established" CRLF, NULL); - ap_rvputs(r, "Proxy-agent: ", ap_get_server_version(), CRLF CRLF, NULL); - ap_rflush(r); - } - - if(apr_poll_setup(&pollfd, 2, r->pool) != APR_SUCCESS) - { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: error apr_poll_setup()"); - return HTTP_INTERNAL_SERVER_ERROR; - } - - /* Add client side to the poll */ -#if 0 -/* FIXME !!!! SDM !!! If someone can figure out how to turn a conn_rec into a ap_sock_t or something - this code might work. However if we must we can change r->connection->client to non-blocking and - just see if a recv gives us anything and do the same to sock (server) side, I'll leave this as TBD so - one can decide the best path to take -*/ - if(apr_os_sock_put(&client_sock, - (apr_os_sock_t *)get_socket(r->connection->client), - r->pool) != APR_SUCCESS) - { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: error creating client apr_socket_t"); - return HTTP_INTERNAL_SERVER_ERROR; - } - apr_poll_socket_add(pollfd, client_sock, APR_POLLIN); -#endif - - /* Add the server side to the poll */ - apr_poll_socket_add(pollfd, sock, APR_POLLIN); - - while (1) { /* Infinite loop until error (one side closes the connection) */ - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, "Going to sleep (poll)"); - if(apr_poll(pollfd, &pollcnt, -1) != APR_SUCCESS) - { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "proxy: error apr_poll()"); - return HTTP_INTERNAL_SERVER_ERROR; - } - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "Woke from select(), i=%d", pollcnt); - - if (pollcnt) { - apr_poll_revents_get(&pollevent, sock, pollfd); - if (pollevent & APR_POLLIN) { - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "sock was set"); - nbytes = HUGE_STRING_LEN; - if(apr_recv(sock, buffer, &nbytes) == APR_SUCCESS) { - int o = 0; - while(nbytes) - { - i = nbytes; - apr_send(r->connection->client_socket, buffer + o, &i); - o += i; - nbytes -= i; - } - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, "Wrote %d bytes to client", nbytes); - } - else - break; - } - - apr_poll_revents_get(&pollevent, client_sock, pollfd); - if (pollevent & APR_POLLIN) { - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "client was set"); - nbytes = HUGE_STRING_LEN; - if(apr_recv(r->connection->client_socket, buffer, &nbytes) == APR_SUCCESS) { - int o = 0; - while(nbytes) - { - i = nbytes; - apr_send(sock, buffer + o, &i); - o += i; - nbytes -= i; - } - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, - NULL, "Wrote %d bytes to server", nbytes); - } - else - break; - } - } - else - break; - } - - apr_socket_close(sock); - - return OK; -} diff --git a/modules/proxy/proxy_ftp.c b/modules/proxy/proxy_ftp.c deleted file mode 100644 index 096d836d9e..0000000000 --- a/modules/proxy/proxy_ftp.c +++ /dev/null @@ -1,1270 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - * - * Portions of this software are based upon public domain software - * originally written at the National Center for Supercomputing Applications, - * University of Illinois, Urbana-Champaign. - */ - -/* FTP routines for Apache proxy */ - -#include "mod_proxy.h" -#include "http_main.h" -#include "http_log.h" -#include "http_core.h" -#include "apr_strings.h" - -#define AUTODETECT_PWD - -static void skiplf(BUFF *foo) -{ - char c; - do - { - c = ap_bgetc(foo); - } while(c != '\n'); -} - -/* - * Decodes a '%' escaped string, and returns the number of characters - */ -static int decodeenc(char *x) -{ - int i, j, ch; - - if (x[0] == '\0') - return 0; /* special case for no characters */ - for (i = 0, j = 0; x[i] != '\0'; i++, j++) { -/* decode it if not already done */ - ch = x[i]; - if (ch == '%' && ap_isxdigit(x[i + 1]) && ap_isxdigit(x[i + 2])) { - ch = ap_proxy_hex2c(&x[i + 1]); - i += 2; - } - x[j] = ch; - } - x[j] = '\0'; - return j; -} - -/* - * checks an encoded ftp string for bad characters, namely, CR, LF or - * non-ascii character - */ -static int ftp_check_string(const char *x) -{ - int i, ch = 0; - - for (i = 0; x[i] != '\0'; i++) { - ch = x[i]; - if (ch == '%' && ap_isxdigit(x[i + 1]) && ap_isxdigit(x[i + 2])) { - ch = ap_proxy_hex2c(&x[i + 1]); - i += 2; - } -#if !APR_CHARSET_EBCDIC - if (ch == '\015' || ch == '\012' || (ch & 0x80)) -#else /*APR_CHARSET_EBCDIC*/ - if (ch == '\r' || ch == '\n' || (os_toascii[ch] & 0x80)) -#endif /*APR_CHARSET_EBCDIC*/ - return 0; - } - return 1; -} - -/* - * Canonicalise ftp URLs. - */ -int ap_proxy_ftp_canon(request_rec *r, char *url) -{ - char *user, *password, *host, *path, *parms, *strp, sport[7]; - apr_pool_t *p = r->pool; - const char *err; - int port; - - port = DEFAULT_FTP_PORT; - err = ap_proxy_canon_netloc(p, &url, &user, &password, &host, &port); - if (err) - return HTTP_BAD_REQUEST; - if (user != NULL && !ftp_check_string(user)) - return HTTP_BAD_REQUEST; - if (password != NULL && !ftp_check_string(password)) - return HTTP_BAD_REQUEST; - -/* now parse path/parameters args, according to rfc1738 */ -/* N.B. if this isn't a true proxy request, then the URL path - * (but not query args) has already been decoded. - * This gives rise to the problem of a ; being decoded into the - * path. - */ - strp = strchr(url, ';'); - if (strp != NULL) { - *(strp++) = '\0'; - parms = ap_proxy_canonenc(p, strp, strlen(strp), enc_parm, - r->proxyreq); - if (parms == NULL) - return HTTP_BAD_REQUEST; - } - else - parms = ""; - - path = ap_proxy_canonenc(p, url, strlen(url), enc_path, r->proxyreq); - if (path == NULL) - return HTTP_BAD_REQUEST; - if (!ftp_check_string(path)) - return HTTP_BAD_REQUEST; - - if (r->proxyreq && r->args != NULL) { - if (strp != NULL) { - strp = ap_proxy_canonenc(p, r->args, strlen(r->args), enc_parm, 1); - if (strp == NULL) - return HTTP_BAD_REQUEST; - parms = apr_pstrcat(p, parms, "?", strp, NULL); - } - else { - strp = ap_proxy_canonenc(p, r->args, strlen(r->args), enc_fpath, 1); - if (strp == NULL) - return HTTP_BAD_REQUEST; - path = apr_pstrcat(p, path, "?", strp, NULL); - } - r->args = NULL; - } - -/* now, rebuild URL */ - - if (port != DEFAULT_FTP_PORT) - apr_snprintf(sport, sizeof(sport), ":%d", port); - else - sport[0] = '\0'; - - r->filename = apr_pstrcat(p, "proxy:ftp://", (user != NULL) ? user : "", - (password != NULL) ? ":" : "", - (password != NULL) ? password : "", - (user != NULL) ? "@" : "", host, sport, "/", path, - (parms[0] != '\0') ? ";" : "", parms, NULL); - - return OK; -} - -/* - * Returns the ftp status code; - * or -1 on I/O error, 0 on data error - */ -static int ftp_getrc(BUFF *f) -{ - int len, status; - char linebuff[100], buff[5]; - - len = ap_bgets(linebuff, sizeof linebuff, f); - if (len == -1) - return -1; -/* check format */ - if (len < 5 || !apr_isdigit(linebuff[0]) || !apr_isdigit(linebuff[1]) || - !apr_isdigit(linebuff[2]) || (linebuff[3] != ' ' && linebuff[3] != '-')) - status = 0; - else - status = 100 * linebuff[0] + 10 * linebuff[1] + linebuff[2] - 111 * '0'; - - if (linebuff[len - 1] != '\n') { - skiplf(f); - } - -/* skip continuation lines */ - if (linebuff[3] == '-') { - memcpy(buff, linebuff, 3); - buff[3] = ' '; - do { - len = ap_bgets(linebuff, sizeof linebuff, f); - if (len == -1) - return -1; - if (linebuff[len - 1] != '\n') { - skiplf(f); - } - } while (memcmp(linebuff, buff, 4) != 0); - } - - return status; -} - -/* - * Like ftp_getrc but returns both the ftp status code and - * remembers the response message in the supplied buffer - */ -static int ftp_getrc_msg(BUFF *f, char *msgbuf, int msglen) -{ - int len, status; - char linebuff[100], buff[5]; - char *mb = msgbuf, - *me = &msgbuf[msglen]; - - len = ap_bgets(linebuff, sizeof linebuff, f); - if (len == -1) - return -1; - if (len < 5 || !apr_isdigit(linebuff[0]) || !apr_isdigit(linebuff[1]) || - !apr_isdigit(linebuff[2]) || (linebuff[3] != ' ' && linebuff[3] != '-')) - status = 0; - else - status = 100 * linebuff[0] + 10 * linebuff[1] + linebuff[2] - 111 * '0'; - - mb = apr_cpystrn(mb, linebuff+4, me - mb); - - if (linebuff[len - 1] != '\n') - skiplf(f); - - if (linebuff[3] == '-') { - memcpy(buff, linebuff, 3); - buff[3] = ' '; - do { - len = ap_bgets(linebuff, sizeof linebuff, f); - if (len == -1) - return -1; - if (linebuff[len - 1] != '\n') { - skiplf(f); - } - mb = apr_cpystrn(mb, linebuff+4, me - mb); - } while (memcmp(linebuff, buff, 4) != 0); - } - return status; -} - -static long int send_dir(BUFF *f, request_rec *r, ap_cache_el *c, char *cwd) -{ - char buf[IOBUFSIZE]; - char buf2[IOBUFSIZE]; - char *filename; - int searchidx = 0; - char *searchptr = NULL; - int firstfile = 1; - apr_ssize_t cntr; - unsigned long total_bytes_sent = 0; - register int n, o, w; - conn_rec *con = r->connection; - char *dir, *path, *reldir, *site; - apr_file_t *cachefp = NULL; - - if(c) ap_cache_el_data(c, &cachefp); - - /* Save "scheme://site" prefix without password */ - site = ap_unparse_uri_components(r->pool, &r->parsed_uri, UNP_OMITPASSWORD|UNP_OMITPATHINFO); - /* ... and path without query args */ - path = ap_unparse_uri_components(r->pool, &r->parsed_uri, UNP_OMITSITEPART|UNP_OMITQUERY); - (void)decodeenc(path); - - /* Copy path, strip (all except the last) trailing slashes */ - path = dir = apr_pstrcat(r->pool, path, "/", NULL); - while ((n = strlen(path)) > 1 && path[n-1] == '/' && path[n-2] == '/') - path[n-1] = '\0'; - - /* print "ftp://host/" */ - n = apr_snprintf(buf, sizeof(buf), DOCTYPE_HTML_3_2 - "<HTML><HEAD><TITLE>%s%s</TITLE>\n" - "<BASE HREF=\"%s%s\"></HEAD>\n" - "<BODY><H2>Directory of " - "<A HREF=\"/\">%s</A>/", - site, path, site, path, site); - total_bytes_sent += ap_proxy_bputs2(buf, con->client_socket, c); - - while ((dir = strchr(dir+1, '/')) != NULL) - { - *dir = '\0'; - if ((reldir = strrchr(path+1, '/'))==NULL) - reldir = path+1; - else - ++reldir; - /* print "path/" component */ - apr_snprintf(buf, sizeof(buf), "<A HREF=\"/%s/\">%s</A>/", path+1, reldir); - total_bytes_sent += ap_proxy_bputs2(buf, con->client_socket, c); - *dir = '/'; - } - /* If the caller has determined the current directory, and it differs */ - /* from what the client requested, then show the real name */ - if (cwd == NULL || strncmp (cwd, path, strlen(cwd)) == 0) { - apr_snprintf(buf, sizeof(buf), "</H2>\n<HR><PRE>"); - } else { - apr_snprintf(buf, sizeof(buf), "</H2>\n(%s)\n<HR><PRE>", cwd); - } - total_bytes_sent += ap_proxy_bputs2(buf, con->client_socket, c); - - while (!con->aborted) { - n = ap_bgets(buf, sizeof buf, f); - if (n == -1) { /* input error */ - if (c != NULL) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: error reading from cache"); - ap_proxy_cache_error(&c); - } - break; - } - if (n == 0) - break; /* EOF */ - if (buf[0] == 'l' && (filename=strstr(buf, " -> ")) != NULL) { - char *link_ptr = filename; - - do { - filename--; - } while (filename[0] != ' '); - *(filename++) = '\0'; - *(link_ptr++) = '\0'; - if ((n = strlen(link_ptr)) > 1 && link_ptr[n - 1] == '\n') - link_ptr[n - 1] = '\0'; - apr_snprintf(buf2, sizeof(buf2), "%s <A HREF=\"%s\">%s %s</A>\n", buf, filename, filename, link_ptr); - apr_cpystrn(buf, buf2, sizeof(buf)); - n = strlen(buf); - } - else if (buf[0] == 'd' || buf[0] == '-' || buf[0] == 'l' || apr_isdigit(buf[0])) { - if (apr_isdigit(buf[0])) { /* handle DOS dir */ - searchptr = strchr(buf, '<'); - if (searchptr != NULL) - *searchptr = '['; - searchptr = strchr(buf, '>'); - if (searchptr != NULL) - *searchptr = ']'; - } - - filename = strrchr(buf, ' '); - *(filename++) = 0; - filename[strlen(filename) - 1] = 0; - - /* handle filenames with spaces in 'em */ - if (!strcmp(filename, ".") || !strcmp(filename, "..") || firstfile) { - firstfile = 0; - searchidx = filename - buf; - } - else if (searchidx != 0 && buf[searchidx] != 0) { - *(--filename) = ' '; - buf[searchidx - 1] = 0; - filename = &buf[searchidx]; - } - - /* Special handling for '.' and '..' */ - if (!strcmp(filename, ".") || !strcmp(filename, "..") || buf[0] == 'd') { - apr_snprintf(buf2, sizeof(buf2), "%s <A HREF=\"%s/\">%s</A>\n", - buf, filename, filename); - } - else { - apr_snprintf(buf2, sizeof(buf2), "%s <A HREF=\"%s\">%s</A>\n", buf, filename, filename); - } - apr_cpystrn(buf, buf2, sizeof(buf)); - n = strlen(buf); - } - - o = 0; - total_bytes_sent += n; - - cntr = n; - if (cachefp && apr_file_write(cachefp, buf, &cntr) != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: error writing to cache"); - ap_proxy_cache_error(&c); - cachefp = NULL; - } - - while (n && !r->connection->aborted) { - cntr = n; - w = apr_send(con->client_socket, &buf[o], &cntr); - if (w <= 0) - break; - n -= w; - o += w; - } - } - - total_bytes_sent += ap_proxy_bputs2("</PRE><HR>\n", con->client_socket, c); - total_bytes_sent += ap_proxy_bputs2(ap_psignature("", r), con->client_socket, c); - total_bytes_sent += ap_proxy_bputs2("</BODY></HTML>\n", con->client_socket, c); - -/* Flushing the actual socket doesn't make much sense, because we don't - * buffer it yet. - ap_flush(con->client); -*/ - return total_bytes_sent; -} - -/* Common routine for failed authorization (i.e., missing or wrong password) - * to an ftp service. This causes most browsers to retry the request - * with username and password (which was presumably queried from the user) - * supplied in the Authorization: header. - * Note that we "invent" a realm name which consists of the - * ftp://user@host part of the reqest (sans password -if supplied but invalid-) - */ -static int ftp_unauthorized (request_rec *r, int log_it) -{ - r->proxyreq = 0; - /* Log failed requests if they supplied a password - * (log username/password guessing attempts) - */ - if (log_it) - ap_log_rerror(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, 0, r, - "proxy: missing or failed auth to %s", - ap_unparse_uri_components(r->pool, - &r->parsed_uri, UNP_OMITPATHINFO)); - - apr_table_setn(r->err_headers_out, "WWW-Authenticate", - apr_pstrcat(r->pool, "Basic realm=\"", - ap_unparse_uri_components(r->pool, &r->parsed_uri, - UNP_OMITPASSWORD|UNP_OMITPATHINFO), - "\"", NULL)); - - return HTTP_UNAUTHORIZED; -} - -/* - * Handles direct access of ftp:// URLs - * Original (Non-PASV) version from - * Troy Morrison <spiffnet@zoom.com> - * PASV added by Chuck - */ -int ap_proxy_ftp_handler(request_rec *r, ap_cache_el *c, char *url) -{ - char *host, *path, *strp, *parms; - char *cwd = NULL; - char *user = NULL; -/* char *account = NULL; how to supply an account in a URL? */ - const char *password = NULL; - apr_socket_t *sock, *dsock, *inc; - int port, i, j, len, rc, nocache = 0; - apr_socket_t *csd; - struct in_addr destaddr; - apr_table_t *resp_hdrs; - BUFF *f; - BUFF *data = NULL; - apr_file_t *cachefp = NULL; - apr_pool_t *p = r->pool; - int one = 1; - const long int zero = 0L; - - void *sconf = r->server->module_config; - proxy_server_conf *conf = - (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); - struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts; - struct nocache_entry *ncent = (struct nocache_entry *) conf->nocaches->elts; - apr_sockaddr_t *localsa; - -/* stuff for PASV mode */ - unsigned int presult, h0, h1, h2, h3, p0, p1; - unsigned short pport; - int pasvmode = 0; - char pasv[64]; - char *pstr, dates[AP_RFC822_DATE_LEN]; - - char *npaddr; - apr_port_t npport; - -/* stuff for responses */ - char resp[MAX_STRING_LEN]; - char *size = NULL; - -/* we only support GET and HEAD */ - - if (r->method_number != M_GET) - return HTTP_NOT_IMPLEMENTED; - -/* We break the URL into host, port, path-search */ - - host = r->parsed_uri.hostname; - port = (r->parsed_uri.port != 0) - ? r->parsed_uri.port - : ap_default_port_for_request(r); - path = apr_pstrdup(p, r->parsed_uri.path); - path = (path != NULL && path[0] != '\0') ? &path[1] : ""; - - /* The "Authorization:" header must be checked first. - * We allow the user to "override" the URL-coded user [ & password ] - * in the Browsers' User&Password Dialog. - * NOTE that this is only marginally more secure than having the - * password travel in plain as part of the URL, because Basic Auth - * simply uuencodes the plain text password. - * But chances are still smaller that the URL is logged regularly. - */ - if ((password = apr_table_get(r->headers_in, "Authorization")) != NULL - && strcasecmp(ap_getword(r->pool, &password, ' '), "Basic") == 0 - && (password = ap_pbase64decode(r->pool, password))[0] != ':') { - /* Note that this allocation has to be made from r->connection->pool - * because it has the lifetime of the connection. The other allocations - * are temporary and can be tossed away any time. - */ - user = ap_getword_nulls (r->pool, &password, ':'); - r->ap_auth_type = "Basic"; - r->user = r->parsed_uri.user = user; - nocache = 1; /* This resource only accessible with username/password */ - } - else if ((user = r->parsed_uri.user) != NULL) { - user = apr_pstrdup(p, user); - decodeenc(user); - if ((password = r->parsed_uri.password) != NULL) { - char *tmp = apr_pstrdup(p, password); - decodeenc(tmp); - password = tmp; - } - nocache = 1; /* This resource only accessible with username/password */ - } - else { - user = "anonymous"; - password = "apache_proxy@"; - } - -/* check if ProxyBlock directive on this host */ - destaddr.s_addr = ap_inet_addr(host); - for (i = 0; i < conf->noproxies->nelts; i++) { - if ((npent[i].name != NULL && ap_strstr_c(host, npent[i].name) != NULL) - || destaddr.s_addr == npent[i].addr.s_addr || npent[i].name[0] == '*') - return ap_proxyerror(r, HTTP_FORBIDDEN, - "Connect to remote machine blocked"); - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: connect to %s:%d", host, port); - - parms = strchr(path, ';'); - if (parms != NULL) - *(parms++) = '\0'; - - if ((apr_socket_create(&sock, APR_INET, SOCK_STREAM, r->pool)) != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: error creating socket"); - return HTTP_INTERNAL_SERVER_ERROR; - } - -#if !defined(TPF) && !defined(BEOS) - if (conf->recv_buffer_size > 0 - && apr_setsocketopt(sock, APR_SO_RCVBUF, - conf->recv_buffer_size)) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default"); - } -#endif - - if (apr_setsocketopt(sock, APR_SO_REUSEADDR, one)) { -#ifndef _OSD_POSIX /* BS2000 has this option "always on" */ - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: error setting reuseaddr option: setsockopt(SO_REUSEADDR)"); - apr_socket_close(sock); - return HTTP_INTERNAL_SERVER_ERROR; -#endif /*_OSD_POSIX*/ - } - - if (ap_proxy_doconnect(sock, host, port, r) != APR_SUCCESS) { - apr_socket_close(sock); - return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_pstrcat(r->pool, - "Could not connect to remote machine: ", - host, NULL)); - } - - f = ap_bcreate(p, B_RDWR); - ap_bpush_socket(f, sock); -/* shouldn't we implement telnet control options here? */ - -#if APR_CHARSET_EBCDIC - ap_bsetflag(f, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 1); -#endif /*APR_CHARSET_EBCDIC*/ - -/* possible results: */ - /* 120 Service ready in nnn minutes. */ - /* 220 Service ready for new user. */ - /* 421 Service not available, closing control connection. */ - i = ftp_getrc_msg(f, resp, sizeof resp); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: returned status %d", i); - if (i == -1) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } -#if 0 - if (i == 120) { - /* RFC2068 states: - * 14.38 Retry-After - * - * The Retry-After response-header field can be used with a 503 (Service - * Unavailable) response to indicate how long the service is expected to - * be unavailable to the requesting client. The value of this field can - * be either an HTTP-date or an integer number of seconds (in decimal) - * after the time of the response. - * Retry-After = "Retry-After" ":" ( HTTP-date | delta-seconds ) - */ - ap_set_header("Retry-After", apr_psprintf(p, "%u", 60*wait_mins); - return ap_proxyerror(r, HTTP_SERVICE_UNAVAILABLE, resp); - } -#endif - if (i != 220) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, resp); - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: connected."); - - ap_bvputs(f, "USER ", user, CRLF, NULL); - ap_bflush(f); /* capture any errors */ - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: USER %s", user); - -/* possible results; 230, 331, 332, 421, 500, 501, 530 */ -/* states: 1 - error, 2 - success; 3 - send password, 4,5 fail */ - /* 230 User logged in, proceed. */ - /* 331 User name okay, need password. */ - /* 332 Need account for login. */ - /* 421 Service not available, closing control connection. */ - /* 500 Syntax error, command unrecognized. */ - /* (This may include errors such as command line too long.) */ - /* 501 Syntax error in parameters or arguments. */ - /* 530 Not logged in. */ - i = ftp_getrc(f); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: returned status %d", i); - if (i == -1) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - if (i == 530) { - return ftp_unauthorized (r, 1); /* log it: user name guessing attempt? */ - } - if (i != 230 && i != 331) { - return HTTP_BAD_GATEWAY; - } - - if (i == 331) { /* send password */ - if (password == NULL) { - return ftp_unauthorized (r, 0); - } - ap_bvputs(f, "PASS ", password, CRLF, NULL); - ap_bflush(f); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: PASS %s", password); -/* possible results 202, 230, 332, 421, 500, 501, 503, 530 */ - /* 230 User logged in, proceed. */ - /* 332 Need account for login. */ - /* 421 Service not available, closing control connection. */ - /* 500 Syntax error, command unrecognized. */ - /* 501 Syntax error in parameters or arguments. */ - /* 503 Bad sequence of commands. */ - /* 530 Not logged in. */ - i = ftp_getrc(f); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: returned status %d", i); - if (i == -1) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - if (i == 332) { - return ap_proxyerror(r, HTTP_UNAUTHORIZED, - "Need account for login"); - } - /* @@@ questionable -- we might as well return a 403 Forbidden here */ - if (i == 530) { - return ftp_unauthorized (r, 1); /* log it: passwd guessing attempt? */ - } - if (i != 230 && i != 202) { - return HTTP_BAD_GATEWAY; - } - } - -/* set the directory (walk directory component by component): - * this is what we must do if we don't know the OS type of the remote - * machine - */ - for (;;) { - strp = strchr(path, '/'); - if (strp == NULL) - break; - *strp = '\0'; - - len = decodeenc(path); - ap_bvputs(f, "CWD ", path, CRLF, NULL); - ap_bflush(f); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: CWD %s", path); - *strp = '/'; -/* responses: 250, 421, 500, 501, 502, 530, 550 */ - /* 250 Requested file action okay, completed. */ - /* 421 Service not available, closing control connection. */ - /* 500 Syntax error, command unrecognized. */ - /* 501 Syntax error in parameters or arguments. */ - /* 502 Command not implemented. */ - /* 530 Not logged in. */ - /* 550 Requested action not taken. */ - i = ftp_getrc(f); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: returned status %d", i); - if (i == -1) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - if (i == 550) { - return HTTP_NOT_FOUND; - } - if (i != 250) { - return HTTP_BAD_GATEWAY; - } - - path = strp + 1; - } - - if (parms != NULL && strncmp(parms, "type=", 5) == 0) { - parms += 5; - if ((parms[0] != 'd' && parms[0] != 'a' && parms[0] != 'i') || - parms[1] != '\0') - parms = ""; - } - else - parms = ""; - - /* changed to make binary transfers the default */ - - if (parms[0] != 'a') { - /* set type to image */ - /* TM - Added CRLF to the end of TYPE I, otherwise it hangs the - connection */ - ap_bputs("TYPE I" CRLF, f); - ap_bflush(f); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: TYPE I"); -/* responses: 200, 421, 500, 501, 504, 530 */ - /* 200 Command okay. */ - /* 421 Service not available, closing control connection. */ - /* 500 Syntax error, command unrecognized. */ - /* 501 Syntax error in parameters or arguments. */ - /* 504 Command not implemented for that parameter. */ - /* 530 Not logged in. */ - i = ftp_getrc(f); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: returned status %d", i); - if (i == -1) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - if (i != 200 && i != 504) { - return HTTP_BAD_GATEWAY; - } -/* Allow not implemented */ - if (i == 504) - parms[0] = '\0'; - } - -/* try to set up PASV data connection first */ - if ((apr_socket_create(&dsock, APR_INET, SOCK_STREAM, r->pool)) != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: error creating PASV socket"); - ap_bclose(f); - return HTTP_INTERNAL_SERVER_ERROR; - } - -#if !defined (TPF) && !defined(BEOS) - if (conf->recv_buffer_size > 0 && apr_setsocketopt(dsock, APR_SO_RCVBUF, - conf->recv_buffer_size)) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default"); - } -#endif - - ap_bputs("PASV" CRLF, f); - ap_bflush(f); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: PASV command issued"); -/* possible results: 227, 421, 500, 501, 502, 530 */ - /* 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). */ - /* 421 Service not available, closing control connection. */ - /* 500 Syntax error, command unrecognized. */ - /* 501 Syntax error in parameters or arguments. */ - /* 502 Command not implemented. */ - /* 530 Not logged in. */ - i = ap_bgets(pasv, sizeof(pasv), f); - if (i == -1) { - ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r, - "PASV: control connection is toast"); - apr_socket_close(dsock); - ap_bclose(f); - return HTTP_INTERNAL_SERVER_ERROR; - } - else { - pasv[i - 1] = '\0'; - pstr = strtok(pasv, " "); /* separate result code */ - if (pstr != NULL) { - presult = atoi(pstr); - if (*(pstr + strlen(pstr) + 1) == '=') - pstr += strlen(pstr) + 2; - else - { - pstr = strtok(NULL, "("); /* separate address & port params */ - if (pstr != NULL) - pstr = strtok(NULL, ")"); - } - } - else - presult = atoi(pasv); - - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: returned status %d", presult); - - if (presult == 227 && pstr != NULL && (sscanf(pstr, - "%d,%d,%d,%d,%d,%d", &h3, &h2, &h1, &h0, &p1, &p0) == 6)) { - /* pardon the parens, but it makes gcc happy */ - destaddr.s_addr = htonl((((((h3 << 8) + h2) << 8) + h1) << 8) + h0); - pport = (p1 << 8) + p0; - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: contacting host %d.%d.%d.%d:%d", - h3, h2, h1, h0, pport); -/* scary */ - if (ap_proxy_doconnect(dsock, inet_ntoa(destaddr), pport, r) == APR_SUCCESS) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - apr_pstrcat(r->pool, - "Could not connect to remote machine: ", - inet_ntoa(destaddr), NULL)); - } - else { - pasvmode = 1; - } - } - else - apr_socket_close(dsock); /* and try the regular way */ - } - - if (!pasvmode) { /* set up data connection */ - if ((apr_socket_create(&dsock, APR_INET, SOCK_STREAM, r->pool)) != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: error creating socket"); - ap_bclose(f); - return HTTP_INTERNAL_SERVER_ERROR; - } - apr_socket_addr_get(&localsa, APR_LOCAL, sock); - apr_sockaddr_port_get(&npport, localsa); - apr_sockaddr_ip_get(&npaddr, localsa); - - if (apr_setsocketopt(dsock, APR_SO_REUSEADDR, one) != APR_SUCCESS) { -#ifndef _OSD_POSIX /* BS2000 has this option "always on" */ - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: error setting reuseaddr option"); - apr_socket_close(dsock); - ap_bclose(f); - return HTTP_INTERNAL_SERVER_ERROR; -#endif /*_OSD_POSIX*/ - } - - if (apr_sockaddr_info_get(&localsa, npaddr, APR_INET, npport, 0, r->pool) - != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: error creating local socket address"); - ap_bclose(f); - return HTTP_INTERNAL_SERVER_ERROR; - } - - if (apr_bind(dsock, localsa) != APR_SUCCESS) { - char buff[22]; - - apr_snprintf(buff, sizeof(buff), "%s:%d", npaddr, npport); - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: error binding to ftp data socket %s", buff); - ap_bclose(f); - apr_socket_close(dsock); - return HTTP_INTERNAL_SERVER_ERROR; - } - apr_listen(dsock, 2); /* only need a short queue */ - } - -/* set request; "path" holds last path component */ - len = decodeenc(path); - - /* TM - if len == 0 then it must be a directory (you can't RETR nothing) */ - - if (len == 0) { - parms = "d"; - } - else { - ap_bvputs(f, "SIZE ", path, CRLF, NULL); - ap_bflush(f); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: SIZE %s", path); - i = ftp_getrc_msg(f, resp, sizeof resp); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: returned status %d with response %s", i, resp); - if (i != 500) { /* Size command not recognized */ - if (i == 550) { /* Not a regular file */ - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: SIZE shows this is a directory"); - parms = "d"; - ap_bvputs(f, "CWD ", path, CRLF, NULL); - ap_bflush(f); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: CWD %s", path); - i = ftp_getrc(f); - /* possible results: 250, 421, 500, 501, 502, 530, 550 */ - /* 250 Requested file action okay, completed. */ - /* 421 Service not available, closing control connection. */ - /* 500 Syntax error, command unrecognized. */ - /* 501 Syntax error in parameters or arguments. */ - /* 502 Command not implemented. */ - /* 530 Not logged in. */ - /* 550 Requested action not taken. */ - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: returned status %d", i); - if (i == -1) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - if (i == 550) { - return HTTP_NOT_FOUND; - } - if (i != 250) { - return HTTP_BAD_GATEWAY; - } - path = ""; - len = 0; - } - else if (i == 213) { /* Size command ok */ - for (j = 0; j < sizeof resp && apr_isdigit(resp[j]); j++) - ; - resp[j] = '\0'; - if (resp[0] != '\0') - size = apr_pstrdup(p, resp); - } - } - } - -#ifdef AUTODETECT_PWD - ap_bvputs(f, "PWD", CRLF, NULL); - ap_bflush(f); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: PWD"); -/* responses: 257, 500, 501, 502, 421, 550 */ - /* 257 "<directory-name>" <commentary> */ - /* 421 Service not available, closing control connection. */ - /* 500 Syntax error, command unrecognized. */ - /* 501 Syntax error in parameters or arguments. */ - /* 502 Command not implemented. */ - /* 550 Requested action not taken. */ - i = ftp_getrc_msg(f, resp, sizeof resp); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: PWD returned status %d", i); - if (i == -1 || i == 421) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - if (i == 550) { - return HTTP_NOT_FOUND; - } - if (i == 257) { - const char *dirp = resp; - cwd = ap_getword_conf(r->pool, &dirp); - } -#endif /*AUTODETECT_PWD*/ - - if (parms[0] == 'd') { - if (len != 0) - ap_bvputs(f, "LIST ", path, CRLF, NULL); - else - ap_bputs("LIST -lag" CRLF, f); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: LIST %s", (len == 0 ? "" : path)); - } - else { - ap_bvputs(f, "RETR ", path, CRLF, NULL); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: RETR %s", path); - } - ap_bflush(f); -/* RETR: 110, 125, 150, 226, 250, 421, 425, 426, 450, 451, 500, 501, 530, 550 - NLST: 125, 150, 226, 250, 421, 425, 426, 450, 451, 500, 501, 502, 530 */ - /* 110 Restart marker reply. */ - /* 125 Data connection already open; transfer starting. */ - /* 150 File status okay; about to open data connection. */ - /* 226 Closing data connection. */ - /* 250 Requested file action okay, completed. */ - /* 421 Service not available, closing control connection. */ - /* 425 Can't open data connection. */ - /* 426 Connection closed; transfer aborted. */ - /* 450 Requested file action not taken. */ - /* 451 Requested action aborted. Local error in processing. */ - /* 500 Syntax error, command unrecognized. */ - /* 501 Syntax error in parameters or arguments. */ - /* 530 Not logged in. */ - /* 550 Requested action not taken. */ - rc = ftp_getrc(f); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: returned status %d", rc); - if (rc == -1) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - if (rc == 550) { - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: RETR failed, trying LIST instead"); - parms = "d"; - ap_bvputs(f, "CWD ", path, CRLF, NULL); - ap_bflush(f); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: CWD %s", path); - /* possible results: 250, 421, 500, 501, 502, 530, 550 */ - /* 250 Requested file action okay, completed. */ - /* 421 Service not available, closing control connection. */ - /* 500 Syntax error, command unrecognized. */ - /* 501 Syntax error in parameters or arguments. */ - /* 502 Command not implemented. */ - /* 530 Not logged in. */ - /* 550 Requested action not taken. */ - rc = ftp_getrc(f); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: returned status %d", rc); - if (rc == -1) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - if (rc == 550) { - return HTTP_NOT_FOUND; - } - if (rc != 250) { - return HTTP_BAD_GATEWAY; - } - -#ifdef AUTODETECT_PWD - ap_bvputs(f, "PWD", CRLF, NULL); - ap_bflush(f); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: PWD"); -/* responses: 257, 500, 501, 502, 421, 550 */ - /* 257 "<directory-name>" <commentary> */ - /* 421 Service not available, closing control connection. */ - /* 500 Syntax error, command unrecognized. */ - /* 501 Syntax error in parameters or arguments. */ - /* 502 Command not implemented. */ - /* 550 Requested action not taken. */ - i = ftp_getrc_msg(f, resp, sizeof resp); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: PWD returned status %d", i); - if (i == -1 || i == 421) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - if (i == 550) { - return HTTP_NOT_FOUND; - } - if (i == 257) { - const char *dirp = resp; - cwd = ap_getword_conf(r->pool, &dirp); - } -#endif /*AUTODETECT_PWD*/ - - ap_bputs("LIST -lag" CRLF, f); - ap_bflush(f); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: LIST -lag"); - rc = ftp_getrc(f); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: returned status %d", rc); - if (rc == -1) - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - if (rc != 125 && rc != 150 && rc != 226 && rc != 250) - return HTTP_BAD_GATEWAY; - - r->status = HTTP_OK; - r->status_line = "200 OK"; - resp_hdrs = ap_make_table(p, 2); - - apr_rfc822_date(dates, r->request_time); - apr_table_setn(resp_hdrs, "Date", dates); - apr_table_setn(resp_hdrs, "Server", ap_get_server_version()); - - if (parms[0] == 'd') - apr_table_setn(resp_hdrs, "Content-Type", "text/html"); - else { - if (r->content_type != NULL) { - apr_table_setn(resp_hdrs, "Content-Type", r->content_type); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: Content-Type set to %s", r->content_type); - } - else { - apr_table_setn(resp_hdrs, "Content-Type", ap_default_type(r)); - } - if (parms[0] != 'a' && size != NULL) { - /* We "trust" the ftp server to really serve (size) bytes... */ - apr_table_setn(resp_hdrs, "Content-Length", size); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: Content-Length set to %s", size); - } - } - if (r->content_encoding != NULL && r->content_encoding[0] != '\0') { - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: Content-Encoding set to %s", r->content_encoding); - apr_table_setn(resp_hdrs, "Content-Encoding", r->content_encoding); - } - ap_cache_el_header_merge(c, resp_hdrs); - -/* check if NoCache directive on this host */ - for (i = 0; i < conf->nocaches->nelts; i++) { - if ((ncent[i].name != NULL && ap_strstr_c(host, ncent[i].name) != NULL) - || destaddr.s_addr == ncent[i].addr.s_addr || ncent[i].name[0] == '*') - nocache = 1; - } - -#if 0 - i = ap_proxy_cache_update(c, resp_hdrs, 0, nocache); - - if (i != DECLINED) { - ap_pclosesocket(p, dsock); - ap_bclose(f); - return i; - } -#endif - - if(nocache || !ap_proxy_cache_should_cache(r, resp_hdrs, 0)) - ap_proxy_cache_error(&c); - else - ap_cache_el_data(c, &cachefp); - - if (!pasvmode) { /* wait for connection */ - for(;;) - { - switch(apr_accept(&inc, dsock, r->pool)) - { - case APR_EINTR: - continue; - case APR_SUCCESS: - break; - default: - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: failed to accept data connection"); - apr_socket_close(dsock); - ap_bclose(f); - if (c != NULL) ap_proxy_cache_error(&c); - return HTTP_BAD_GATEWAY; - } - } - data = ap_bcreate(p, B_RDWR); - ap_bpush_socket(f, csd); - } - else { - data = ap_bcreate(p, B_RDWR); - ap_bpush_socket(data, dsock); - } - -/* send response */ -/* write status line */ - if (!r->assbackwards) - ap_rvputs(r, "HTTP/1.0 ", r->status_line, CRLF, NULL); - if (cachefp && apr_file_puts(apr_pstrcat(r->pool, "HTTP/1.0 ", - r->status_line, CRLF, NULL), cachefp) != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: error writing CRLF to cache"); - ap_proxy_cache_error(&c); - cachefp = NULL; - } - -/* send headers */ - ap_cache_el_header_walk(c, ap_proxy_send_hdr_line, r, NULL); - if (!r->assbackwards) - ap_rputs(CRLF, r); - if (cachefp && apr_file_puts(CRLF, cachefp) == -1) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: error writing CRLF to cache"); - ap_proxy_cache_error(&c); - cachefp = NULL; - } - -/* This is done by a filter now, so this can probably be removed cleanly. - ap_bsetopt(r->connection->client, BO_BYTECT, &zero); -*/ - r->sent_bodyct = 1; -/* send body */ - if (!r->header_only) { - if (parms[0] != 'd') { - ap_proxy_send_fb(NULL, data, r, c); - } else - send_dir(data, r, c, cwd); - - if (rc == 125 || rc == 150) - rc = ftp_getrc(f); - - /* XXX: we checked for 125||150||226||250 above. This is redundant. */ - if (rc != 226 && rc != 250) - /* XXX: we no longer log an "error writing to c->tempfile" - should we? */ - ap_proxy_cache_error(&c); - } - else { -/* abort the transfer */ - ap_bputs("ABOR" CRLF, f); - ap_bflush(f); - if (!pasvmode) - ap_bclose(data); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: ABOR"); -/* responses: 225, 226, 421, 500, 501, 502 */ - /* 225 Data connection open; no transfer in progress. */ - /* 226 Closing data connection. */ - /* 421 Service not available, closing control connection. */ - /* 500 Syntax error, command unrecognized. */ - /* 501 Syntax error in parameters or arguments. */ - /* 502 Command not implemented. */ - i = ftp_getrc(f); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: returned status %d", i); - } - -/* finish */ - ap_bputs("QUIT" CRLF, f); - ap_bflush(f); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: QUIT"); -/* responses: 221, 500 */ - /* 221 Service closing control connection. */ - /* 500 Syntax error, command unrecognized. */ - i = ftp_getrc(f); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "FTP: QUIT: status %d", i); - - if (pasvmode) - ap_bclose(data); - ap_bclose(f); - - ap_rflush(r); /* flush before garbage collection */ - - if(c) ap_proxy_cache_update(c); - return OK; -} diff --git a/modules/proxy/proxy_http.c b/modules/proxy/proxy_http.c deleted file mode 100644 index de1ef550a3..0000000000 --- a/modules/proxy/proxy_http.c +++ /dev/null @@ -1,532 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - * - * Portions of this software are based upon public domain software - * originally written at the National Center for Supercomputing Applications, - * University of Illinois, Urbana-Champaign. - */ - -/* HTTP routines for Apache proxy */ - -#define CORE_PRIVATE - -#include "mod_proxy.h" -#include "apr_strings.h" -#include "apr_buckets.h" -#include "util_filter.h" -#include "ap_config.h" -#include "http_log.h" -#include "http_main.h" -#include "http_core.h" -#include "http_connection.h" -#include "util_date.h" - -/* - * Canonicalise http-like URLs. - * scheme is the scheme for the URL - * url is the URL starting with the first '/' - * def_port is the default port for this scheme. - */ -int ap_proxy_http_canon(request_rec *r, char *url, const char *scheme, int def_port) -{ - char *host, *path, *search, sport[7]; - const char *err; - int port; - -/* do syntatic check. - * We break the URL into host, port, path, search - */ - port = def_port; - err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port); - if (err) - return HTTP_BAD_REQUEST; - -/* now parse path/search args, according to rfc1738 */ -/* N.B. if this isn't a true proxy request, then the URL _path_ - * has already been decoded. True proxy requests have r->uri - * == r->unparsed_uri, and no others have that property. - */ - if (r->uri == r->unparsed_uri) { - search = strchr(url, '?'); - if (search != NULL) - *(search++) = '\0'; - } - else - search = r->args; - -/* process path */ - path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, r->proxyreq); - if (path == NULL) - return HTTP_BAD_REQUEST; - - if (port != def_port) - apr_snprintf(sport, sizeof(sport), ":%d", port); - else - sport[0] = '\0'; - - r->filename = apr_pstrcat(r->pool, "proxy:", scheme, "://", host, sport, "/", - path, (search) ? "?" : "", (search) ? search : "", NULL); - return OK; -} - -static const char *proxy_location_reverse_map(request_rec *r, const char *url) -{ - void *sconf; - proxy_server_conf *conf; - struct proxy_alias *ent; - int i, l1, l2; - char *u; - - sconf = r->server->module_config; - conf = (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module); - l1 = strlen(url); - ent = (struct proxy_alias *)conf->raliases->elts; - for (i = 0; i < conf->raliases->nelts; i++) { - l2 = strlen(ent[i].real); - if (l1 >= l2 && strncmp(ent[i].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; -} - -/* Clear all connection-based headers from the incoming headers table */ -static void clear_connection(apr_pool_t *p, apr_table_t *headers) -{ - const char *name; - char *next = apr_pstrdup(p, apr_table_get(headers, "Connection")); - - apr_table_unset(headers, "Proxy-Connection"); - if (!next) - return; - - while (*next) { - name = next; - while (*next && !apr_isspace(*next) && (*next != ',')) - ++next; - while (*next && (apr_isspace(*next) || (*next == ','))) { - *next = '\0'; - ++next; - } - apr_table_unset(headers, name); - } - apr_table_unset(headers, "Connection"); -} - -/* - * This handles http:// URLs, and other URLs using a remote proxy over http - * If proxyhost is NULL, then contact the server directly, otherwise - * go via the proxy. - * Note that if a proxy is used, then URLs other than http: can be accessed, - * also, if we have trouble which is clearly specific to the proxy, then - * we return DECLINED so that we can try another proxy. (Or the direct - * route.) - */ -int ap_proxy_http_handler(request_rec *r, char *url, - const char *proxyhost, int proxyport) -{ - const char *strp; - char *strp2; - char *desthost; - apr_socket_t *sock; - int i, len, backasswards, content_length = -1; - apr_status_t err; - apr_array_header_t *reqhdrs_arr; - apr_table_t *resp_hdrs = NULL; - apr_table_entry_t *reqhdrs; - struct sockaddr_in server; - struct in_addr destaddr; - char buffer[HUGE_STRING_LEN]; - char *buffer2; - char portstr[32]; - apr_pool_t *p = r->pool; - int destport = 0; - char *destportstr = NULL; - const char *urlptr = NULL; - apr_ssize_t cntr; - apr_file_t *cachefp = NULL; - char *buf; - conn_rec *origin; - apr_bucket *e; - apr_bucket_brigade *bb = apr_brigade_create(r->pool); - - void *sconf = r->server->module_config; - proxy_server_conf *conf = - (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); - struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts; - int nocache = 0; - - memset(&server, '\0', sizeof(server)); - server.sin_family = AF_INET; - -/* We break the URL into host, port, path-search */ - - urlptr = strstr(url, "://"); - if (urlptr == NULL) - return HTTP_BAD_REQUEST; - urlptr += 3; - destport = DEFAULT_HTTP_PORT; - strp = ap_strchr_c(urlptr, '/'); - if (strp == NULL) { - desthost = apr_pstrdup(p, urlptr); - urlptr = "/"; - } - else { - char *q = apr_palloc(p, strp - urlptr + 1); - memcpy(q, urlptr, strp - urlptr); - q[strp - urlptr] = '\0'; - urlptr = strp; - desthost = q; - } - - strp2 = ap_strchr(desthost, ':'); - if (strp2 != NULL) { - *(strp2++) = '\0'; - if (apr_isdigit(*strp2)) { - destport = atoi(strp2); - destportstr = strp2; - } - } - -/* check if ProxyBlock directive on this host */ - destaddr.s_addr = apr_inet_addr(desthost); - for (i = 0; i < conf->noproxies->nelts; i++) { - if ((npent[i].name != NULL - && ap_strstr_c(desthost, npent[i].name) != NULL) - || destaddr.s_addr == npent[i].addr.s_addr - || npent[i].name[0] == '*') - return ap_proxyerror(r, HTTP_FORBIDDEN, - "Connect to remote machine blocked"); - } - - if ((apr_socket_create(&sock, APR_INET, SOCK_STREAM, r->pool)) != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: error creating socket"); - return HTTP_INTERNAL_SERVER_ERROR; - } - -#if !defined(TPF) && !defined(BEOS) - if (conf->recv_buffer_size > 0 && apr_setsocketopt(sock, APR_SO_RCVBUF, - conf->recv_buffer_size)) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default"); - } -#endif - - if (proxyhost != NULL) { - err = ap_proxy_doconnect(sock, (char *)proxyhost, proxyport, r); - } - else { - err = ap_proxy_doconnect(sock, (char *)desthost, destport, r); - } - - if (err != APR_SUCCESS) { - if (proxyhost != NULL) - return DECLINED; /* try again another way */ - else - return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_pstrcat(r->pool, - "Could not connect to remote machine: ", - desthost, NULL)); - } - - origin = ap_new_connection(r->pool, r->server, sock, 0); - if (!origin) { - /* the peer reset the connection already; ap_new_connection() - * closed the socket */ - /* XXX somebody that knows what they're doing add an error path */ - } - - ap_add_output_filter("CORE", NULL, NULL, origin); - - clear_connection(r->pool, r->headers_in); /* Strip connection-based headers */ - - buf = apr_pstrcat(r->pool, r->method, " ", proxyhost ? url : urlptr, - " HTTP/1.0" CRLF, NULL); - e = apr_bucket_pool_create(buf, strlen(buf), r->pool); - APR_BRIGADE_INSERT_TAIL(bb, e); - if (destportstr != NULL && destport != DEFAULT_HTTP_PORT) { - buf = apr_pstrcat(r->pool, "Host: ", desthost, ":", destportstr, CRLF, NULL); - e = apr_bucket_pool_create(buf, strlen(buf), r->pool); - APR_BRIGADE_INSERT_TAIL(bb, e); - } - else { - buf = apr_pstrcat(r->pool, "Host: ", desthost, CRLF, NULL); - e = apr_bucket_pool_create(buf, strlen(buf), r->pool); - APR_BRIGADE_INSERT_TAIL(bb, e); - } - - if (conf->viaopt == via_block) { - /* Block all outgoing Via: headers */ - apr_table_unset(r->headers_in, "Via"); - } else if (conf->viaopt != via_off) { - /* Create a "Via:" request header entry and merge it */ - i = ap_get_server_port(r); - if (ap_is_default_port(i,r)) { - strcpy(portstr,""); - } else { - apr_snprintf(portstr, sizeof portstr, ":%d", i); - } - /* Generate outgoing Via: header with/without server comment: */ - ap_table_mergen(r->headers_in, "Via", - (conf->viaopt == via_full) - ? apr_psprintf(p, "%d.%d %s%s (%s)", - HTTP_VERSION_MAJOR(r->proto_num), - HTTP_VERSION_MINOR(r->proto_num), - ap_get_server_name(r), portstr, - AP_SERVER_BASEVERSION) - : apr_psprintf(p, "%d.%d %s%s", - HTTP_VERSION_MAJOR(r->proto_num), - HTTP_VERSION_MINOR(r->proto_num), - ap_get_server_name(r), portstr) - ); - } - - reqhdrs_arr = apr_table_elts(r->headers_in); - reqhdrs = (apr_table_entry_t *) reqhdrs_arr->elts; - for (i = 0; i < reqhdrs_arr->nelts; i++) { - if (reqhdrs[i].key == NULL || reqhdrs[i].val == NULL - /* Clear out headers not to send */ - || !strcasecmp(reqhdrs[i].key, "Host") /* Already sent */ - /* XXX: @@@ FIXME: "Proxy-Authorization" should *only* be - * suppressed if THIS server requested the authentication, - * not when a frontend proxy requested it! - */ - || !strcasecmp(reqhdrs[i].key, "Proxy-Authorization")) - continue; - buf = apr_pstrcat(r->pool, reqhdrs[i].key, ": ", reqhdrs[i].val, CRLF, NULL); - e = apr_bucket_pool_create(buf, strlen(buf), r->pool); - APR_BRIGADE_INSERT_TAIL(bb, e); - - } - - e = apr_bucket_pool_create(CRLF, strlen(CRLF), r->pool); - APR_BRIGADE_INSERT_TAIL(bb, e); - e = apr_bucket_flush_create(); - APR_BRIGADE_INSERT_TAIL(bb, e); - - ap_pass_brigade(origin->output_filters, bb); -/* send the request data, if any. */ - - if (ap_should_client_block(r)) { - while ((i = ap_get_client_block(r, buffer, sizeof buffer)) > 0) { - e = apr_bucket_pool_create(buffer, i, r->pool); - APR_BRIGADE_INSERT_TAIL(bb, e); - } - } - /* Flush the data to the origin server */ - e = apr_bucket_flush_create(); - APR_BRIGADE_INSERT_TAIL(bb, e); - ap_pass_brigade(origin->output_filters, bb); - - ap_add_input_filter("HTTP_IN", NULL, NULL, origin); - ap_add_input_filter("CORE_IN", NULL, NULL, origin); - - apr_brigade_destroy(bb); - bb = apr_brigade_create(r->pool); - - /* Tell http_filter to grab the data one line at a time. */ - origin->remain = 0; - - ap_get_brigade(origin->input_filters, bb, AP_MODE_BLOCKING); - e = APR_BRIGADE_FIRST(bb); - apr_bucket_read(e, (const char **)&buffer2, &len, APR_BLOCK_READ); - if (len == -1) { - apr_socket_close(sock); - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "ap_get_brigade() - proxy receive - Error reading from remote server %s (length %d)", - proxyhost ? proxyhost : desthost, len); - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } else if (len == 0) { - apr_socket_close(sock); - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Document contains no data"); - } - APR_BUCKET_REMOVE(e); - apr_bucket_destroy(e); - -/* Is it an HTTP/1 response? This is buggy if we ever see an HTTP/1.10 */ - if (ap_checkmask(buffer2, "HTTP/#.# ###*")) { - int major, minor; - if (2 != sscanf(buffer2, "HTTP/%u.%u", &major, &minor)) { - major = 1; - minor = 0; - } - -/* If not an HTTP/1 message or if the status line was > 8192 bytes */ - if (buffer2[5] != '1' || buffer2[len - 1] != '\n') { - apr_socket_close(sock); - return HTTP_BAD_GATEWAY; - } - backasswards = 0; - buffer2[--len] = '\0'; - - buffer2[12] = '\0'; - r->status = atoi(&buffer2[9]); - - buffer2[12] = ' '; - r->status_line = apr_pstrdup(p, &buffer2[9]); - -/* read the headers. */ -/* N.B. for HTTP/1.0 clients, we have to fold line-wrapped headers */ -/* Also, take care with headers with multiple occurences. */ - - resp_hdrs = ap_proxy_read_headers(r, buffer, HUGE_STRING_LEN, origin); - if (resp_hdrs == NULL) { - ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r->server, - "proxy: Bad HTTP/%d.%d header returned by %s (%s)", - major, minor, r->uri, r->method); - nocache = 1; /* do not cache this broken file */ - } - else - { - clear_connection(p, resp_hdrs); /* Strip Connection hdrs */ - if (apr_table_get(resp_hdrs, "Content-type")) { - r->content_type = apr_pstrdup(r->pool, apr_table_get(resp_hdrs, "Content-type")); - } - } - - if (conf->viaopt != via_off && conf->viaopt != via_block) { - /* Create a "Via:" response header entry and merge it */ - i = ap_get_server_port(r); - if (ap_is_default_port(i,r)) { - strcpy(portstr,""); - } else { - apr_snprintf(portstr, sizeof portstr, ":%d", i); - } - } - } - else { -/* an http/0.9 response */ - backasswards = 1; - r->status = 200; - r->status_line = "200 OK"; - } - -/* - * HTTP/1.0 requires us to accept 3 types of dates, but only generate - * one type - */ - -#if 0 - if (ap_cache_el_header(c, "Date", &datestr) == APR_SUCCESS) - ap_cache_el_header_set(c, "Date", ap_proxy_date_canon(p, datestr)); - if (ap_cache_el_header(c, "Last-Modified", &datestr) == APR_SUCCESS) - ap_cache_el_header_set(c, "Last-Modified", ap_proxy_date_canon(p, datestr)); - if (ap_cache_el_header(c, "Expires", &datestr) == APR_SUCCESS) - ap_cache_el_header_set(c, "Expires", ap_proxy_date_canon(p, datestr)); - - if (ap_cache_el_header(c, "Location", &datestr) == APR_SUCCESS) - ap_cache_el_header_set(c, "Location", proxy_location_reverse_map(r, datestr)); - if (ap_cache_el_header(c, "URI", &datestr) == APR_SUCCESS) - ap_cache_el_header_set(c, "URI", proxy_location_reverse_map(r, datestr)); -#endif - -/* write status line */ -#if 0 - if (!r->assbackwards) - ap_rvputs(r, "HTTP/1.0 ", r->status_line, CRLF, NULL); - - if (cachefp && apr_file_puts(apr_pstrcat(r->pool, "HTTP/1.0 ", - r->status_line, CRLF, NULL), cachefp) != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: error writing status line to cache"); - ap_proxy_cache_error(&c); - cachefp = NULL; - } -#endif - -#if 0 -/* send headers */ - ap_cache_el_header_walk(c, ap_proxy_send_hdr_line, r, NULL); -#endif -/* - if (!r->assbackwards) - ap_rputs(CRLF, r); -*/ - r->sent_bodyct = 1; -/* Is it an HTTP/0.9 response? If so, send the extra data */ - if (backasswards) { - cntr = len; - e = apr_bucket_heap_create(buffer, cntr, 0, NULL); - APR_BRIGADE_INSERT_TAIL(bb, e); - if (cachefp && apr_file_write(cachefp, buffer, &cntr) != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: error writing extra data to cache"); - } - } - - /* send body */ - /* if header only, then cache will be NULL */ - /* HTTP/1.0 tells us to read to EOF, rather than content-length bytes */ - if (!r->header_only) { - proxy_completion pc; - pc.content_length = content_length; - pc.cache_completion = conf->cache_completion; - - origin->remain = content_length; - while (ap_get_brigade(origin->input_filters, bb, AP_MODE_BLOCKING) == APR_SUCCESS) { - if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) { - ap_pass_brigade(r->output_filters, bb); - break; - } - ap_pass_brigade(r->output_filters, bb); - apr_brigade_destroy(bb); - bb = apr_brigade_create(r->pool); - } - } - - apr_socket_close(sock); - return OK; -} diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c deleted file mode 100644 index 18eb2c4e2c..0000000000 --- a/modules/proxy/proxy_util.c +++ /dev/null @@ -1,1323 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - * - * Portions of this software are based upon public domain software - * originally written at the National Center for Supercomputing Applications, - * University of Illinois, Urbana-Champaign. - */ - -#define CORE_PRIVATE - -/* Utility routines for Apache proxy */ -#include "mod_proxy.h" -#include "http_core.h" -#include "http_main.h" -#include "http_log.h" -#include "util_uri.h" -#include "util_date.h" /* get ap_checkmask() decl. */ -#include "apr_md5.h" -#include "apr_pools.h" -#include "apr_strings.h" - -static int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r); -static int proxy_match_domainname(struct dirconn_entry *This, request_rec *r); -static int proxy_match_hostname(struct dirconn_entry *This, request_rec *r); -static int proxy_match_word(struct dirconn_entry *This, request_rec *r); -static struct per_thread_data *get_per_thread_data(void); -/* already called in the knowledge that the characters are hex digits */ -int ap_proxy_hex2c(const char *x) -{ - int i, ch; - -#if !APR_CHARSET_EBCDIC - ch = x[0]; - if (apr_isdigit(ch)) - i = ch - '0'; - else if (apr_isupper(ch)) - i = ch - ('A' - 10); - else - i = ch - ('a' - 10); - i <<= 4; - - ch = x[1]; - if (apr_isdigit(ch)) - i += ch - '0'; - else if (apr_isupper(ch)) - i += ch - ('A' - 10); - else - i += ch - ('a' - 10); - return i; -#else /*APR_CHARSET_EBCDIC*/ - return (1 == sscanf(x, "%2x", &i)) ? os_toebcdic[i&0xFF] : 0; -#endif /*APR_CHARSET_EBCDIC*/ -} - -void ap_proxy_c2hex(int ch, char *x) -{ -#if !APR_CHARSET_EBCDIC - int i; - - x[0] = '%'; - i = (ch & 0xF0) >> 4; - if (i >= 10) - x[1] = ('A' - 10) + i; - else - x[1] = '0' + i; - - i = ch & 0x0F; - if (i >= 10) - x[2] = ('A' - 10) + i; - else - x[2] = '0' + i; -#else /*APR_CHARSET_EBCDIC*/ - static const char ntoa[] = { "0123456789ABCDEF" }; - ch &= 0xFF; - x[0] = '%'; - x[1] = ntoa[(os_toascii[ch]>>4)&0x0F]; - x[2] = ntoa[os_toascii[ch]&0x0F]; - x[3] = '\0'; -#endif /*APR_CHARSET_EBCDIC*/ -} - -/* - * canonicalise a URL-encoded string - */ - -/* - * Convert a URL-encoded string to canonical form. - * It decodes characters which need not be encoded, - * and encodes those which must be encoded, and does not touch - * those which must not be touched. - */ -char *ap_proxy_canonenc(apr_pool_t *p, const char *x, int len, enum enctype t, - int isenc) -{ - int i, j, ch; - char *y; - char *allowed; /* characters which should not be encoded */ - char *reserved; /* characters which much not be en/de-coded */ - -/* N.B. in addition to :@&=, this allows ';' in an http path - * and '?' in an ftp path -- this may be revised - * - * Also, it makes a '+' character in a search string reserved, as - * it may be form-encoded. (Although RFC 1738 doesn't allow this - - * it only permits ; / ? : @ = & as reserved chars.) - */ - if (t == enc_path) - allowed = "$-_.+!*'(),;:@&="; - else if (t == enc_search) - allowed = "$-_.!*'(),;:@&="; - else if (t == enc_user) - allowed = "$-_.+!*'(),;@&="; - else if (t == enc_fpath) - allowed = "$-_.+!*'(),?:@&="; - else /* if (t == enc_parm) */ - allowed = "$-_.+!*'(),?/:@&="; - - if (t == enc_path) - reserved = "/"; - else if (t == enc_search) - reserved = "+"; - else - reserved = ""; - - y = apr_palloc(p, 3 * len + 1); - - for (i = 0, j = 0; i < len; i++, j++) { -/* always handle '/' first */ - ch = x[i]; - if (strchr(reserved, ch)) { - y[j] = ch; - continue; - } -/* decode it if not already done */ - if (isenc && ch == '%') { - if (!ap_isxdigit(x[i + 1]) || !ap_isxdigit(x[i + 2])) - return NULL; - ch = ap_proxy_hex2c(&x[i + 1]); - i += 2; - if (ch != 0 && strchr(reserved, ch)) { /* keep it encoded */ - ap_proxy_c2hex(ch, &y[j]); - j += 2; - continue; - } - } -/* recode it, if necessary */ - if (!apr_isalnum(ch) && !strchr(allowed, ch)) { - ap_proxy_c2hex(ch, &y[j]); - j += 2; - } - else - y[j] = ch; - } - y[j] = '\0'; - return y; -} - -/* - * Parses network-location. - * urlp on input the URL; on output the path, after the leading / - * user NULL if no user/password permitted - * password holder for password - * host holder for host - * port port number; only set if one is supplied. - * - * Returns an error string. - */ -char * - ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, char **userp, - char **passwordp, char **hostp, int *port) -{ - int i; - char *strp, *host, *url = *urlp; - char *user = NULL, *password = NULL; - - if (url[0] != '/' || url[1] != '/') - return "Malformed URL"; - host = url + 2; - url = strchr(host, '/'); - if (url == NULL) - url = ""; - else - *(url++) = '\0'; /* skip seperating '/' */ - - /* find _last_ '@' since it might occur in user/password part */ - strp = strrchr(host, '@'); - - if (strp != NULL) { - *strp = '\0'; - user = host; - host = strp + 1; - -/* find password */ - strp = strchr(user, ':'); - if (strp != NULL) { - *strp = '\0'; - password = ap_proxy_canonenc(p, strp + 1, strlen(strp + 1), enc_user, 1); - if (password == NULL) - return "Bad %-escape in URL (password)"; - } - - user = ap_proxy_canonenc(p, user, strlen(user), enc_user, 1); - if (user == NULL) - return "Bad %-escape in URL (username)"; - } - if (userp != NULL) { - *userp = user; - } - if (passwordp != NULL) { - *passwordp = password; - } - - strp = strrchr(host, ':'); - if (strp != NULL) { - *(strp++) = '\0'; - - for (i = 0; strp[i] != '\0'; i++) - if (!apr_isdigit(strp[i])) - break; - - /* if (i == 0) the no port was given; keep default */ - if (strp[i] != '\0') { - return "Bad port number in URL"; - } else if (i > 0) { - *port = atoi(strp); - if (*port > 65535) - return "Port number in URL > 65535"; - } - } - ap_str_tolower(host); /* DNS names are case-insensitive */ - if (*host == '\0') - return "Missing host in URL"; -/* check hostname syntax */ - for (i = 0; host[i] != '\0'; i++) - if (!apr_isdigit(host[i]) && host[i] != '.') - break; - /* must be an IP address */ -#if defined(WIN32) || defined(NETWARE) || defined(TPF) || defined(BEOS) - if (host[i] == '\0' && (inet_addr(host) == -1)) -#else - if (host[i] == '\0' && (ap_inet_addr(host) == -1 || inet_network(host) == -1)) -#endif - { - return "Bad IP address in URL"; - } - -/* if (strchr(host,'.') == NULL && domain != NULL) - host = pstrcat(p, host, domain, NULL); - */ - *urlp = url; - *hostp = host; - - return NULL; -} - -static const char * const lwday[7] = -{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; - -/* - * If the date is a valid RFC 850 date or asctime() date, then it - * is converted to the RFC 1123 format, otherwise it is not modified. - * This routine is not very fast at doing conversions, as it uses - * sscanf and sprintf. However, if the date is already correctly - * formatted, then it exits very quickly. - */ -const char * - ap_proxy_date_canon(apr_pool_t *p, const char *x1) -{ - char *x = apr_pstrdup(p, x1); - int wk, mday, year, hour, min, sec, mon; - char *q, month[4], zone[4], week[4]; - - q = strchr(x, ','); - /* check for RFC 850 date */ - if (q != NULL && q - x > 3 && q[1] == ' ') { - *q = '\0'; - for (wk = 0; wk < 7; wk++) - if (strcmp(x, lwday[wk]) == 0) - break; - *q = ','; - if (wk == 7) - return x; /* not a valid date */ - if (q[4] != '-' || q[8] != '-' || q[11] != ' ' || q[14] != ':' || - q[17] != ':' || strcmp(&q[20], " GMT") != 0) - return x; - if (sscanf(q + 2, "%u-%3s-%u %u:%u:%u %3s", &mday, month, &year, - &hour, &min, &sec, zone) != 7) - return x; - if (year < 70) - year += 2000; - else - year += 1900; - } - else { -/* check for acstime() date */ - if (x[3] != ' ' || x[7] != ' ' || x[10] != ' ' || x[13] != ':' || - x[16] != ':' || x[19] != ' ' || x[24] != '\0') - return x; - if (sscanf(x, "%3s %3s %u %u:%u:%u %u", week, month, &mday, &hour, - &min, &sec, &year) != 7) - return x; - for (wk = 0; wk < 7; wk++) - if (strcmp(week, ap_day_snames[wk]) == 0) - break; - if (wk == 7) - return x; - } - -/* check date */ - for (mon = 0; mon < 12; mon++) - if (strcmp(month, ap_month_snames[mon]) == 0) - break; - if (mon == 12) - return x; - - q = apr_palloc(p, 30); - apr_snprintf(q, 30, "%s, %.2d %s %d %.2d:%.2d:%.2d GMT", ap_day_snames[wk], - mday, ap_month_snames[mon], year, hour, min, sec); - return q; -} - -static request_rec *make_fake_req(conn_rec *c) -{ - request_rec *r = apr_pcalloc(c->pool, sizeof(*r)); - core_request_config *req_cfg; - - r->pool = c->pool; - r->status = HTTP_OK; - - r->headers_in = apr_table_make(r->pool, 50); - r->subprocess_env = apr_table_make(r->pool, 50); - r->headers_out = apr_table_make(r->pool, 12); - r->err_headers_out = apr_table_make(r->pool, 5); - r->notes = apr_table_make(r->pool, 5); - - r->read_body = REQUEST_NO_BODY; - r->connection = c; - r->output_filters = c->output_filters; - r->input_filters = c->input_filters; - - r->request_config = ap_create_request_config(r->pool); - req_cfg = apr_pcalloc(r->pool, sizeof(core_request_config)); - req_cfg->bb = apr_brigade_create(r->pool); - ap_set_module_config(r->request_config, &core_module, req_cfg); - - return r; -} - -/* - * Reads headers from a buffer and returns an array of headers. - * Returns NULL on file error - * This routine tries to deal with too long lines and continuation lines. - * @@@: XXX: FIXME: currently the headers are passed thru un-merged. - * Is that okay, or should they be collapsed where possible? - */ -apr_table_t *ap_proxy_read_headers(request_rec *r, char *buffer, int size, conn_rec *c) -{ - apr_table_t *resp_hdrs; - int len; - char *value, *end; - char field[MAX_STRING_LEN]; - request_rec *rr = make_fake_req(c); - - resp_hdrs = ap_make_table(r->pool, 20); - - /* - * Read header lines until we get the empty separator line, a read error, - * the connection closes (EOF), or we timeout. - */ - while ((len = ap_getline(buffer, size, rr, 1)) > 0) { - - if (!(value = strchr(buffer, ':'))) { /* Find the colon separator */ - - /* Buggy MS IIS servers sometimes return invalid headers - * (an extra "HTTP/1.0 200, OK" line sprinkled in between - * the usual MIME headers). Try to deal with it in a sensible - * way, but log the fact. - * XXX: The mask check is buggy if we ever see an HTTP/1.10 */ - - if (!ap_checkmask(buffer, "HTTP/#.# ###*")) { - /* Nope, it wasn't even an extra HTTP header. Give up. */ - return NULL; - } - - ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r->server, - "proxy: Ignoring duplicate 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'; - - ap_table_add(resp_hdrs, buffer, value); - - /* 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, r, 1)) - >= MAX_STRING_LEN - 1) { - /* soak up the extra data */ - } - if (len == 0) /* time to exit the larger loop as well */ - break; - } - } - return resp_hdrs; -} - -#if 0 -long int ap_proxy_send_fb(proxy_completion *completion, BUFF *f, request_rec *r, ap_cache_el *c) -{ - int ok; - char buf[IOBUFSIZE]; - long total_bytes_rcvd, in_buffer; - apr_ssize_t cntr; - register int n, o; - conn_rec *con = r->connection; - int alternate_timeouts = 1; /* 1 if we alternate between soft & hard timeouts */ - apr_file_t *cachefp = NULL; - int written = 0, wrote_to_cache; - - total_bytes_rcvd = 0; - if (c) ap_cache_el_data(c, &cachefp); - -#if APR_CHARSET_EBCDIC - /* The cache copy is ASCII, not EBCDIC, even for text/html) */ - ap_bsetflag(f, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0); - if (c != NULL && c->fp != NULL) - ap_bsetflag(c->fp, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0); - ap_bsetflag(con->client, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0); -#endif - - /* Since we are reading from one buffer and writing to another, - * it is unsafe to do a soft_timeout here, at least until the proxy - * has its own timeout handler which can set both buffers to EOUT. - */ - -#if defined(WIN32) || defined(TPF) || defined(NETWARE) - /* works fine under win32, so leave it */ - alternate_timeouts = 0; -#else - /* CHECKME! Since hard_timeout won't work in unix on sends with partial - * cache completion, we have to alternate between hard_timeout - * for reads, and soft_timeout for send. This is because we need - * to get a return from ap_bwrite to be able to continue caching. - * BUT, if we *can't* continue anyway, just use hard_timeout. - * (Also, if no cache file is written, use hard timeouts) - */ - - if (!completion || completion->content_length > 0 - || completion->cache_completion == 1.0) { - alternate_timeouts = 0; - } -#endif - - /* Loop and ap_bread() while we can successfully read and write, - * or (after the client aborted) while we can successfully - * read and finish the configured cache_completion. - */ - for (ok = 1; ok; cntr = 0) { - /* Read block from server */ - if (ap_bread(f, buf, IOBUFSIZE, &cntr) != APR_SUCCESS && !cntr) - { - if (c != NULL) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: error reading from %s", c->name); - ap_proxy_cache_error(&c); - } - break; - } - else if(cntr == 0) break; - - /* Write to cache first. */ - /*@@@ XXX FIXME: Assuming that writing the cache file won't time out?!!? */ - wrote_to_cache = cntr; - if (cachefp && apr_file_write(cachefp, &buf[0], &wrote_to_cache) != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: error writing to cache"); - ap_proxy_cache_error(&c); - } else { - written += n; - } - - o = 0; - total_bytes_rcvd += cntr; - in_buffer = cntr; - - /* Write the block to the client, detect aborted transfers */ - while (!con->aborted && in_buffer > 0) { - if ((cntr = ap_rwrite(&buf[o], in_buffer, r))) { - if (completion) { - /* when a send failure occurs, we need to decide - * whether to continue loading and caching the - * document, or to abort the whole thing - */ - ok = (completion->content_length > 0) && - (completion->cache_completion > 0) && - (completion->content_length * completion->cache_completion < total_bytes_rcvd); - - if (!ok) - ap_proxy_cache_error(&c); - } - con->aborted = 1; - break; - } - in_buffer -= cntr; - o += cntr; - } /* while client alive and more data to send */ - } /* loop and ap_bread while "ok" */ - - if (!con->aborted) - ap_rflush(r); - - return total_bytes_rcvd; -} -#endif /* 0, ap_proxy_send_fb */ - -/* - * Sends response line and headers. Uses the client fd and the - * headers_out array from the passed request_rec to talk to the client - * and to properly set the headers it sends for things such as logging. - * - * A timeout should be set before calling this routine. - */ -void ap_proxy_send_headers(request_rec *r, const char *respline, apr_table_t *t) -{ - int i; - apr_socket_t *fp = r->connection->client_socket; - apr_table_entry_t *elts = (apr_table_entry_t *) apr_table_elts(t)->elts; - - char *temp = apr_pstrcat(r->pool, respline, CRLF, NULL); - apr_size_t len = strlen(temp); - apr_send(fp, temp, &len); - - for (i = 0; i < ap_table_elts(t)->nelts; ++i) { - if (elts[i].key != NULL) { - temp = apr_pstrcat(r->pool, elts[i].key, ": ", elts[i].val, CRLF, NULL); - apr_send(fp, temp, &len); - apr_table_addn(r->headers_out, elts[i].key, elts[i].val); - } - } - - len = 2; - apr_send(fp, CRLF, &len); -} - - -/* - * 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. - */ -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; -} - -/* - * Converts 8 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 < 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 - */ -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'; -} - - -void ap_proxy_cache_error(ap_cache_el **c) -{ - if (c && *c) { - const char *name = (*c)->name; - ap_cache_el_finalize((*c)); - ap_cache_remove((*c)->cache, name); - *c = NULL; - } -} - -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), - " ", - 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() */ - apr_table_setn(r->notes, "verbose-error-to", apr_pstrdup(r->pool, "*")); - - r->status_line = apr_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 (!apr_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 = 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|APLOG_NOERRNO, 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) */ -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 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 (!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 | APLOG_NOERRNO, 0, NULL, - "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) { - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "Warning: NetMask and IP-Addr disagree in %s/%ld\n", - inet_ntoa(This->addr), bits); - This->addr.s_addr &= This->mask.s_addr; - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - " 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 - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "1)IP-Match: %s[%s] <-> ", host, inet_ntoa(addr)); - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "%s/", inet_ntoa(This->addr)); - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "%s", inet_ntoa(This->mask)); -#endif - return 1; - } -#if DEBUGGING - else { - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "1)IP-NoMatch: %s[%s] <-> ", host, inet_ntoa(addr)); - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "%s/", inet_ntoa(This->addr)); - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "%s", 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 - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "2)IP-NoMatch: hostname=%s msg=%s", 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 - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "3)IP-Match: %s[%s] <-> ", found, inet_ntoa(*ip_list)); - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "%s/", inet_ntoa(This->addr)); - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "%s", inet_ntoa(This->mask)); -#endif - return 1; - } -#if DEBUGGING - else { - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "3)IP-NoMatch: %s[%s] <-> ", found, inet_ntoa(*ip_list)); - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "%s/", inet_ntoa(This->addr)); - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "%s", inet_ntoa(This->mask)); - } -#endif - } - } - - return 0; -} - -/* Return TRUE if addr represents a domain name */ -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 | APLOG_NOERRNO, 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; -} - -/* Create a copy of a "struct hostent" record; it was presumably returned - * from a call to gethostbyname() and lives in static storage. - * By creating a copy we can tuck it away for later use. - */ -static struct hostent * pduphostent(apr_pool_t *p, const struct hostent *hp) -{ - struct hostent *newent; - char **ptrs; - char **aliases; - struct in_addr *addrs; - int i = 0, j = 0; - - if (hp == NULL) - return NULL; - - /* Count number of alias entries */ - if (hp->h_aliases != NULL) - for (; hp->h_aliases[j] != NULL; ++j) - continue; - - /* Count number of in_addr entries */ - if (hp->h_addr_list != NULL) - for (; hp->h_addr_list[i] != NULL; ++i) - continue; - - /* Allocate hostent structure, alias ptrs, addr ptrs, addrs */ - newent = (struct hostent *) apr_palloc(p, sizeof(*hp)); - aliases = (char **) apr_palloc(p, (j+1) * sizeof(char*)); - ptrs = (char **) apr_palloc(p, (i+1) * sizeof(char*)); - addrs = (struct in_addr *) apr_palloc(p, (i+1) * sizeof(struct in_addr)); - - *newent = *hp; - newent->h_name = apr_pstrdup(p, hp->h_name); - newent->h_aliases = aliases; - newent->h_addr_list = (char**) ptrs; - - /* Copy Alias Names: */ - for (j = 0; hp->h_aliases[j] != NULL; ++j) { - aliases[j] = apr_pstrdup(p, hp->h_aliases[j]); - } - aliases[j] = NULL; - - /* Copy address entries */ - for (i = 0; hp->h_addr_list[i] != NULL; ++i) { - ptrs[i] = (char*) &addrs[i]; - addrs[i] = *(struct in_addr *) hp->h_addr_list[i]; - } - ptrs[i] = NULL; - - return newent; -} - -/* Return TRUE if addr represents a host name */ -int ap_proxy_is_hostname(struct dirconn_entry *This, apr_pool_t *p) -{ - struct hostent host; - char *addr = This->name; - int i; - - /* Host names must not 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); - -#if 0 - if (addr[i] == ':') { - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "@@@@ handle optional port in proxy_is_hostname()"); - /* @@@@ handle optional port */ - } -#endif - - if (addr[i] != '\0' || ap_proxy_host2addr(addr, &host) != NULL) - return 0; - - This->hostentry = pduphostent (p, &host); - - /* Strip trailing dots */ - for (i = strlen(addr) - 1; i > 0 && addr[i] == '.'; --i) - addr[i] = '\0'; - - 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 - unsigned long *ip_list; - - /* Try to deal with multiple IP addr's for a host */ - for (ip_list = *This->hostentry->h_addr_list; *ip_list != 0UL; ++ip_list) - if (*ip_list == ? ? ? ? ? ? ? ? ? ? ? ? ?) - return 1; -#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 */ -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; -} - -apr_status_t ap_proxy_doconnect(apr_socket_t *sock, char *host, apr_uint32_t port, request_rec *r) -{ - apr_status_t rv; - apr_sockaddr_t *destsa; - - rv = apr_sockaddr_info_get(&destsa, host, AF_INET, port, 0, r->pool); - if (rv == APR_SUCCESS) { - rv = apr_connect(sock, destsa); - } - else if (rv != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "proxy connect to %s port %d failed", host, port); - } - return rv; -} - -/* This function is called by ap_table_do() for all header lines */ -/* (from proxy_http.c and proxy_ftp.c) */ -/* It is passed a table_do_args struct pointer and a MIME field and value pair */ -int ap_proxy_send_hdr_line(void *p, const char *key, const char *value) -{ - struct request_rec *r = (struct request_rec *)p; - if (key == NULL || value == NULL || value[0] == '\0') - return 1; - if (!r->assbackwards) - ap_rvputs(r, key, ": ", value, CRLF, NULL); - return 1; /* tell ap_table_do() to continue calling us for more headers */ -} - -/* send a text line to one or two BUFF's; return line length */ -unsigned ap_proxy_bputs2(const char *data, apr_socket_t *client, ap_cache_el *cache) -{ - unsigned len = strlen(data); - apr_file_t *cachefp = NULL; - - apr_send(client, data, &len); - - if (ap_cache_el_data(cache, &cachefp) == APR_SUCCESS) - apr_file_puts(data, cachefp); - return len; -} - -#if defined WIN32 - -static DWORD tls_index; - -BOOL WINAPI DllMain (HINSTANCE dllhandle, DWORD reason, LPVOID reserved) -{ - LPVOID memptr; - - switch (reason) { - case DLL_PROCESS_ATTACH: - tls_index = TlsAlloc(); - case DLL_THREAD_ATTACH: /* intentional no break */ - TlsSetValue (tls_index, malloc (sizeof (struct per_thread_data))); - break; - case DLL_THREAD_DETACH: - memptr = TlsGetValue (tls_index); - if (memptr) { - free (memptr); - TlsSetValue (tls_index, 0); - } - break; - } - - return TRUE; -} - -#endif - -static struct per_thread_data *get_per_thread_data(void) -{ -#if 0 -#if defined(WIN32) - - return (struct per_thread_data *) TlsGetValue (tls_index); - -#else - - static APACHE_TLS struct per_thread_data sptd; - return &sptd; - -#endif -#endif - return NULL; -} - -/* This function is completely bogus. This should become a part of the - * cache filter when it is finished. RBB - */ -int ap_proxy_cache_send(request_rec *r, ap_cache_el *c) -{ - apr_file_t *cachefp = NULL; - apr_socket_t *fp = r->connection->client_socket; - char buffer[500]; - apr_size_t len; - apr_off_t offset = 0; - apr_finfo_t finfo; - - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "Sending cache file for %s", c->name); - if(ap_cache_el_data(c, &cachefp) != APR_SUCCESS) - return HTTP_INTERNAL_SERVER_ERROR; - /* send the response */ - if(apr_file_gets(buffer, sizeof(buffer), cachefp)) { - len = strlen(buffer); - apr_send(fp, buffer, &len); - offset +=len; - } - /* send headers */ - ap_cache_el_header_walk(c, ap_proxy_send_hdr_line, r, NULL); - len = 2; - apr_send(fp, CRLF, &len); - /* send data */ - apr_file_info_get(&finfo, APR_FINFO_MIN, cachefp); - if(!r->header_only && ap_send_fd(cachefp, r, offset, finfo.size, &len)) - return HTTP_INTERNAL_SERVER_ERROR; - return OK; -} - -int ap_proxy_cache_should_cache(request_rec *r, apr_table_t *resp_hdrs, const int is_HTTP1) -{ - const char *expire = apr_table_get(resp_hdrs, "Expires"); - time_t expc; - if (expire != NULL) - expc = ap_parseHTTPdate(expire); - else - expc = BAD_DATE; - if((r->status != HTTP_OK && r->status != HTTP_MOVED_PERMANENTLY && r->status != HTTP_NOT_MODIFIED) || - (r->status == HTTP_NOT_MODIFIED) || - r->header_only || - apr_table_get(r->headers_in, "Authorization") != NULL || - (expire != NULL && expc == BAD_DATE) || - (r->status == HTTP_OK && !apr_table_get(resp_hdrs, "Last-Modified") && is_HTTP1)) - { - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "proxy: Response is not cacheable: %s", r->unparsed_uri); - return 0; - } - return 1; -} - -/* - * what responses should we not cache? - * Unknown status responses and those known to be uncacheable - * 304 HTTP_NOT_MODIFIED response when we have no valid cache file, or - * 200 HTTP_OK response from HTTP/1.0 and up without a Last-Modified header, or - * HEAD requests, or - * requests with an Authorization header, or - * protocol requests nocache (e.g. ftp with user/password) - */ -/* @@@ XXX FIXME: is the test "r->status != HTTP_MOVED_PERMANENTLY" correct? - * or shouldn't it be "ap_is_HTTP_REDIRECT(r->status)" ? -MnKr */ -int ap_proxy_cache_update(ap_cache_el *c) -{ - ap_cache_handle_t *h = c ? c->cache : NULL; - if(!h) return DECLINED; - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL, - "proxy: Cache finalized: %s", c->name); - ap_cache_el_finalize(c); - ap_cache_garbage_collect(h); - return DECLINED; -} diff --git a/modules/test/mod_optional_fn_export.c b/modules/test/mod_optional_fn_export.c deleted file mode 100644 index b214a36621..0000000000 --- a/modules/test/mod_optional_fn_export.c +++ /dev/null @@ -1,86 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - */ - -#include "httpd.h" -#include "http_config.h" -#include "http_log.h" -#include "mod_optional_fn_export.h" - -/* The alert will note a strange mirror-image style resemblance to - * mod_generic_hook_import.c. Yes, I _did_ mean import. Think about it. - */ - -static int TestOptionalFn(const char *szStr) -{ - ap_log_error(APLOG_MARK,APLOG_ERR,OK,NULL, - "Optional function test said: %s",szStr); - - return OK; -} - -static void ExportRegisterHooks(apr_pool_t *p) -{ - APR_REGISTER_OPTIONAL_FN(TestOptionalFn); -} - -module optional_fn_export_module= -{ - STANDARD20_MODULE_STUFF, - NULL, - NULL, - NULL, - NULL, - NULL, - ExportRegisterHooks -}; diff --git a/modules/test/mod_optional_fn_export.h b/modules/test/mod_optional_fn_export.h deleted file mode 100644 index a1950f373b..0000000000 --- a/modules/test/mod_optional_fn_export.h +++ /dev/null @@ -1,3 +0,0 @@ -#include "apr_optional.h" - -APR_DECLARE_OPTIONAL_FN(int,TestOptionalFn,(const char *)); diff --git a/modules/test/mod_optional_fn_import.c b/modules/test/mod_optional_fn_import.c deleted file mode 100644 index 3be3b6be6d..0000000000 --- a/modules/test/mod_optional_fn_import.c +++ /dev/null @@ -1,93 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. - */ - -#include "httpd.h" -#include "http_config.h" -#include "mod_optional_fn_export.h" -#include "http_protocol.h" - -/* The alert will note a strange mirror-image style resemblance to - * mod_generic_hook_export.c. Yes, I _did_ mean export. Think about it. - */ - -static APR_OPTIONAL_FN_TYPE(TestOptionalFn) *pfn; - -static int ImportLogTransaction(request_rec *r) -{ - if(pfn) - return pfn(r->the_request); - return DECLINED; -} - -static void ImportFnRetrieve(void) -{ - pfn=APR_RETRIEVE_OPTIONAL_FN(TestOptionalFn); -} - -static void ImportRegisterHooks(apr_pool_t *p) -{ - ap_hook_log_transaction(ImportLogTransaction,NULL,NULL,APR_HOOK_MIDDLE); - ap_hook_optional_fn_retrieve(ImportFnRetrieve,NULL,NULL,APR_HOOK_MIDDLE); -} - -module optional_fn_import_module = -{ - STANDARD20_MODULE_STUFF, - NULL, - NULL, - NULL, - NULL, - NULL, - ImportRegisterHooks -}; |