| 373 |
return APR_SUCCESS; |
return APR_SUCCESS; |
| 374 |
} |
} |
| 375 |
/* PR 39727: we're screwing up our clients if we leave a strong ETag |
/* PR 39727: we're screwing up our clients if we leave a strong ETag |
| 376 |
* header while transforming content. A minimal fix that makes us |
* header while transforming content. Henrik Nordstrom suggests |
| 377 |
* protocol-compliant is to make it a weak ETag. Whether we can |
* appending ";gzip". |
|
* use this ourselves (e.g. in mod_cache) is a different issue. |
|
| 378 |
* |
* |
| 379 |
* Henrik Nordstrom suggests instead appending ";gzip", commenting: |
* Pending a more thorough review of our Etag handling, let's just |
| 380 |
* "This should allows for easy bidirectional mapping, simplifying most |
* implement his suggestion. It fixes the bug, or at least turns it |
| 381 |
* conditionals as no transformation of the entity body is needed to find |
* from a showstopper to an inefficiency. And it breaks nothing that |
| 382 |
* the etag, and the simple format makes it easier to trace should any |
* wasn't already broken. |
|
* misunderstandings occur." |
|
|
* |
|
|
* We might consider such a strategy in future if we implement support |
|
|
* for such a scheme. |
|
| 383 |
*/ |
*/ |
| 384 |
static void deflate_check_etag(request_rec *r) |
static void deflate_check_etag(request_rec *r, const char *transform) |
| 385 |
{ |
{ |
| 386 |
const char *etag = apr_table_get(r->headers_out, "ETag"); |
const char *etag = apr_table_get(r->headers_out, "ETag"); |
| 387 |
if (etag && (((etag[0] != 'W') && (etag[0] !='w')) || (etag[1] != '/'))) { |
if (etag && (((etag[0] != 'W') && (etag[0] !='w')) || (etag[1] != '/'))) { |
| 388 |
apr_table_set(r->headers_out, "ETag", |
apr_table_set(r->headers_out, "ETag", |
| 389 |
apr_pstrcat(r->pool, "W/", etag, NULL)); |
apr_pstrcat(r->pool, etag, "-", transform, NULL)); |
| 390 |
} |
} |
| 391 |
} |
} |
| 392 |
static apr_status_t deflate_out_filter(ap_filter_t *f, |
static apr_status_t deflate_out_filter(ap_filter_t *f, |
| 586 |
} |
} |
| 587 |
apr_table_unset(r->headers_out, "Content-Length"); |
apr_table_unset(r->headers_out, "Content-Length"); |
| 588 |
apr_table_unset(r->headers_out, "Content-MD5"); |
apr_table_unset(r->headers_out, "Content-MD5"); |
| 589 |
deflate_check_etag(r); |
deflate_check_etag(r, "gzip"); |
| 590 |
|
|
| 591 |
/* initialize deflate output buffer */ |
/* initialize deflate output buffer */ |
| 592 |
ctx->stream.next_out = ctx->buffer; |
ctx->stream.next_out = ctx->buffer; |
| 1079 |
/* these are unlikely to be set anyway, but ... */ |
/* these are unlikely to be set anyway, but ... */ |
| 1080 |
apr_table_unset(r->headers_out, "Content-Length"); |
apr_table_unset(r->headers_out, "Content-Length"); |
| 1081 |
apr_table_unset(r->headers_out, "Content-MD5"); |
apr_table_unset(r->headers_out, "Content-MD5"); |
| 1082 |
deflate_check_etag(r); |
deflate_check_etag(r, "gunzip"); |
| 1083 |
|
|
| 1084 |
/* initialize inflate output buffer */ |
/* initialize inflate output buffer */ |
| 1085 |
ctx->stream.next_out = ctx->buffer; |
ctx->stream.next_out = ctx->buffer; |