When following conditions are met, mod_deflate (as a filter) does not propagate EOS to the upper level and leads to WRONG REQUEST (HTTP 400) responce. 1. enable mod_dav, mod_dav_fs, mod_deflate 2. compression is enabled for both - input and output 3. client sends PROPFIND HTTP/1.1 request with Content-Encoding: gzip header and a properly gzip'ed xml content. Example of httpd.conf: ###httpd.conf BEGIN ... skipped all common options ... LoadModule deflate_module modules/mod_deflate.so NameVirtualHost localhost:80 NameVirtualHost localhost:801 <VirtualHost localhost:80> </VirtualHost> <VirtualHost localhost:801> DAVLockDB logs/DavLock <Directory "D:/apa2_0_43_15JAN03/Debug/htdocs"> SetInputFilter DEFLATE SetOutputFilter DEFLATE DAV On <Limit PUT POST DELETE PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK> AuthName "Foo" AuthType Basic AuthUserFile logs/passw Require user dmitri </Limit> </Directory> </VirtualHost> ###httpd.conf END My investigation showed that the trouble is in xml_util.c and mod_delate.c files. First requires data until a len=0 (normal condition) or len<0 (error) returned while the second never returns EOS and as a result len is never 0. See mod_deflate.c:662: /* If we actually see the EOS, that means we screwed up! */ if (APR_BUCKET_IS_EOS(bkt)) { return APR_EGENERAL; } I propose a patch that works: --- mod_deflate.c~ 2003-01-03 02:12:36.000000000 +0300 +++ mod_deflate.c 2003-01-15 23:15:38.000000000 +0300 @@ -648,6 +648,15 @@ apr_brigade_cleanup(ctx->bb); } + if (APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(ctx->bb))) { + apr_bucket *eos; + + apr_brigade_cleanup(ctx->bb); + eos = apr_bucket_eos_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, eos); + return APR_SUCCESS; + } + if (APR_BRIGADE_EMPTY(ctx->proc_bb)) { rv = ap_get_brigade(f->next, ctx->bb, mode, block, readbytes); I'm not sure that it's absolutely correct and it needs to be reviewed by somebody who knows Apache2 architecture better.
Once again the proposed patch agains the most recent version of mod_deflate.c: --- mod_deflate.c~ 2003-01-03 02:12:36.000000000 +0300 +++ mod_deflate.c 2003-01-15 23:31:04.000000000 +0300 @@ -557,7 +557,7 @@ int zRC; apr_status_t rv; deflate_filter_config *c; - + /* just get out of the way of things we don't want. */ if (mode != AP_MODE_READBYTES) { return ap_get_brigade(f->next, bb, mode, block, readbytes); @@ -655,6 +655,15 @@ return rv; } + if (APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(ctx->bb))) { + apr_bucket *eos; + + apr_brigade_cleanup(ctx->bb); + eos = apr_bucket_eos_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, eos); + return APR_SUCCESS; + } + APR_BRIGADE_FOREACH(bkt, ctx->bb) { const char *data; apr_size_t len;
Changed how ap_xml_parse_input works in server/util_xml.c r1.22 so that it realizes when EOS is sent. I've proposed this to be backported to the next stable release. Thanks for using Apache HTTP Server!