rse 98/02/23 00:04:13
Modified: src CHANGES htdocs/manual new_features_1_3.html htdocs/manual/mod mod_proxy.html src/modules/proxy mod_proxy.h mod_proxy.c proxy_http.c . STATUS Log: Add the ProxyPassReverse directive which allows Apache to be used as a full-featured Reverse Proxy in front of a backend webserver cluster. Submitted by: Ralf S. Engelschall Reviewed by: Martin Kraemer, Ralf S. Engelschall Revision Changes Path 1.658 +7 -0 apache-1.3/src/CHANGES Index: CHANGES =================================================================== RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v retrieving revision 1.657 retrieving revision 1.658 diff -u -r1.657 -r1.658 --- CHANGES 1998/02/23 07:58:42 1.657 +++ CHANGES 1998/02/23 08:04:05 1.658 @@ -1,5 +1,12 @@ Changes with Apache 1.3b6 + *) Add a new directive to mod_proxy similar to ProxyPass: `ProxyPassReverse'. + This directive lets Apache adjust the URL in Location-headers on HTTP + redirect responses sent by the remote server. This way the virtually + mapped area is no longer left on redirects and thus by-passed which is + especially essential when running Apache as a reverse proxy. + [Ralf S. Engelschall] + *) Hide Proxy-Authorization from CGI/SSI/etc just like Authorization is hidden. [Alvaro Martinez Echevarria] 1.45 +9 -0 apache-1.3/htdocs/manual/new_features_1_3.html Index: new_features_1_3.html =================================================================== RCS file: /export/home/cvs/apache-1.3/htdocs/manual/new_features_1_3.html,v retrieving revision 1.44 retrieving revision 1.45 diff -u -r1.44 -r1.45 --- new_features_1_3.html 1998/02/22 21:10:06 1.44 +++ new_features_1_3.html 1998/02/23 08:04:08 1.45 @@ -553,6 +553,15 @@ off</SAMP> Apache will use the hostname and port supplied by the client, if available. </LI> + + <LI><STRONG>New <SAMP><A HREF="mod/mod_proxy.html#proxypassreverse">ProxyPassReverse</A></SAMP> directive</STRONG> + <BR> + This directive was added in addition to the <SAMP>ProxyPass</SAMP> + directive. It lets Apache adjust the URL in the <TT>Location</TT> header on + HTTP redirect responses. For instance this is essential when Apache is used + as a reverse proxy to avoid by-passing the reverse proxy because of HTTP + redirects on the backend servers which stay behind the reverse proxy. + </LI> </UL> <!--#include virtual="footer.html" --> 1.35 +66 -0 apache-1.3/htdocs/manual/mod/mod_proxy.html Index: mod_proxy.html =================================================================== RCS file: /export/home/cvs/apache-1.3/htdocs/manual/mod/mod_proxy.html,v retrieving revision 1.34 retrieving revision 1.35 diff -u -r1.34 -r1.35 --- mod_proxy.html 1998/02/05 22:34:05 1.34 +++ mod_proxy.html 1998/02/23 08:04:09 1.35 @@ -43,6 +43,7 @@ <LI><A HREF="#proxyrequests">ProxyRequests</A> <LI><A HREF="#proxyremote">ProxyRemote</A> <LI><A HREF="#proxypass">ProxyPass</A> +<LI><A HREF="#proxypassreverse">ProxyPassReverse</A> <LI><A HREF="#proxyblock">ProxyBlock</A> <LI><A HREF="#noproxy">NoProxy</A> <LI><A HREF="#proxydomain">ProxyDomain</A> @@ -197,6 +198,71 @@ <<SAMP>http://wibble.org/mirror/foo/bar</SAMP>> to be internally converted into a proxy request to <<SAMP>http://foo.com/bar</SAMP>>. + +<HR> + +<H2><A NAME="proxypassreverse">ProxyPassReverse</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> ProxyPassReverse <EM><path> <url></EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <EM>None</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_proxy<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> ProxyPassReverse is only available in +Apache 1.3b6 and later.<P> + +This directive lets Apache adjust the URL in the <TT>Location</TT> header on +HTTP redirect responses. For instance this is essential when Apache is used as +a reverse proxy to avoid by-passing the reverse proxy because of HTTP +redirects on the backend servers which stay behind the reverse proxy. +<P> +<path> is the name of a local virtual path.<BR> +<url> is a partial URL for the remote server - the same way they are +used for the <TT>ProxyPass</TT> directive. +<P> +Example:<BR> +Suppose the local server has address <SAMP>http://wibble.org/</SAMP>; then +<PRE> + ProxyPass /mirror/foo http://foo.com + ProxyPassReverse /mirror/foo http://foo.com +</PRE> +will not only cause a local request for the +<<SAMP>http://wibble.org/mirror/foo/bar</SAMP>> to be internally +converted into a proxy request to <<SAMP>http://foo.com/bar</SAMP>> (the +functionality <SAMP>ProxyPass</SAMP> provides here). It also takes care of +redirects the server foo.com sends: when <SAMP>http://foo.com/bar</SAMP> is +redirected by him to <SAMP>http://foo.com/quux</SAMP> Apache adjusts this to +<SAMP>http://wibble.org/mirror/foo/quux</SAMP> before forwarding the HTTP +redirect response to the client. +<P> +Note that this <SAMP>ProxyPassReverse</SAMP> directive can also by used in +conjunction with the proxy pass-through feature ("<SAMP>RewriteRule ... +[P]</SAMP>") from +<A + HREF="mod_rewrite.html#RewriteRule" +><TT>mod_rewrite</TT></A> because its doesn't depend on a corresponding +<SAMP>ProxyPass</SAMP> directive. <HR> 1.28 +1 -0 apache-1.3/src/modules/proxy/mod_proxy.h Index: mod_proxy.h =================================================================== RCS file: /export/home/cvs/apache-1.3/src/modules/proxy/mod_proxy.h,v retrieving revision 1.27 retrieving revision 1.28 diff -u -r1.27 -r1.28 --- mod_proxy.h 1998/02/22 21:35:30 1.27 +++ mod_proxy.h 1998/02/23 08:04:10 1.28 @@ -197,6 +197,7 @@ struct cache_conf cache; /* cache configuration */ array_header *proxies; array_header *aliases; + array_header *raliases; array_header *noproxies; array_header *dirconn; array_header *nocaches; 1.38 +18 -0 apache-1.3/src/modules/proxy/mod_proxy.c Index: mod_proxy.c =================================================================== RCS file: /export/home/cvs/apache-1.3/src/modules/proxy/mod_proxy.c,v retrieving revision 1.37 retrieving revision 1.38 diff -u -r1.37 -r1.38 --- mod_proxy.c 1998/02/22 21:22:12 1.37 +++ mod_proxy.c 1998/02/23 08:04:10 1.38 @@ -379,6 +379,7 @@ ps->proxies = make_array(p, 10, sizeof(struct proxy_remote)); ps->aliases = make_array(p, 10, sizeof(struct proxy_alias)); + ps->raliases = make_array(p, 10, sizeof(struct proxy_alias)); ps->noproxies = make_array(p, 10, sizeof(struct noproxy_entry)); ps->dirconn = make_array(p, 10, sizeof(struct dirconn_entry)); ps->nocaches = make_array(p, 10, sizeof(struct nocache_entry)); @@ -455,6 +456,21 @@ } static const char * + add_pass_reverse(cmd_parms *cmd, void *dummy, char *f, char *r) +{ + server_rec *s = cmd->server; + proxy_server_conf *conf; + struct proxy_alias *new; + + conf = (proxy_server_conf *)get_module_config(s->module_config, + &proxy_module); + new = push_array(conf->raliases); + new->fake = f; + new->real = r; + return NULL; +} + +static const char * set_proxy_exclude(cmd_parms *parms, void *dummy, char *arg) { server_rec *s = parms->server; @@ -727,6 +743,8 @@ "a scheme, partial URL or '*' and a proxy server"}, {"ProxyPass", add_pass, NULL, RSRC_CONF, TAKE2, "a virtual path and a URL"}, + {"ProxyPassReverse", add_pass_reverse, NULL, RSRC_CONF, TAKE2, + "a virtual path and a URL for reverse proxy behaviour"}, {"ProxyBlock", set_proxy_exclude, NULL, RSRC_CONF, ITERATE, "A list of names, hosts or domains to which the proxy will not connect"}, {"NoProxy", set_proxy_dirconn, NULL, RSRC_CONF, ITERATE, 1.39 +26 -0 apache-1.3/src/modules/proxy/proxy_http.c Index: proxy_http.c =================================================================== RCS file: /export/home/cvs/apache-1.3/src/modules/proxy/proxy_http.c,v retrieving revision 1.38 retrieving revision 1.39 diff -u -r1.38 -r1.39 --- proxy_http.c 1998/02/22 21:35:31 1.38 +++ proxy_http.c 1998/02/23 08:04:11 1.39 @@ -56,6 +56,7 @@ #include "mod_proxy.h" #include "http_log.h" #include "http_main.h" +#include "http_core.h" #include "util_date.h" /* @@ -113,6 +114,28 @@ path, (search) ? "?" : "", (search) ? search : "", NULL); return OK; } + +static char *proxy_location_reverse_map(request_rec *r, 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 *)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 = pstrcat(r->pool, ent[i].fake, &url[l2], NULL); + return construct_url(r->pool, u, r); + } + } + return url; +} /* Clear all connection-based headers from the incoming headers table */ static void clear_connection(table *headers) @@ -365,6 +388,9 @@ strcasecmp(strp, "Last-Modified") == 0 || strcasecmp(strp, "Expires") == 0) hdr[i].value = proxy_date_canon(p, hdr[i].value); + if (strcasecmp(strp, "Location") == 0 || + strcasecmp(strp, "URI") == 0) + hdr[i].value = proxy_location_reverse_map(r, hdr[i].value); } /* check if NoCache directive on this host */ 1.161 +0 -4 apache-1.3/STATUS Index: STATUS =================================================================== RCS file: /export/home/cvs/apache-1.3/STATUS,v retrieving revision 1.160 retrieving revision 1.161 diff -u -r1.160 -r1.161 --- STATUS 1998/02/22 15:04:08 1.160 +++ STATUS 1998/02/23 08:04:13 1.161 @@ -34,10 +34,6 @@ <[EMAIL PROTECTED]> Status: Ralf +1 - * Ralf's [PATCH] Apache as a Reverse Proxy - <[EMAIL PROTECTED]> - Status: Ralf +1, Martin +1 - Concepts: * Dean's [PRE-PATCH] expanding ap_snprintf()