From e70247afa2e23c982afceeba5c62d9546dc55412 Mon Sep 17 00:00:00 2001 From: Stefan Eissing Date: Wed, 27 Jan 2016 14:51:53 +0000 Subject: [PATCH] new hook pre_close_connection git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1727071 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 5 +++++ include/http_connection.h | 14 ++++++++++++++ server/connection.c | 20 +++++++++++++++++--- server/mpm/event/event.c | 3 ++- 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index f4cbda6a23..ff45fc222b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,11 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 + *) core: new hook "pre_close_connection" which is run before the lingering + close of connections is started. This gives protocol handlers one last + chance to use a connection before it goes down. + [Stefan Eissing] + *) mod_filter: Fix AddOutputFilterByType with non-content-level filters. PR58856 [Micha Lenk ] diff --git a/include/http_connection.h b/include/http_connection.h index 58389a4fb4..8bc009da3b 100644 --- a/include/http_connection.h +++ b/include/http_connection.h @@ -75,6 +75,8 @@ AP_CORE_DECLARE(void) ap_flush_conn(conn_rec *c); */ AP_DECLARE(void) ap_lingering_close(conn_rec *c); +AP_DECLARE(int) ap_prep_lingering_close(conn_rec *c); + AP_DECLARE(int) ap_start_lingering_close(conn_rec *c); /* Hooks */ @@ -121,6 +123,18 @@ AP_DECLARE_HOOK(int,pre_connection,(conn_rec *c, void *csd)) */ AP_DECLARE_HOOK(int,process_connection,(conn_rec *c)) +/** + * This hook implements different protocols. Before a connection is closed, + * protocols might have to perform some housekeeping actions, such as + * sending one last goodbye packet. The connection is, unless some other + * error already happened before, still open and operational. + * All pre-close-connection hooks are run until one returns something + * other than ok or decline + * @param c The connection on which the request has been received. + * @return OK or DECLINED + */ +AP_DECLARE_HOOK(int,pre_close_connection,(conn_rec *c)) + /** End Of Connection (EOC) bucket */ AP_DECLARE_DATA extern const apr_bucket_type_t ap_bucket_type_eoc; diff --git a/server/connection.c b/server/connection.c index ccf685fcd3..0959b8550d 100644 --- a/server/connection.c +++ b/server/connection.c @@ -34,12 +34,15 @@ APR_HOOK_STRUCT( APR_HOOK_LINK(create_connection) APR_HOOK_LINK(process_connection) APR_HOOK_LINK(pre_connection) + APR_HOOK_LINK(pre_close_connection) ) AP_IMPLEMENT_HOOK_RUN_FIRST(conn_rec *,create_connection, (apr_pool_t *p, server_rec *server, apr_socket_t *csd, long conn_id, void *sbh, apr_bucket_alloc_t *alloc), (p, server, csd, conn_id, sbh, alloc), NULL) AP_IMPLEMENT_HOOK_RUN_FIRST(int,process_connection,(conn_rec *c),(c),DECLINED) AP_IMPLEMENT_HOOK_RUN_ALL(int,pre_connection,(conn_rec *c, void *csd),(c, csd),OK,DECLINED) +AP_IMPLEMENT_HOOK_RUN_ALL(int,pre_close_connection,(conn_rec *c),(c),OK,DECLINED) + /* * More machine-dependent networking gooo... on some systems, * you've got to be *really* sure that all the packets are acknowledged @@ -92,6 +95,17 @@ AP_CORE_DECLARE(void) ap_flush_conn(conn_rec *c) (void)ap_shutdown_conn(c, 1); } +AP_DECLARE(int) ap_prep_lingering_close(conn_rec *c) +{ + /* Give protocol handlers one last chance to raise their voice */ + ap_run_pre_close_connection(c); + + if (c->sbh) { + ap_update_child_status(c->sbh, SERVER_CLOSING, NULL); + } + return 0; +} + /* we now proceed to read from the client until we get EOF, or until * MAX_SECS_TO_LINGER has passed. The reasons for doing this are * documented in a draft: @@ -112,10 +126,10 @@ AP_DECLARE(int) ap_start_lingering_close(conn_rec *c) return 1; } - if (c->sbh) { - ap_update_child_status(c->sbh, SERVER_CLOSING, NULL); + if (!ap_prep_lingering_close(c)) { + return 1; } - + /* Close the connection, being careful to send out whatever is still * in our buffers. If possible, try to avoid a hard close until the * client has ACKed our FIN and/or has stopped sending us data. diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c index d4f5c68b98..21ddd283d9 100644 --- a/server/mpm/event/event.c +++ b/server/mpm/event/event.c @@ -940,7 +940,8 @@ static int start_lingering_close_nonblocking(event_conn_state_t *cs) conn_rec *c = cs->c; apr_socket_t *csd = cs->pfd.desc.s; - if (c->aborted + if (ap_prep_lingering_close(cs->c) + || c->aborted || ap_shutdown_conn(c, 0) != APR_SUCCESS || c->aborted || apr_socket_shutdown(csd, APR_SHUTDOWN_WRITE) != APR_SUCCESS) { apr_socket_close(csd); -- 2.40.0