Attached you'll find a more or less straightforward port of
ap_escape_logitem, introduced in 1.3.25.
Two questions:
- is this a minor mmn bump? (I'd say: yes, because new api)
- should we make it configurable (via LogFormat?), I'm not sure ...
TIA, nd
*mumbling something about outdated docs, I've just discovered this feature
accidentally ;-)*
--
package Hacker::Perl::Another::Just;print
[EMAIL PROTECTED] split/::/ =>__PACKAGE__]}~;
# Andr� Malo # http://pub.perlig.de #
diff -Nur httpd-2.1\include\httpd.h httpd-2.1.escape\include\httpd.h
--- httpd-2.1\include\httpd.h Mon Feb 03 18:52:53 2003
+++ httpd-2.1.escape\include\httpd.h Wed Mar 05 01:08:12 2003
@@ -1360,6 +1360,14 @@
AP_DECLARE(char *) ap_escape_html(apr_pool_t *p, const char *s);
/**
+ * Escape a string for logging
+ * @param p The pool to allocate from
+ * @param s The string to escape
+ * @return The escaped string
+ */
+AP_DECLARE(char *) ap_escape_logitem(apr_pool_t *p, const char *str);
+
+/**
* Construct a full hostname
* @param p The pool to allocate from
* @param hostname The hostname of the server
diff -Nur httpd-2.1\modules\loggers\mod_log_config.c
httpd-2.1.escape\modules\loggers\mod_log_config.c
--- httpd-2.1\modules\loggers\mod_log_config.c Fri Feb 14 15:25:44 2003
+++ httpd-2.1.escape\modules\loggers\mod_log_config.c Wed Mar 05 01:55:29 2003
@@ -333,8 +333,9 @@
static const char *log_remote_host(request_rec *r, char *a)
{
- return ap_get_remote_host(r->connection, r->per_dir_config,
- REMOTE_NAME, NULL);
+ return ap_escape_logitem(r->pool, ap_get_remote_host(r->connection,
+ r->per_dir_config,
+ REMOTE_NAME, NULL));
}
static const char *log_remote_address(request_rec *r, char *a)
@@ -349,7 +350,7 @@
static const char *log_remote_logname(request_rec *r, char *a)
{
- return ap_get_remote_logname(r);
+ return ap_escape_logitem(r->pool, ap_get_remote_logname(r));
}
static const char *log_remote_user(request_rec *r, char *a)
@@ -362,6 +363,10 @@
else if (strlen(rvalue) == 0) {
rvalue = "\"\"";
}
+ else {
+ rvalue = ap_escape_logitem(r->pool, rvalue);
+ }
+
return rvalue;
}
@@ -372,33 +377,37 @@
* (note the truncation before the protocol string for HTTP/0.9 requests)
* (note also that r->the_request contains the unmodified request)
*/
- return (r->parsed_uri.password)
- ? apr_pstrcat(r->pool, r->method, " ",
- apr_uri_unparse(r->pool, &r->parsed_uri, 0),
- r->assbackwards ? NULL : " ", r->protocol, NULL)
- : r->the_request;
+ return ap_escape_logitem(r->pool,
+ (r->parsed_uri.password)
+ ? apr_pstrcat(r->pool, r->method, " ",
+ apr_uri_unparse(r->pool,
+ &r->parsed_uri, 0),
+ r->assbackwards ? NULL : " ",
+ r->protocol, NULL)
+ : r->the_request);
}
static const char *log_request_file(request_rec *r, char *a)
{
- return r->filename;
+ return ap_escape_logitem(r->pool, r->filename);
}
static const char *log_request_uri(request_rec *r, char *a)
{
- return r->uri;
+ return ap_escape_logitem(r->pool, r->uri);
}
static const char *log_request_method(request_rec *r, char *a)
{
- return r->method;
+ return ap_escape_logitem(r->pool, r->method);
}
static const char *log_request_protocol(request_rec *r, char *a)
{
- return r->protocol;
+ return ap_escape_logitem(r->pool, r->protocol);
}
static const char *log_request_query(request_rec *r, char *a)
{
- return (r->args != NULL) ? apr_pstrcat(r->pool, "?", r->args, NULL)
- : "";
+ return (r->args) ? apr_pstrcat(r->pool, "?",
+ ap_escape_logitem(r->pool, r->args), NULL)
+ : "";
}
static const char *log_status(request_rec *r, char *a)
{
@@ -428,7 +437,7 @@
static const char *log_header_in(request_rec *r, char *a)
{
- return apr_table_get(r->headers_in, a);
+ return ap_escape_logitem(r->pool, apr_table_get(r->headers_in, a));
}
static const char *log_header_out(request_rec *r, char *a)
@@ -438,18 +447,18 @@
cp = ap_field_noparam(r->pool, r->content_type);
}
if (cp) {
- return cp;
+ return ap_escape_logitem(r->pool, cp);
}
- return apr_table_get(r->err_headers_out, a);
+ return ap_escape_logitem(r->pool, apr_table_get(r->err_headers_out, a));
}
static const char *log_note(request_rec *r, char *a)
{
- return apr_table_get(r->notes, a);
+ return ap_escape_logitem(r->pool, apr_table_get(r->notes, a));
}
static const char *log_env_var(request_rec *r, char *a)
{
- return apr_table_get(r->subprocess_env, a);
+ return ap_escape_logitem(r->pool, apr_table_get(r->subprocess_env, a));
}
static const char *log_cookie(request_rec *r, char *a)
@@ -467,7 +476,7 @@
if (end_cookie) {
*end_cookie = '\0';
}
- return cookie;
+ return ap_escape_logitem(r->pool, cookie);
}
}
return NULL;
@@ -585,7 +594,7 @@
*/
static const char *log_virtual_host(request_rec *r, char *a)
{
- return r->server->server_hostname;
+ return ap_escape_logitem(r->pool, r->server->server_hostname);
}
static const char *log_server_port(request_rec *r, char *a)
@@ -599,7 +608,7 @@
*/
static const char *log_server_name(request_rec *r, char *a)
{
- return ap_get_server_name(r);
+ return ap_escape_logitem(r->pool, ap_get_server_name(r));
}
static const char *log_child_pid(request_rec *r, char *a)
diff -Nur httpd-2.1\server\gen_test_char.c httpd-2.1.escape\server\gen_test_char.c
--- httpd-2.1\server\gen_test_char.c Mon Feb 03 18:53:18 2003
+++ httpd-2.1.escape\server\gen_test_char.c Wed Mar 05 01:11:22 2003
@@ -73,6 +73,7 @@
#define T_ESCAPE_PATH_SEGMENT (0x02)
#define T_OS_ESCAPE_PATH (0x04)
#define T_HTTP_TOKEN_STOP (0x08)
+#define T_ESCAPE_LOGITEM (0x10)
int main(int argc, char *argv[])
{
@@ -85,13 +86,15 @@
"#define T_ESCAPE_PATH_SEGMENT (%u)\n"
"#define T_OS_ESCAPE_PATH (%u)\n"
"#define T_HTTP_TOKEN_STOP (%u)\n"
+ "#define T_ESCAPE_LOGITEM (%u)\n"
"\n"
"static const unsigned char test_char_table[256] = {\n"
" 0,",
T_ESCAPE_SHELL_CMD,
T_ESCAPE_PATH_SEGMENT,
T_OS_ESCAPE_PATH,
- T_HTTP_TOKEN_STOP);
+ T_HTTP_TOKEN_STOP,
+ T_ESCAPE_LOGITEM);
/* we explicitly dealt with NUL above
* in case some strchr() do bogosity with it */
@@ -135,8 +138,16 @@
flags |= T_HTTP_TOKEN_STOP;
}
- printf("%u%c", flags, (c < 255) ? ',' : ' ');
+ /* For logging, escape all control characters,
+ * double quotes (because they delimit the request in the log file)
+ * backslashes (because we use backslash for escaping)
+ * and 8-bit chars with the high bit set
+ */
+ if (!apr_isprint(c) || c == '"' || c == '\\' || apr_iscntrl(c)) {
+ flags |= T_ESCAPE_LOGITEM;
+ }
+ printf("%u%c", flags, (c < 255) ? ',' : ' ');
}
printf("\n};\n");
diff -Nur httpd-2.1\server\util.c httpd-2.1.escape\server\util.c
--- httpd-2.1\server\util.c Thu Feb 13 03:42:51 2003
+++ httpd-2.1.escape\server\util.c Wed Mar 05 00:16:31 2003
@@ -1784,6 +1784,58 @@
return x;
}
+AP_DECLARE(char *) ap_escape_logitem(apr_pool_t *p, const char *str)
+{
+ char *ret;
+ unsigned char *d;
+ const unsigned char *s;
+
+ if (!str) {
+ return NULL;
+ }
+
+ ret = apr_palloc(p, 4 * strlen(str) + 1); /* Be safe */
+ d = (unsigned char *)ret;
+ s = (const unsigned char *)str;
+ for (; *s; ++s) {
+
+ if (TEST_CHAR(*s, T_ESCAPE_LOGITEM)) {
+ *d++ = '\\';
+ switch(*s) {
+ case '\b':
+ *d++ = 'b';
+ break;
+ case '\n':
+ *d++ = 'n';
+ break;
+ case '\r':
+ *d++ = 'r';
+ break;
+ case '\t':
+ *d++ = 't';
+ break;
+ case '\v':
+ *d++ = 'v';
+ break;
+ case '\\':
+ case '"':
+ *d++ = *s;
+ break;
+ default:
+ c2x(*s, d);
+ *d = 'x';
+ d += 3;
+ }
+ }
+ else {
+ *d++ = *s;
+ }
+ }
+ *d = '\0';
+
+ return ret;
+}
+
AP_DECLARE(int) ap_is_directory(apr_pool_t *p, const char *path)
{
apr_finfo_t finfo;