mirror of
https://github.com/apache/httpd.git
synced 2025-08-08 15:02:10 +03:00
core: follow up to r1710095, r1710105.
We can do this in a single (no inner) loop, and simplify again the logic. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1711902 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -230,91 +230,94 @@ AP_DECLARE(void) ap_die(int type, request_rec *r)
|
|||||||
|
|
||||||
static void check_pipeline(conn_rec *c, apr_bucket_brigade *bb)
|
static void check_pipeline(conn_rec *c, apr_bucket_brigade *bb)
|
||||||
{
|
{
|
||||||
|
apr_status_t rv;
|
||||||
|
int num_blank_lines = DEFAULT_LIMIT_BLANK_LINES;
|
||||||
|
ap_input_mode_t mode = AP_MODE_SPECULATIVE;
|
||||||
|
apr_size_t cr = 0;
|
||||||
|
char buf[2];
|
||||||
|
|
||||||
c->data_in_input_filters = 0;
|
c->data_in_input_filters = 0;
|
||||||
if (c->keepalive != AP_CONN_CLOSE && !c->aborted) {
|
while (c->keepalive != AP_CONN_CLOSE && !c->aborted) {
|
||||||
apr_status_t rv;
|
apr_size_t len = cr + 1;
|
||||||
int num_blank_lines = DEFAULT_LIMIT_BLANK_LINES;
|
|
||||||
ap_input_mode_t mode = AP_MODE_SPECULATIVE;
|
|
||||||
apr_size_t len, cr = 0;
|
|
||||||
char buf[2];
|
|
||||||
|
|
||||||
do {
|
apr_brigade_cleanup(bb);
|
||||||
apr_brigade_cleanup(bb);
|
rv = ap_get_brigade(c->input_filters, bb, mode,
|
||||||
rv = ap_get_brigade(c->input_filters, bb, mode,
|
APR_NONBLOCK_READ, len);
|
||||||
APR_NONBLOCK_READ, cr + 1);
|
if (rv != APR_SUCCESS || APR_BRIGADE_EMPTY(bb)) {
|
||||||
if (rv != APR_SUCCESS || APR_BRIGADE_EMPTY(bb)) {
|
/*
|
||||||
/*
|
* Error or empty brigade: There is no data present in the input
|
||||||
* Error or empty brigade: There is no data present in the input
|
* filter
|
||||||
* filter
|
|
||||||
*/
|
|
||||||
if (mode == AP_MODE_READBYTES) {
|
|
||||||
/* Unexpected error, stop with this connection */
|
|
||||||
ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(02967)
|
|
||||||
"Can't consume pipelined empty lines");
|
|
||||||
c->keepalive = AP_CONN_CLOSE;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ignore trailing blank lines (which must not be interpreted as
|
|
||||||
* pipelined requests) up to the limit, otherwise we would block
|
|
||||||
* on the next read without flushing data, and hence possibly delay
|
|
||||||
* pending response(s) until the next/real request comes in or the
|
|
||||||
* keepalive timeout expires.
|
|
||||||
*/
|
*/
|
||||||
len = cr + 1;
|
|
||||||
rv = apr_brigade_flatten(bb, buf, &len);
|
|
||||||
if (rv != APR_SUCCESS || len != cr + 1) {
|
|
||||||
int level;
|
|
||||||
if (mode == AP_MODE_READBYTES) {
|
|
||||||
/* Unexpected error, stop with this connection */
|
|
||||||
c->keepalive = AP_CONN_CLOSE;
|
|
||||||
level = APLOG_ERR;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* Let outside (non-speculative/blocking) read determine
|
|
||||||
* where this possible failure comes from (metadata,
|
|
||||||
* morphed EOF socket => empty bucket? debug only here).
|
|
||||||
*/
|
|
||||||
c->data_in_input_filters = 1;
|
|
||||||
level = APLOG_DEBUG;
|
|
||||||
}
|
|
||||||
ap_log_cerror(APLOG_MARK, level, rv, c, APLOGNO(02968)
|
|
||||||
"Can't check pipelined data");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode == AP_MODE_READBYTES) {
|
if (mode == AP_MODE_READBYTES) {
|
||||||
mode = AP_MODE_SPECULATIVE;
|
/* Unexpected error, stop with this connection */
|
||||||
cr = 0;
|
ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(02967)
|
||||||
continue;
|
"Can't consume pipelined empty lines");
|
||||||
|
c->keepalive = AP_CONN_CLOSE;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (cr) {
|
/* Ignore trailing blank lines (which must not be interpreted as
|
||||||
AP_DEBUG_ASSERT(len == 2 && buf[0] == APR_ASCII_CR);
|
* pipelined requests) up to the limit, otherwise we would block
|
||||||
if (buf[1] != APR_ASCII_LF) {
|
* on the next read without flushing data, and hence possibly delay
|
||||||
return;
|
* pending response(s) until the next/real request comes in or the
|
||||||
}
|
* keepalive timeout expires.
|
||||||
|
*/
|
||||||
|
rv = apr_brigade_flatten(bb, buf, &len);
|
||||||
|
if (rv != APR_SUCCESS || len != cr + 1) {
|
||||||
|
int log_level;
|
||||||
|
if (mode == AP_MODE_READBYTES) {
|
||||||
|
/* Unexpected error, stop with this connection */
|
||||||
|
c->keepalive = AP_CONN_CLOSE;
|
||||||
|
log_level = APLOG_ERR;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Let outside (non-speculative/blocking) read determine
|
||||||
|
* where this possible failure comes from (metadata,
|
||||||
|
* morphed EOF socket => empty bucket? debug only here).
|
||||||
|
*/
|
||||||
|
c->data_in_input_filters = 1;
|
||||||
|
log_level = APLOG_DEBUG;
|
||||||
|
}
|
||||||
|
ap_log_cerror(APLOG_MARK, log_level, rv, c, APLOGNO(02968)
|
||||||
|
"Can't check pipelined data");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == AP_MODE_READBYTES) {
|
||||||
|
mode = AP_MODE_SPECULATIVE;
|
||||||
|
cr = 0;
|
||||||
|
}
|
||||||
|
else if (cr) {
|
||||||
|
AP_DEBUG_ASSERT(len == 2 && buf[0] == APR_ASCII_CR);
|
||||||
|
if (buf[1] == APR_ASCII_LF) {
|
||||||
mode = AP_MODE_READBYTES;
|
mode = AP_MODE_READBYTES;
|
||||||
num_blank_lines--;
|
num_blank_lines--;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (buf[0] == APR_ASCII_CR) {
|
c->data_in_input_filters = 1;
|
||||||
cr = 1;
|
break;
|
||||||
}
|
|
||||||
else if (buf[0] == APR_ASCII_LF) {
|
|
||||||
mode = AP_MODE_READBYTES;
|
|
||||||
num_blank_lines--;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
c->data_in_input_filters = 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} while (num_blank_lines >= 0);
|
}
|
||||||
|
else {
|
||||||
/* Don't recycle this (abused) connection */
|
if (buf[0] == APR_ASCII_LF) {
|
||||||
c->keepalive = AP_CONN_CLOSE;
|
mode = AP_MODE_READBYTES;
|
||||||
|
num_blank_lines--;
|
||||||
|
}
|
||||||
|
else if (buf[0] == APR_ASCII_CR) {
|
||||||
|
cr = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c->data_in_input_filters = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Enough blank lines with this connection?
|
||||||
|
* Stop and don't recycle it.
|
||||||
|
*/
|
||||||
|
if (num_blank_lines < 0) {
|
||||||
|
c->keepalive = AP_CONN_CLOSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user