You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by co...@hyperreal.org on 1999/07/28 19:37:23 UTC

cvs commit: apache-1.3/src/support httpd.exp

coar        99/07/28 10:37:22

  Modified:    .        STATUS
               src      CHANGES
               src/include alloc.h
               src/main alloc.c
               src/modules/standard mod_headers.c mod_negotiation.c
                        mod_rewrite.c
               src/support httpd.exp
  Log:
  	Treat the Vary response header field specially; change the
  	modules that touch it to use a new routine that only adds a
  	token if it isn't already present.  O(n^2) behaviour as
  	Dean points out, but absent set/atom operations it seems
  	a reasonable stopgap for 1.3.7.
  
  PR:		4118 (previously closed with 'use "force-no-vary"')
  Reviewed by:	Ken Coar
  
  Revision  Changes    Path
  1.727     +1 -8      apache-1.3/STATUS
  
  Index: STATUS
  ===================================================================
  RCS file: /home/cvs/apache-1.3/STATUS,v
  retrieving revision 1.726
  retrieving revision 1.727
  diff -u -r1.726 -r1.727
  --- STATUS	1999/07/28 14:06:20	1.726
  +++ STATUS	1999/07/28 17:37:05	1.727
  @@ -1,5 +1,5 @@
     1.3 STATUS:
  -  Last modified at [$Date: 1999/07/28 14:06:20 $]
  +  Last modified at [$Date: 1999/07/28 17:37:05 $]
   
   Release:
   
  @@ -67,13 +67,6 @@
   
   RELEASE SHOWSTOPPERS:
   
  -    * The Vary header field stuff is still broken (multiple
  -      entries occur, etc.).  The result is that some browsers (AFAIK at least
  -      MSIE) are horribly confused by the responses.
  -      Status: It should be fixed before 1.3.7 went out. For details
  -              how it should be done, please look at new-httpd mailing list
  -              archive: Ken, Ralf and Roy have already found consensus in the
  -              past there.
   
   RELEASE NON-SHOWSTOPPERS BUT WOULD BE REAL NICE TO WRAP THESE UP:
   
  
  
  
  1.1400    +7 -0      apache-1.3/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/CHANGES,v
  retrieving revision 1.1399
  retrieving revision 1.1400
  diff -u -r1.1399 -r1.1400
  --- CHANGES	1999/07/24 18:48:20	1.1399
  +++ CHANGES	1999/07/28 17:37:09	1.1400
  @@ -1,5 +1,12 @@
   Changes with Apache 1.3.7
   
  +  *) Sanitise "Vary" values by not adding duplicate keywords.  A
  +     separate routine needs to be used to do this, so any module
  +     that frobs "Vary" needs to be changed.  The standard modules
  +     have all been modified.  This solution is somewhat inelegant,
  +     but it does the job for now.  PR#4118 (better fix than before)
  +     [Ken Coar, Roy Fielding]
  +
     *) Link DSO's with "gcc -shared" instead of "ld -Bshareable" at 
        least on Linux and FreeBSD for now.  
        [Rasmus Lerdorf]
  
  
  
  1.69      +4 -0      apache-1.3/src/include/alloc.h
  
  Index: alloc.h
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/include/alloc.h,v
  retrieving revision 1.68
  retrieving revision 1.69
  diff -u -r1.68 -r1.69
  --- alloc.h	1999/05/13 19:44:14	1.68
  +++ alloc.h	1999/07/28 17:37:14	1.69
  @@ -225,6 +225,10 @@
   API_EXPORT(const char *) ap_table_get(const table *, const char *);
   API_EXPORT(void) ap_table_set(table *, const char *name, const char *val);
   API_EXPORT(void) ap_table_setn(table *, const char *name, const char *val);
  +API_EXPORT(void) ap_table_merge_unique_token(table *t, const char *key,
  +					     const char *val);
  +API_EXPORT(void) ap_table_mergen_unique_token(table *t, const char *key,
  +					      const char *val);
   API_EXPORT(void) ap_table_merge(table *, const char *name, const char *more_val);
   API_EXPORT(void) ap_table_mergen(table *, const char *name, const char *more_val);
   API_EXPORT(void) ap_table_unset(table *, const char *key);
  
  
  
  1.114     +26 -0     apache-1.3/src/main/alloc.c
  
  Index: alloc.c
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/main/alloc.c,v
  retrieving revision 1.113
  retrieving revision 1.114
  diff -u -r1.113 -r1.114
  --- alloc.c	1999/05/25 15:32:54	1.113
  +++ alloc.c	1999/07/28 17:37:16	1.114
  @@ -1346,6 +1346,32 @@
       }
   }
   
  +/*
  + * Merge an HTTP token into a table entry IFF it isn't already in there.
  + * (Intended primarily to avoid "Vary: host, host".)
  + */
  +API_EXPORT(void) ap_table_merge_unique_token(table *t, const char *key,
  +					     const char *val)
  +{
  +    const char *curval;
  +
  +    curval = ap_table_get(t, key);
  +    if ((curval == NULL) || (!ap_find_token(t->a.pool, curval, val))) {
  +	ap_table_merge(t, key, val);
  +    }
  +}
  +
  +API_EXPORT(void) ap_table_mergen_unique_token(table *t, const char *key,
  +					      const char *val)
  +{
  +    const char *curval;
  +
  +    curval = ap_table_get(t, key);
  +    if ((curval == NULL) || (!ap_find_token(t->a.pool, curval, val))) {
  +	ap_table_mergen(t, key, val);
  +    }
  +}
  +
   API_EXPORT(void) ap_table_merge(table *t, const char *key, const char *val)
   {
       table_entry *elts = (table_entry *) t->a.elts;
  
  
  
  1.19      +11 -1     apache-1.3/src/modules/standard/mod_headers.c
  
  Index: mod_headers.c
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_headers.c,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- mod_headers.c	1999/01/01 19:05:09	1.18
  +++ mod_headers.c	1999/07/28 17:37:18	1.19
  @@ -213,7 +213,17 @@
               ap_table_addn(r->headers_out, hdr->header, hdr->value);
               break;
           case hdr_append:
  -            ap_table_mergen(r->headers_out, hdr->header, hdr->value);
  +	    /*
  +	     * "Vary" is particularly sensitive to duplicate tokens;
  +	     * they break some browsers.
  +	     */
  +	    if (strcasecmp(hdr->header, "Vary") == 0) {
  +		ap_table_mergen_unique_token(r->headers_out, hdr->header,
  +					     hdr->value);
  +	    }
  +	    else {
  +		ap_table_mergen(r->headers_out, hdr->header, hdr->value);
  +	    }
               break;
           case hdr_set:
               ap_table_setn(r->headers_out, hdr->header, hdr->value);
  
  
  
  1.100     +15 -6     apache-1.3/src/modules/standard/mod_negotiation.c
  
  Index: mod_negotiation.c
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_negotiation.c,v
  retrieving revision 1.99
  retrieving revision 1.100
  diff -u -r1.99 -r1.100
  --- mod_negotiation.c	1999/06/04 17:15:51	1.99
  +++ mod_negotiation.c	1999/07/28 17:37:18	1.100
  @@ -2194,12 +2194,21 @@
       if (neg->is_transparent || vary_by_type || vary_by_language ||
           vary_by_language || vary_by_charset || vary_by_encoding) {
   
  -        ap_table_mergen(hdrs, "Vary", 2 + ap_pstrcat(r->pool,
  -            neg->is_transparent ? ", negotiate"       : "",
  -            vary_by_type        ? ", accept"          : "",
  -            vary_by_language    ? ", accept-language" : "",
  -            vary_by_charset     ? ", accept-charset"  : "",
  -            vary_by_encoding    ? ", accept-encoding" : "", NULL));
  +	if (neg->is_transparent) {
  +	    ap_table_mergen_unique_token(hdrs, "Vary", "negotiate");
  +	}
  +	if (vary_by_type) {
  +	    ap_table_mergen_unique_token(hdrs, "Vary", "accept");
  +	}
  +	if (vary_by_language) {
  +	    ap_table_mergen_unique_token(hdrs, "Vary", "accept-language");
  +	}
  +	if (vary_by_charset) {
  +	    ap_table_mergen_unique_token(hdrs, "Vary", "accept-charset");
  +	}
  +	if (vary_by_encoding) {
  +	    ap_table_mergen_unique_token(hdrs, "Vary", "accept-encoding");
  +	}
       }
   
       if (neg->is_transparent) { /* Create TCN response header */
  
  
  
  1.142     +2 -2      apache-1.3/src/modules/standard/mod_rewrite.c
  
  Index: mod_rewrite.c
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_rewrite.c,v
  retrieving revision 1.141
  retrieving revision 1.142
  diff -u -r1.141 -r1.142
  --- mod_rewrite.c	1999/06/29 08:37:43	1.141
  +++ mod_rewrite.c	1999/07/28 17:37:20	1.142
  @@ -1880,7 +1880,7 @@
           }
   	vary = ap_table_get(r->notes, VARY_KEY_THIS);
   	if (vary != NULL) {
  -	    ap_table_merge(r->notes, VARY_KEY, vary);
  +	    ap_table_merge_unique_token(r->notes, VARY_KEY, vary);
   	    ap_table_unset(r->notes, VARY_KEY_THIS);
   	}
       }
  @@ -3781,7 +3781,7 @@
               continue;
           }
           if (strcasecmp(hdrs[i].key, name) == 0) {
  -	    ap_table_merge(r->notes, VARY_KEY_THIS, name);
  +	    ap_table_merge_unique_token(r->notes, VARY_KEY_THIS, name);
               return hdrs[i].val;
           }
       }
  
  
  
  1.22      +2 -0      apache-1.3/src/support/httpd.exp
  
  Index: httpd.exp
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/support/httpd.exp,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- httpd.exp	1999/06/16 21:27:20	1.21
  +++ httpd.exp	1999/07/28 17:37:22	1.22
  @@ -337,6 +337,8 @@
   ap_table_get
   ap_table_merge
   ap_table_mergen
  +ap_table_mergen_unique_token
  +ap_table_merge_unique_token
   ap_table_set
   ap_table_setn
   ap_table_unset
  
  
  

Re: cvs commit: apache-1.3/src/support httpd.exp

Posted by Rodent of Unusual Size <Ke...@Golux.Com>.
This actually points up yet another deficiency.  mod_negotiation
puts its field manipulations into r->err_headers_out, and
mod_headers puts them into r->headers_out.  The result is that
you can get multiple Vary fields (or others) in the response
header.

I'm not sure whether mod_neg should put them into r->headers_out,
or mod_headers should put them into r->err_headers_out, or
if the current situation is arguably 'correct.'

I'm inclined to have mod_headers use err_headers_out, since its
directives are pretty arbitrary and unconditional.  Besides,
mod_negotiation needs to use err_headers_out since the fields
should be available in the various non-200 success response cases
it can produce.
-- 
#ken    P-)}

Ken Coar                    <http://Web.Golux.Com/coar/>
Apache Software Foundation  <http://www.apache.org/>
"Apache Server for Dummies" <http://ASFD.MeepZor.Com/>

Re: cvs commit: apache-1.3/src/support httpd.exp

Posted by Dirk-Willem van Gulik <di...@webweaving.org>.
Good stuff. And a usefull extra function in the API as well.

Dw

On 28 Jul 1999 coar@hyperreal.org wrote:

> coar        99/07/28 10:37:22
> 
>   Modified:    .        STATUS
>                src      CHANGES
>                src/include alloc.h
>                src/main alloc.c
>                src/modules/standard mod_headers.c mod_negotiation.c
>                         mod_rewrite.c
>                src/support httpd.exp
>   Log:
>   	Treat the Vary response header field specially; change the
>   	modules that touch it to use a new routine that only adds a
>   	token if it isn't already present.  O(n^2) behaviour as
>   	Dean points out, but absent set/atom operations it seems
>   	a reasonable stopgap for 1.3.7.
>   
>   PR:		4118 (previously closed with 'use "force-no-vary"')
>   Reviewed by:	Ken Coar
>   
>   Revision  Changes    Path
>   1.727     +1 -8      apache-1.3/STATUS
>   
>   Index: STATUS
>   ===================================================================
>   RCS file: /home/cvs/apache-1.3/STATUS,v
>   retrieving revision 1.726
>   retrieving revision 1.727
>   diff -u -r1.726 -r1.727
>   --- STATUS	1999/07/28 14:06:20	1.726
>   +++ STATUS	1999/07/28 17:37:05	1.727
>   @@ -1,5 +1,5 @@
>      1.3 STATUS:
>   -  Last modified at [$Date: 1999/07/28 14:06:20 $]
>   +  Last modified at [$Date: 1999/07/28 17:37:05 $]
>    
>    Release:
>    
>   @@ -67,13 +67,6 @@
>    
>    RELEASE SHOWSTOPPERS:
>    
>   -    * The Vary header field stuff is still broken (multiple
>   -      entries occur, etc.).  The result is that some browsers (AFAIK at least
>   -      MSIE) are horribly confused by the responses.
>   -      Status: It should be fixed before 1.3.7 went out. For details
>   -              how it should be done, please look at new-httpd mailing list
>   -              archive: Ken, Ralf and Roy have already found consensus in the
>   -              past there.
>    
>    RELEASE NON-SHOWSTOPPERS BUT WOULD BE REAL NICE TO WRAP THESE UP:
>    
>   
>   
>   
>   1.1400    +7 -0      apache-1.3/src/CHANGES
>   
>   Index: CHANGES
>   ===================================================================
>   RCS file: /home/cvs/apache-1.3/src/CHANGES,v
>   retrieving revision 1.1399
>   retrieving revision 1.1400
>   diff -u -r1.1399 -r1.1400
>   --- CHANGES	1999/07/24 18:48:20	1.1399
>   +++ CHANGES	1999/07/28 17:37:09	1.1400
>   @@ -1,5 +1,12 @@
>    Changes with Apache 1.3.7
>    
>   +  *) Sanitise "Vary" values by not adding duplicate keywords.  A
>   +     separate routine needs to be used to do this, so any module
>   +     that frobs "Vary" needs to be changed.  The standard modules
>   +     have all been modified.  This solution is somewhat inelegant,
>   +     but it does the job for now.  PR#4118 (better fix than before)
>   +     [Ken Coar, Roy Fielding]
>   +
>      *) Link DSO's with "gcc -shared" instead of "ld -Bshareable" at 
>         least on Linux and FreeBSD for now.  
>         [Rasmus Lerdorf]
>   
>   
>   
>   1.69      +4 -0      apache-1.3/src/include/alloc.h
>   
>   Index: alloc.h
>   ===================================================================
>   RCS file: /home/cvs/apache-1.3/src/include/alloc.h,v
>   retrieving revision 1.68
>   retrieving revision 1.69
>   diff -u -r1.68 -r1.69
>   --- alloc.h	1999/05/13 19:44:14	1.68
>   +++ alloc.h	1999/07/28 17:37:14	1.69
>   @@ -225,6 +225,10 @@
>    API_EXPORT(const char *) ap_table_get(const table *, const char *);
>    API_EXPORT(void) ap_table_set(table *, const char *name, const char *val);
>    API_EXPORT(void) ap_table_setn(table *, const char *name, const char *val);
>   +API_EXPORT(void) ap_table_merge_unique_token(table *t, const char *key,
>   +					     const char *val);
>   +API_EXPORT(void) ap_table_mergen_unique_token(table *t, const char *key,
>   +					      const char *val);
>    API_EXPORT(void) ap_table_merge(table *, const char *name, const char *more_val);
>    API_EXPORT(void) ap_table_mergen(table *, const char *name, const char *more_val);
>    API_EXPORT(void) ap_table_unset(table *, const char *key);
>   
>   
>   
>   1.114     +26 -0     apache-1.3/src/main/alloc.c
>   
>   Index: alloc.c
>   ===================================================================
>   RCS file: /home/cvs/apache-1.3/src/main/alloc.c,v
>   retrieving revision 1.113
>   retrieving revision 1.114
>   diff -u -r1.113 -r1.114
>   --- alloc.c	1999/05/25 15:32:54	1.113
>   +++ alloc.c	1999/07/28 17:37:16	1.114
>   @@ -1346,6 +1346,32 @@
>        }
>    }
>    
>   +/*
>   + * Merge an HTTP token into a table entry IFF it isn't already in there.
>   + * (Intended primarily to avoid "Vary: host, host".)
>   + */
>   +API_EXPORT(void) ap_table_merge_unique_token(table *t, const char *key,
>   +					     const char *val)
>   +{
>   +    const char *curval;
>   +
>   +    curval = ap_table_get(t, key);
>   +    if ((curval == NULL) || (!ap_find_token(t->a.pool, curval, val))) {
>   +	ap_table_merge(t, key, val);
>   +    }
>   +}
>   +
>   +API_EXPORT(void) ap_table_mergen_unique_token(table *t, const char *key,
>   +					      const char *val)
>   +{
>   +    const char *curval;
>   +
>   +    curval = ap_table_get(t, key);
>   +    if ((curval == NULL) || (!ap_find_token(t->a.pool, curval, val))) {
>   +	ap_table_mergen(t, key, val);
>   +    }
>   +}
>   +
>    API_EXPORT(void) ap_table_merge(table *t, const char *key, const char *val)
>    {
>        table_entry *elts = (table_entry *) t->a.elts;
>   
>   
>   
>   1.19      +11 -1     apache-1.3/src/modules/standard/mod_headers.c
>   
>   Index: mod_headers.c
>   ===================================================================
>   RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_headers.c,v
>   retrieving revision 1.18
>   retrieving revision 1.19
>   diff -u -r1.18 -r1.19
>   --- mod_headers.c	1999/01/01 19:05:09	1.18
>   +++ mod_headers.c	1999/07/28 17:37:18	1.19
>   @@ -213,7 +213,17 @@
>                ap_table_addn(r->headers_out, hdr->header, hdr->value);
>                break;
>            case hdr_append:
>   -            ap_table_mergen(r->headers_out, hdr->header, hdr->value);
>   +	    /*
>   +	     * "Vary" is particularly sensitive to duplicate tokens;
>   +	     * they break some browsers.
>   +	     */
>   +	    if (strcasecmp(hdr->header, "Vary") == 0) {
>   +		ap_table_mergen_unique_token(r->headers_out, hdr->header,
>   +					     hdr->value);
>   +	    }
>   +	    else {
>   +		ap_table_mergen(r->headers_out, hdr->header, hdr->value);
>   +	    }
>                break;
>            case hdr_set:
>                ap_table_setn(r->headers_out, hdr->header, hdr->value);
>   
>   
>   
>   1.100     +15 -6     apache-1.3/src/modules/standard/mod_negotiation.c
>   
>   Index: mod_negotiation.c
>   ===================================================================
>   RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_negotiation.c,v
>   retrieving revision 1.99
>   retrieving revision 1.100
>   diff -u -r1.99 -r1.100
>   --- mod_negotiation.c	1999/06/04 17:15:51	1.99
>   +++ mod_negotiation.c	1999/07/28 17:37:18	1.100
>   @@ -2194,12 +2194,21 @@
>        if (neg->is_transparent || vary_by_type || vary_by_language ||
>            vary_by_language || vary_by_charset || vary_by_encoding) {
>    
>   -        ap_table_mergen(hdrs, "Vary", 2 + ap_pstrcat(r->pool,
>   -            neg->is_transparent ? ", negotiate"       : "",
>   -            vary_by_type        ? ", accept"          : "",
>   -            vary_by_language    ? ", accept-language" : "",
>   -            vary_by_charset     ? ", accept-charset"  : "",
>   -            vary_by_encoding    ? ", accept-encoding" : "", NULL));
>   +	if (neg->is_transparent) {
>   +	    ap_table_mergen_unique_token(hdrs, "Vary", "negotiate");
>   +	}
>   +	if (vary_by_type) {
>   +	    ap_table_mergen_unique_token(hdrs, "Vary", "accept");
>   +	}
>   +	if (vary_by_language) {
>   +	    ap_table_mergen_unique_token(hdrs, "Vary", "accept-language");
>   +	}
>   +	if (vary_by_charset) {
>   +	    ap_table_mergen_unique_token(hdrs, "Vary", "accept-charset");
>   +	}
>   +	if (vary_by_encoding) {
>   +	    ap_table_mergen_unique_token(hdrs, "Vary", "accept-encoding");
>   +	}
>        }
>    
>        if (neg->is_transparent) { /* Create TCN response header */
>   
>   
>   
>   1.142     +2 -2      apache-1.3/src/modules/standard/mod_rewrite.c
>   
>   Index: mod_rewrite.c
>   ===================================================================
>   RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_rewrite.c,v
>   retrieving revision 1.141
>   retrieving revision 1.142
>   diff -u -r1.141 -r1.142
>   --- mod_rewrite.c	1999/06/29 08:37:43	1.141
>   +++ mod_rewrite.c	1999/07/28 17:37:20	1.142
>   @@ -1880,7 +1880,7 @@
>            }
>    	vary = ap_table_get(r->notes, VARY_KEY_THIS);
>    	if (vary != NULL) {
>   -	    ap_table_merge(r->notes, VARY_KEY, vary);
>   +	    ap_table_merge_unique_token(r->notes, VARY_KEY, vary);
>    	    ap_table_unset(r->notes, VARY_KEY_THIS);
>    	}
>        }
>   @@ -3781,7 +3781,7 @@
>                continue;
>            }
>            if (strcasecmp(hdrs[i].key, name) == 0) {
>   -	    ap_table_merge(r->notes, VARY_KEY_THIS, name);
>   +	    ap_table_merge_unique_token(r->notes, VARY_KEY_THIS, name);
>                return hdrs[i].val;
>            }
>        }
>   
>   
>   
>   1.22      +2 -0      apache-1.3/src/support/httpd.exp
>   
>   Index: httpd.exp
>   ===================================================================
>   RCS file: /home/cvs/apache-1.3/src/support/httpd.exp,v
>   retrieving revision 1.21
>   retrieving revision 1.22
>   diff -u -r1.21 -r1.22
>   --- httpd.exp	1999/06/16 21:27:20	1.21
>   +++ httpd.exp	1999/07/28 17:37:22	1.22
>   @@ -337,6 +337,8 @@
>    ap_table_get
>    ap_table_merge
>    ap_table_mergen
>   +ap_table_mergen_unique_token
>   +ap_table_merge_unique_token
>    ap_table_set
>    ap_table_setn
>    ap_table_unset
>   
>   
>   
> 


Re: cvs commit: apache-1.3/src/support httpd.exp

Posted by Dmitry Khrustalev <di...@bog.msu.su>.
On Thu, 29 Jul 1999, Rodent of Unusual Size wrote:
> Dmitry Khrustalev wrote:
> > 
> > Well, "n" functions were made because i could not change semantics
> > of existing old ones. There is no need to clutter api with dual
> > variants of new functions.
> 
> Mmm, no, I don't think it's clutter.  The 'n' variants don't pstrdup()
> the arguments, which is a reasonable thing.

Of course this is reasonable. There is no need to have unreasonable
variants that do pstrdup internally, caller can do it.

	-Dima



Re: cvs commit: apache-1.3/src/support httpd.exp

Posted by Rodent of Unusual Size <Ke...@Golux.Com>.
Dmitry Khrustalev wrote:
> 
> Well, "n" functions were made because i could not change semantics
> of existing old ones. There is no need to clutter api with dual
> variants of new functions.

Mmm, no, I don't think it's clutter.  The 'n' variants don't pstrdup()
the arguments, which is a reasonable thing.
-- 
#ken    P-)}

Ken Coar                    <http://Web.Golux.Com/coar/>
Apache Software Foundation  <http://www.apache.org/>
"Apache Server for Dummies" <http://ASFD.MeepZor.Com/>

Re: cvs commit: apache-1.3/src/support httpd.exp

Posted by Dmitry Khrustalev <di...@bog.msu.su>.
>   +API_EXPORT(void) ap_table_merge_unique_token(table *t, const char *key,
>   +					     const char *val);
>   +API_EXPORT(void) ap_table_mergen_unique_token(table *t, const char *key,
>   +					      const char *val);

	Well, "n" functions were made because i could not change semantics
of existing old ones. There is no need to clutter api with dual variants
of new functions.

	-Dima


Re: cvs commit: apache-1.3/src/support httpd.exp

Posted by Dirk-Willem van Gulik <di...@webweaving.org>.
Good stuff. And a usefull extra function in the API as well.

Dw

On 28 Jul 1999 coar@hyperreal.org wrote:

> coar        99/07/28 10:37:22
> 
>   Modified:    .        STATUS
>                src      CHANGES
>                src/include alloc.h
>                src/main alloc.c
>                src/modules/standard mod_headers.c mod_negotiation.c
>                         mod_rewrite.c
>                src/support httpd.exp
>   Log:
>   	Treat the Vary response header field specially; change the
>   	modules that touch it to use a new routine that only adds a
>   	token if it isn't already present.  O(n^2) behaviour as
>   	Dean points out, but absent set/atom operations it seems
>   	a reasonable stopgap for 1.3.7.
>   
>   PR:		4118 (previously closed with 'use "force-no-vary"')
>   Reviewed by:	Ken Coar
>   
>   Revision  Changes    Path
>   1.727     +1 -8      apache-1.3/STATUS
>   
>   Index: STATUS
>   ===================================================================
>   RCS file: /home/cvs/apache-1.3/STATUS,v
>   retrieving revision 1.726
>   retrieving revision 1.727
>   diff -u -r1.726 -r1.727
>   --- STATUS	1999/07/28 14:06:20	1.726
>   +++ STATUS	1999/07/28 17:37:05	1.727
>   @@ -1,5 +1,5 @@
>      1.3 STATUS:
>   -  Last modified at [$Date: 1999/07/28 14:06:20 $]
>   +  Last modified at [$Date: 1999/07/28 17:37:05 $]
>    
>    Release:
>    
>   @@ -67,13 +67,6 @@
>    
>    RELEASE SHOWSTOPPERS:
>    
>   -    * The Vary header field stuff is still broken (multiple
>   -      entries occur, etc.).  The result is that some browsers (AFAIK at least
>   -      MSIE) are horribly confused by the responses.
>   -      Status: It should be fixed before 1.3.7 went out. For details
>   -              how it should be done, please look at new-httpd mailing list
>   -              archive: Ken, Ralf and Roy have already found consensus in the
>   -              past there.
>    
>    RELEASE NON-SHOWSTOPPERS BUT WOULD BE REAL NICE TO WRAP THESE UP:
>    
>   
>   
>   
>   1.1400    +7 -0      apache-1.3/src/CHANGES
>   
>   Index: CHANGES
>   ===================================================================
>   RCS file: /home/cvs/apache-1.3/src/CHANGES,v
>   retrieving revision 1.1399
>   retrieving revision 1.1400
>   diff -u -r1.1399 -r1.1400
>   --- CHANGES	1999/07/24 18:48:20	1.1399
>   +++ CHANGES	1999/07/28 17:37:09	1.1400
>   @@ -1,5 +1,12 @@
>    Changes with Apache 1.3.7
>    
>   +  *) Sanitise "Vary" values by not adding duplicate keywords.  A
>   +     separate routine needs to be used to do this, so any module
>   +     that frobs "Vary" needs to be changed.  The standard modules
>   +     have all been modified.  This solution is somewhat inelegant,
>   +     but it does the job for now.  PR#4118 (better fix than before)
>   +     [Ken Coar, Roy Fielding]
>   +
>      *) Link DSO's with "gcc -shared" instead of "ld -Bshareable" at 
>         least on Linux and FreeBSD for now.  
>         [Rasmus Lerdorf]
>   
>   
>   
>   1.69      +4 -0      apache-1.3/src/include/alloc.h
>   
>   Index: alloc.h
>   ===================================================================
>   RCS file: /home/cvs/apache-1.3/src/include/alloc.h,v
>   retrieving revision 1.68
>   retrieving revision 1.69
>   diff -u -r1.68 -r1.69
>   --- alloc.h	1999/05/13 19:44:14	1.68
>   +++ alloc.h	1999/07/28 17:37:14	1.69
>   @@ -225,6 +225,10 @@
>    API_EXPORT(const char *) ap_table_get(const table *, const char *);
>    API_EXPORT(void) ap_table_set(table *, const char *name, const char *val);
>    API_EXPORT(void) ap_table_setn(table *, const char *name, const char *val);
>   +API_EXPORT(void) ap_table_merge_unique_token(table *t, const char *key,
>   +					     const char *val);
>   +API_EXPORT(void) ap_table_mergen_unique_token(table *t, const char *key,
>   +					      const char *val);
>    API_EXPORT(void) ap_table_merge(table *, const char *name, const char *more_val);
>    API_EXPORT(void) ap_table_mergen(table *, const char *name, const char *more_val);
>    API_EXPORT(void) ap_table_unset(table *, const char *key);
>   
>   
>   
>   1.114     +26 -0     apache-1.3/src/main/alloc.c
>   
>   Index: alloc.c
>   ===================================================================
>   RCS file: /home/cvs/apache-1.3/src/main/alloc.c,v
>   retrieving revision 1.113
>   retrieving revision 1.114
>   diff -u -r1.113 -r1.114
>   --- alloc.c	1999/05/25 15:32:54	1.113
>   +++ alloc.c	1999/07/28 17:37:16	1.114
>   @@ -1346,6 +1346,32 @@
>        }
>    }
>    
>   +/*
>   + * Merge an HTTP token into a table entry IFF it isn't already in there.
>   + * (Intended primarily to avoid "Vary: host, host".)
>   + */
>   +API_EXPORT(void) ap_table_merge_unique_token(table *t, const char *key,
>   +					     const char *val)
>   +{
>   +    const char *curval;
>   +
>   +    curval = ap_table_get(t, key);
>   +    if ((curval == NULL) || (!ap_find_token(t->a.pool, curval, val))) {
>   +	ap_table_merge(t, key, val);
>   +    }
>   +}
>   +
>   +API_EXPORT(void) ap_table_mergen_unique_token(table *t, const char *key,
>   +					      const char *val)
>   +{
>   +    const char *curval;
>   +
>   +    curval = ap_table_get(t, key);
>   +    if ((curval == NULL) || (!ap_find_token(t->a.pool, curval, val))) {
>   +	ap_table_mergen(t, key, val);
>   +    }
>   +}
>   +
>    API_EXPORT(void) ap_table_merge(table *t, const char *key, const char *val)
>    {
>        table_entry *elts = (table_entry *) t->a.elts;
>   
>   
>   
>   1.19      +11 -1     apache-1.3/src/modules/standard/mod_headers.c
>   
>   Index: mod_headers.c
>   ===================================================================
>   RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_headers.c,v
>   retrieving revision 1.18
>   retrieving revision 1.19
>   diff -u -r1.18 -r1.19
>   --- mod_headers.c	1999/01/01 19:05:09	1.18
>   +++ mod_headers.c	1999/07/28 17:37:18	1.19
>   @@ -213,7 +213,17 @@
>                ap_table_addn(r->headers_out, hdr->header, hdr->value);
>                break;
>            case hdr_append:
>   -            ap_table_mergen(r->headers_out, hdr->header, hdr->value);
>   +	    /*
>   +	     * "Vary" is particularly sensitive to duplicate tokens;
>   +	     * they break some browsers.
>   +	     */
>   +	    if (strcasecmp(hdr->header, "Vary") == 0) {
>   +		ap_table_mergen_unique_token(r->headers_out, hdr->header,
>   +					     hdr->value);
>   +	    }
>   +	    else {
>   +		ap_table_mergen(r->headers_out, hdr->header, hdr->value);
>   +	    }
>                break;
>            case hdr_set:
>                ap_table_setn(r->headers_out, hdr->header, hdr->value);
>   
>   
>   
>   1.100     +15 -6     apache-1.3/src/modules/standard/mod_negotiation.c
>   
>   Index: mod_negotiation.c
>   ===================================================================
>   RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_negotiation.c,v
>   retrieving revision 1.99
>   retrieving revision 1.100
>   diff -u -r1.99 -r1.100
>   --- mod_negotiation.c	1999/06/04 17:15:51	1.99
>   +++ mod_negotiation.c	1999/07/28 17:37:18	1.100
>   @@ -2194,12 +2194,21 @@
>        if (neg->is_transparent || vary_by_type || vary_by_language ||
>            vary_by_language || vary_by_charset || vary_by_encoding) {
>    
>   -        ap_table_mergen(hdrs, "Vary", 2 + ap_pstrcat(r->pool,
>   -            neg->is_transparent ? ", negotiate"       : "",
>   -            vary_by_type        ? ", accept"          : "",
>   -            vary_by_language    ? ", accept-language" : "",
>   -            vary_by_charset     ? ", accept-charset"  : "",
>   -            vary_by_encoding    ? ", accept-encoding" : "", NULL));
>   +	if (neg->is_transparent) {
>   +	    ap_table_mergen_unique_token(hdrs, "Vary", "negotiate");
>   +	}
>   +	if (vary_by_type) {
>   +	    ap_table_mergen_unique_token(hdrs, "Vary", "accept");
>   +	}
>   +	if (vary_by_language) {
>   +	    ap_table_mergen_unique_token(hdrs, "Vary", "accept-language");
>   +	}
>   +	if (vary_by_charset) {
>   +	    ap_table_mergen_unique_token(hdrs, "Vary", "accept-charset");
>   +	}
>   +	if (vary_by_encoding) {
>   +	    ap_table_mergen_unique_token(hdrs, "Vary", "accept-encoding");
>   +	}
>        }
>    
>        if (neg->is_transparent) { /* Create TCN response header */
>   
>   
>   
>   1.142     +2 -2      apache-1.3/src/modules/standard/mod_rewrite.c
>   
>   Index: mod_rewrite.c
>   ===================================================================
>   RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_rewrite.c,v
>   retrieving revision 1.141
>   retrieving revision 1.142
>   diff -u -r1.141 -r1.142
>   --- mod_rewrite.c	1999/06/29 08:37:43	1.141
>   +++ mod_rewrite.c	1999/07/28 17:37:20	1.142
>   @@ -1880,7 +1880,7 @@
>            }
>    	vary = ap_table_get(r->notes, VARY_KEY_THIS);
>    	if (vary != NULL) {
>   -	    ap_table_merge(r->notes, VARY_KEY, vary);
>   +	    ap_table_merge_unique_token(r->notes, VARY_KEY, vary);
>    	    ap_table_unset(r->notes, VARY_KEY_THIS);
>    	}
>        }
>   @@ -3781,7 +3781,7 @@
>                continue;
>            }
>            if (strcasecmp(hdrs[i].key, name) == 0) {
>   -	    ap_table_merge(r->notes, VARY_KEY_THIS, name);
>   +	    ap_table_merge_unique_token(r->notes, VARY_KEY_THIS, name);
>                return hdrs[i].val;
>            }
>        }
>   
>   
>   
>   1.22      +2 -0      apache-1.3/src/support/httpd.exp
>   
>   Index: httpd.exp
>   ===================================================================
>   RCS file: /home/cvs/apache-1.3/src/support/httpd.exp,v
>   retrieving revision 1.21
>   retrieving revision 1.22
>   diff -u -r1.21 -r1.22
>   --- httpd.exp	1999/06/16 21:27:20	1.21
>   +++ httpd.exp	1999/07/28 17:37:22	1.22
>   @@ -337,6 +337,8 @@
>    ap_table_get
>    ap_table_merge
>    ap_table_mergen
>   +ap_table_mergen_unique_token
>   +ap_table_merge_unique_token
>    ap_table_set
>    ap_table_setn
>    ap_table_unset
>   
>   
>   
>