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 */
  
  
  

Reply via email to