mirror of
https://github.com/apache/httpd.git
synced 2025-08-08 15:02:10 +03:00
core: Cleanup the request soon/even if some output filter fails to
handle the EOR bucket. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1666998 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
3
CHANGES
3
CHANGES
@@ -6,6 +6,9 @@ Changes with Apache 2.5.0
|
|||||||
to a local URL-path with the INCLUDES filter active, introduced
|
to a local URL-path with the INCLUDES filter active, introduced
|
||||||
in 2.4.11. PR 57531. [Yann Ylavic]
|
in 2.4.11. PR 57531. [Yann Ylavic]
|
||||||
|
|
||||||
|
*) core: Cleanup the request soon/even if some output filter fails to
|
||||||
|
handle the EOR bucket. [Yann Ylavic]
|
||||||
|
|
||||||
*) mpm_event: Allow for timer events duplicates. [Jim Jagielski, Yann Ylavic]
|
*) mpm_event: Allow for timer events duplicates. [Jim Jagielski, Yann Ylavic]
|
||||||
|
|
||||||
*) mod_dav: Avoid a potential integer underflow in the lock timeout value sent
|
*) mod_dav: Avoid a potential integer underflow in the lock timeout value sent
|
||||||
|
@@ -228,12 +228,12 @@ AP_DECLARE(void) ap_die(int type, request_rec *r)
|
|||||||
ap_die_r(type, r, r->status);
|
ap_die_r(type, r, r->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_pipeline(conn_rec *c)
|
static void check_pipeline(conn_rec *c, apr_bucket_brigade *bb)
|
||||||
{
|
{
|
||||||
if (c->keepalive != AP_CONN_CLOSE) {
|
if (c->keepalive != AP_CONN_CLOSE && !c->aborted) {
|
||||||
apr_status_t rv;
|
apr_status_t rv;
|
||||||
apr_bucket_brigade *bb = apr_brigade_create(c->pool, c->bucket_alloc);
|
|
||||||
|
|
||||||
|
AP_DEBUG_ASSERT(APR_BRIGADE_EMPTY(bb));
|
||||||
rv = ap_get_brigade(c->input_filters, bb, AP_MODE_SPECULATIVE,
|
rv = ap_get_brigade(c->input_filters, bb, AP_MODE_SPECULATIVE,
|
||||||
APR_NONBLOCK_READ, 1);
|
APR_NONBLOCK_READ, 1);
|
||||||
if (rv != APR_SUCCESS || APR_BRIGADE_EMPTY(bb)) {
|
if (rv != APR_SUCCESS || APR_BRIGADE_EMPTY(bb)) {
|
||||||
@@ -246,7 +246,6 @@ static void check_pipeline(conn_rec *c)
|
|||||||
else {
|
else {
|
||||||
c->data_in_input_filters = 1;
|
c->data_in_input_filters = 1;
|
||||||
}
|
}
|
||||||
apr_brigade_destroy(bb);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,20 +260,30 @@ AP_DECLARE(void) ap_process_request_after_handler(request_rec *r)
|
|||||||
* this bucket is destroyed, the request will be logged and
|
* this bucket is destroyed, the request will be logged and
|
||||||
* its pool will be freed
|
* its pool will be freed
|
||||||
*/
|
*/
|
||||||
bb = apr_brigade_create(r->connection->pool, r->connection->bucket_alloc);
|
bb = apr_brigade_create(c->pool, c->bucket_alloc);
|
||||||
b = ap_bucket_eor_create(r->connection->bucket_alloc, r);
|
b = ap_bucket_eor_create(c->bucket_alloc, r);
|
||||||
APR_BRIGADE_INSERT_HEAD(bb, b);
|
APR_BRIGADE_INSERT_HEAD(bb, b);
|
||||||
|
|
||||||
ap_pass_brigade(r->connection->output_filters, bb);
|
ap_pass_brigade(c->output_filters, bb);
|
||||||
|
|
||||||
|
/* The EOR bucket has either been handled by an output filter (eg.
|
||||||
|
* deleted or moved to a buffered_bb => no more in bb), or an error
|
||||||
|
* occured before that (eg. c->aborted => still in bb) and we ought
|
||||||
|
* to destroy it now. So cleanup any remaining bucket along with
|
||||||
|
* the orphan request (if any).
|
||||||
|
*/
|
||||||
|
apr_brigade_cleanup(bb);
|
||||||
|
|
||||||
/* From here onward, it is no longer safe to reference r
|
/* From here onward, it is no longer safe to reference r
|
||||||
* or r->pool, because r->pool may have been destroyed
|
* or r->pool, because r->pool may have been destroyed
|
||||||
* already by the EOR bucket's cleanup function.
|
* already by the EOR bucket's cleanup function.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
check_pipeline(c, bb);
|
||||||
|
apr_brigade_destroy(bb);
|
||||||
if (c->cs)
|
if (c->cs)
|
||||||
c->cs->state = CONN_STATE_WRITE_COMPLETION;
|
c->cs->state = (c->aborted) ? CONN_STATE_LINGER
|
||||||
check_pipeline(c);
|
: CONN_STATE_WRITE_COMPLETION;
|
||||||
AP_PROCESS_REQUEST_RETURN((uintptr_t)r, r->uri, r->status);
|
AP_PROCESS_REQUEST_RETURN((uintptr_t)r, r->uri, r->status);
|
||||||
if (ap_extended_status) {
|
if (ap_extended_status) {
|
||||||
ap_time_process_request(c->sbh, STOP_PREQUEST);
|
ap_time_process_request(c->sbh, STOP_PREQUEST);
|
||||||
|
@@ -468,17 +468,16 @@ apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *new_bb)
|
|||||||
if (new_bb == NULL) {
|
if (new_bb == NULL) {
|
||||||
rv = send_brigade_nonblocking(net->client_socket, bb,
|
rv = send_brigade_nonblocking(net->client_socket, bb,
|
||||||
&(ctx->bytes_written), c);
|
&(ctx->bytes_written), c);
|
||||||
if (APR_STATUS_IS_EAGAIN(rv)) {
|
if (rv != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(rv)) {
|
||||||
rv = APR_SUCCESS;
|
|
||||||
}
|
|
||||||
else if (rv != APR_SUCCESS) {
|
|
||||||
/* The client has aborted the connection */
|
/* The client has aborted the connection */
|
||||||
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c,
|
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c,
|
||||||
"core_output_filter: writing data to the network");
|
"core_output_filter: writing data to the network");
|
||||||
|
apr_brigade_cleanup(bb);
|
||||||
c->aborted = 1;
|
c->aborted = 1;
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
setaside_remaining_output(f, ctx, bb, c);
|
setaside_remaining_output(f, ctx, bb, c);
|
||||||
return rv;
|
return APR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes_in_brigade = 0;
|
bytes_in_brigade = 0;
|
||||||
@@ -560,6 +559,7 @@ apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *new_bb)
|
|||||||
/* The client has aborted the connection */
|
/* The client has aborted the connection */
|
||||||
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c,
|
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c,
|
||||||
"core_output_filter: writing data to the network");
|
"core_output_filter: writing data to the network");
|
||||||
|
apr_brigade_cleanup(bb);
|
||||||
c->aborted = 1;
|
c->aborted = 1;
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@@ -587,6 +587,7 @@ apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *new_bb)
|
|||||||
/* The client has aborted the connection */
|
/* The client has aborted the connection */
|
||||||
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c,
|
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, rv, c,
|
||||||
"core_output_filter: writing data to the network");
|
"core_output_filter: writing data to the network");
|
||||||
|
apr_brigade_cleanup(bb);
|
||||||
c->aborted = 1;
|
c->aborted = 1;
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user