On Tue, Jun 1, 2010 at 10:39 AM, Brian Pane <brianp...@gmail.com> wrote: > In a filter module I'm writing, it's possible for the first pass > through the output filter to end up calling: > ap_pass_brigade(f->next, an_empty_brigade) > > If mod_deflate's output filter appears later in the output filter > chain, bad things happen: > 1. On the first trip through the output filter chain, mod_deflate just > passes the empty brigade through to the next filter: > /* Do nothing if asked to filter nothing. */ > if (APR_BRIGADE_EMPTY(bb)) { > return ap_pass_brigade(f->next, bb); > } > 2. Control eventually reaches core_output_filter, which sends the > response headers. > 3. On a subsequent trip through the output filter chain, my module calls: > ap_pass_brigade(f->next, a non_empty_brigade) > 4. Upon seeing the non empty brigade, mod_deflate's output filter does > all the initialization that it would normally do at the start of a > response. If the response is compressible, deflate_out_filter adds > "Content-Encoding: gzip" to the output headers. The output headers > have been sent already, though, so the Content-Encoding never gets > sent. > 5. The client receives a compressed response without a Content-Encoding > header. > > I can prevent this by not calling ap_pass_brigade in my module until I > have the first non-empty brigade for the rest of the output filter > chain to work with. > > I'm curious, though: which module is doing the wrong thing: > - My module, by sending an empty brigade through the rest of the > output filter chain prior to sending the first non-empty brigade? > - Or mod_deflate, by adding fields to the response header after > calling ap_pass_brigade?
Would it do harm if the core output filter did the same check as mod_deflate before committing the headers? Seems like a filter could have just dropped the content of your first brigade anyway. -- Eric Covener cove...@gmail.com