]> granicus.if.org Git - apache/commitdiff
merging pre_close_connection hook, prep_lingering_close and ap_update_child() additio...
authorStefan Eissing <icing@apache.org>
Thu, 25 Feb 2016 10:27:27 +0000 (10:27 +0000)
committerStefan Eissing <icing@apache.org>
Thu, 25 Feb 2016 10:27:27 +0000 (10:27 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1732275 13f79535-47bb-0310-9956-ffa450edef68

include/ap_mmn.h
include/http_connection.h
include/scoreboard.h
modules/generators/mod_status.c
modules/ssl/ssl_engine_kernel.c
server/connection.c
server/mpm/event/event.c
server/scoreboard.c

index 90e56c43000114d8276ad9770fd69609349d12ae..368830c038fb09d9aaeac31c505bc41634084662 100644 (file)
  * 20120211.54 (2.4.19-dev) Add ap_proxy_buckets_lifetime_transform and
  *                          ap_proxy_transfer_between_connections to
  *                          mod_proxy.h
+ * 20120211.55 (2.4.19-dev) Add new ap_update_child_status...() methods,
+ *                          add protocol to worker_score in scoreboard.h,
+ *                          Add pre_close connection hook and 
+ *                          ap_prep_lingering_close().
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
 #define MODULE_MAGIC_NUMBER_MAJOR 20120211
 #endif
-#define MODULE_MAGIC_NUMBER_MINOR 54                   /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 55                   /* 0...n */
 
 /**
  * Determine if the server's current MODULE_MAGIC_NUMBER is at least a
index 58389a4fb4ea7a010627e8989f11df55ee6cc981..8bc009da3b7fb9f22854d141d9ad5ce24ce19a89 100644 (file)
@@ -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;
 
index 99d6ba743294d4df5a09cabd13be5982f8bd29c2..d712bd43b48949a291efe0adc66c00b87fae8c98 100644 (file)
@@ -115,6 +115,7 @@ struct worker_score {
     char client[32];            /* Keep 'em small... */
     char request[64];           /* We just want an idea... */
     char vhost[32];             /* What virtual host is being accessed? */
+    char protocol[16];          /* What protocol is used on the connection? */
 };
 
 typedef struct {
@@ -181,6 +182,10 @@ AP_DECLARE(int) ap_update_child_status(ap_sb_handle_t *sbh, int status, request_
 AP_DECLARE(int) ap_update_child_status_from_indexes(int child_num, int thread_num,
                                                     int status, request_rec *r);
 AP_DECLARE(int) ap_update_child_status_from_conn(ap_sb_handle_t *sbh, int status, conn_rec *c);
+AP_DECLARE(int) ap_update_child_status_from_server(ap_sb_handle_t *sbh, int status, 
+                                                   conn_rec *c, server_rec *s);
+AP_DECLARE(int) ap_update_child_status_descr(ap_sb_handle_t *sbh, int status, const char *descr);
+
 AP_DECLARE(void) ap_time_process_request(ap_sb_handle_t *sbh, int status);
 
 AP_DECLARE(worker_score *) ap_get_scoreboard_worker(ap_sb_handle_t *sbh);
index 9bd4e8aa04e84c2965b6bae9964e1864d64606a3..4ff9df1988380f198e82ed153f99414005df7b47 100644 (file)
@@ -662,7 +662,7 @@ static int status_handler(request_rec *r)
 #endif
                      "<th>SS</th><th>Req</th>"
                      "<th>Conn</th><th>Child</th><th>Slot</th>"
-                     "<th>Client</th><th>VHost</th>"
+                     "<th>Client</th><th>Protocol</th><th>VHost</th>"
                      "<th>Request</th></tr>\n\n", r);
 
         for (i = 0; i < server_limit; ++i) {
@@ -776,12 +776,14 @@ static int status_handler(request_rec *r)
                     format_byte_out(r, bytes);
                     ap_rputs(")\n", r);
                     ap_rprintf(r,
-                               " <i>%s {%s}</i> <b>[%s]</b><br />\n\n",
+                               " <i>%s {%s}</i> <i>(%s)</i> <b>[%s]</b><br />\n\n",
                                ap_escape_html(r->pool,
                                               ws_record->client),
                                ap_escape_html(r->pool,
                                               ap_escape_logitem(r->pool,
                                                                 ws_record->request)),
+                               ap_escape_html(r->pool,
+                                              ws_record->protocol),
                                ap_escape_html(r->pool,
                                               ws_record->vhost));
                 }
@@ -860,10 +862,12 @@ static int status_handler(request_rec *r)
                                (float)conn_bytes / KBYTE, (float) my_bytes / MBYTE,
                                (float)bytes / MBYTE);
 
-                    ap_rprintf(r, "</td><td>%s</td><td nowrap>%s</td>"
+                    ap_rprintf(r, "</td><td>%s</td><td>%s</td><td nowrap>%s</td>"
                                   "<td nowrap>%s</td></tr>\n\n",
                                ap_escape_html(r->pool,
                                               ws_record->client),
+                               ap_escape_html(r->pool,
+                                              ws_record->protocol),
                                ap_escape_html(r->pool,
                                               ws_record->vhost),
                                ap_escape_html(r->pool,
index 381f3e016cc02cdd7eea75408b58b3ded4576300..2f85c3fdc1ec3cd4274306ea0f00deb1f94f4594 100644 (file)
@@ -31,6 +31,7 @@
 #include "ssl_private.h"
 #include "mod_ssl.h"
 #include "util_md5.h"
+#include "scoreboard.h"
 
 static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn);
 #ifdef HAVE_TLSEXT
@@ -2202,6 +2203,7 @@ static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s)
         sslcon->server = s;
         sslcon->cipher_suite = sc->server->auth.cipher_suite;
         
+        ap_update_child_status_from_server(c->sbh, SERVER_BUSY_READ, c, s);
         /*
          * There is one special filter callback, which is set
          * very early depending on the base_server's log level.
index 44a6dbe49aed6349904c40c3659a5bef34fe73a5..917e661c4fb89d651f0a4323b870f205eeab3e56 100644 (file)
@@ -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;
     }
-
+    
 #ifdef NO_LINGCLOSE
     ap_flush_conn(c); /* just close it */
     apr_socket_close(csd);
index 7346cc51732643020aa8059a39c717f279181e62..e76dee3441bedfe86b1aa1dddd8fbe294ab21349 100644 (file)
@@ -905,7 +905,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(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);
index 6d1b3befb474c431447e47dd711f538e2eabc468..8040fc6a833e6b911464e07cf8e781fd179ad202 100644 (file)
@@ -32,6 +32,7 @@
 #include "http_main.h"
 #include "http_core.h"
 #include "http_config.h"
+#include "http_protocol.h"
 #include "ap_mpm.h"
 
 #include "scoreboard.h"
@@ -457,7 +458,9 @@ static int update_child_status_internal(int child_num,
                                         int thread_num,
                                         int status,
                                         conn_rec *c,
-                                        request_rec *r)
+                                        server_rec *s,
+                                        request_rec *r,
+                                        const char *descr)
 {
     int old_status;
     worker_score *ws;
@@ -466,19 +469,22 @@ static int update_child_status_internal(int child_num,
 
     ws = &ap_scoreboard_image->servers[child_num][thread_num];
     old_status = ws->status;
-    ws->status = status;
-
-    ps = &ap_scoreboard_image->parent[child_num];
-
-    if (status == SERVER_READY
-        && old_status == SERVER_STARTING) {
-        ws->thread_num = child_num * thread_limit + thread_num;
-        ap_mpm_query(AP_MPMQ_GENERATION, &mpm_generation);
-        ps->generation = mpm_generation;
+    if (status >= 0) {
+        ws->status = status;
+        
+        ps = &ap_scoreboard_image->parent[child_num];
+        
+        if (status == SERVER_READY
+            && old_status == SERVER_STARTING) {
+            ws->thread_num = child_num * thread_limit + thread_num;
+            ap_mpm_query(AP_MPMQ_GENERATION, &mpm_generation);
+            ps->generation = mpm_generation;
+        }
     }
 
     if (ap_extended_status) {
-        ws->last_used = apr_time_now();
+        const char *val;
+        
         if (status == SERVER_READY || status == SERVER_DEAD) {
             /*
              * Reset individual counters
@@ -489,28 +495,44 @@ static int update_child_status_internal(int child_num,
             }
             ws->conn_count = 0;
             ws->conn_bytes = 0;
+            ws->last_used = apr_time_now();
         }
-        if (r) {
-            const char *client = ap_get_remote_host(c, r->per_dir_config,
-                                 REMOTE_NOLOOKUP, NULL);
-            if (!client || !strcmp(client, c->client_ip)) {
-                apr_cpystrn(ws->client, r->useragent_ip, sizeof(ws->client));
+        if (status == SERVER_READY) {
+            ws->client[0]='\0';
+            ws->vhost[0]='\0';
+            ws->request[0]='\0';
+            ws->protocol[0]='\0';
+        }
+        else {
+            if (descr) {
+                apr_cpystrn(ws->request, descr, sizeof(ws->request));
             }
-            else {
-                apr_cpystrn(ws->client, client, sizeof(ws->client));
+            else if (r) {
+                copy_request(ws->request, sizeof(ws->request), r);
             }
-            copy_request(ws->request, sizeof(ws->request), r);
-            if (r->server) {
-                apr_snprintf(ws->vhost, sizeof(ws->vhost), "%s:%d",
-                             r->server->server_hostname,
-                             r->connection->local_addr->port);
+            if (r || c) {
+                val = ap_get_remote_host(c, r? r->per_dir_config : NULL, 
+                                         REMOTE_NOLOOKUP, NULL);
+                if (r && (!val || !strcmp(val, c->client_ip))) {
+                    apr_cpystrn(ws->client, r->useragent_ip, sizeof(ws->client));
+                }
+                else {
+                    apr_cpystrn(ws->client, val, sizeof(ws->client));
+                }
+            }
+            if (s) {
+                if (c) {
+                    apr_snprintf(ws->vhost, sizeof(ws->vhost), "%s:%d",
+                                 s->server_hostname, c->local_addr->port);
+                }
+                else {
+                    apr_cpystrn(ws->vhost, s->server_hostname, sizeof(ws->vhost));
+                }
+            }
+            if (c) {
+                val = ap_get_protocol(c);
+                apr_cpystrn(ws->protocol, val, sizeof(ws->protocol));
             }
-        }
-        else if (c) {
-            apr_cpystrn(ws->client, ap_get_remote_host(c, NULL,
-                        REMOTE_NOLOOKUP, NULL), sizeof(ws->client));
-            ws->request[0]='\0';
-            ws->vhost[0]='\0';
         }
     }
 
@@ -528,7 +550,8 @@ AP_DECLARE(int) ap_update_child_status_from_indexes(int child_num,
 
     return update_child_status_internal(child_num, thread_num, status,
                                         r ? r->connection : NULL,
-                                        r);
+                                        r ? r->server : NULL,
+                                        r, NULL);
 }
 
 AP_DECLARE(int) ap_update_child_status(ap_sb_handle_t *sbh, int status,
@@ -540,17 +563,37 @@ AP_DECLARE(int) ap_update_child_status(ap_sb_handle_t *sbh, int status,
     return update_child_status_internal(sbh->child_num, sbh->thread_num,
                                         status,
                                         r ? r->connection : NULL,
-                                        r);
+                                        r ? r->server : NULL,
+                                        r, NULL);
 }
 
 AP_DECLARE(int) ap_update_child_status_from_conn(ap_sb_handle_t *sbh, int status,
-                                       conn_rec *c)
+                                                 conn_rec *c)
+{
+    if (!sbh || (sbh->child_num < 0))
+        return -1;
+
+    return update_child_status_internal(sbh->child_num, sbh->thread_num,
+                                        status, c, NULL, NULL, NULL);
+}
+
+AP_DECLARE(int) ap_update_child_status_from_server(ap_sb_handle_t *sbh, int status, 
+                                                   conn_rec *c, server_rec *s)
+{
+    if (!sbh || (sbh->child_num < 0))
+        return -1;
+
+    return update_child_status_internal(sbh->child_num, sbh->thread_num,
+                                        status, c, s, NULL, NULL);
+}
+
+AP_DECLARE(int) ap_update_child_status_descr(ap_sb_handle_t *sbh, int status, const char *descr)
 {
     if (!sbh || (sbh->child_num < 0))
         return -1;
 
     return update_child_status_internal(sbh->child_num, sbh->thread_num,
-                                        status, c, NULL);
+                                        status, NULL, NULL, NULL, descr);
 }
 
 AP_DECLARE(void) ap_time_process_request(ap_sb_handle_t *sbh, int status)
@@ -567,10 +610,10 @@ AP_DECLARE(void) ap_time_process_request(ap_sb_handle_t *sbh, int status)
     ws = &ap_scoreboard_image->servers[sbh->child_num][sbh->thread_num];
 
     if (status == START_PREQUEST) {
-        ws->start_time = apr_time_now();
+        ws->start_time = ws->last_used = apr_time_now();
     }
     else if (status == STOP_PREQUEST) {
-        ws->stop_time = apr_time_now();
+        ws->stop_time = ws->last_used = apr_time_now();
     }
 }
 
@@ -605,6 +648,7 @@ AP_DECLARE(void) ap_copy_scoreboard_worker(worker_score *dest,
     dest->client[sizeof(dest->client) - 1] = '\0';
     dest->request[sizeof(dest->request) - 1] = '\0';
     dest->vhost[sizeof(dest->vhost) - 1] = '\0';
+    dest->protocol[sizeof(dest->protocol) - 1] = '\0';
 }
 
 AP_DECLARE(process_score *) ap_get_scoreboard_process(int x)