This should really work now and it should not cause major dramas
compatibility wise. Let me know what you think.
Bojan
diff -ruN httpd-2.0-vanilla/include/http_core.h httpd-2.0/include/http_core.h
--- httpd-2.0-vanilla/include/http_core.h Tue Oct 15 03:42:45 2002
+++ httpd-2.0/include/http_core.h Fri Oct 25 08:04:28 2002
@@ -61,6 +61,7 @@
#include "apr.h"
#include "apr_hash.h"
+#include "apr_optional.h"
#include "util_filter.h"
#if APR_HAVE_STRUCT_RLIMIT
@@ -626,6 +627,16 @@
/* ---------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------
+ *
+ * I/O logging with mod_logio
+ */
+
+APR_DECLARE_OPTIONAL_FN(void, ap_logio_add_bytes_out,
+ (conn_rec *c, apr_off_t bytes));
+
+/* ---------------------------------------------------------------------- */
+
#ifdef __cplusplus
}
#endif
diff -ruN 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 Fri Oct 25 08:04:14 2002
@@ -79,6 +79,7 @@
#include "ap_config.h"
#include "mod_log_config.h"
#include "httpd.h"
+#include "http_core.h"
#include "http_config.h"
#include "http_protocol.h"
@@ -96,6 +97,16 @@
} logio_config_t;
/*
+ * Optional function for the core to add to bytes_out
+ */
+
+static void ap_logio_add_bytes_out(conn_rec *c, apr_off_t bytes){
+ logio_config_t *cf = ap_get_module_config(c->conn_config, &logio_module);
+
+ cf->bytes_out+=bytes;
+}
+
+/*
* Format items...
*/
@@ -133,24 +144,6 @@
* 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,
@@ -162,11 +155,6 @@
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)
@@ -175,11 +163,30 @@
return status;
}
+static apr_status_t logio_out_filter(ap_filter_t *f,
+ apr_bucket_brigade *bb) {
+ apr_bucket *b = APR_BRIGADE_LAST(bb);
+
+ /* End of data, make sure we flush */
+ if (APR_BUCKET_IS_EOS(b)) {
+ APR_BRIGADE_INSERT_TAIL(bb,
+ apr_bucket_flush_create(f->c->bucket_alloc));
+ APR_BUCKET_REMOVE(b);
+ apr_bucket_destroy(b);
+ }
+
+ return ap_pass_brigade(f->next, bb);
+}
+
/*
* The hooks...
*/
static int logio_pre_conn(conn_rec *c) {
+ logio_config_t *cf = apr_pcalloc(c->pool, sizeof(*cf));
+
+ ap_set_module_config(c->conn_config, &logio_module, cf);
+
ap_add_input_filter(logio_filter_name, NULL, NULL, c);
ap_add_output_filter(logio_filter_name, NULL, NULL, c);
@@ -212,6 +219,8 @@
AP_FTYPE_NETWORK - 1);
ap_register_output_filter(logio_filter_name, logio_out_filter, NULL,
AP_FTYPE_NETWORK - 1);
+
+ APR_REGISTER_OPTIONAL_FN(ap_logio_add_bytes_out);
}
module AP_MODULE_DECLARE_DATA logio_module =
diff -ruN httpd-2.0-vanilla/server/core.c httpd-2.0/server/core.c
--- httpd-2.0-vanilla/server/core.c Tue Oct 15 06:08:15 2002
+++ httpd-2.0/server/core.c Fri Oct 25 08:08:22 2002
@@ -2737,6 +2737,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;
@@ -2748,11 +2749,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 */
@@ -3647,6 +3652,11 @@
*/
#define MAX_IOVEC_TO_WRITE 16
+/* Optional function coming from mod_logio, used for logging of output
+ * traffic
+ */
+static APR_OPTIONAL_FN_TYPE(ap_logio_add_bytes_out) *logio_add_bytes_out;
+
static apr_status_t core_output_filter(ap_filter_t *f, apr_bucket_brigade *b)
{
apr_status_t rv;
@@ -3908,6 +3918,8 @@
if (fd) {
apr_hdtr_t hdtr;
+ apr_size_t bytes_sent;
+
#if APR_HAS_SENDFILE
apr_int32_t flags = 0;
#endif
@@ -3938,25 +3950,35 @@
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 (logio_add_bytes_out && bytes_sent > 0)
+ logio_add_bytes_out(c, bytes_sent);
}
else
#endif
{
- apr_size_t unused_bytes_sent;
rv = emulate_sendfile(net, fd, &hdtr, foffset, flen,
- &unused_bytes_sent);
+ &bytes_sent);
+
+ if (logio_add_bytes_out && bytes_sent > 0)
+ logio_add_bytes_out(c, 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 (logio_add_bytes_out && bytes_sent > 0)
+ logio_add_bytes_out(c, bytes_sent);
}
apr_brigade_destroy(b);
@@ -4149,6 +4171,8 @@
net->out_ctx = NULL;
net->client_socket = csd;
+ logio_add_bytes_out = APR_RETRIEVE_OPTIONAL_FN(ap_logio_add_bytes_out);
+
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_output_filter_handle(ap_core_output_filter_handle, net, NULL, net->c);