I'm aware that some people might not like this due to the fact that it's
inserting yet another default filter, but here it is, just for completeness.

Bojan
diff -u --recursive --new-file httpd-2.0-vanilla/include/ap_mmn.h 
httpd-2.0/include/ap_mmn.h
--- httpd-2.0-vanilla/include/ap_mmn.h  Wed Sep  4 14:12:20 2002
+++ httpd-2.0/include/ap_mmn.h  Mon Oct 14 11:47:46 2002
@@ -111,12 +111,13 @@
  * 20020625 (2.0.40-dev) Changed conn_rec->keepalive to an enumeration
  * 20020628 (2.0.40-dev) Added filter_init to filter registration functions
  * 20020903 (2.0.41-dev) APR's error constants changed
+ * 20021014 (2.0.44-dev) conn_rec gets bytes_in and bytes_out fields
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503230UL /* "AP20" */
 
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
-#define MODULE_MAGIC_NUMBER_MAJOR 20020903
+#define MODULE_MAGIC_NUMBER_MAJOR 20021014
 #endif
 #define MODULE_MAGIC_NUMBER_MINOR 0                     /* 0...n */
 
diff -u --recursive --new-file httpd-2.0-vanilla/include/httpd.h 
httpd-2.0/include/httpd.h
--- httpd-2.0-vanilla/include/httpd.h   Sat Oct 12 02:12:28 2002
+++ httpd-2.0/include/httpd.h   Mon Oct 14 11:47:46 2002
@@ -1018,6 +1018,10 @@
     void *sbh;
     /** The bucket allocator to use for all bucket/brigade creations */
     struct apr_bucket_alloc_t *bucket_alloc;
+    /** Input bytes on this connection */
+    apr_off_t bytes_in;
+    /** Output bytes on this connection */
+    apr_off_t bytes_out;
 };
 
 /* Per-vhost config... */
diff -u --recursive --new-file httpd-2.0-vanilla/modules/loggers/mod_logio.c 
httpd-2.0/modules/loggers/mod_logio.c
--- httpd-2.0-vanilla/modules/loggers/mod_logio.c       Sat Sep 28 14:18:35 2002
+++ httpd-2.0/modules/loggers/mod_logio.c       Mon Oct 14 14:56:09 2002
@@ -84,35 +84,18 @@
 
 module AP_MODULE_DECLARE_DATA logio_module;
 
-static const char logio_filter_name[] = "LOG_INPUT_OUTPUT";
-
-/*
- * Logging of input and output config...
- */
-
-typedef struct logio_config_t {
-    apr_off_t bytes_in;
-    apr_off_t bytes_out;
-} logio_config_t;
-
 /*
  * Format items...
  */
 
 static const char *log_bytes_in(request_rec *r, char *a)
 {
-    logio_config_t *cf = ap_get_module_config(r->connection->conn_config,
-                                              &logio_module);
-
-    return apr_off_t_toa(r->pool, cf->bytes_in);
+    return apr_off_t_toa(r->pool, r->connection->bytes_in);
 }
 
 static const char *log_bytes_out(request_rec *r, char *a)
 {
-    logio_config_t *cf = ap_get_module_config(r->connection->conn_config,
-                                              &logio_module);
-
-    return apr_off_t_toa(r->pool, cf->bytes_out);
+    return apr_off_t_toa(r->pool, r->connection->bytes_out);
 }
 
 /*
@@ -121,71 +104,15 @@
 
 static int logio_transaction(request_rec *r)
 {
-    logio_config_t *cf = ap_get_module_config(r->connection->conn_config,
-                                              &logio_module);
-
-    cf->bytes_in = cf->bytes_out = 0;
+    r->connection->bytes_in = r->connection->bytes_out = 0;
 
     return OK;
 }
 
 /*
- * Logging of input and output filters...
- */
-
-static apr_status_t logio_out_filter(ap_filter_t *f,
-                                     apr_bucket_brigade *bb) {
-    apr_off_t length;
-    logio_config_t *cf = ap_get_module_config(f->c->conn_config, &logio_module);
-
-    if (!cf) { /* Create config */
-        cf = apr_pcalloc(f->c->pool, sizeof(*cf));
-        ap_set_module_config(f->c->conn_config, &logio_module, cf);
-    }
-
-    apr_brigade_length (bb, 0, &length);
-
-    if (length > 0)
-        cf->bytes_out += length;
-
-    return ap_pass_brigade(f->next, bb);
-}
-
-static apr_status_t logio_in_filter(ap_filter_t *f,
-                                    apr_bucket_brigade *bb,
-                                    ap_input_mode_t mode,
-                                    apr_read_type_e block,
-                                    apr_off_t readbytes) {
-    apr_off_t length;
-    apr_status_t status;
-    logio_config_t *cf = ap_get_module_config(f->c->conn_config, &logio_module);
-
-    status = ap_get_brigade(f->next, bb, mode, block, readbytes);
-
-    if (!cf) { /* Create config */
-        cf = apr_pcalloc(f->c->pool, sizeof(*cf));
-        ap_set_module_config(f->c->conn_config, &logio_module, cf);
-    }
-
-    apr_brigade_length (bb, 0, &length);
-
-    if (length > 0)
-        cf->bytes_in += length;
-
-    return status;
-}
-
-/*
  * The hooks...
  */
 
-static int logio_pre_conn(conn_rec *c) {
-    ap_add_input_filter(logio_filter_name, NULL, NULL, c);
-    ap_add_output_filter(logio_filter_name, NULL, NULL, c);
-
-    return OK;
-}
-
 static int logio_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp)
 {
     static APR_OPTIONAL_FN_TYPE(ap_register_log_handler) *log_pfn_register;
@@ -204,14 +131,8 @@
 {
     static const char *pre[] = { "mod_log_config.c", NULL };
 
-    ap_hook_pre_connection(logio_pre_conn, NULL, NULL, APR_HOOK_MIDDLE);
     ap_hook_pre_config(logio_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
     ap_hook_log_transaction(logio_transaction, pre, NULL, APR_HOOK_MIDDLE);
-
-    ap_register_input_filter(logio_filter_name, logio_in_filter, NULL,
-                             AP_FTYPE_NETWORK - 1);
-    ap_register_output_filter(logio_filter_name, logio_out_filter, NULL,
-                              AP_FTYPE_NETWORK - 1);
 }
 
 module AP_MODULE_DECLARE_DATA logio_module =
diff -u --recursive --new-file httpd-2.0-vanilla/server/core.c httpd-2.0/server/core.c
--- httpd-2.0-vanilla/server/core.c     Mon Oct 14 08:12:34 2002
+++ httpd-2.0/server/core.c     Mon Oct 14 14:54:48 2002
@@ -125,6 +125,7 @@
 AP_DECLARE_DATA ap_filter_rec_t *ap_content_length_filter_handle;
 AP_DECLARE_DATA ap_filter_rec_t *ap_net_time_filter_handle;
 AP_DECLARE_DATA ap_filter_rec_t *ap_core_input_filter_handle;
+AP_DECLARE_DATA ap_filter_rec_t *ap_core_in_cnt_filter_handle;
 
 static void *create_core_dir_config(apr_pool_t *a, char *dir)
 {
@@ -2709,6 +2710,7 @@
                                     apr_off_t   file_offset,
                                     apr_size_t  file_bytes_left,
                                     apr_size_t  total_bytes_left,
+                                    apr_size_t  *bytes_sent,
                                     apr_int32_t flags)
 {
     apr_status_t rv;
@@ -2720,11 +2722,15 @@
                          == APR_SUCCESS)
                     && timeout > 0);  /* socket must be in timeout mode */
 
+    /* Reset the bytes_sent field */
+    *bytes_sent = 0;
+
     do {
         apr_size_t tmplen = file_bytes_left;
 
         rv = apr_sendfile(c->client_socket, fd, hdtr, &file_offset, &tmplen,
                           flags);
+        *bytes_sent += tmplen;
         total_bytes_left -= tmplen;
         if (!total_bytes_left || rv != APR_SUCCESS) {
             return rv;        /* normal case & error exit */
@@ -3605,6 +3611,25 @@
     return rv;
 }
 
+/* Input filter for counting of number of input bytes */
+static apr_status_t core_in_cnt_filter(ap_filter_t *f,
+                                       apr_bucket_brigade *bb,
+                                       ap_input_mode_t mode,
+                                       apr_read_type_e block,
+                                       apr_off_t readbytes) {
+    apr_off_t length;
+    apr_status_t status;
+
+    status = ap_get_brigade(f->next, bb, mode, block, readbytes);
+
+    apr_brigade_length (bb, 0, &length);
+
+    if (length > 0)
+        f->c->bytes_in += length;
+
+    return status;
+}
+
 /* Default filter.  This filter should almost always be used.  Its only job
  * is to send the headers if they haven't already been sent, and then send
  * the actual data.
@@ -3872,6 +3897,7 @@
 
         if (fd) {
             apr_hdtr_t hdtr;
+            apr_size_t bytes_sent;
 #if APR_HAS_SENDFILE
             apr_int32_t flags = 0;
 #endif
@@ -3900,9 +3926,14 @@
                                               sending from              */
                                  flen,     /* length of file            */
                                  nbytes + flen, /* total length including
-                                                   headers                */
+                                                   headers              */
+                                 &bytes_sent,   /* how many bytes were
+                                                   sent                 */
                                  flags);   /* apr_sendfile flags        */
 
+            if (bytes_sent > 0)
+                c->bytes_out += bytes_sent;
+
             /* If apr_sendfile() returns APR_ENOTIMPL, call emulate_sendfile().
              * emulate_sendfile() is useful to enable the same Apache binary
              * distribution to support Windows NT/2000 (supports TransmitFile)
@@ -3911,19 +3942,24 @@
             if (rv == APR_ENOTIMPL)
 #endif
             {
-                apr_size_t unused_bytes_sent;
                 rv = emulate_sendfile(net, fd, &hdtr, foffset, flen,
-                                      &unused_bytes_sent);
+                                      &bytes_sent);
+
+                if (bytes_sent > 0)
+                    c->bytes_out += bytes_sent;
             }
 
             fd = NULL;
         }
         else {
-            apr_size_t unused_bytes_sent;
+            apr_size_t bytes_sent;
 
             rv = writev_it_all(net->client_socket,
                                vec, nvec,
-                               nbytes, &unused_bytes_sent);
+                               nbytes, &bytes_sent);
+
+            if (bytes_sent > 0)
+                c->bytes_out += bytes_sent;
         }
 
         apr_brigade_destroy(b);
@@ -4118,6 +4154,7 @@
 
     ap_set_module_config(net->c->conn_config, &core_module, csd);
     ap_add_input_filter_handle(ap_core_input_filter_handle, net, NULL, net->c);
+    ap_add_input_filter_handle(ap_core_in_cnt_filter_handle, net, NULL, net->c);
     ap_add_output_filter_handle(ap_core_output_filter_handle, net, NULL, net->c);
     return DONE;
 }
@@ -4156,6 +4193,9 @@
     ap_core_input_filter_handle =
         ap_register_input_filter("CORE_IN", core_input_filter,
                                  NULL, AP_FTYPE_NETWORK);
+    ap_core_in_cnt_filter_handle =
+        ap_register_input_filter("CORE_IN_CNT", core_in_cnt_filter,
+                                 NULL, AP_FTYPE_NETWORK - 1);
     ap_net_time_filter_handle =
         ap_register_input_filter("NET_TIME", net_time_filter,
                                  NULL, AP_FTYPE_PROTOCOL);

Reply via email to