On Thu, 22 Jul 2004, Nick Kew wrote:
> On Mon, 19 Jul 2004, Joe Orton wrote:
>
> > Nothing like that was posted to the list, at least. Patch below is
> > still sufficient to fix the proxy+304 case; does it work for you too?
>
> Yes, mostly (it fixes the important bug that was previously a
> showstopper).
I attach a new patch based on yours. it fixes my testcases including
headers for HEAD requests. Look OK to you?
--
Nick Kew
--- mod_deflate.c.bak 2004-07-22 11:12:53.000000000 +0100
+++ mod_deflate.c 2004-07-22 12:17:13.000000000 +0100
@@ -247,7 +247,6 @@
apr_bucket_brigade *bb, *proc_bb;
} deflate_ctx;
-static void* const deflate_yes = (void*)"YES";
static apr_status_t deflate_out_filter(ap_filter_t *f,
apr_bucket_brigade *bb)
{
@@ -255,14 +254,14 @@
request_rec *r = f->r;
deflate_ctx *ctx = f->ctx;
int zRC;
- char* buf;
- int eos_only = 1;
- apr_bucket *bkt;
- char *token;
- const char *encoding = NULL;
deflate_filter_config *c = ap_get_module_config(r->server->module_config,
&deflate_module);
+ /* Do nothing if asked to filter nothing. */
+ if (APR_BRIGADE_EMPTY(bb)) {
+ return APR_SUCCESS;
+ }
+
/* If we don't have a context, we need to ensure that it is okay to send
* the deflated content. If we have a context, that means we've done
* this before and we liked it.
@@ -270,6 +269,8 @@
* we're in better shape.
*/
if (!ctx) {
+ char *buf, *token;
+ const char *encoding;
/* only work on main request/no subrequests */
if (r->main) {
@@ -349,7 +350,6 @@
*/
apr_table_setn(r->headers_out, "Vary", "Accept-Encoding");
-
/* force-gzip will just force it out regardless if the browser
* can actually do anything with it.
*/
@@ -384,39 +384,22 @@
}
}
- /* don't deflate responses with zero length e.g. proxied 304's but
- * we do set the header on eos_only at this point for headers_filter
- *
- * if we get eos_only and come round again, we want to avoid redoing
- * what we've already done, so set f->ctx to a flag here
+ /* Deflating a zero-length response would make it longer; the
+ * proxy may pass through an empty response for a 304 too.
+ * So we just need to fix up the headers as if we had a body.
*/
- f->ctx = ctx = deflate_yes;
- }
- if (ctx == deflate_yes) {
- /* deal with the pathological case of lots of empty brigades and
- * no knowledge of whether content will follow
- */
- for (bkt = APR_BRIGADE_FIRST(bb);
- bkt != APR_BRIGADE_SENTINEL(bb);
- bkt = APR_BUCKET_NEXT(bkt))
- {
- if (!APR_BUCKET_IS_EOS(bkt)) {
- eos_only = 0;
- break;
- }
- }
- if (eos_only) {
- if (!encoding || !strcasecmp(encoding, "identity")) {
+ if (APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(bb))) {
+ if (!encoding || !strcasecmp(encoding, "identity")) {
apr_table_set(r->headers_out, "Content-Encoding", "gzip");
}
else {
apr_table_merge(r->headers_out, "Content-Encoding", "gzip");
}
apr_table_unset(r->headers_out, "Content-Length");
+
+ ap_remove_output_filter(f);
return ap_pass_brigade(f->next, bb);
}
- }
- if (!ctx || (ctx==deflate_yes)) {
/* We're cool with filtering this. */
ctx = f->ctx = apr_pcalloc(r->pool, sizeof(*ctx));
@@ -912,6 +895,11 @@
apr_status_t rv;
deflate_filter_config *c;
+ /* Do nothing if asked to filter nothing. */
+ if (APR_BRIGADE_EMPTY(bb)) {
+ return APR_SUCCESS;
+ }
+
c = ap_get_module_config(r->server->module_config, &deflate_module);
if (!ctx) {
@@ -950,6 +938,13 @@
}
apr_table_unset(r->headers_out, "Content-Encoding");
+ /* No need to inflate HEAD or 204/304 */
+ if (APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(bb))) {
+ ap_remove_output_filter(f);
+ return ap_pass_brigade(f->next, bb);
+ }
+
+
f->ctx = ctx = apr_pcalloc(f->r->pool, sizeof(*ctx));
ctx->proc_bb = apr_brigade_create(r->pool, f->c->bucket_alloc);
ctx->buffer = apr_palloc(r->pool, c->bufferSize);
@@ -983,9 +978,10 @@
apr_size_t len;
/* If we actually see the EOS, that means we screwed up! */
+ /* no it doesn't - not in a HEAD or 204/304 */
if (APR_BUCKET_IS_EOS(bkt)) {
inflateEnd(&ctx->stream);
- return APR_EGENERAL;
+ return ap_pass_brigade(f->next, bb);
}
if (APR_BUCKET_IS_FLUSH(bkt)) {