From: Jim Jagielski Date: Tue, 10 Mar 2009 15:00:54 +0000 (+0000) Subject: Backported and commited X-Git-Tag: 2.2.12~196 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=70699d021e6654c11b38d466507083d8809f6998;p=thirdparty%2Fapache%2Fhttpd.git Backported and commited git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@752129 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/STATUS b/STATUS index 780533feb5e..b4924c460aa 100644 --- a/STATUS +++ b/STATUS @@ -86,16 +86,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * mod_deflate: Fix creation of invalid Etags with mod_deflate - (PR 39727, comment #22) - (updated to use Roy's patch) - Trunk version of patch: - (http://svn.apache.org/viewvc?view=rev&revision=740149) - http://svn.apache.org/viewvc?view=rev&revision=743595 - Backport version for 2.2.x of patch: - http://people.apache.org/~lars/mod_deflate_etagfix.patch - +1: lars, fielding, minfrin - PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/modules/filters/mod_deflate.c b/modules/filters/mod_deflate.c index de1a57d78a3..ebeab75759b 100644 --- a/modules/filters/mod_deflate.c +++ b/modules/filters/mod_deflate.c @@ -372,22 +372,40 @@ static apr_status_t deflate_ctx_cleanup(void *data) ctx->libz_end_func(&ctx->stream); return APR_SUCCESS; } -/* PR 39727: we're screwing up our clients if we leave a strong ETag - * header while transforming content. Henrik Nordstrom suggests - * appending ";gzip". - * - * Pending a more thorough review of our Etag handling, let's just - * implement his suggestion. It fixes the bug, or at least turns it - * from a showstopper to an inefficiency. And it breaks nothing that - * wasn't already broken. +/* ETag must be unique among the possible representations, so a change + * to content-encoding requires a corresponding change to the ETag. + * This routine appends -transform (e.g., -gzip) to the entity-tag + * value inside the double-quotes if an ETag has already been set + * and its value already contains double-quotes. PR 39727 */ static void deflate_check_etag(request_rec *r, const char *transform) { const char *etag = apr_table_get(r->headers_out, "ETag"); - if (etag && (((etag[0] != 'W') && (etag[0] !='w')) || (etag[1] != '/'))) { - apr_table_set(r->headers_out, "ETag", - apr_pstrcat(r->pool, etag, "-", transform, NULL)); - } + apr_size_t etaglen; + + if ((etag && ((etaglen = strlen(etag)) > 2))) { + if (etag[etaglen - 1] == '"') { + apr_size_t transformlen = strlen(transform); + char *newtag = apr_palloc(r->pool, etaglen + transformlen + 2); + char *d = newtag; + char *e = d + etaglen - 1; + const char *s = etag; + + for (; d < e; ++d, ++s) { + *d = *s; /* copy etag to newtag up to last quote */ + } + *d++ = '-'; /* append dash to newtag */ + s = transform; + e = d + transformlen; + for (; d < e; ++d, ++s) { + *d = *s; /* copy transform to newtag */ + } + *d++ = '"'; /* append quote to newtag */ + *d = '\0'; /* null terminate newtag */ + + apr_table_setn(r->headers_out, "ETag", newtag); + } + } } static apr_status_t deflate_out_filter(ap_filter_t *f, apr_bucket_brigade *bb)