| 381 |
ctx->libz_end_func(&ctx->stream); |
ctx->libz_end_func(&ctx->stream); |
| 382 |
return APR_SUCCESS; |
return APR_SUCCESS; |
| 383 |
} |
} |
| 384 |
/* PR 39727: we're screwing up our clients if we leave a strong ETag |
|
| 385 |
* header while transforming content. Henrik Nordstrom suggests |
/* ETag must be unique among the possible representations, so a change |
| 386 |
* appending ";gzip". |
* to content-encoding requires a corresponding change to the ETag. |
| 387 |
* |
* This routine appends -transform (e.g., -gzip) to the entity-tag |
| 388 |
* Pending a more thorough review of our Etag handling, let's just |
* value inside the double-quotes if an ETag has already been set |
| 389 |
* implement his suggestion. It fixes the bug, or at least turns it |
* and its value already contains double-quotes. PR 39727 |
|
* from a showstopper to an inefficiency. And it breaks nothing that |
|
|
* wasn't already broken. |
|
| 390 |
*/ |
*/ |
| 391 |
static void deflate_check_etag(request_rec *r, const char *transform) |
static void deflate_check_etag(request_rec *r, const char *transform) |
| 392 |
{ |
{ |
| 393 |
const char *etag = apr_table_get(r->headers_out, "ETag"); |
const char *etag = apr_table_get(r->headers_out, "ETag"); |
| 394 |
if ((etag && (strlen(etag) > 2))) { |
apr_size_t etaglen; |
| 395 |
if (etag[0] == '"') { |
|
| 396 |
etag = apr_pstrndup(r->pool, etag, strlen(etag) - 1); |
if ((etag && ((etaglen = strlen(etag)) > 2))) { |
| 397 |
apr_table_set(r->headers_out, "ETag", |
if (etag[etaglen - 1] == '"') { |
| 398 |
apr_pstrcat(r->pool, etag, "-", transform, "\"", NULL)); |
apr_size_t transformlen = strlen(transform); |
| 399 |
|
char *newtag = apr_palloc(r->pool, etaglen + transformlen + 2); |
| 400 |
|
char *d = newtag; |
| 401 |
|
char *e = d + etaglen - 1; |
| 402 |
|
const char *s = etag; |
| 403 |
|
|
| 404 |
|
for (; d < e; ++d, ++s) { |
| 405 |
|
*d = *s; /* copy etag to newtag up to last quote */ |
| 406 |
|
} |
| 407 |
|
*d++ = '-'; /* append dash to newtag */ |
| 408 |
|
s = transform; |
| 409 |
|
e = d + transformlen; |
| 410 |
|
for (; d < e; ++d, ++s) { |
| 411 |
|
*d = *s; /* copy transform to newtag */ |
| 412 |
|
} |
| 413 |
|
*d++ = '"'; /* append quote to newtag */ |
| 414 |
|
*d = '\0'; /* null terminate newtag */ |
| 415 |
|
|
| 416 |
|
apr_table_setn(r->headers_out, "ETag", newtag); |
| 417 |
} |
} |
| 418 |
} |
} |
| 419 |
} |
} |
| 420 |
|
|
| 421 |
static apr_status_t deflate_out_filter(ap_filter_t *f, |
static apr_status_t deflate_out_filter(ap_filter_t *f, |
| 422 |
apr_bucket_brigade *bb) |
apr_bucket_brigade *bb) |
| 423 |
{ |
{ |