On 01/05/2006 09:04 PM, Graham Leggett wrote:
> Matthias Behrens wrote:
[..cut..]
>
> This is an interesting problem, but definitely worth looking into fixing.
The logic in mod_proxy_http.c of 2.2.x already tries to address this issue by
flushing the data if no more data is available from the backend right now:
apr_read_type_e mode = APR_NONBLOCK_READ;
int finish = FALSE;
do {
apr_off_t readbytes;
apr_status_t rv;
rv = ap_get_brigade(rp->input_filters, bb,
AP_MODE_READBYTES, mode,
conf->io_buffer_size);
/* ap_get_brigade will return success with an empty brigade
* for a non-blocking read which would block: */
if (APR_STATUS_IS_EAGAIN(rv)
|| (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb))) {
/* flush to the client and switch to blocking mode */
e = apr_bucket_flush_create(c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, e);
if (ap_pass_brigade(r->output_filters, bb)
|| c->aborted) {
backend->close = 1;
break;
}
apr_brigade_cleanup(bb);
mode = APR_BLOCK_READ;
continue;
}
else if (rv == APR_EOF) {
break;
}
else if (rv != APR_SUCCESS) {
ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c,
"proxy: error reading response");
break;
}
/* next time try a non-blocking read */
mode = APR_NONBLOCK_READ;
Anyway, it does not work as expected, as it seems that the condition
(APR_STATUS_IS_EAGAIN(rv)
|| (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb))) {
never gets true. I did not have the time to dig in deeper, but maybe you want
to do some search.
BTW: mod_proxy_ajp currently addresses this issue with a bandaid until
the AJP protocol has some sort of flushing command. It is also based on
a check if more data is available from the backend right now.
[..cut..]
Regards
Rüdiger