On 18 Nov 2013, at 1:24 PM, "Plüm, Rüdiger, Vodafone Group" <ruediger.pl...@vodafone.com> wrote:
> + rv = send_brigade_nonblocking(net->client_socket, bb, > + &(ctx->bytes_written), c); > + if (APR_STATUS_IS_EAGAIN(rv)) { > + setaside_remaining_output(f, ctx, bb, c); > + } > + else if (rv != APR_EAGAIN) { > > What if rv is APR_SUCCESS? This is indeed broken, fixed. Some more testing has revealed that mod_ssl's output filter breaks rules 2 and 5 of the 10 output filter rules published here: http://httpd.apache.org/docs/trunk/da/developer/output-filters.html#rules Instead of passing on all metadata buckets as required, mod_ssl only takes into account EOS, EOC and FLUSH, and tries to consume metadata buckets as normal data buckets. SSL_write() then sees the zero length write and treats it as a noop. The core filter is never called, the event mpm interprets a non zero c->data_in_output_filters as an invitation to try again, and we go into a spin. If mod_ssl does this, we can expect other modules in the wild to be a problem. A possible solution to this dilemma is to try and detect buggy filters and compensate for the problem. We might have a protocol helper filter that run early on and passes the brigade upstream. If we started with c->data_in_output_filters as non zero and we are in WRITE_COMPLETION, and on return the filter sees APR_SUCCESS from upstream, but c->data_in_output_filters is still not zero, we may not have reached the core filter, so call the core filter directly once with a nonblock bucket simulating the behaviour we have now. This will ensure the setaside data in the core output filter will always be written at least once on each call, preventing the spin. This path in theory should only be followed if the buggy filter is present, because when the buggy filter is not present and the core is successfully reached the return code will be APR_EAGAIN, or APR_SUCCESS with c->data_in_output_filters going to zero. Regards, Graham --