martin 98/08/16 13:51:57
Modified: htdocs/manual/mod mod_proxy.html src CHANGES src/include httpd.h src/modules/proxy mod_proxy.c mod_proxy.h proxy_http.c Log: Add proxy Via: header management. Currently, Via: headers can be left unchanged (compatibility), can be set to protocol and host only, or to protocol, host and comment. Optionally, all Via: headers can be suppressed if intranet privacy in companies is desired when going out over a firewall apache. Revision Changes Path 1.44 +53 -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.43 retrieving revision 1.44 diff -u -u -r1.43 -r1.44 --- mod_proxy.html 1998/08/06 01:05:30 1.43 +++ mod_proxy.html 1998/08/16 20:51:52 1.44 @@ -48,6 +48,7 @@ <LI><A HREF="#proxyreceivebuffersize">ProxyReceiveBufferSize</A> <LI><A HREF="#noproxy">NoProxy</A> <LI><A HREF="#proxydomain">ProxyDomain</A> +<LI><A HREF="#proxyvia">ProxyVia</A> <LI><A HREF="#cacheroot">CacheRoot</A> <LI><A HREF="#cachesize">CacheSize</A> <LI><A HREF="#cachemaxexpire">CacheMaxExpire</A> @@ -549,6 +550,58 @@ NoProxy .mycompany.com 192.168.112.0/21 ProxyDomain .mycompany.com </PRE> + +<HR> + +<H2><A NAME="proxyvia">ProxyVia</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> ProxyVia { <EM>off</EM> + | <EM>on</EM> + | <EM>full</EM> + | <EM>block</EM> + }<BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <EM>ProxyVia off</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> ProxyVia is only available in +Apache 1.3.2 and later.<P> + +This directive controls the use of the <SAMP>Via:</SAMP> HTTP header +by the proxy. Its intended use is to control the flow of of proxy +requests along a chain of proxy servers. +See RFC2068 (HTTP/1.1) for an explanation of <SAMP>Via:</SAMP> header lines.<UL> +<LI>If set to <EM>off</EM>, which is the default, no special +processing is performed. If a request or reply contains a <SAMP>Via:</SAMP> header, +it is passed through unchanged. +<LI>If set to <EM>on</EM>, each request and reply will get a <SAMP>Via:</SAMP> header +line added for the current host. +<LI>If set to <EM>full</EM>, each generated <SAMP>Via:</SAMP> header line will +additionally have the Apache server version shown as a <SAMP>Via:</SAMP> comment field. +<LI>If set to <EM>block</EM>, every proxy request will have all its +<SAMP>Via:</SAMP> header lines removed. No new <SAMP>Via:</SAMP> header will be generated. +</UL> <HR> 1.1028 +3 -0 apache-1.3/src/CHANGES Index: CHANGES =================================================================== RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v retrieving revision 1.1027 retrieving revision 1.1028 diff -u -u -r1.1027 -r1.1028 --- CHANGES 1998/08/16 20:21:24 1.1027 +++ CHANGES 1998/08/16 20:51:53 1.1028 @@ -1,5 +1,8 @@ Changes with Apache 1.3.2 + *) Make the proxy generate and understand Via: headers + [Martin Kraemer] + *) Change the proxy to use tables instead of array_headers for the header lines. [Martin Kraemer] 1.238 +2 -0 apache-1.3/src/include/httpd.h Index: httpd.h =================================================================== RCS file: /export/home/cvs/apache-1.3/src/include/httpd.h,v retrieving revision 1.237 retrieving revision 1.238 diff -u -u -r1.237 -r1.238 --- httpd.h 1998/08/13 02:59:33 1.237 +++ httpd.h 1998/08/16 20:51:54 1.238 @@ -122,6 +122,8 @@ /* -- Internal representation for a HTTP protocol number, e.g., HTTP/1.1 -- */ #define HTTP_VERSION(major,minor) (1000*(major)+(minor)) +#define HTTP_VERSION_MAJOR(number) ((number)/1000) +#define HTTP_VERSION_MINOR(number) ((number)%1000) /* -------------- Port number for server running standalone --------------- */ 1.60 +27 -2 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.59 retrieving revision 1.60 diff -u -u -r1.59 -r1.60 --- mod_proxy.c 1998/08/16 20:21:26 1.59 +++ mod_proxy.c 1998/08/16 20:51:55 1.60 @@ -67,12 +67,12 @@ /* 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}, - {"http", DEFAULT_HTTP_PORT}, {"nntp", DEFAULT_NNTP_PORT}, {"wais", DEFAULT_WAIS_PORT}, - {"https", DEFAULT_HTTPS_PORT}, {"snews", DEFAULT_SNEWS_PORT}, {"prospero", DEFAULT_PROSPERO_PORT}, {NULL, -1} /* unknown port */ @@ -415,6 +415,7 @@ ps->dirconn = ap_make_array(p, 10, sizeof(struct dirconn_entry)); ps->nocaches = ap_make_array(p, 10, sizeof(struct nocache_entry)); ps->domain = NULL; + ps->viaopt = via_off; /* initially backward compatible with 1.3.1 */ ps->req = 0; ps->cache.root = NULL; @@ -780,6 +781,28 @@ return NULL; } +static const char* + set_via_opt(cmd_parms *parms, void *dummy, 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 handler_rec proxy_handlers[] = { {"proxy-server", proxy_handler}, @@ -824,6 +847,8 @@ "A list of names, hosts or domains for which caching is *not* provided"}, {"CacheForceCompletion", set_cache_completion, NULL, RSRC_CONF, TAKE1, "Force a http cache completion after this percentage is loaded"}, + {"ProxyVia", set_via_opt, NULL, RSRC_CONF, TAKE1, + "Configure Via: proxy header header to one of: on | off | block | full"}, {NULL} }; 1.39 +6 -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.38 retrieving revision 1.39 diff -u -u -r1.38 -r1.39 --- mod_proxy.h 1998/08/16 20:21:27 1.38 +++ mod_proxy.h 1998/08/16 20:51:55 1.39 @@ -212,6 +212,12 @@ array_header *nocaches; char *domain; /* domain name to use in absence of a domain name in the request */ int req; /* true if proxy requests are enabled */ + enum { + via_off, + via_on, + via_block, + via_full + } viaopt; /* how to deal with proxy Via: headers */ size_t recv_buffer_size; } proxy_server_conf; 1.58 +61 -5 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.57 retrieving revision 1.58 diff -u -u -r1.57 -r1.58 --- proxy_http.c 1998/08/16 20:21:28 1.57 +++ proxy_http.c 1998/08/16 20:51:56 1.58 @@ -180,6 +180,7 @@ struct hostent server_hp; BUFF *f; char buffer[HUGE_STRING_LEN]; + char portstr[32]; pool *p = r->pool; const long int zero = 0L; int destport = 0; @@ -303,18 +304,47 @@ ap_hard_timeout("proxy send", r); ap_bvputs(f, r->method, " ", proxyhost ? url : urlptr, " HTTP/1.0" CRLF, NULL); - ap_bvputs(f, "Host: ", desthost, NULL); if (destportstr != NULL && destport != DEFAULT_HTTP_PORT) - ap_bvputs(f, ":", destportstr, CRLF, NULL); + ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL); else - ap_bputs(CRLF, f); + ap_bvputs(f, "Host: ", desthost, CRLF, NULL); + if (conf->viaopt == via_block) { + /* Block all outgoing Via: headers */ + ap_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 { + ap_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) + ? ap_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, + SERVER_BASEVERSION) + : ap_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 = ap_table_elts(r->headers_in); reqhdrs = (table_entry *) 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; ap_bvputs(f, reqhdrs[i].key, ": ", reqhdrs[i].val, CRLF, NULL); @@ -341,7 +371,13 @@ /* Is it an HTTP/1 response? This is buggy if we ever see an HTTP/1.10 */ if (ap_checkmask(buffer, "HTTP/#.# ###*")) { -/* If not an HTTP/1 messsage or if the status line was > 8192 bytes */ + int major, minor; + if (2 != sscanf(buffer, "HTTP/%u.%u", &major, &minor)) { + major = 1; + minor = 0; + } + +/* If not an HTTP/1 message or if the status line was > 8192 bytes */ if (buffer[5] != '1' || buffer[len - 1] != '\n') { ap_bclose(f); ap_kill_timeout(r); @@ -360,8 +396,28 @@ /* Also, take care with headers with multiple occurences. */ resp_hdrs = ap_proxy_read_headers(p, buffer, HUGE_STRING_LEN, f); + + 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 { + ap_snprintf(portstr, sizeof portstr, ":%d", i); + } + ap_table_mergen((table *)resp_hdrs, "Via", + (conf->viaopt == via_full) + ? ap_psprintf(p, "%d.%d %s%s (%s)", + major, minor, + ap_get_server_name(r), portstr, + SERVER_BASEVERSION) + : ap_psprintf(p, "%d.%d %s%s", + major, minor, + ap_get_server_name(r), portstr) + ); + } - clear_connection(p, (table *) resp_hdrs); /* Strip Connection hdrs */ + clear_connection(p, resp_hdrs); /* Strip Connection hdrs */ } else { /* an http/0.9 response */