00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "apr_strings.h"
00030 #include "apr_lib.h"
00031 #include "apr_hash.h"
00032 #include "apr_optional.h"
00033
00034 #define APR_WANT_STRFUNC
00035 #include "apr_want.h"
00036
00037 #include "ap_config.h"
00038 #include "mod_log_config.h"
00039 #include "httpd.h"
00040 #include "http_core.h"
00041 #include "http_config.h"
00042 #include "http_connection.h"
00043 #include "http_protocol.h"
00044
00045 module AP_MODULE_DECLARE_DATA logio_module;
00046
00047 static const char logio_filter_name[] = "LOG_INPUT_OUTPUT";
00048
00049
00050
00051
00052
00053 typedef struct logio_config_t {
00054 apr_off_t bytes_in;
00055 apr_off_t bytes_out;
00056 } logio_config_t;
00057
00058
00059
00060
00061
00062 static void ap_logio_add_bytes_out(conn_rec *c, apr_off_t bytes){
00063 logio_config_t *cf = ap_get_module_config(c->conn_config, &logio_module);
00064
00065 cf->bytes_out += bytes;
00066 }
00067
00068
00069
00070
00071
00072 static const char *log_bytes_in(request_rec *r, char *a)
00073 {
00074 logio_config_t *cf = ap_get_module_config(r->connection->conn_config,
00075 &logio_module);
00076
00077 return apr_off_t_toa(r->pool, cf->bytes_in);
00078 }
00079
00080 static const char *log_bytes_out(request_rec *r, char *a)
00081 {
00082 logio_config_t *cf = ap_get_module_config(r->connection->conn_config,
00083 &logio_module);
00084
00085 return apr_off_t_toa(r->pool, cf->bytes_out);
00086 }
00087
00088
00089
00090
00091
00092 static int logio_transaction(request_rec *r)
00093 {
00094 logio_config_t *cf = ap_get_module_config(r->connection->conn_config,
00095 &logio_module);
00096
00097 cf->bytes_in = cf->bytes_out = 0;
00098
00099 return OK;
00100 }
00101
00102
00103
00104
00105
00106 static apr_status_t logio_in_filter(ap_filter_t *f,
00107 apr_bucket_brigade *bb,
00108 ap_input_mode_t mode,
00109 apr_read_type_e block,
00110 apr_off_t readbytes) {
00111 apr_off_t length;
00112 apr_status_t status;
00113 logio_config_t *cf = ap_get_module_config(f->c->conn_config, &logio_module);
00114
00115 status = ap_get_brigade(f->next, bb, mode, block, readbytes);
00116
00117 apr_brigade_length (bb, 0, &length);
00118
00119 if (length > 0)
00120 cf->bytes_in += length;
00121
00122 return status;
00123 }
00124
00125 static apr_status_t logio_out_filter(ap_filter_t *f,
00126 apr_bucket_brigade *bb) {
00127 apr_bucket *b = APR_BRIGADE_LAST(bb);
00128
00129
00130 if (APR_BUCKET_IS_EOS(b)) {
00131 APR_BUCKET_INSERT_BEFORE(b,
00132 apr_bucket_flush_create(f->c->bucket_alloc));
00133 }
00134
00135 return ap_pass_brigade(f->next, bb);
00136 }
00137
00138
00139
00140
00141
00142 static int logio_pre_conn(conn_rec *c, void *csd) {
00143 logio_config_t *cf = apr_pcalloc(c->pool, sizeof(*cf));
00144
00145 ap_set_module_config(c->conn_config, &logio_module, cf);
00146
00147 ap_add_input_filter(logio_filter_name, NULL, NULL, c);
00148 ap_add_output_filter(logio_filter_name, NULL, NULL, c);
00149
00150 return OK;
00151 }
00152
00153 static int logio_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp)
00154 {
00155 static APR_OPTIONAL_FN_TYPE(ap_register_log_handler) *log_pfn_register;
00156
00157 log_pfn_register = APR_RETRIEVE_OPTIONAL_FN(ap_register_log_handler);
00158
00159 if (log_pfn_register) {
00160 log_pfn_register(p, "I", log_bytes_in, 0);
00161 log_pfn_register(p, "O", log_bytes_out, 0);
00162 }
00163
00164 return OK;
00165 }
00166
00167 static void register_hooks(apr_pool_t *p)
00168 {
00169 static const char *pre[] = { "mod_log_config.c", NULL };
00170
00171 ap_hook_pre_connection(logio_pre_conn, NULL, NULL, APR_HOOK_MIDDLE);
00172 ap_hook_pre_config(logio_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
00173 ap_hook_log_transaction(logio_transaction, pre, NULL, APR_HOOK_MIDDLE);
00174
00175 ap_register_input_filter(logio_filter_name, logio_in_filter, NULL,
00176 AP_FTYPE_NETWORK - 1);
00177 ap_register_output_filter(logio_filter_name, logio_out_filter, NULL,
00178 AP_FTYPE_NETWORK - 1);
00179
00180 APR_REGISTER_OPTIONAL_FN(ap_logio_add_bytes_out);
00181 }
00182
00183 module AP_MODULE_DECLARE_DATA logio_module =
00184 {
00185 STANDARD20_MODULE_STUFF,
00186 NULL,
00187 NULL,
00188 NULL,
00189 NULL,
00190 NULL,
00191 register_hooks
00192 };