httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From c...@hyperreal.org
Subject cvs commit: apache-1.3/src/main http_protocol.c
Date Thu, 29 Jul 1999 22:22:09 GMT
coar        99/07/29 15:22:09

  Modified:    .        STATUS
               src      .gdbinit CHANGES
               src/main http_protocol.c
  Log:
  	Fix the IE-identified problems with Vary (multiple instances,
  	duplicate tokens) for good and all.  We can't be sure we're
  	putting in all the right values for all circumstances, but
  	at least now we know the field we send to the client is
  	syntactically sane.  (Not that it wasn't before, but it *was*
  	slightly questionable.)
  
  PR:		4118
  Submitted by:	Dean Gaudet, Roy Fielding, Ken Coar
  Reviewed by:	Ken Coar
  
  Revision  Changes    Path
  1.730     +1 -16     apache-1.3/STATUS
  
  Index: STATUS
  ===================================================================
  RCS file: /home/cvs/apache-1.3/STATUS,v
  retrieving revision 1.729
  retrieving revision 1.730
  diff -u -r1.729 -r1.730
  --- STATUS	1999/07/29 17:55:54	1.729
  +++ STATUS	1999/07/29 22:21:49	1.730
  @@ -1,5 +1,5 @@
     1.3 STATUS:
  -  Last modified at [$Date: 1999/07/29 17:55:54 $]
  +  Last modified at [$Date: 1999/07/29 22:21:49 $]
   
   Release:
   
  @@ -66,23 +66,8 @@
   
   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:
  -
  -    * 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.
   
       * Graham Legget has found that if he uses the 1.3.7-dev core, and
         the 1.3.6 proxy code (plus a small patch of his) he doesn't get
  
  
  
  1.3       +13 -0     apache-1.3/src/.gdbinit
  
  Index: .gdbinit
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/.gdbinit,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- .gdbinit	1998/04/15 18:14:38	1.2
  +++ .gdbinit	1999/07/29 22:21:50	1.3
  @@ -13,3 +13,16 @@
   document dump_table
       Print the key/value pairs in a table.
   end
  +
  +define dump_string_array
  +    set $a = (char **)((array_header *)$arg0)->elts
  +    set $n = (int)((array_header *)$arg0)->nelts
  +    set $i = 0
  +    while $i < $n
  +	printf "[%u] '%s'\n", $i, $a[$i]
  +	set $i = $i + 1
  +    end
  +end
  +document dump_string_array
  +    Print all of the elements in an array of strings.
  +end
  \ No newline at end of file
  
  
  
  1.1403    +8 -7      apache-1.3/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/CHANGES,v
  retrieving revision 1.1402
  retrieving revision 1.1403
  diff -u -r1.1402 -r1.1403
  --- CHANGES	1999/07/29 18:13:10	1.1402
  +++ CHANGES	1999/07/29 22:21:50	1.1403
  @@ -1,13 +1,14 @@
   Changes with Apache 1.3.7
   
  -  *) Portability changes for BeOS. [David Reid abb37@dial.pipex.com]
  +  *) The "Vary" response header field is now sanitised right before
  +     the header is sent back to the client.  Multiple "Vary" fields
  +     are combined, and duplicate tokens (e.g., "Vary: host, host" or
  +     "Vary: host, negotiate, host, accept-language") are reduced to
  +     single instances.  This is a better solution than the force-no-vary
  +     one (which is still valid for clients that can't cope with Vary
  +     at all).  PR#3118 [Dean Gaudet, Roy Fielding, Ken Coar]
   
  -  *) 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]
  +  *) Portability changes for BeOS. [David Reid abb37@dial.pipex.com]
   
     *) Link DSO's with "gcc -shared" instead of "ld -Bshareable" at 
        least on Linux and FreeBSD for now.  
  
  
  
  1.273     +110 -0    apache-1.3/src/main/http_protocol.c
  
  Index: http_protocol.c
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/main/http_protocol.c,v
  retrieving revision 1.272
  retrieving revision 1.273
  diff -u -r1.272 -r1.273
  --- http_protocol.c	1999/07/19 10:15:58	1.272
  +++ http_protocol.c	1999/07/29 22:22:04	1.273
  @@ -1446,6 +1446,113 @@
                && strstr(ua, "MSIE 3")));
   }
   
  +/*
  + * qsort comparison routine for fixup_vary().
  + */
  +static int compare_vary(const void *va, const void *vb)
  +{
  +    return strcasecmp(*(const char **)va, *(const char **)vb);
  +}
  +
  +/*
  + * ap_table_get() only picks up the first occurrence of a key,
  + * which means that if there's a Vary in r->headers_out and another
  + * in r->err_headers_out, one might get ignored.  This routine
  + * is called by ap_table_do and merges all instances of Vary into
  + * a temporary list in r->notes.
  + */
  +static int merge_vary_fields(void *d, const char *key, const char *val)
  +{
  +    request_rec *r;
  +
  +    r = (request_rec *)d;
  +    ap_table_merge(r->notes, "Vary-list", val);
  +    return 1;
  +}
  +
  +/*
  + * Since some clients choke violently on multiple Vary fields, or
  + * Vary fields with duplicate tokens, combine any multiples and remove
  + * any duplicates.
  + */
  +static void fixup_vary(request_rec *r)
  +{
  +    const char *vary;
  +    array_header *arr;
  +    char *start;
  +    char *e;
  +    char **ecur;
  +    char **eend;
  +    char **ekeep;
  +
  +    /* Don't do any unnecessary manipulations..
  +     */
  +    if (ap_table_get(r->headers_out, "Vary") == NULL) {
  +	return;
  +    }
  +    ap_table_do((int (*)(void *, const char *, const char *))merge_vary_fields,
  +		(void *) r, r->headers_out, "Vary");
  +    vary = ap_table_get(r->notes, "Vary-list");
  +
  +    /* XXX: we could make things a lot better, by having r->vary,
  +     * which is an array of char * -- which modules append to as they
  +     * find things which the request varies on.  This is probably
  +     * better than a table, because a table would require O(n^2)
  +     * string comparisons... another option would be to use a table
  +     * but indicate that folks should use ap_table_add...
  +     * at any rate, if we had such an array, we would just set
  +     * arr = r->vary here (or arr = ap_table_elts(r->vary)).
  +     */
  +    arr = ap_make_array(r->pool, 5, sizeof(char *));
  +
  +    /* XXX: this part could become a new routine which takes a string
  +     * and breaks it up, appending to an array, spliting on /[,\s]+/.
  +     */
  +    e = ap_pstrdup(r->pool, vary);
  +    start = e;
  +    while (*e) {
  +	while (ap_isspace(*e)) {
  +	    ++e;
  +	}
  +	start = e;
  +	e = strchr(e, ',');
  +	if (!e) {
  +	    break;
  +	}
  +	*e = '\0';
  +	*(char **)ap_push_array(arr) = start;
  +	++e;
  +    }
  +    if (*start) {
  +	*(char **)ap_push_array(arr) = start;
  +    }
  +
  +    /* XXX: this part could become a new routine which modifies an
  +     * array of char * in place, eliminating duplicate entries
  +     */
  +    if (arr->nelts > 1) {
  +	qsort(arr->elts, arr->nelts, sizeof(char *), compare_vary);
  +
  +	/* now pluck out the non-duplicates */
  +	ekeep = (char **)arr->elts;
  +	ecur = ekeep + 1;
  +	eend = ekeep + arr->nelts - 1;
  +	while (ecur <= eend) {
  +	    if (strcasecmp(*ecur, *ekeep)) {
  +		*++ekeep = *ecur;
  +	    }
  +	    ++ecur;
  +	}
  +	arr->nelts = ekeep - (char **)arr->elts + 1;
  +    }
  +
  +    /* and finally we're done, we can just merge the array adding ,
  +     * between entries
  +     */
  +    ap_table_setn(r->headers_out, "Vary",
  +		  ap_array_pstrcat(r->pool, arr, ','));
  +}
  +
   API_EXPORT(void) ap_send_http_header(request_rec *r)
   {
       int i;
  @@ -1479,6 +1586,9 @@
   	ap_table_unset(r->headers_out, "Vary");
   	r->proto_num = HTTP_VERSION(1,0);
   	ap_table_set(r->subprocess_env, "force-response-1.0", "1");
  +    }
  +    else {
  +	fixup_vary(r);
       }
   
       ap_hard_timeout("send headers", r);
  
  
  

Mime
View raw message