You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Dean Gaudet <dg...@arctic.org> on 1999/07/29 20:40:11 UTC
vary
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);
Re: vary
Posted by Rodent of Unusual Size <Ke...@Golux.Com>.
Dean Gaudet wrote:
>
> This is lightly tested. The comments say more.
A definitely better solution, but there's a boundary condition
I'm tracking down..
--
#ken P-)}
Ken Coar <http://Web.Golux.Com/coar/>
Apache Software Foundation <http://www.apache.org/>
"Apache Server for Dummies" <http://ASFD.MeepZor.Com/>