@@ -41,16 +41,19 @@ typedef struct dumpio_conf_t {
4141 int loglevel ;
4242} dumpio_conf_t ;
4343
44+ /* consider up to 80 additional characters, and factor the longest
45+ * line length of all \xNN sequences; log_error cannot record more
46+ * than MAX_STRING_LEN characters.
47+ */
48+ #define dumpio_MAX_STRING_LEN MAX_STRING_LEN / 4 - 80
49+
4450/*
4551 * Workhorse function: simply log to the current error_log
4652 * info about the data in the bucket as well as the data itself
4753 */
48- static void dumpit (ap_filter_t * f , apr_bucket * b )
54+ static void dumpit (ap_filter_t * f , apr_bucket * b , dumpio_conf_t * ptr )
4955{
5056 conn_rec * c = f -> c ;
51- dumpio_conf_t * ptr =
52- (dumpio_conf_t * ) ap_get_module_config (c -> base_server -> module_config ,
53- & dumpio_module );
5457
5558 ap_log_error (APLOG_MARK , ptr -> loglevel , 0 , c -> base_server ,
5659 "mod_dumpio: %s (%s-%s): %" APR_SIZE_T_FMT " bytes" ,
@@ -59,33 +62,53 @@ static void dumpit(ap_filter_t *f, apr_bucket *b)
5962 b -> type -> name ,
6063 b -> length ) ;
6164
62- if (!(APR_BUCKET_IS_METADATA (b ))) {
65+ if (!(APR_BUCKET_IS_METADATA (b )))
66+ {
67+ #if APR_CHARSET_EBCDIC
68+ char xlatebuf [dumpio_MAX_STRING_LEN + 1 ];
69+ #endif
6370 const char * buf ;
6471 apr_size_t nbytes ;
65- char * obuf ;
66- if (apr_bucket_read (b , & buf , & nbytes , APR_BLOCK_READ ) == APR_SUCCESS ) {
67- if (nbytes ) {
68- obuf = malloc (nbytes + 1 ); /* use pool? */
69- memcpy (obuf , buf , nbytes );
72+ apr_size_t logbytes ;
73+ apr_status_t rv = apr_bucket_read (b , & buf , & nbytes , APR_BLOCK_READ );
74+
75+ if (rv == APR_SUCCESS )
76+ {
77+ while (nbytes )
78+ {
79+ logbytes = nbytes ;
80+ if (logbytes > dumpio_MAX_STRING_LEN )
81+ logbytes = dumpio_MAX_STRING_LEN ;
82+ nbytes -= logbytes ;
83+
7084#if APR_CHARSET_EBCDIC
71- ap_xlate_proto_from_ascii ( obuf , nbytes );
72- #endif
73- obuf [ nbytes ] = '\0' ;
85+ memcpy ( xlatebuf , buf , logbytes );
86+ ap_xlate_proto_from_ascii ( xlatebuf , logbytes );
87+ xlatebuf [ logbytes ] = '\0' ;
7488 ap_log_error (APLOG_MARK , ptr -> loglevel , 0 , c -> base_server ,
75- "mod_dumpio: %s (%s-%s): %s" ,
76- f -> frec -> name ,
77- (APR_BUCKET_IS_METADATA (b )) ? "metadata" : "data" ,
78- b -> type -> name ,
79- obuf );
80- free (obuf );
89+ "mod_dumpio: %s (%s-%s): %s" , f -> frec -> name ,
90+ (APR_BUCKET_IS_METADATA (b )) ? "metadata" : "data" ,
91+ b -> type -> name , xlatebuf );
92+ #else
93+ /* XXX: Seriously flawed; we do not pay attention to embedded
94+ * \0's in the request body, these should be escaped; however,
95+ * the logging function already performs a significant amount
96+ * of escaping, and so any escaping would be double-escaped.
97+ * The coding solution is to throw away the current logic
98+ * within ap_log_error, and introduce new vformatter %-escapes
99+ * for escaping text, and for binary text (fixed len strings).
100+ */
101+ ap_log_error (APLOG_MARK | APLOG_NOERRNO , ptr -> loglevel , 0 , c -> base_server ,
102+ "mod_dumpio: %s (%s-%s): %.*s" , f -> frec -> name ,
103+ (APR_BUCKET_IS_METADATA (b )) ? "metadata" : "data" ,
104+ b -> type -> name , logbytes , buf );
105+ #endif
81106 }
82107 } else {
83- ap_log_error (APLOG_MARK , ptr -> loglevel , 0 , c -> base_server ,
84- "mod_dumpio: %s (%s-%s): %s" ,
85- f -> frec -> name ,
86- (APR_BUCKET_IS_METADATA (b )) ? "metadata" : "data" ,
87- b -> type -> name ,
88- "error reading data" );
108+ ap_log_error (APLOG_MARK , ptr -> loglevel , rv , c -> base_server ,
109+ "mod_dumpio: %s (%s-%s): %s" , f -> frec -> name ,
110+ (APR_BUCKET_IS_METADATA (b )) ? "metadata" : "data" ,
111+ b -> type -> name , "error reading data" );
89112 }
90113 }
91114}
@@ -106,7 +129,7 @@ static int dumpio_input_filter (ap_filter_t *f, apr_bucket_brigade *bb,
106129 apr_bucket * b ;
107130 apr_status_t ret ;
108131 conn_rec * c = f -> c ;
109- dumpio_conf_t * ptr =
132+ dumpio_conf_t * ptr = f -> ctx ;
110133 (dumpio_conf_t * ) ap_get_module_config (c -> base_server -> module_config ,
111134 & dumpio_module );
112135
@@ -121,7 +144,7 @@ static int dumpio_input_filter (ap_filter_t *f, apr_bucket_brigade *bb,
121144
122145 if (ret == APR_SUCCESS ) {
123146 for (b = APR_BRIGADE_FIRST (bb ); b != APR_BRIGADE_SENTINEL (bb ); b = APR_BUCKET_NEXT (b )) {
124- dumpit (f , b );
147+ dumpit (f , b , ptr );
125148 }
126149 } else {
127150 ap_log_error (APLOG_MARK , ptr -> loglevel , 0 , c -> base_server ,
@@ -135,7 +158,7 @@ static int dumpio_output_filter (ap_filter_t *f, apr_bucket_brigade *bb)
135158{
136159 apr_bucket * b ;
137160 conn_rec * c = f -> c ;
138- dumpio_conf_t * ptr =
161+ dumpio_conf_t * ptr = f -> ctx ;
139162 (dumpio_conf_t * ) ap_get_module_config (c -> base_server -> module_config ,
140163 & dumpio_module );
141164
@@ -149,22 +172,23 @@ static int dumpio_output_filter (ap_filter_t *f, apr_bucket_brigade *bb)
149172 apr_bucket * flush = apr_bucket_flush_create (f -> c -> bucket_alloc );
150173 APR_BUCKET_INSERT_BEFORE (b , flush );
151174 }
152- dumpit (f , b );
175+ dumpit (f , b , ptr );
153176 }
154177
155178 return ap_pass_brigade (f -> next , bb ) ;
156179}
157180
158181static int dumpio_pre_conn (conn_rec * c , void * csd )
159182{
160- dumpio_conf_t * ptr =
161- (dumpio_conf_t * ) ap_get_module_config (c -> base_server -> module_config ,
162- & dumpio_module );
183+ dumpio_conf_t * ptr ;
184+
185+ ptr = (dumpio_conf_t * ) ap_get_module_config (c -> base_server -> module_config ,
186+ & dumpio_module );
163187
164188 if (ptr -> enable_input )
165- ap_add_input_filter ("DUMPIO_IN" , NULL , NULL , c );
189+ ap_add_input_filter ("DUMPIO_IN" , ptr , NULL , c );
166190 if (ptr -> enable_output )
167- ap_add_output_filter ("DUMPIO_OUT" , NULL , NULL , c );
191+ ap_add_output_filter ("DUMPIO_OUT" , ptr , NULL , c );
168192 return OK ;
169193}
170194
0 commit comments