--- include/http_core.h (revision 1523591) +++ include/http_core.h (working copy) @@ -698,6 +698,14 @@ apr_status_t ap_core_input_filter(ap_filter_t *f, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes); apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *b); +/** + * When ap_core_input_filter with AP_MODE_GETLINE gets an immediate EOF from + * the socket, should it return APR_SUCCESS with an empty brigade (legacy) or + * return APR_EOF (default) ? + */ +#ifndef AP_CORE_INPUT_FILTER_GETLINE_EOF +#define AP_CORE_INPUT_FILTER_GETLINE_EOF 1 +#endif AP_DECLARE(const char*) ap_get_server_protocol(server_rec* s); --- server/core_filters.c (revision 1523591) +++ server/core_filters.c (working copy) @@ -152,6 +152,25 @@ apr_status_t ap_core_input_filter(ap_filter_t *f, if (APR_STATUS_IS_EAGAIN(rv) && block == APR_NONBLOCK_READ) { rv = APR_SUCCESS; } +#if AP_CORE_INPUT_FILTER_GETLINE_EOF + /* When the socket is immediatly EOF, apr_brigade_split_line returns + * APR_SUCCESS with an empty brigade (socket_bucket_read morphes the + * socket into an empty buffer which in turn is stripped by + * apr_brigade_split_line). + * + * In blocking mode we should never return APR_SUCCESS with an empty + * brigade, we are APR_EOF now and for the next calls. + * + * XXX: Note that we are EOF in any blocking mode (although callers + * are used to empty brigade in non-blocking mode), should that break + * some logic, one can "&& block == APR_BLOCK_READ" here, but if it's + * OK, let's avoid a next call... + */ + else if (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(b) + && APR_BRIGADE_EMPTY(ctx->b)) { + rv = APR_EOF; + } +#endif return rv; }