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);