mod_proxy.c revision d7387fcd4969206172e3a2a8bbcd25a3d7011ac5
842ae4bd224140319ae7feec1872b93dfd491143fielding/* ====================================================================
842ae4bd224140319ae7feec1872b93dfd491143fielding * The Apache Software License, Version 1.1
842ae4bd224140319ae7feec1872b93dfd491143fielding *
842ae4bd224140319ae7feec1872b93dfd491143fielding * Copyright (c) 2000 The Apache Software Foundation. All rights
842ae4bd224140319ae7feec1872b93dfd491143fielding * reserved.
842ae4bd224140319ae7feec1872b93dfd491143fielding *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Redistribution and use in source and binary forms, with or without
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * modification, are permitted provided that the following conditions
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * are met:
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd *
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * 1. Redistributions of source code must retain the above copyright
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * notice, this list of conditions and the following disclaimer.
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd *
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * 2. Redistributions in binary form must reproduce the above copyright
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * notice, this list of conditions and the following disclaimer in
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * the documentation and/or other materials provided with the
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * distribution.
9d129b55f5a43abf43865c6b0eb6dd19bc22aba8ianh *
9d129b55f5a43abf43865c6b0eb6dd19bc22aba8ianh * 3. The end-user documentation included with the redistribution,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * if any, must include the following acknowledgment:
9d129b55f5a43abf43865c6b0eb6dd19bc22aba8ianh * "This product includes software developed by the
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Apache Software Foundation (http://www.apache.org/)."
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Alternately, this acknowledgment may appear in the software itself,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * if and wherever such third-party acknowledgments normally appear.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * 4. The names "Apache" and "Apache Software Foundation" must
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * not be used to endorse or promote products derived from this
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * software without prior written permission. For written
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * permission, please contact apache@apache.org.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * 5. Products derived from this software may not be called "Apache",
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * nor may "Apache" appear in their name, without prior written
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * permission of the Apache Software Foundation.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
f888346b48f5e5b5e3f0a47dedb8cefd2759a4e2gregames * SUCH DAMAGE.
750d12c59545dbbac70390988de94f7e901b08f2niq * ====================================================================
82632a19f2f9c346fee2b28a65920ba9737b3973minfrin *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * This software consists of voluntary contributions made by many
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * individuals on behalf of the Apache Software Foundation. For more
db455cbc662c98dbbf53175393c50086ff63370cchrisd * information on the Apache Software Foundation, please see
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * <http://www.apache.org/>.
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * Portions of this software are based upon public domain software
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * originally written at the National Center for Supercomputing Applications,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * University of Illinois, Urbana-Champaign.
36ef8f77bffe75d1aa327882be1b5bdbe2ff567asf */
36ef8f77bffe75d1aa327882be1b5bdbe2ff567asf
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb#include "mod_proxy.h"
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz#define CORE_PRIVATE
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz#include "http_log.h"
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz#include "http_vhost.h"
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz#include "http_request.h"
18b5268e013574026b2503b1641baf3299045f45sf#include "util_date.h"
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz/* Some WWW schemes and their default ports; this is basically /etc/services */
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz/* This will become global when the protocol abstraction comes */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbbstatic struct proxy_services defports[] =
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb{
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb {"http", DEFAULT_HTTP_PORT},
4f9c22c4f27571d54197be9674e1fc0d528192aestriker {"ftp", DEFAULT_FTP_PORT},
a2a0abd88b19e042a3eb2a9fa1702c25ad51303dwrowe {"https", DEFAULT_HTTPS_PORT},
4f9c22c4f27571d54197be9674e1fc0d528192aestriker {"gopher", DEFAULT_GOPHER_PORT},
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb {"nntp", DEFAULT_NNTP_PORT},
4f9c22c4f27571d54197be9674e1fc0d528192aestriker {"wais", DEFAULT_WAIS_PORT},
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb {"snews", DEFAULT_SNEWS_PORT},
4f9c22c4f27571d54197be9674e1fc0d528192aestriker {"prospero", DEFAULT_PROSPERO_PORT},
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb {NULL, -1} /* unknown port */
4f9c22c4f27571d54197be9674e1fc0d528192aestriker};
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
4f9c22c4f27571d54197be9674e1fc0d528192aestriker/*
18b5268e013574026b2503b1641baf3299045f45sf * A Web proxy module. Stages:
18b5268e013574026b2503b1641baf3299045f45sf *
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * translate_name: set filename to proxy:<URL>
4f9c22c4f27571d54197be9674e1fc0d528192aestriker * type_checker: set type to PROXY_MAGIC_TYPE if filename begins proxy:
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb * fix_ups: convert the URL stored in the filename to the
4f9c22c4f27571d54197be9674e1fc0d528192aestriker * canonical form.
4f9c22c4f27571d54197be9674e1fc0d528192aestriker * handler: handle proxy requests
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb */
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd/* -------------------------------------------------------------- */
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd/* Translate the URL into a 'filename' */
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowestatic int alias_match(const char *uri, const char *alias_fakename)
963f8b44ac95132458ea3b6aaa8ebc135188e473takashi{
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe const char *end_fakename = alias_fakename + strlen(alias_fakename);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe const char *aliasp = alias_fakename, *urip = uri;
2d399cd7535887fceaa9f8f116eb98ce68ddd602trawick
c2cf53a40a9814eb91db2cdf820f97d943f21628coar while (aliasp < end_fakename) {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if (*aliasp == '/') {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe /* any number of '/' in the alias matches any number in
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar * the supplied URI, but there must be at least one...
4760b58cc9fe170e4ad4648ed4ff7a422a2cef38sf */
4760b58cc9fe170e4ad4648ed4ff7a422a2cef38sf if (*urip != '/')
4760b58cc9fe170e4ad4648ed4ff7a422a2cef38sf return 0;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar while (*aliasp == '/')
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe ++aliasp;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe while (*urip == '/')
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe ++urip;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe else {
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe /* Other characters are compared literally */
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if (*urip++ != *aliasp++)
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe return 0;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
3e392a5afd51526de3cb15d57ee46d8cb160ae65gregames }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
efd83d1dd1a25688a3093c5a542ae16bacef62ddsf /* Check last alias path component matched all the way */
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe if (aliasp[-1] != '/' && *urip != '\0' && *urip != '/')
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe return 0;
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar /* Return number of characters from URI which matched (may be
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar * greater than length of alias, since we may have matched
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar * doubled slashes)
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar */
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar return urip - uri;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz}
2a6e98ba4ffa30ded5d8831664c5cb2a170a56b6coar
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar/* Detect if an absoluteURI should be proxied or not. Note that we
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar * have to do this during this phase because later phases are
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar * "short-circuiting"... i.e. translate_names will end when the first
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar * module returns OK. So for example, if the request is something like:
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar *
8419e6f8bff1a3617933f3ba760d2bdec7442f44coar * GET http://othervhost/cgi-bin/printenv HTTP/1.0
2a6e98ba4ffa30ded5d8831664c5cb2a170a56b6coar *
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz * mod_alias will notice the /cgi-bin part and ScriptAlias it and
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz * short-circuit the proxy... just because of the ordering in the
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe * configuration file.
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe */
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowestatic int proxy_detect(request_rec *r)
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe{
4f9c22c4f27571d54197be9674e1fc0d528192aestriker void *sconf = r->server->module_config;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker proxy_server_conf *conf;
3e392a5afd51526de3cb15d57ee46d8cb160ae65gregames
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe conf = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if (conf->req && r->parsed_uri.scheme) {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe /* but it might be something vhosted */
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe if (!(r->parsed_uri.hostname
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe && !strcasecmp(r->parsed_uri.scheme, ap_http_method(r))
efd83d1dd1a25688a3093c5a542ae16bacef62ddsf && ap_matches_request_vhost(r, r->parsed_uri.hostname,
efd83d1dd1a25688a3093c5a542ae16bacef62ddsf r->parsed_uri.port_str ? r->parsed_uri.port : ap_default_port(r)))) {
efd83d1dd1a25688a3093c5a542ae16bacef62ddsf r->proxyreq = 1;
efd83d1dd1a25688a3093c5a542ae16bacef62ddsf r->uri = r->unparsed_uri;
efd83d1dd1a25688a3093c5a542ae16bacef62ddsf r->filename = apr_pstrcat(r->pool, "proxy:", r->uri, NULL);
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe r->handler = "proxy-server";
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe }
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe /* We need special treatment for CONNECT proxying: it has no scheme part */
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe else if (conf->req && r->method_number == M_CONNECT
4f9c22c4f27571d54197be9674e1fc0d528192aestriker && r->parsed_uri.hostname
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe && r->parsed_uri.port_str) {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe r->proxyreq = 1;
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe r->uri = r->unparsed_uri;
c2cf53a40a9814eb91db2cdf820f97d943f21628coar r->filename = apr_pstrcat(r->pool, "proxy:", r->uri, NULL);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe r->handler = "proxy-server";
4775dfc34c90fada8c7c4d6a57ed8a3114d55c2dtrawick }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe return DECLINED;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe}
11a0edf478ca9c59d80bf73491d89cf019259feeniq
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowestatic int proxy_trans(request_rec *r)
11a0edf478ca9c59d80bf73491d89cf019259feeniq{
11a0edf478ca9c59d80bf73491d89cf019259feeniq void *sconf = r->server->module_config;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe proxy_server_conf *conf =
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
efd83d1dd1a25688a3093c5a542ae16bacef62ddsf int i, len;
efd83d1dd1a25688a3093c5a542ae16bacef62ddsf struct proxy_alias *ent = (struct proxy_alias *) conf->aliases->elts;
efd83d1dd1a25688a3093c5a542ae16bacef62ddsf
efd83d1dd1a25688a3093c5a542ae16bacef62ddsf if (r->proxyreq) {
efd83d1dd1a25688a3093c5a542ae16bacef62ddsf /* someone has already set up the proxy, it was possibly ourselves
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe * in proxy_detect
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe */
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe return OK;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe }
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe /* XXX: since r->uri has been manipulated already we're not really
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe * compliant with RFC1945 at this point. But this probably isn't
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe * an issue because this is a hybrid proxy/origin server.
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe */
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe for (i = 0; i < conf->aliases->nelts; i++) {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe len = alias_match(r->uri, ent[i].fake);
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd
4f9c22c4f27571d54197be9674e1fc0d528192aestriker if (len > 0) {
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe r->filename = apr_pstrcat(r->pool, "proxy:", ent[i].real,
fa06de8a28a737e8fbaad76d7f3ff67aaa5e4a09wrowe r->uri + len, NULL);
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd r->handler = "proxy-server";
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd r->proxyreq = 1;
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd return OK;
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar }
0d26b42fc1735e110c6dc83b114c56257b20070bbnicholes return DECLINED;
0d26b42fc1735e110c6dc83b114c56257b20070bbnicholes}
0d26b42fc1735e110c6dc83b114c56257b20070bbnicholes
0d26b42fc1735e110c6dc83b114c56257b20070bbnicholes/* -------------------------------------------------------------- */
18b5268e013574026b2503b1641baf3299045f45sf/* Fixup the filename */
18b5268e013574026b2503b1641baf3299045f45sf
0d26b42fc1735e110c6dc83b114c56257b20070bbnicholes/*
4f9c22c4f27571d54197be9674e1fc0d528192aestriker * Canonicalise the URL
18b5268e013574026b2503b1641baf3299045f45sf */
18b5268e013574026b2503b1641baf3299045f45sfstatic int proxy_fixup(request_rec *r)
18b5268e013574026b2503b1641baf3299045f45sf{
18b5268e013574026b2503b1641baf3299045f45sf char *url, *p;
d9cc5de428947d5c7221d7d42ceefea649bcab48sf
18b5268e013574026b2503b1641baf3299045f45sf if (!r->proxyreq || strncmp(r->filename, "proxy:", 6) != 0)
18b5268e013574026b2503b1641baf3299045f45sf return DECLINED;
18b5268e013574026b2503b1641baf3299045f45sf
18b5268e013574026b2503b1641baf3299045f45sf url = &r->filename[6];
18b5268e013574026b2503b1641baf3299045f45sf
18b5268e013574026b2503b1641baf3299045f45sf/* canonicalise each specific scheme */
404381a78d109fd3a4a7702e69815e4d7ff6d93asf if (strncasecmp(url, "http:", 5) == 0)
404381a78d109fd3a4a7702e69815e4d7ff6d93asf return ap_proxy_http_canon(r, url + 5, "http", DEFAULT_HTTP_PORT);
1a7a4f8c6a312cb237e428c77da0792eb165dc7aniq else if (strncasecmp(url, "ftp:", 4) == 0)
1a7a4f8c6a312cb237e428c77da0792eb165dc7aniq return ap_proxy_ftp_canon(r, url + 4);
1a7a4f8c6a312cb237e428c77da0792eb165dc7aniq
1a7a4f8c6a312cb237e428c77da0792eb165dc7aniq p = strchr(url, ':');
1a7a4f8c6a312cb237e428c77da0792eb165dc7aniq if (p == NULL || p == url)
1a7a4f8c6a312cb237e428c77da0792eb165dc7aniq return HTTP_BAD_REQUEST;
1a7a4f8c6a312cb237e428c77da0792eb165dc7aniq
1a7a4f8c6a312cb237e428c77da0792eb165dc7aniq return OK; /* otherwise; we've done the best we can */
18b5268e013574026b2503b1641baf3299045f45sf}
18b5268e013574026b2503b1641baf3299045f45sf
18b5268e013574026b2503b1641baf3299045f45sf/* Send a redirection if the request contains a hostname which is not */
0d26b42fc1735e110c6dc83b114c56257b20070bbnicholes/* fully qualified, i.e. doesn't have a domain name appended. Some proxy */
0d26b42fc1735e110c6dc83b114c56257b20070bbnicholes/* servers like Netscape's allow this and access hosts from the local */
0d26b42fc1735e110c6dc83b114c56257b20070bbnicholes/* domain in this case. I think it is better to redirect to a FQDN, since */
18b5268e013574026b2503b1641baf3299045f45sf/* these will later be found in the bookmarks files. */
18b5268e013574026b2503b1641baf3299045f45sf/* The "ProxyDomain" directive determines what domain will be appended */
18b5268e013574026b2503b1641baf3299045f45sfstatic int proxy_needsdomain(request_rec *r, const char *url, const char *domain)
18b5268e013574026b2503b1641baf3299045f45sf{
18b5268e013574026b2503b1641baf3299045f45sf char *nuri;
18b5268e013574026b2503b1641baf3299045f45sf const char *ref;
18b5268e013574026b2503b1641baf3299045f45sf
4f9c22c4f27571d54197be9674e1fc0d528192aestriker /* We only want to worry about GETs */
18b5268e013574026b2503b1641baf3299045f45sf if (!r->proxyreq || r->method_number != M_GET || !r->parsed_uri.hostname)
18b5268e013574026b2503b1641baf3299045f45sf return DECLINED;
18b5268e013574026b2503b1641baf3299045f45sf
18b5268e013574026b2503b1641baf3299045f45sf /* If host does contain a dot already, or it is "localhost", decline */
d9cc5de428947d5c7221d7d42ceefea649bcab48sf if (strchr(r->parsed_uri.hostname, '.') != NULL
18b5268e013574026b2503b1641baf3299045f45sf || strcasecmp(r->parsed_uri.hostname, "localhost") == 0)
18b5268e013574026b2503b1641baf3299045f45sf return DECLINED; /* host name has a dot already */
18b5268e013574026b2503b1641baf3299045f45sf
18b5268e013574026b2503b1641baf3299045f45sf ref = apr_table_get(r->headers_in, "Referer");
18b5268e013574026b2503b1641baf3299045f45sf
0d26b42fc1735e110c6dc83b114c56257b20070bbnicholes /* Reassemble the request, but insert the domain after the host name */
18b5268e013574026b2503b1641baf3299045f45sf /* Note that the domain name always starts with a dot */
0d26b42fc1735e110c6dc83b114c56257b20070bbnicholes r->parsed_uri.hostname = apr_pstrcat(r->pool, r->parsed_uri.hostname,
0d26b42fc1735e110c6dc83b114c56257b20070bbnicholes domain, NULL);
0d26b42fc1735e110c6dc83b114c56257b20070bbnicholes nuri = ap_unparse_uri_components(r->pool,
0d26b42fc1735e110c6dc83b114c56257b20070bbnicholes &r->parsed_uri,
0d26b42fc1735e110c6dc83b114c56257b20070bbnicholes UNP_REVEALPASSWORD);
0d26b42fc1735e110c6dc83b114c56257b20070bbnicholes
0d26b42fc1735e110c6dc83b114c56257b20070bbnicholes apr_table_set(r->headers_out, "Location", nuri);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe ap_log_rerror(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, 0, r,
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe "Domain missing: %s sent to %s%s%s", r->uri,
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe ap_unparse_uri_components(r->pool, &r->parsed_uri,
4f9c22c4f27571d54197be9674e1fc0d528192aestriker UNP_OMITUSERINFO),
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe ref ? " from " : "", ref ? ref : "");
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
d176cb9e596e4603f76490f9211f62b5581b3091rooneg return HTTP_MOVED_PERMANENTLY;
d4abb06ac220bb280ae996b6d21bbd257db51bb1jerenkrantz}
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe/* -------------------------------------------------------------- */
d176cb9e596e4603f76490f9211f62b5581b3091rooneg/* Invoke handler */
4760b58cc9fe170e4ad4648ed4ff7a422a2cef38sf
4760b58cc9fe170e4ad4648ed4ff7a422a2cef38sfstatic int proxy_handler(request_rec *r)
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe{
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe char *url, *scheme, *p;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe const char *p2;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe void *sconf = r->server->module_config;
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe proxy_server_conf *conf = (proxy_server_conf *)
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe ap_get_module_config(sconf, &proxy_module);
83a8dc5a596a8a1b9d14f063268287d123b9ed7ewrowe apr_array_header_t *proxies = conf->proxies;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe struct proxy_remote *ents = (struct proxy_remote *) proxies->elts;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe int i, rc;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe ap_cache_el *cr = NULL;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe int direct_connect = 0;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe const char *maxfwd_str;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker const char *pragma, *auth, *imstr;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe if (!r->proxyreq || strncmp(r->filename, "proxy:", 6) != 0)
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe return DECLINED;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe
0540a0b469147b52e858587270dba31c2aaa9e09wrowe if (r->method_number == M_TRACE &&
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe (maxfwd_str = apr_table_get(r->headers_in, "Max-Forwards")) != NULL) {
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe long maxfwd = strtol(maxfwd_str, NULL, 10);
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe if (maxfwd < 1) {
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe int access_status;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe r->proxyreq = 0;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker if ((access_status = ap_send_http_trace(r)))
4f9c22c4f27571d54197be9674e1fc0d528192aestriker ap_die(access_status, r);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker else
4f9c22c4f27571d54197be9674e1fc0d528192aestriker ap_finalize_request_protocol(r);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker return OK;
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd }
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd apr_table_setn(r->headers_in, "Max-Forwards",
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe apr_psprintf(r->pool, "%ld", (maxfwd > 0) ? maxfwd-1 : 0));
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe }
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)))
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd return rc;
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd url = r->filename + 6;
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd p = strchr(url, ':');
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd if (p == NULL)
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd return HTTP_BAD_REQUEST;
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd pragma = apr_table_get(r->headers_in, "Pragma");
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd auth = apr_table_get(r->headers_in, "Authorization");
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd imstr = apr_table_get(r->headers_in, "If-Modified-Since");
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp "Request for %s, pragma=%s, auth=%s, imstr=%s", url,
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp pragma, auth, imstr);
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp /* can this request be cached at all? */
4f9c22c4f27571d54197be9674e1fc0d528192aestriker if (r->method_number == M_GET && strlen(url) < 1024 &&
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd !ap_proxy_liststr(pragma, "no-cache") && auth == NULL)
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd {
4f9c22c4f27571d54197be9674e1fc0d528192aestriker if(ap_cache_seek(conf->cache, url, &cr) == APR_SUCCESS)
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd {
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd int has_m = 0;
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd /* now we need to check if the last modified date is write if */
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd if(imstr)
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd {
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd time_t ims = (time_t)ap_parseHTTPdate(ap_proxy_date_canon(r->pool, imstr));
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd if(ims == BAD_DATE)
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd apr_table_unset(r->headers_in, "If-Modified-Since");
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd else
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe {
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd /* ok we were asked to check, so let's do that */
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd if(ap_cache_el_header(cr, "Last-Modified",
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe (char **)&imstr) == APR_SUCCESS)
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd {
4f9c22c4f27571d54197be9674e1fc0d528192aestriker time_t lm =
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd ap_parseHTTPdate(ap_proxy_date_canon(r->pool, imstr)); if(lm != BAD_DATE)
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd {
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd if(ims < lm)
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd apr_table_set(r->headers_in,
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd "If-Modified-Since", imstr);
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd else
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd {
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd has_m = 1;
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe }
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd }
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd }
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd }
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe }
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe return has_m ? HTTP_NOT_MODIFIED : ap_proxy_cache_send(r, cr);
cc9582e53aead2a044077c4a92f3dfc3605590b3wrowe }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* if there wasn't an entry in the cache we get here,
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb we need to create one */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ap_cache_create(conf->cache, url, &cr);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb /* If the host doesn't have a domain name, add one and redirect. */
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (conf->domain != NULL) {
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb rc = proxy_needsdomain(r, url, conf->domain);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb if (ap_is_HTTP_REDIRECT(rc))
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb return HTTP_MOVED_PERMANENTLY;
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb }
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *p = '\0';
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb scheme = apr_pstrdup(r->pool, url);
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb *p = ':';
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe /* Check URI's destination host against NoProxy hosts */
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe /* Bypass ProxyRemote server lookup if configured as NoProxy */
4f9c22c4f27571d54197be9674e1fc0d528192aestriker /* we only know how to handle communication to a proxy via http */
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe /*if (strcasecmp(scheme, "http") == 0) */
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe {
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe int ii;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe struct dirconn_entry *list = (struct dirconn_entry *) conf->dirconn->elts;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe for (direct_connect = ii = 0; ii < conf->dirconn->nelts && !direct_connect; ii++) {
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe direct_connect = list[ii].matcher(&list[ii], r);
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe }
4f9c22c4f27571d54197be9674e1fc0d528192aestriker#if DEBUGGING
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r,
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe (direct_connect) ? "NoProxy for %s" : "UseProxy for %s",
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe r->uri);
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe#endif
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe }
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe/* firstly, try a proxy, unless a NoProxy directive is active */
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe if (!direct_connect)
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar for (i = 0; i < proxies->nelts; i++) {
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe p2 = ap_strchr_c(ents[i].scheme, ':'); /* is it a partial URL? */
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz if (strcmp(ents[i].scheme, "*") == 0 ||
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz (p2 == NULL && strcasecmp(scheme, ents[i].scheme) == 0) ||
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz (p2 != NULL &&
1e911973bcb9df6701a4c16c037771ecf25ade13niq strncasecmp(url, ents[i].scheme, strlen(ents[i].scheme)) == 0)) {
1e911973bcb9df6701a4c16c037771ecf25ade13niq /* CONNECT is a special method that bypasses the normal
c3e233736c4a453cbb2166a041f779e86230630asf * proxy code.
c3e233736c4a453cbb2166a041f779e86230630asf */
c3e233736c4a453cbb2166a041f779e86230630asf if (r->method_number == M_CONNECT)
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe rc = ap_proxy_connect_handler(r, cr, url, ents[i].hostname,
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar ents[i].port);
11fb2f3611e6ff9a541e10b13e3108934f828141gregames/* we only know how to handle communication to a proxy via http */
11fb2f3611e6ff9a541e10b13e3108934f828141gregames else if (strcasecmp(ents[i].protocol, "http") == 0)
11fb2f3611e6ff9a541e10b13e3108934f828141gregames rc = ap_proxy_http_handler(r, cr, url, ents[i].hostname,
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz ents[i].port);
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz else
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz rc = DECLINED;
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz
4f9c22c4f27571d54197be9674e1fc0d528192aestriker /* an error or success */
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe if (rc != DECLINED && rc != HTTP_BAD_GATEWAY)
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe return rc;
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe /* we failed to talk to the upstream proxy */
4f9c22c4f27571d54197be9674e1fc0d528192aestriker }
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe }
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe/* otherwise, try it direct */
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar/* N.B. what if we're behind a firewall, where we must use a proxy or
c3e233736c4a453cbb2166a041f779e86230630asf * give up??
c3e233736c4a453cbb2166a041f779e86230630asf */
c3e233736c4a453cbb2166a041f779e86230630asf /* handle the scheme */
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe if (r->method_number == M_CONNECT)
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar return ap_proxy_connect_handler(r, cr, url, NULL, 0);
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar if (strcasecmp(scheme, "http") == 0)
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe return ap_proxy_http_handler(r, cr, url, NULL, 0);
c3e233736c4a453cbb2166a041f779e86230630asf if (strcasecmp(scheme, "ftp") == 0)
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe return ap_proxy_ftp_handler(r, cr, url);
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar else
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe return HTTP_FORBIDDEN;
1fbf6ba0f5207e6637b49f9a9dfcc779bbe952a9trawick}
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar/* -------------------------------------------------------------- */
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe/* Setup configurable data */
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowestatic void * create_proxy_config(apr_pool_t *p, server_rec *s)
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz{
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz proxy_server_conf *ps = ap_pcalloc(p, sizeof(proxy_server_conf));
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz
7c301a1818939f85da8f3629cc3e9b5588610ef0jerenkrantz ps->proxies = ap_make_array(p, 10, sizeof(struct proxy_remote));
4f9c22c4f27571d54197be9674e1fc0d528192aestriker ps->aliases = ap_make_array(p, 10, sizeof(struct proxy_alias));
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe ps->raliases = ap_make_array(p, 10, sizeof(struct proxy_alias));
290ecc1ddceca1ed49bc1a5338921264b5c3e07cwrowe ps->noproxies = ap_make_array(p, 10, sizeof(struct noproxy_entry));
b38846b15c8891c6dec44dcc4f96ca40721bf663rbb ps->dirconn = ap_make_array(p, 10, sizeof(struct dirconn_entry));
8aefbd756763807188d2e3ce336a8680e4893066wrowe ps->nocaches = ap_make_array(p, 10, sizeof(struct nocache_entry));
700b96db75e7cfadb5219978c1735b710d583763wrowe ps->allowed_connect_ports = ap_make_array(p, 10, sizeof(int));
700b96db75e7cfadb5219978c1735b710d583763wrowe ps->cache_completion = DEFAULT_CACHE_COMPLETION;
700b96db75e7cfadb5219978c1735b710d583763wrowe ps->domain = NULL;
700b96db75e7cfadb5219978c1735b710d583763wrowe ps->viaopt = via_off; /* initially backward compatible with 1.3.1 */
700b96db75e7cfadb5219978c1735b710d583763wrowe ps->req = 0;
700b96db75e7cfadb5219978c1735b710d583763wrowe
700b96db75e7cfadb5219978c1735b710d583763wrowe ap_cache_init(&ps->cache, "mod_proxy cache", s);
700b96db75e7cfadb5219978c1735b710d583763wrowe return ps;
700b96db75e7cfadb5219978c1735b710d583763wrowe}
700b96db75e7cfadb5219978c1735b710d583763wrowe
700b96db75e7cfadb5219978c1735b710d583763wrowestatic const char *
700b96db75e7cfadb5219978c1735b710d583763wrowe add_proxy(cmd_parms *cmd, void *dummy, const char *f1, const char *r1)
700b96db75e7cfadb5219978c1735b710d583763wrowe{
700b96db75e7cfadb5219978c1735b710d583763wrowe server_rec *s = cmd->server;
700b96db75e7cfadb5219978c1735b710d583763wrowe proxy_server_conf *conf =
700b96db75e7cfadb5219978c1735b710d583763wrowe (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module);
103a93c625bcde1a6a7a5155b64dcda36f612180pquerna struct proxy_remote *new;
700b96db75e7cfadb5219978c1735b710d583763wrowe char *p, *q;
700b96db75e7cfadb5219978c1735b710d583763wrowe char *r, *f;
6964758306167dd898baedd21048bd1515dd9d30trawick int port;
700b96db75e7cfadb5219978c1735b710d583763wrowe
700b96db75e7cfadb5219978c1735b710d583763wrowe r = apr_pstrdup(cmd->pool, r1);
700b96db75e7cfadb5219978c1735b710d583763wrowe f = apr_pstrdup(cmd->pool, f1);
700b96db75e7cfadb5219978c1735b710d583763wrowe p = strchr(r, ':');
700b96db75e7cfadb5219978c1735b710d583763wrowe if (p == NULL || p[1] != '/' || p[2] != '/' || p[3] == '\0')
700b96db75e7cfadb5219978c1735b710d583763wrowe return "ProxyRemote: Bad syntax for a remote proxy server";
700b96db75e7cfadb5219978c1735b710d583763wrowe q = strchr(p + 3, ':');
700b96db75e7cfadb5219978c1735b710d583763wrowe if (q != NULL) {
700b96db75e7cfadb5219978c1735b710d583763wrowe if (sscanf(q + 1, "%u", &port) != 1 || port > 65535)
700b96db75e7cfadb5219978c1735b710d583763wrowe return "ProxyRemote: Bad syntax for a remote proxy server (bad port number)";
700b96db75e7cfadb5219978c1735b710d583763wrowe *q = '\0';
700b96db75e7cfadb5219978c1735b710d583763wrowe }
700b96db75e7cfadb5219978c1735b710d583763wrowe else
700b96db75e7cfadb5219978c1735b710d583763wrowe port = -1;
700b96db75e7cfadb5219978c1735b710d583763wrowe *p = '\0';
700b96db75e7cfadb5219978c1735b710d583763wrowe if (strchr(f, ':') == NULL)
700b96db75e7cfadb5219978c1735b710d583763wrowe ap_str_tolower(f); /* lowercase scheme */
700b96db75e7cfadb5219978c1735b710d583763wrowe ap_str_tolower(p + 3); /* lowercase hostname */
700b96db75e7cfadb5219978c1735b710d583763wrowe
700b96db75e7cfadb5219978c1735b710d583763wrowe if (port == -1) {
700b96db75e7cfadb5219978c1735b710d583763wrowe int i;
700b96db75e7cfadb5219978c1735b710d583763wrowe for (i = 0; defports[i].scheme != NULL; i++)
103a93c625bcde1a6a7a5155b64dcda36f612180pquerna if (strcasecmp(defports[i].scheme, r) == 0)
103a93c625bcde1a6a7a5155b64dcda36f612180pquerna break;
700b96db75e7cfadb5219978c1735b710d583763wrowe port = defports[i].port;
700b96db75e7cfadb5219978c1735b710d583763wrowe }
700b96db75e7cfadb5219978c1735b710d583763wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe new = apr_push_array(conf->proxies);
8aefbd756763807188d2e3ce336a8680e4893066wrowe new->scheme = f;
8aefbd756763807188d2e3ce336a8680e4893066wrowe new->protocol = r;
8aefbd756763807188d2e3ce336a8680e4893066wrowe new->hostname = p + 3;
8aefbd756763807188d2e3ce336a8680e4893066wrowe new->port = port;
8aefbd756763807188d2e3ce336a8680e4893066wrowe return NULL;
8aefbd756763807188d2e3ce336a8680e4893066wrowe}
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowestatic const char *
8aefbd756763807188d2e3ce336a8680e4893066wrowe set_cache_exclude(cmd_parms *cmd, void *dummy, const char *arg)
8aefbd756763807188d2e3ce336a8680e4893066wrowe{
8aefbd756763807188d2e3ce336a8680e4893066wrowe server_rec *s = cmd->server;
8aefbd756763807188d2e3ce336a8680e4893066wrowe proxy_server_conf *psf = (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module);
8aefbd756763807188d2e3ce336a8680e4893066wrowe struct nocache_entry *new;
8aefbd756763807188d2e3ce336a8680e4893066wrowe struct nocache_entry *list = (struct nocache_entry *) psf->nocaches->elts;
a2a0abd88b19e042a3eb2a9fa1702c25ad51303dwrowe struct hostent hp;
8aefbd756763807188d2e3ce336a8680e4893066wrowe int found = 0;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe int i;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe /* Don't duplicate entries */
2fa5b5878e7567e2875807c3e2a2b3b0d3ef74bewrowe for (i = 0; i < psf->nocaches->nelts; i++) {
2fa5b5878e7567e2875807c3e2a2b3b0d3ef74bewrowe if (strcasecmp(arg, list[i].name) == 0) /* ignore case for host names */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe found = 1;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe }
8aefbd756763807188d2e3ce336a8680e4893066wrowe
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd if (!found) {
8aefbd756763807188d2e3ce336a8680e4893066wrowe new = apr_push_array(psf->nocaches);
dc8692c6c0ca616a09aa12dad005f2ef23baa1a0wrowe new->name = arg;
a8d11d78181478da6a672f7fbc58b8d523351f49wrowe /* Don't do name lookups on things that aren't dotted */
4f9c22c4f27571d54197be9674e1fc0d528192aestriker if (ap_strchr_c(arg, '.') != NULL &&
23c6309e36a63b13b61c35999c978017521993d6wrowe ap_proxy_host2addr(new->name, &hp) == NULL)
23c6309e36a63b13b61c35999c978017521993d6wrowe /*@@@FIXME: This copies only the first of (possibly many) IP addrs */ memcpy(&new->addr, hp.h_addr, sizeof(struct in_addr));
4f9c22c4f27571d54197be9674e1fc0d528192aestriker else
23c6309e36a63b13b61c35999c978017521993d6wrowe new->addr.s_addr = 0;
8aefbd756763807188d2e3ce336a8680e4893066wrowe }
23c6309e36a63b13b61c35999c978017521993d6wrowe return NULL;
2d399cd7535887fceaa9f8f116eb98ce68ddd602trawick}
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
23c6309e36a63b13b61c35999c978017521993d6wrowestatic const char *
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe add_pass(cmd_parms *cmd, void *dummy, const char *f, const char *r)
8aefbd756763807188d2e3ce336a8680e4893066wrowe{
8aefbd756763807188d2e3ce336a8680e4893066wrowe server_rec *s = cmd->server;
cf6ef072483172309861d06e85b1aeff4573c060wrowe proxy_server_conf *conf =
cf6ef072483172309861d06e85b1aeff4573c060wrowe (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module);
cf6ef072483172309861d06e85b1aeff4573c060wrowe struct proxy_alias *new;
8aefbd756763807188d2e3ce336a8680e4893066wrowe
4f9c22c4f27571d54197be9674e1fc0d528192aestriker new = apr_push_array(conf->aliases);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker new->fake = f;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe new->real = r;
2d399cd7535887fceaa9f8f116eb98ce68ddd602trawick return NULL;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe}
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
a8d11d78181478da6a672f7fbc58b8d523351f49wrowestatic const char *
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe add_pass_reverse(cmd_parms *cmd, void *dummy, const char *f, const char *r)
8aefbd756763807188d2e3ce336a8680e4893066wrowe{
8aefbd756763807188d2e3ce336a8680e4893066wrowe server_rec *s = cmd->server;
cf6ef072483172309861d06e85b1aeff4573c060wrowe proxy_server_conf *conf;
cf6ef072483172309861d06e85b1aeff4573c060wrowe struct proxy_alias *new;
cf6ef072483172309861d06e85b1aeff4573c060wrowe
8aefbd756763807188d2e3ce336a8680e4893066wrowe conf = (proxy_server_conf *)ap_get_module_config(s->module_config,
cf6ef072483172309861d06e85b1aeff4573c060wrowe &proxy_module);
cf6ef072483172309861d06e85b1aeff4573c060wrowe new = apr_push_array(conf->raliases);
a2b181763cb35fd899feb4a436aeadaa80bf91eabrianp new->fake = f;
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd new->real = r;
cf6ef072483172309861d06e85b1aeff4573c060wrowe return NULL;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker}
cf6ef072483172309861d06e85b1aeff4573c060wrowe
cf6ef072483172309861d06e85b1aeff4573c060wrowestatic const char *
cf6ef072483172309861d06e85b1aeff4573c060wrowe set_proxy_exclude(cmd_parms *parms, void *dummy, const char *arg)
cf6ef072483172309861d06e85b1aeff4573c060wrowe{
cf6ef072483172309861d06e85b1aeff4573c060wrowe server_rec *s = parms->server;
cf6ef072483172309861d06e85b1aeff4573c060wrowe proxy_server_conf *conf =
cf6ef072483172309861d06e85b1aeff4573c060wrowe ap_get_module_config(s->module_config, &proxy_module);
cf6ef072483172309861d06e85b1aeff4573c060wrowe struct noproxy_entry *new;
cf6ef072483172309861d06e85b1aeff4573c060wrowe struct noproxy_entry *list = (struct noproxy_entry *) conf->noproxies->elts;
69adb3d949e3dd17c0492a01fc2cf298832c7eefwrowe struct hostent hp;
ecde48c75338ff5712f2036711f813c6dedca28ewrowe int found = 0;
d75626f0952c6152a99acd013a4f127d46f0f9edtrawick int i;
d75626f0952c6152a99acd013a4f127d46f0f9edtrawick
d75626f0952c6152a99acd013a4f127d46f0f9edtrawick /* Don't duplicate entries */
d75626f0952c6152a99acd013a4f127d46f0f9edtrawick for (i = 0; i < conf->noproxies->nelts; i++) {
d75626f0952c6152a99acd013a4f127d46f0f9edtrawick if (strcasecmp(arg, list[i].name) == 0) /* ignore case for host names */
d75626f0952c6152a99acd013a4f127d46f0f9edtrawick found = 1;
d75626f0952c6152a99acd013a4f127d46f0f9edtrawick }
d75626f0952c6152a99acd013a4f127d46f0f9edtrawick
ecde48c75338ff5712f2036711f813c6dedca28ewrowe if (!found) {
ecde48c75338ff5712f2036711f813c6dedca28ewrowe new = apr_push_array(conf->noproxies);
d75626f0952c6152a99acd013a4f127d46f0f9edtrawick new->name = arg;
ecde48c75338ff5712f2036711f813c6dedca28ewrowe /* Don't do name lookups on things that aren't dotted */
ecde48c75338ff5712f2036711f813c6dedca28ewrowe if (ap_strchr_c(arg, '.') != NULL &&
ecde48c75338ff5712f2036711f813c6dedca28ewrowe ap_proxy_host2addr(new->name, &hp) == NULL)
ecde48c75338ff5712f2036711f813c6dedca28ewrowe /*@@@FIXME: This copies only the first of (possibly many) IP addrs */
ecde48c75338ff5712f2036711f813c6dedca28ewrowe memcpy(&new->addr, hp.h_addr, sizeof(struct in_addr));
d75626f0952c6152a99acd013a4f127d46f0f9edtrawick else
cf6ef072483172309861d06e85b1aeff4573c060wrowe new->addr.s_addr = 0;
cf6ef072483172309861d06e85b1aeff4573c060wrowe }
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar return NULL;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe}
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar/*
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe * Set the ports CONNECT can use
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar */
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowestatic const char *
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe set_allowed_ports(cmd_parms *parms, void *dummy, const char *arg)
4f9c22c4f27571d54197be9674e1fc0d528192aestriker{
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe server_rec *s = parms->server;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe proxy_server_conf *conf =
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd ap_get_module_config(s->module_config, &proxy_module);
23c6309e36a63b13b61c35999c978017521993d6wrowe int *New;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
4f9c22c4f27571d54197be9674e1fc0d528192aestriker if (!apr_isdigit(arg[0]))
4f9c22c4f27571d54197be9674e1fc0d528192aestriker return "AllowCONNECT: port number must be numeric";
c2cf53a40a9814eb91db2cdf820f97d943f21628coar
170476518c96db46fff6fdce7cb9a3f24abfaea7rpluem New = apr_push_array(conf->allowed_connect_ports);
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem *New = atoi(arg);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return NULL;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker}
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe/* Similar to set_proxy_exclude(), but defining directly connected hosts,
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe * which should never be accessed via the configured ProxyRemote servers
a9a4544168a37b43bd180b3703ccee995f27a80awrowe */
170476518c96db46fff6fdce7cb9a3f24abfaea7rpluemstatic const char *
a9a4544168a37b43bd180b3703ccee995f27a80awrowe set_proxy_dirconn(cmd_parms *parms, void *dummy, const char *arg)
4f9c22c4f27571d54197be9674e1fc0d528192aestriker{
a9a4544168a37b43bd180b3703ccee995f27a80awrowe server_rec *s = parms->server;
a9a4544168a37b43bd180b3703ccee995f27a80awrowe proxy_server_conf *conf =
170476518c96db46fff6fdce7cb9a3f24abfaea7rpluem ap_get_module_config(s->module_config, &proxy_module);
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem struct dirconn_entry *New;
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem struct dirconn_entry *list = (struct dirconn_entry *) conf->dirconn->elts;
170476518c96db46fff6fdce7cb9a3f24abfaea7rpluem int found = 0;
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem int i;
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem /* Don't duplicate entries */
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem for (i = 0; i < conf->dirconn->nelts; i++) {
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem if (strcasecmp(arg, list[i].name) == 0)
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem found = 1;
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem }
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem if (!found) {
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem New = apr_push_array(conf->dirconn);
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem New->name = apr_pstrdup(parms->pool, arg);
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem New->hostentry = NULL;
ad099b4d62597be19f8dba650663e796cbaa8d28rpluem
ad099b4d62597be19f8dba650663e796cbaa8d28rpluem if (ap_proxy_is_ipaddr(New, parms->pool)) {
ad099b4d62597be19f8dba650663e796cbaa8d28rpluem#if DEBUGGING
eb12400ff685a3b69476736ca4b5389f348b9d63rpluem ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
eb12400ff685a3b69476736ca4b5389f348b9d63rpluem "Parsed addr %s", inet_ntoa(New->addr));
eb12400ff685a3b69476736ca4b5389f348b9d63rpluem ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
eb12400ff685a3b69476736ca4b5389f348b9d63rpluem "Parsed mask %s", inet_ntoa(New->mask));
eb12400ff685a3b69476736ca4b5389f348b9d63rpluem#endif
eb12400ff685a3b69476736ca4b5389f348b9d63rpluem }
eb12400ff685a3b69476736ca4b5389f348b9d63rpluem else if (ap_proxy_is_domainname(New, parms->pool)) {
eb12400ff685a3b69476736ca4b5389f348b9d63rpluem ap_str_tolower(New->name);
ad099b4d62597be19f8dba650663e796cbaa8d28rpluem#if DEBUGGING
ad099b4d62597be19f8dba650663e796cbaa8d28rpluem ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
ad099b4d62597be19f8dba650663e796cbaa8d28rpluem "Parsed domain %s", New->name);
ad099b4d62597be19f8dba650663e796cbaa8d28rpluem#endif
ad099b4d62597be19f8dba650663e796cbaa8d28rpluem }
ad099b4d62597be19f8dba650663e796cbaa8d28rpluem else if (ap_proxy_is_hostname(New, parms->pool)) {
ad099b4d62597be19f8dba650663e796cbaa8d28rpluem ap_str_tolower(New->name);
ad099b4d62597be19f8dba650663e796cbaa8d28rpluem#if DEBUGGING
ad099b4d62597be19f8dba650663e796cbaa8d28rpluem ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
75c02648f9afe9a1da5d5482703fcbca306ffcdcpquerna "Parsed host %s", New->name);
75c02648f9afe9a1da5d5482703fcbca306ffcdcpquerna#endif
ad099b4d62597be19f8dba650663e796cbaa8d28rpluem }
ad099b4d62597be19f8dba650663e796cbaa8d28rpluem else {
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem ap_proxy_is_word(New, parms->pool);
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem#if DEBUGGING
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem fprintf(stderr, "Parsed word %s\n", New->name);
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem#endif
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem }
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem }
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem return NULL;
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem}
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluemstatic const char *
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem set_proxy_domain(cmd_parms *parms, void *dummy, const char *arg)
534611d341a1a48b93c7a1fd5e333dbd261527d3rpluem{
a9a4544168a37b43bd180b3703ccee995f27a80awrowe proxy_server_conf *psf =
a9a4544168a37b43bd180b3703ccee995f27a80awrowe ap_get_module_config(parms->server->module_config, &proxy_module);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar if (arg[0] != '.')
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return "ProxyDomain: domain name must start with a dot.";
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar
731344ed8f3677d1661c261ca5fcdd2ee3dbc74ccoar psf->domain = arg;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe return NULL;
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe}
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowestatic const char *
8aefbd756763807188d2e3ce336a8680e4893066wrowe set_proxy_req(cmd_parms *parms, void *dummy, int flag)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe{
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe proxy_server_conf *psf =
a72211e92bab814bfa28ee086ca9b2a1a6095c92chrisd ap_get_module_config(parms->server->module_config, &proxy_module);
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe psf->req = flag;
700b96db75e7cfadb5219978c1735b710d583763wrowe return NULL;
cf6ef072483172309861d06e85b1aeff4573c060wrowe}
cf6ef072483172309861d06e85b1aeff4573c060wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowestatic const char *
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe set_recv_buffer_size(cmd_parms *parms, void *dummy, const char *arg)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe{
8aefbd756763807188d2e3ce336a8680e4893066wrowe proxy_server_conf *psf =
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz ap_get_module_config(parms->server->module_config, &proxy_module);
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz int s = atoi(arg);
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz if (s < 512 && s != 0) {
cf6ef072483172309861d06e85b1aeff4573c060wrowe return "ProxyReceiveBufferSize must be >= 512 bytes, or 0 for system default.";
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe }
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe psf->recv_buffer_size = s;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker return NULL;
3dcf67a5060400edb8ccef3fb4a2024388965af9martin}
3dcf67a5060400edb8ccef3fb4a2024388965af9martin
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowestatic const char*
2fd8d1e14fc47762d1e01660b544d5e2a75c825dtrawick set_via_opt(cmd_parms *parms, void *dummy, const char *arg)
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe{
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe proxy_server_conf *psf =
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe ap_get_module_config(parms->server->module_config, &proxy_module);
8aefbd756763807188d2e3ce336a8680e4893066wrowe
e4a3f3c2f080cac75a15a6454cca429b8161c050wrowe if (strcasecmp(arg, "Off") == 0)
700b96db75e7cfadb5219978c1735b710d583763wrowe psf->viaopt = via_off;
700b96db75e7cfadb5219978c1735b710d583763wrowe else if (strcasecmp(arg, "On") == 0)
700b96db75e7cfadb5219978c1735b710d583763wrowe psf->viaopt = via_on;
700b96db75e7cfadb5219978c1735b710d583763wrowe else if (strcasecmp(arg, "Block") == 0)
e0c4ebfec83bb3b424184984e5788f31297fe429sctemme psf->viaopt = via_block;
8aefbd756763807188d2e3ce336a8680e4893066wrowe else if (strcasecmp(arg, "Full") == 0)
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe psf->viaopt = via_full;
4f9c22c4f27571d54197be9674e1fc0d528192aestriker else {
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe return "ProxyVia must be one of: "
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe "off | on | full | block";
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe }
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe return NULL;
59513b1275fdc2021d4949ee03ae8229469abb86wrowe}
4f9c22c4f27571d54197be9674e1fc0d528192aestriker
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowestatic const char*
4f9c22c4f27571d54197be9674e1fc0d528192aestriker set_cache_completion(cmd_parms *parms, void *dummy, const char *arg)
4f9c22c4f27571d54197be9674e1fc0d528192aestriker{
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe proxy_server_conf *psf = ap_get_module_config(parms->server->module_config, &proxy_module);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker int s = atoi(arg);
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (s > 100 || s < 0) {
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe return "CacheForceCompletion must be <= 100 percent, "
4f9c22c4f27571d54197be9674e1fc0d528192aestriker "or 0 for system default.";
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe }
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe if (s > 0)
4f9c22c4f27571d54197be9674e1fc0d528192aestriker psf->cache_completion = ((float)s / 100);
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe return NULL;
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe}
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowestatic const handler_rec proxy_handlers[] =
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe{
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe {"proxy-server", proxy_handler},
cf6ef072483172309861d06e85b1aeff4573c060wrowe {NULL}
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe};
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
4f9c22c4f27571d54197be9674e1fc0d528192aestrikerstatic const command_rec proxy_cmds[] =
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe{
4f9c22c4f27571d54197be9674e1fc0d528192aestriker AP_INIT_FLAG("ProxyRequests", set_proxy_req, NULL, RSRC_CONF,
4f9c22c4f27571d54197be9674e1fc0d528192aestriker "on if the true proxy requests should be accepted"),
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe AP_INIT_TAKE2("ProxyRemote", add_proxy, NULL, RSRC_CONF,
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe "a scheme, partial URL or '*' and a proxy server"),
4f9c22c4f27571d54197be9674e1fc0d528192aestriker AP_INIT_TAKE2("ProxyPass", add_pass, NULL, RSRC_CONF,
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe "a virtual path and a URL"),
4f9c22c4f27571d54197be9674e1fc0d528192aestriker AP_INIT_TAKE2("ProxyPassReverse", add_pass_reverse, NULL, RSRC_CONF,
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe "a virtual path and a URL for reverse proxy behaviour"),
4f9c22c4f27571d54197be9674e1fc0d528192aestriker AP_INIT_ITERATE("ProxyBlock", set_proxy_exclude, NULL, RSRC_CONF,
4f9c22c4f27571d54197be9674e1fc0d528192aestriker "A list of names, hosts or domains to which the proxy will not connect"),
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe AP_INIT_TAKE1("ProxyReceiveBufferSize", set_recv_buffer_size, NULL, RSRC_CONF,
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe "Receive buffer size for outgoing HTTP and FTP connections in bytes"),
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe AP_INIT_ITERATE("NoProxy", set_proxy_dirconn, NULL, RSRC_CONF,
4f9c22c4f27571d54197be9674e1fc0d528192aestriker "A list of domains, hosts, or subnets to which the proxy will connect directly"),
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe AP_INIT_TAKE1("ProxyDomain", set_proxy_domain, NULL, RSRC_CONF,
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe "The default intranet domain name (in absence of a domain in the URL)"),
4f9c22c4f27571d54197be9674e1fc0d528192aestriker AP_INIT_ITERATE("AllowCONNECT", set_allowed_ports, NULL, RSRC_CONF,
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe "A list of ports which CONNECT may connect to"),
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe AP_INIT_TAKE1("ProxyVia", set_via_opt, NULL, RSRC_CONF,
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe "Configure Via: proxy header header to one of: on | off | block | full"),
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe AP_INIT_ITERATE("ProxyNoCache", set_cache_exclude, NULL, RSRC_CONF,
4f9c22c4f27571d54197be9674e1fc0d528192aestriker "A list of names, hosts or domains for which caching is *not* provided"),
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe AP_INIT_TAKE1("ProxyCacheForceCompletion", set_cache_completion, NULL, RSRC_CONF,
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe "Force a http cache completion after this percentage is loaded"),
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe {NULL}
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe};
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowestatic void register_hooks(void)
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe{
cf6ef072483172309861d06e85b1aeff4573c060wrowe /* [2] filename-to-URI translation */
4f9c22c4f27571d54197be9674e1fc0d528192aestriker ap_hook_translate_name(proxy_trans, NULL, NULL, AP_HOOK_FIRST);
4f9c22c4f27571d54197be9674e1fc0d528192aestriker /* [8] fixups */
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe ap_hook_fixups(proxy_fixup, NULL, NULL, AP_HOOK_FIRST);
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe /* [1] post read_request handling */
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe ap_hook_post_read_request(proxy_detect, NULL, NULL, AP_HOOK_FIRST);
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe}
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowemodule AP_MODULE_DECLARE_DATA proxy_module =
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe{
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe STANDARD20_MODULE_STUFF,
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe NULL, /* create per-directory config structure */
38bcc87d9a06e8ba81165421403f275eca4e313btrawick NULL, /* merge per-directory config structures */
38bcc87d9a06e8ba81165421403f275eca4e313btrawick create_proxy_config, /* create per-server config structure */
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe NULL, /* merge per-server config structures */
0e58e92812f2f679d6bf2ff66cbcfa6c1d1e14bbjerenkrantz proxy_cmds, /* command table */
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe proxy_handlers, /* handlers */
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe register_hooks
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe};
1b315ee865b0f11e582beb64127ca3a99a319d2fwrowe