httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dean Gaudet <dgau...@arctic.org>
Subject vary
Date Thu, 29 Jul 1999 18:40:11 GMT
This is lightly tested.  The comments say more. 

Dean

Index: main/http_protocol.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_protocol.c,v
retrieving revision 1.272
diff -u -r1.272 http_protocol.c
--- http_protocol.c	1999/07/19 10:15:58	1.272
+++ http_protocol.c	1999/07/29 18:38:44
@@ -1446,6 +1446,89 @@
              && strstr(ua, "MSIE 3")));
 }
 
+static int compare_vary(const void *va, const void *vb)
+{
+    return strcasecmp(*(const char **)va, *(const char **)vb);
+}
+
+static void fixup_vary(request_rec *r)
+{
+    const char *vary;
+    array_header *arr;
+    char *work;
+    char *start;
+    char *e;
+    char **ecur;
+    char **eend;
+    char **ekeep;
+
+    vary = ap_table_get(r->headers_out, "Vary");
+    if (!vary) {
+	return;
+    }
+
+    /* 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]+/.
+     */
+    work = ap_pstrdup(r->pool, vary);
+    e = work;
+    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 */
+	ecur = (char **)arr->elts;
+	ekeep = ecur;
+	eend = ecur + arr->nelts - 1;
+	while (ecur < eend) {
+	    if (strcasecmp(ecur[0], ecur[1])) {
+		*ekeep++ = *ecur;
+		if (ecur + 1 == eend) {
+		    *ekeep++ = ecur[1];
+		    break;
+		}
+	    }
+	    ++ecur;
+	}
+	arr->nelts = ekeep - (char **)arr->elts;
+    }
+
+    /* 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 +1562,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