From: Stefan Fritsch Date: Tue, 28 Sep 2010 11:53:17 +0000 (+0000) Subject: Add generate_log_id hook to allow to use the ID generated by mod_unique_id as X-Git-Tag: 2.3.9~402 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b65066c6ac6dab9990da1f641b8c7c74ee9087b5;p=apache Add generate_log_id hook to allow to use the ID generated by mod_unique_id as error log ID for requests. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1002125 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 9591b97d2a..5ea1450253 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,9 @@ Changes with Apache 2.3.9 + *) core/mod_unique_id: Add generate_log_id hook to allow to use + the ID generated by mod_unique_id as error log ID for requests. + *) mod_cache: Make sure that we never allow a 304 Not Modified response that we asked for to leak to the client should the 304 response be uncacheable. PR45341 [Graham Leggett] diff --git a/docs/manual/mod/core.xml b/docs/manual/mod/core.xml index 1a30ea90fa..885d1db96d 100644 --- a/docs/manual/mod/core.xml +++ b/docs/manual/mod/core.xml @@ -1175,7 +1175,8 @@ in case of an error same connection or request, which request happens on which connection. A %L format string is also available in mod_log_config, to allow to correlate access log entries - with error log lines.

+ with error log lines. If mod_unique_id is loaded, its + unique id will be used as log ID for requests.

Example (somewhat similar to default format) ErrorLogFormat "[%{u}t] [%-m:%l] [pid %P] %7F: %E: [client\ %a] diff --git a/include/ap_mmn.h b/include/ap_mmn.h index b147c5e108..8377a7ba42 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -270,6 +270,7 @@ * cache_server_conf, cache_enable, cache_disable, * cache_request_rec and cache_provider_list private. * 20100923.1 (2.3.9-dev) Add cache_status hook. + * 20100923.2 (2.3.9-dev) Add generate_log_id hook. */ #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */ @@ -277,7 +278,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20100923 #endif -#define MODULE_MAGIC_NUMBER_MINOR 1 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 2 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/include/http_core.h b/include/http_core.h index a4a90461ab..6ee92ce9d3 100644 --- a/include/http_core.h +++ b/include/http_core.h @@ -729,7 +729,7 @@ typedef struct { unsigned int min_loglevel; /* only log if level is higher than this */ } ap_errorlog_format_item; -AP_DECLARE(void) ap_register_builtin_errorlog_handlers(apr_pool_t *p); +AP_DECLARE(void) ap_register_log_hooks(apr_pool_t *p); /* ---------------------------------------------------------------------- * diff --git a/include/http_log.h b/include/http_log.h index f263c9c299..724f8e132f 100644 --- a/include/http_log.h +++ b/include/http_log.h @@ -618,6 +618,18 @@ AP_DECLARE_HOOK(void, error_log, (const char *file, int line, const request_rec *r, apr_pool_t *pool, const char *errstr)) +/** + * hook method to generate unique id for connection or request + * @ingroup hooks + * @param c the conn_rec of the connections + * @param r the request_req (may be NULL) + * @param id the place where to store the unique id + * @return OK or DECLINE + */ +AP_DECLARE_HOOK(int, generate_log_id, + (const conn_rec *c, const request_rec *r, const char **id)) + + #ifdef __cplusplus } #endif diff --git a/modules/metadata/mod_unique_id.c b/modules/metadata/mod_unique_id.c index ef74301966..fa2d871e41 100644 --- a/modules/metadata/mod_unique_id.c +++ b/modules/metadata/mod_unique_id.c @@ -281,7 +281,7 @@ static const char uuencoder[64] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '@', '-', }; -static int gen_unique_id(request_rec *r) +static const char *gen_unique_id(const request_rec *r) { char *str; /* @@ -295,17 +295,8 @@ static int gen_unique_id(request_rec *r) } paddedbuf; unsigned char *x,*y; unsigned short counter; - const char *e; int i,j,k; - /* copy the unique_id if this is an internal redirect (we're never - * actually called for sub requests, so we don't need to test for - * them) */ - if (r->prev && (e = apr_table_get(r->subprocess_env, "REDIRECT_UNIQUE_ID"))) { - apr_table_setn(r->subprocess_env, "UNIQUE_ID", e); - return DECLINED; - } - new_unique_id.in_addr = cur_unique_id.in_addr; new_unique_id.pid = cur_unique_id.pid; new_unique_id.counter = cur_unique_id.counter; @@ -344,14 +335,64 @@ static int gen_unique_id(request_rec *r) } str[k++] = '\0'; - /* set the environment variable */ - apr_table_setn(r->subprocess_env, "UNIQUE_ID", str); - /* and increment the identifier for the next call */ counter = ntohs(new_unique_id.counter) + 1; cur_unique_id.counter = htons(counter); + return str; +} + +/* + * There are two ways the generation of a unique id can be triggered: + * + * - from the post_read_request hook which calls set_unique_id() + * - from error logging via the generate_log_id hook which calls + * generate_log_id(). This may happen before or after set_unique_id() + * has been called, or not at all. + */ + +static int generate_log_id(const conn_rec *c, const request_rec *r, + const char **id) +{ + /* we do not care about connection ids */ + if (r == NULL) + return DECLINED; + + /* XXX: do we need special handling for internal redirects? */ + + /* if set_unique_id() has been called for this request, use it */ + *id = apr_table_get(r->subprocess_env, "UNIQUE_ID"); + + if (!*id) + *id = gen_unique_id(r); + return OK; +} + +static int set_unique_id(request_rec *r) +{ + const char *id = NULL; + /* copy the unique_id if this is an internal redirect (we're never + * actually called for sub requests, so we don't need to test for + * them) */ + if (r->prev) { + id = apr_table_get(r->subprocess_env, "REDIRECT_UNIQUE_ID"); + } + + if (!id) { + /* if we have a log id, it was set by our generate_log_id() function + * and we should reuse the same id + */ + id = r->log_id; + } + + if (!id) { + id = gen_unique_id(r); + } + + /* set the environment variable */ + apr_table_setn(r->subprocess_env, "UNIQUE_ID", id); + return DECLINED; } @@ -359,7 +400,8 @@ static void register_hooks(apr_pool_t *p) { ap_hook_post_config(unique_id_global_init, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_child_init(unique_id_child_init, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_post_read_request(gen_unique_id, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_post_read_request(set_unique_id, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_generate_log_id(generate_log_id, NULL, NULL, APR_HOOK_MIDDLE); } AP_DECLARE_MODULE(unique_id) = { diff --git a/server/core.c b/server/core.c index 84e37f358c..ccb9d5e276 100644 --- a/server/core.c +++ b/server/core.c @@ -3900,8 +3900,6 @@ static int core_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptem { ap_mutex_init(pconf); - ap_register_builtin_errorlog_handlers(pconf); - return APR_SUCCESS; } @@ -4114,6 +4112,7 @@ static int core_pre_connection(conn_rec *c, void *csd) static void register_hooks(apr_pool_t *p) { errorlog_hash = apr_hash_make(p); + ap_register_log_hooks(p); /* create_connection and pre_connection should always be hooked * APR_HOOK_REALLY_LAST by core to give other modules the opportunity diff --git a/server/log.c b/server/log.c index 3c3f56ce03..028eaecbad 100644 --- a/server/log.c +++ b/server/log.c @@ -60,6 +60,7 @@ typedef struct { APR_HOOK_STRUCT( APR_HOOK_LINK(error_log) + APR_HOOK_LINK(generate_log_id) ) int AP_DECLARE_DATA ap_default_loglevel = DEFAULT_LOGLEVEL; @@ -782,25 +783,8 @@ static int log_env_var(const ap_errorlog_info *info, const char *arg, return 0; } -AP_DECLARE(void) ap_register_builtin_errorlog_handlers(apr_pool_t *p) -{ - ap_register_errorlog_handler(p, "a", log_remote_address, 0); - ap_register_errorlog_handler(p, "A", log_local_address, 0); - ap_register_errorlog_handler(p, "e", log_env_var, 0); - ap_register_errorlog_handler(p, "E", log_apr_status, 0); - ap_register_errorlog_handler(p, "F", log_file_line, 0); - ap_register_errorlog_handler(p, "i", log_header, 0); - ap_register_errorlog_handler(p, "k", log_keepalives, 0); - ap_register_errorlog_handler(p, "l", log_loglevel, 0); - ap_register_errorlog_handler(p, "L", log_log_id, 0); - ap_register_errorlog_handler(p, "m", log_module_name, 0); - ap_register_errorlog_handler(p, "n", log_note, 0); - ap_register_errorlog_handler(p, "P", log_pid, 0); - ap_register_errorlog_handler(p, "t", log_ctime, 0); - ap_register_errorlog_handler(p, "T", log_tid, 0); -} - -static void add_log_id(const conn_rec *c, const request_rec *r) +static int core_generate_log_id(const conn_rec *c, const request_rec *r, + const char **idstring) { apr_uint64_t id, tmp; pid_t pid; @@ -843,15 +827,46 @@ static void add_log_id(const conn_rec *c, const request_rec *r) apr_base64_encode(encoded, (char *)&id, sizeof(id)); /* Skip the last char, it is always '=' */ - encoded[len - 2] = '\0'; + encoded[len - 2] = '\0'; + + *idstring = encoded; + + return OK; +} +static void add_log_id(const conn_rec *c, const request_rec *r) +{ + const char **id; /* need to cast const away */ if (r) { - ((request_rec *)r)->log_id = encoded; + id = &((request_rec *)r)->log_id; } else { - ((conn_rec *)c)->log_id = encoded; + id = &((conn_rec *)c)->log_id; } + + ap_run_generate_log_id(c, r, id); +} + +AP_DECLARE(void) ap_register_log_hooks(apr_pool_t *p) +{ + ap_hook_generate_log_id(core_generate_log_id, NULL, NULL, + APR_HOOK_REALLY_LAST); + + ap_register_errorlog_handler(p, "a", log_remote_address, 0); + ap_register_errorlog_handler(p, "A", log_local_address, 0); + ap_register_errorlog_handler(p, "e", log_env_var, 0); + ap_register_errorlog_handler(p, "E", log_apr_status, 0); + ap_register_errorlog_handler(p, "F", log_file_line, 0); + ap_register_errorlog_handler(p, "i", log_header, 0); + ap_register_errorlog_handler(p, "k", log_keepalives, 0); + ap_register_errorlog_handler(p, "l", log_loglevel, 0); + ap_register_errorlog_handler(p, "L", log_log_id, 0); + ap_register_errorlog_handler(p, "m", log_module_name, 0); + ap_register_errorlog_handler(p, "n", log_note, 0); + ap_register_errorlog_handler(p, "P", log_pid, 0); + ap_register_errorlog_handler(p, "t", log_ctime, 0); + ap_register_errorlog_handler(p, "T", log_tid, 0); } /* @@ -1694,3 +1709,8 @@ AP_IMPLEMENT_HOOK_VOID(error_log, const request_rec *r, apr_pool_t *pool, const char *errstr), (file, line, module_index, level, status, s, r, pool, errstr)) + +AP_IMPLEMENT_HOOK_RUN_FIRST(int, generate_log_id, + (const conn_rec *c, const request_rec *r, + const char **id), + (c, r, id), DECLINED)