--- /dev/null
+/* Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Originally written @ Covalent by Jim Jagielski
+ */
+
+/*
+ * mod_dumpio.c:
+ * Think of this as a filter sniffer for Apache 2.x. It logs
+ * all filter data right before and after it goes out on the
+ * wire (BUT right before SSL encoded or after SSL decoded).
+ * It can produce a *huge* amount of data.
+ */
+
+
+#include <httpd.h>
+#include <http_config.h>
+#include <http_core.h>
+#include <http_log.h>
+
+module AP_MODULE_DECLARE_DATA dumpio_module ;
+
+typedef struct dumpio_conf_t {
+ int enable_input;
+ int enable_output;
+} dumpio_conf_t;
+
+/*
+ * Workhorse function: simply log to the current error_log
+ * info about the data in the bucket as well as the data itself
+ */
+static void dumpit(ap_filter_t *f, apr_bucket *b)
+{
+ conn_rec *c = f->c;
+
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, NULL, c->base_server,
+ "mod_dumpio: %s (%s-%s): %" APR_SIZE_T_FMT " bytes",
+ f->frec->name,
+ (APR_BUCKET_IS_METADATA(b)) ? "metadata" : "data",
+ b->type->name,
+ b->length) ;
+
+ if (!(APR_BUCKET_IS_METADATA(b))) {
+ const char *buf;
+ apr_size_t nbytes;
+ char *obuf;
+ if (apr_bucket_read(b, &buf, &nbytes, APR_BLOCK_READ) == APR_SUCCESS) {
+ if (nbytes) {
+ obuf = malloc(nbytes+1); /* use pool? */
+ memcpy(obuf, buf, nbytes);
+ obuf[nbytes] = '\0';
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, NULL, c->base_server,
+ "mod_dumpio: %s (%s-%s): %s",
+ f->frec->name,
+ (APR_BUCKET_IS_METADATA(b)) ? "metadata" : "data",
+ b->type->name,
+ obuf);
+ free(obuf);
+ }
+ } else {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, NULL, c->base_server,
+ "mod_dumpio: %s (%s-%s): %s",
+ f->frec->name,
+ (APR_BUCKET_IS_METADATA(b)) ? "metadata" : "data",
+ b->type->name,
+ "error reading data");
+ }
+ }
+}
+
+#define whichmode( mode ) \
+ ( (( mode ) == AP_MODE_READBYTES) ? "readbytes" : \
+ (( mode ) == AP_MODE_GETLINE) ? "getline" : \
+ (( mode ) == AP_MODE_EATCRLF) ? "eatcrlf" : \
+ (( mode ) == AP_MODE_SPECULATIVE) ? "speculative" : \
+ (( mode ) == AP_MODE_EXHAUSTIVE) ? "exhaustive" : \
+ (( mode ) == AP_MODE_INIT) ? "init" : "unknown" \
+ )
+
+static int dumpio_input_filter (ap_filter_t *f, apr_bucket_brigade *bb,
+ ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes)
+{
+
+ apr_bucket *b;
+ apr_status_t ret;
+ conn_rec *c = f->c;
+
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, NULL, c->base_server,
+ "mod_dumpio: %s [%s-%s] %" APR_OFF_T_FMT " readbytes",
+ f->frec->name,
+ whichmode(mode),
+ ((block) == APR_BLOCK_READ) ? "blocking" : "nonblocking",
+ readbytes) ;
+
+ ret = ap_get_brigade(f->next, bb, mode, block, readbytes);
+
+ if (ret == APR_SUCCESS) {
+ for (b = APR_BRIGADE_FIRST(bb); b != APR_BRIGADE_SENTINEL(bb); b = APR_BUCKET_NEXT(b)) {
+ dumpit(f, b);
+ }
+ } else {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, NULL, c->base_server,
+ "mod_dumpio: %s - %d", f->frec->name, ret) ;
+ }
+
+ return APR_SUCCESS ;
+}
+
+static int dumpio_output_filter (ap_filter_t *f, apr_bucket_brigade *bb)
+{
+ apr_bucket *b;
+ conn_rec *c = f->c;
+
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, NULL, c->base_server, "mod_dumpio: %s", f->frec->name) ;
+
+ for (b = APR_BRIGADE_FIRST(bb); b != APR_BRIGADE_SENTINEL(bb); b = APR_BUCKET_NEXT(b)) {
+ /*
+ * If we ever see an EOS, make sure to FLUSH.
+ */
+ if (APR_BUCKET_IS_EOS(b)) {
+ apr_bucket *flush = apr_bucket_flush_create(f->c->bucket_alloc);
+ APR_BUCKET_INSERT_BEFORE(b, flush);
+ }
+ dumpit(f, b);
+ }
+
+ return ap_pass_brigade(f->next, bb) ;
+}
+
+static int dumpio_pre_conn(conn_rec *c, void *csd)
+{
+ dumpio_conf_t *ptr =
+ (dumpio_conf_t *) ap_get_module_config(c->base_server->module_config,
+ &dumpio_module);
+
+ if (ptr->enable_input)
+ ap_add_input_filter("DUMPIO_IN", NULL, NULL, c);
+ if (ptr->enable_output)
+ ap_add_output_filter("DUMPIO_OUT", NULL, NULL, c);
+ return OK;
+}
+
+static void dumpio_register_hooks(apr_pool_t *p)
+{
+/*
+ * We know that SSL is CONNECTION + 5
+ */
+ ap_register_output_filter("DUMPIO_OUT", dumpio_output_filter,
+ NULL, AP_FTYPE_CONNECTION + 3) ;
+
+ ap_register_input_filter("DUMPIO_IN", dumpio_input_filter,
+ NULL, AP_FTYPE_CONNECTION + 3) ;
+
+ ap_hook_pre_connection(dumpio_pre_conn, NULL, NULL, APR_HOOK_MIDDLE);
+}
+
+static void *dumpio_create_sconfig(apr_pool_t *p, server_rec *s)
+{
+ dumpio_conf_t *ptr = apr_pcalloc(p, sizeof *ptr);
+ ptr->enable_input = ptr->enable_output = 0;
+ return ptr;
+}
+
+static const char *dumpio_enable_input(cmd_parms *cmd, void *dummy, int arg)
+{
+ dumpio_conf_t *ptr =
+ (dumpio_conf_t *) ap_get_module_config(cmd->server->module_config,
+ &dumpio_module);
+
+ ptr->enable_input = arg;
+ return NULL;
+}
+
+static const char *dumpio_enable_output(cmd_parms *cmd, void *dummy, int arg)
+{
+ dumpio_conf_t *ptr =
+ (dumpio_conf_t *) ap_get_module_config(cmd->server->module_config,
+ &dumpio_module);
+
+ ptr->enable_output = arg;
+ return NULL;
+}
+
+static const command_rec dumpio_cmds[] = {
+ AP_INIT_FLAG("DumpIOInput", dumpio_enable_input, NULL,
+ RSRC_CONF, "Enable I/O Dump on Input Data"),
+ AP_INIT_FLAG("DumpIOOutput", dumpio_enable_output, NULL,
+ RSRC_CONF, "Enable I/O Dump on Output Data"),
+ { NULL }
+};
+
+module AP_MODULE_DECLARE_DATA dumpio_module = {
+ STANDARD20_MODULE_STUFF,
+ NULL,
+ NULL,
+ dumpio_create_sconfig,
+ NULL,
+ dumpio_cmds,
+ dumpio_register_hooks
+};
--- /dev/null
+# Microsoft Developer Studio Project File - Name="mod_dumpio" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_dumpio - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_dumpio.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_dumpio.mak" CFG="mod_dumpio - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_dumpio - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_dumpio - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_dumpio - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /Zi /O2 /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_dumpio_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/mod_dumpio.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dumpio.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Release/mod_dumpio.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dumpio.so /opt:ref
+
+!ELSEIF "$(CFG)" == "mod_dumpio - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_dumpio_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_dumpio.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dumpio.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_dumpio.so" /base:@..\..\os\win32\BaseAddr.ref,mod_dumpio.so
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_dumpio - Win32 Release"
+# Name "mod_dumpio - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_dumpio.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mod_dumpio.rc
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\win32ver.awk
+
+!IF "$(CFG)" == "mod_dumpio - Win32 Release"
+
+# PROP Ignore_Default_Tool 1
+# Begin Custom Build - Creating Version Resource
+InputPath=..\..\build\win32\win32ver.awk
+
+".\mod_dumpio.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ awk -f ../../build/win32/win32ver.awk mod_dumpio.so "bucketeer_module for Apache" ../../include/ap_release.h > .\mod_dumpio.rc
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "mod_dumpio - Win32 Debug"
+
+# PROP Ignore_Default_Tool 1
+# Begin Custom Build - Creating Version Resource
+InputPath=..\..\build\win32\win32ver.awk
+
+".\mod_dumpio.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ awk -f ../../build/win32/win32ver.awk mod_dumpio.so "bucketeer_module for Apache" ../../include/ap_release.h > .\mod_dumpio.rc
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Target
+# End Project