Hi Glenn,
Could you update at least the apache2 connector ? This features makes
sense on all servers actually ( i.e. IIS, etc ) - but we should have it
at least in 1.3 and 2.0.
Also, any chance to update this on native2 ? I'll do it later if you don't
have the time.
Costin
On 21 Apr 2002 [EMAIL PROTECTED] wrote:
> glenn 02/04/21 15:57:11
>
> Modified: jk/native/apache-1.3 mod_jk.c
> jk/native/common jk_logger.h jk_uri_worker_map.c jk_util.c
> jk/doc mod_jk-howto.html
> Log:
> Apache mod_jk 1.2 new features.
>
> Added JkRequestLogFormat for Apache style request logging
> including Tocmat request latency in seconds and microseconds.
>
> Added JkAutoAlias, this can be used to automatically Alias
> web application context directories so that static files
> can be served by Apache instead of Tomcat. When configured,
> requests for a WAR file in the Tomcat appBase (webapps) directory
> are forbidden. Requests for the WEB-INF and META-INF directories
> within a web application context dir are also forbidden and will
> return an HTTP 403 error.
>
> Added ability to JkMount so that /*/servlet/ can be used to
> configure mod_jk to pass all servlet requests on to Tomcat
> for any web application context.
>
> Revision Changes Path
> 1.26 +521 -12 jakarta-tomcat-connectors/jk/native/apache-1.3/mod_jk.c
>
> Index: mod_jk.c
> ===================================================================
> RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native/apache-1.3/mod_jk.c,v
> retrieving revision 1.25
> retrieving revision 1.26
> diff -u -r1.25 -r1.26
> --- mod_jk.c 3 Apr 2002 00:49:19 -0000 1.25
> +++ mod_jk.c 21 Apr 2002 22:57:11 -0000 1.26
> @@ -61,7 +61,7 @@
> * Author: Gal Shachor <[EMAIL PROTECTED]> *
> * Dan Milstein <[EMAIL PROTECTED]> *
> * Henri Gomez <[EMAIL PROTECTED]> *
> - * Version: $Revision: 1.25 $ *
> + * Version: $Revision: 1.26 $ *
> ***************************************************************************/
>
> /*
> @@ -101,6 +101,7 @@
>
> #define JK_WORKER_ID ("jakarta.worker")
> #define JK_HANDLER ("jakarta-servlet")
> +#define JK_DURATION ("jakarta.worker.duration")
> #define JK_MAGIC_TYPE ("application/x-jakarta-servlet")
> #define NULL_FOR_EMPTY(x) ((x && !strlen(x)) ? NULL : x)
>
> @@ -139,6 +140,18 @@
> jk_uri_worker_map_t *uw_map;
>
> /*
> + * Automatic context path apache alias
> + */
> + char *alias_dir;
> +
> + /*
> + * Request Logging
> + */
> +
> + char *format_string;
> + array_header *format;
> +
> + /*
> * SSL Support
> */
> int ssl_enable;
> @@ -742,7 +755,7 @@
> /*
> * JkLogLevel Directive Handling
> *
> - * JkLogLevel debug/info/error/emerg
> + * JkLogLevel debug/info/request/error/emerg
> */
>
> static const char *jk_set_log_level(cmd_parms *cmd,
> @@ -773,6 +786,402 @@
> }
>
> /*
> + * JkAutoAlias Directive Handling
> + *
> + * JkAutoAlias application directory
> + */
> +
> +static const char *jk_set_auto_alias(cmd_parms *cmd,
> + void *dummy,
> + char *directory)
> +{
> + server_rec *s = cmd->server;
> + jk_server_conf_t *conf =
> + (jk_server_conf_t *)ap_get_module_config(s->module_config, &jk_module);
> +
> + conf->alias_dir = directory;
> +
> + if (conf->alias_dir == NULL)
> + return "JkAutoAlias directory invalid";
> +
> + return NULL;
> +}
> +
> +/*****************************************************************
> + *
> + * Actually logging.
> + */
> +
> +typedef const char *(*item_key_func) (request_rec *, char *);
> +
> +typedef struct {
> + item_key_func func;
> + char *arg;
> +} request_log_format_item;
> +
> +static const char *process_item(request_rec *r,
> + request_log_format_item *item)
> +{
> + const char *cp;
> +
> + cp = (*item->func) (r,item->arg);
> + return cp ? cp : "-";
> +}
> +
> +static int request_log_transaction(request_rec *r,
> + jk_server_conf_t *conf)
> +{
> + request_log_format_item *items;
> + char *str, *s;
> + int i;
> + int len = 0;
> + const char **strs;
> + int *strl;
> + array_header *format = conf->format;
> +
> + strs = ap_palloc(r->pool, sizeof(char *) * (format->nelts));
> + strl = ap_palloc(r->pool, sizeof(int) * (format->nelts));
> + items = (request_log_format_item *) format->elts;
> + for (i = 0; i < format->nelts; ++i) {
> + strs[i] = process_item(r, &items[i]);
> + }
> + for (i = 0; i < format->nelts; ++i) {
> + len += strl[i] = strlen(strs[i]);
> + }
> + str = ap_palloc(r->pool, len + 1);
> + for (i = 0, s = str; i < format->nelts; ++i) {
> + memcpy(s, strs[i], strl[i]);
> + s += strl[i];
> + }
> + *s = 0;
> + jk_log(conf->log ? conf->log : main_log,JK_LOG_REQUEST,str);
> +}
> +
> +/*****************************************************************
> + *
> + * Parsing the log format string
> + */
> +
> +static char *format_integer(pool *p, int i)
> +{
> + return ap_psprintf(p, "%d", i);
> +}
> +
> +static char *pfmt(pool *p, int i)
> +{
> + if (i <= 0) {
> + return "-";
> + }
> + else {
> + return format_integer(p, i);
> + }
> +}
> +
> +static const char *constant_item(request_rec *dummy, char *stuff)
> +{
> + return stuff;
> +}
> +
> +static const char *log_worker_name(request_rec *r, char *a)
> +{
> + return ap_table_get(r->notes, JK_WORKER_ID);
> +}
> +
> +
> +static const char *log_request_duration(request_rec *r, char *a)
> +{
> + return ap_table_get(r->notes, JK_DURATION);
> +}
> +
> +static const char *log_request_line(request_rec *r, char *a)
> +{
> + /* NOTE: If the original request contained a password, we
> + * re-write the request line here to contain XXXXXX instead:
> + * (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) ? ap_pstrcat(r->pool, r->method, " ",
> + ap_unparse_uri_components(r->pool,
>&r->parsed_uri, 0),
> + r->assbackwards ? NULL : " ",
>r->protocol, NULL)
> + : r->the_request;
> +}
> +
> +/* These next two routines use the canonical name:port so that log
> + * parsers don't need to duplicate all the vhost parsing crud.
> + */
> +static const char *log_virtual_host(request_rec *r, char *a)
> +{
> + return r->server->server_hostname;
> +}
> +
> +static const char *log_server_port(request_rec *r, char *a)
> +{
> + return ap_psprintf(r->pool, "%u",
> + r->server->port ? r->server->port : ap_default_port(r));
> +}
> +
> +/* This respects the setting of UseCanonicalName so that
> + * the dynamic mass virtual hosting trick works better.
> + */
> +static const char *log_server_name(request_rec *r, char *a)
> +{
> + return ap_get_server_name(r);
> +}
> +
> +static const char *log_request_uri(request_rec *r, char *a)
> +{
> + return r->uri;
> +}
> +static const char *log_request_method(request_rec *r, char *a)
> +{
> + return r->method;
> +}
> +
> +static const char *log_request_protocol(request_rec *r, char *a)
> +{
> + return r->protocol;
> +}
> +static const char *log_request_query(request_rec *r, char *a)
> +{
> + return (r->args != NULL) ? ap_pstrcat(r->pool, "?", r->args, NULL)
> + : "";
> +}
> +static const char *log_status(request_rec *r, char *a)
> +{
> + return pfmt(r->pool,r->status);
> +}
> +
> +static const char *clf_log_bytes_sent(request_rec *r, char *a)
> +{
> + if (!r->sent_bodyct) {
> + return "-";
> + }
> + else {
> + long int bs;
> + ap_bgetopt(r->connection->client, BO_BYTECT, &bs);
> + return ap_psprintf(r->pool, "%ld", bs);
> + }
> +}
> +
> +static const char *log_bytes_sent(request_rec *r, char *a)
> +{
> + if (!r->sent_bodyct) {
> + return "0";
> + }
> + else {
> + long int bs;
> + ap_bgetopt(r->connection->client, BO_BYTECT, &bs);
> + return ap_psprintf(r->pool, "%ld", bs);
> + }
> +}
> +
> +static struct log_item_list {
> + char ch;
> + item_key_func func;
> +} log_item_keys[] = {
> +
> + {
> + 'T', log_request_duration
> + },
> + {
> + 'r', log_request_line
> + },
> + {
> + 'U', log_request_uri
> + },
> + {
> + 's', log_status
> + },
> + {
> + 'b', clf_log_bytes_sent
> + },
> + {
> + 'B', log_bytes_sent
> + },
> + {
> + 'V', log_server_name
> + },
> + {
> + 'v', log_virtual_host
> + },
> + {
> + 'p', log_server_port
> + },
> + {
> + 'H', log_request_protocol
> + },
> + {
> + 'm', log_request_method
> + },
> + {
> + 'q', log_request_query
> + },
> + {
> + 'w', log_worker_name
> + },
> + {
> + '\0'
> + }
> +};
> +
> +static struct log_item_list *find_log_func(char k)
> +{
> + int i;
> +
> + for (i = 0; log_item_keys[i].ch; ++i)
> + if (k == log_item_keys[i].ch) {
> + return &log_item_keys[i];
> + }
> +
> + return NULL;
> +}
> +
> +static char *parse_request_log_misc_string(pool *p,
> + request_log_format_item *it,
> + const char **sa)
> +{
> + const char *s;
> + char *d;
> +
> + it->func = constant_item;
> +
> + s = *sa;
> + while (*s && *s != '%') {
> + s++;
> + }
> + /*
> + * This might allocate a few chars extra if there's a backslash
> + * escape in the format string.
> + */
> + it->arg = ap_palloc(p, s - *sa + 1);
> +
> + d = it->arg;
> + s = *sa;
> + while (*s && *s != '%') {
> + if (*s != '\\') {
> + *d++ = *s++;
> + }
> + else {
> + s++;
> + switch (*s) {
> + case '\\':
> + *d++ = '\\';
> + s++;
> + break;
> + case 'n':
> + *d++ = '\n';
> + s++;
> + break;
> + case 't':
> + *d++ = '\t';
> + s++;
> + break;
> + default:
> + /* copy verbatim */
> + *d++ = '\\';
> + /*
> + * Allow the loop to deal with this *s in the normal
> + * fashion so that it handles end of string etc.
> + * properly.
> + */
> + break;
> + }
> + }
> + }
> + *d = '\0';
> +
> + *sa = s;
> + return NULL;
> +}
> +
> +static char *parse_request_log_item(pool *p,
> + request_log_format_item *it,
> + const char **sa)
> +{
> + const char *s = *sa;
> + int i;
> + struct log_item_list *l;
> +
> + if (*s != '%') {
> + return parse_request_log_misc_string(p, it, sa);
> + }
> +
> + ++s;
> + it->arg = ""; /* For safety's sake... */
> +
> + l = find_log_func(*s++);
> + if (!l) {
> + char dummy[2];
> +
> + dummy[0] = s[-1];
> + dummy[1] = '\0';
> + return ap_pstrcat(p, "Unrecognized JkRequestLogFormat directive %",
> + dummy, NULL);
> + }
> + it->func = l->func;
> + *sa = s;
> + return NULL;
> +}
> +
> +static array_header *parse_request_log_string(pool *p, const char *s,
> + const char **err)
> +{
> + array_header *a = ap_make_array(p, 15, sizeof(request_log_format_item));
> + char *res;
> +
> + while (*s) {
> + if ((res = parse_request_log_item(p, (request_log_format_item *)
>ap_push_array(a), &s))) {
> + *err = res;
> + return NULL;
> + }
> + }
> +
> + s = "\n";
> + parse_request_log_item(p, (request_log_format_item *) ap_push_array(a), &s);
> + return a;
> +}
> +
> +/*
> + * JkRequestLogFormat Directive Handling
> + *
> + * JkRequestLogFormat format string
> + *
> + * %b - Bytes sent, excluding HTTP headers. In CLF format
> + * %B - Bytes sent, excluding HTTP headers.
> + * %H - The request protocol
> + * %m - The request method
> + * %p - The canonical Port of the server serving the request
> + * %q - The query string (prepended with a ? if a query string exists,
> + * otherwise an empty string)
> + * %r - First line of request
> + * %s - request HTTP status code
> + * %T - Requset duration, elapsed time to handle request in seconds '.' micro
>seconds
> + * %U - The URL path requested, not including any query string.
> + * %v - The canonical ServerName of the server serving the request.
> + * %V - The server name according to the UseCanonicalName setting.
> + * %w - Tomcat worker name
> + */
> +
> +static const char *jk_set_request_log_format(cmd_parms *cmd,
> + void *dummy,
> + char *format)
> +{
> + const char *err_string = NULL;
> + server_rec *s = cmd->server;
> + jk_server_conf_t *conf =
> + (jk_server_conf_t *)ap_get_module_config(s->module_config, &jk_module);
> +
> + conf->format_string = ap_pstrdup(cmd->pool,format);
> + if( format != NULL ) {
> + conf->format = parse_request_log_string(cmd->pool, format, &err_string);
> + }
> + if( conf->format == NULL )
> + return "JkRequestLogFormat format array NULL";
> +
> + return err_string;
> +}
> +
> +/*
> * JkExtractSSL Directive Handling
> *
> * JkExtractSSL On/Off
> @@ -1006,14 +1415,23 @@
> /*
> * JkLogFile & JkLogLevel specifies to where should the plugin log
> * its information and how much.
> - * JkLogStampFormat specify the time-stamp to be used on log
> + * JkLogStampFormat specify the time-stamp to be used on log
> */
> {"JkLogFile", jk_set_log_file, NULL, RSRC_CONF, TAKE1,
> "Full path to the Jakarta mod_jk module log file"},
> {"JkLogLevel", jk_set_log_level, NULL, RSRC_CONF, TAKE1,
> - "The Jakarta mod_jk module log level, can be debug, info, error or emerg"},
> + "The Jakarta mod_jk module log level, can be debug, info, request, error, or
>emerg"},
> {"JkLogStampFormat", jk_set_log_fmt, NULL, RSRC_CONF, TAKE1,
> "The Jakarta mod_jk module log format, follow strftime synthax"},
> + {"JkRequestLogFormat", jk_set_request_log_format, NULL, RSRC_CONF, TAKE1,
> + "The Jakarta mod_jk module request log format string"},
> +
> + /*
> + * Automatically Alias webapp context directories into the Apache
> + * document space.
> + */
> + {"JkAutoAlias", jk_set_auto_alias, NULL, RSRC_CONF, TAKE1,
> + "The Jakarta mod_jk module automatic context apache alias directory"},
>
> /*
> * Apache has multiple SSL modules (for example apache_ssl, stronghold
> @@ -1093,6 +1511,7 @@
> jk_worker_t *worker = wc_get_worker_for_name(worker_name, l);
>
> if(worker) {
> + struct timeval tv_begin,tv_end;
> int rc = JK_FALSE;
> apache_private_data_t private_data;
> jk_ws_service_t s;
> @@ -1107,7 +1526,10 @@
>
> s.ws_private = &private_data;
> s.pool = &private_data.p;
> -
> + if(conf->format != NULL) {
> + gettimeofday(&tv_begin, NULL);
> + }
> +
> if(init_ws_service(&private_data, &s, conf)) {
> jk_endpoint_t *end = NULL;
> if(worker->get_endpoint(worker, &end, l)) {
> @@ -1131,6 +1553,21 @@
> }
> end->done(&end, l);
> }
> + if(conf->format != NULL) {
> + char *duration = NULL;
> + char *status = NULL;
> + long micro,seconds;
> + gettimeofday(&tv_end, NULL);
> + if( tv_end.tv_usec < tv_begin.tv_usec ) {
> + tv_end.tv_usec += 1000000;
> + tv_end.tv_sec--;
> + }
> + micro = tv_end.tv_usec - tv_begin.tv_usec;
> + seconds = tv_end.tv_sec - tv_begin.tv_sec;
> + duration = ap_psprintf(r->pool,"%.1d.%.6d",seconds,micro);
> + ap_table_setn(r->notes, JK_DURATION, duration);
> + request_log_transaction(r,conf);
> + }
> }
>
> jk_close_pool(&private_data.p);
> @@ -1152,12 +1589,15 @@
> jk_server_conf_t *c =
> (jk_server_conf_t *) ap_pcalloc(p, sizeof(jk_server_conf_t));
>
> - c->worker_file = NULL;
> - c->log_file = NULL;
> - c->log_level = -1;
> - c->log = NULL;
> - c->mountcopy = JK_FALSE;
> - c->options = JK_OPT_FWDURIDEFAULT;
> + c->worker_file = NULL;
> + c->log_file = NULL;
> + c->log_level = -1;
> + c->log = NULL;
> + c->alias_dir = NULL;
> + c->format_string = NULL;
> + c->format = NULL;
> + c->mountcopy = JK_FALSE;
> + c->options = JK_OPT_FWDURIDEFAULT;
>
> /*
> * By default we will try to gather SSL info.
> @@ -1332,11 +1772,80 @@
> (jk_server_conf_t *)ap_get_module_config(r->server->module_config,
>&jk_module);
>
> if(conf) {
> - char *worker = map_uri_to_worker(conf->uw_map, r->uri, conf->log ?
>conf->log : main_log);
> + jk_logger_t *l = conf->log ? conf->log : main_log;
> + char *worker = map_uri_to_worker(conf->uw_map, r->uri, l);
>
> if(worker) {
> r->handler = ap_pstrdup(r->pool, JK_HANDLER);
> ap_table_setn(r->notes, JK_WORKER_ID, worker);
> + } else if(conf->alias_dir != NULL) {
> + /* Automatically map uri to a context static file */
> + jk_log(l, JK_LOG_DEBUG,
> + "mod_jk::jk_translate, check alias_dir:
>%s\n",conf->alias_dir);
> + if (strlen(r->uri) > 1) {
> + /* Get the context directory name */
> + char *context_dir = NULL;
> + char *context_path = NULL;
> + char *child_dir = NULL;
> + char *index = r->uri;
> + char *suffix = strchr(index+1,'/');
> + if( suffix != NULL ) {
> + int size = suffix - index;
> + context_dir = ap_pstrndup(r->pool,index,size);
> + /* Get the context child directory name */
> + index = index + size + 1;
> + suffix = strchr(index,'/');
> + if( suffix != NULL ) {
> + size = suffix - index;
> + child_dir = ap_pstrndup(r->pool,index,size);
> + } else {
> + child_dir = index;
> + }
> + /* Deny access to WEB-INF and META-INF directories */
> + if( child_dir != NULL ) {
> + jk_log(l, JK_LOG_DEBUG,
> + "mod_jk::jk_translate, AutoAlias child_dir: %s\n",
> + child_dir);
> + if( !strcasecmp(child_dir,"WEB-INF") ||
> + !strcasecmp(child_dir,"META-INF") ) {
> + jk_log(l, JK_LOG_DEBUG,
> + "mod_jk::jk_translate, AutoAlias FORBIDDEN
>for URI: %s\n",
> + r->uri);
> + return FORBIDDEN;
> + }
> + }
> + } else {
> + context_dir = ap_pstrdup(r->pool,index);
> + }
> +
> + context_path = ap_pstrcat(r->pool,conf->alias_dir,
> +
>ap_os_escape_path(r->pool,context_dir,1),
> + NULL);
> + if( context_path != NULL ) {
> + DIR *dir = ap_popendir(r->pool,context_path);
> + if( dir != NULL ) {
> + char *escurl = ap_os_escape_path(r->pool, r->uri, 1);
> + char *ret =
>ap_pstrcat(r->pool,conf->alias_dir,escurl,NULL);
> + ap_pclosedir(r->pool,dir);
> + /* Add code to verify real path ap_os_canonical_name
>*/
> + if( ret != NULL ) {
> + jk_log(l, JK_LOG_DEBUG,
> + "mod_jk::jk_translate, AutoAlias OK for file:
>%s\n",ret);
> + r->filename = ret;
> + return OK;
> + }
> + } else {
> + /* Deny access to war files in web app directory */
> + int size = strlen(context_dir);
> + if( size > 4 &&
>!strcasecmp(context_dir+(size-4),".war") ) {
> + jk_log(l, JK_LOG_DEBUG,
> + "mod_jk::jk_translate, AutoAlias FORBIDDEN
>for URI: %s\n",
> + r->uri);
> + return FORBIDDEN;
> + }
> + }
> + }
> + }
> }
> }
> }
>
>
>
> 1.3 +11 -9 jakarta-tomcat-connectors/jk/native/common/jk_logger.h
>
> Index: jk_logger.h
> ===================================================================
> RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native/common/jk_logger.h,v
> retrieving revision 1.2
> retrieving revision 1.3
> diff -u -r1.2 -r1.3
> --- jk_logger.h 18 Jun 2001 14:15:49 -0000 1.2
> +++ jk_logger.h 21 Apr 2002 22:57:11 -0000 1.3
> @@ -58,7 +58,7 @@
> /***************************************************************************
> * Description: Logger object definitions *
> * Author: Gal Shachor <[EMAIL PROTECTED]> *
> - * Version: $Revision: 1.2 $ *
> + * Version: $Revision: 1.3 $ *
> ***************************************************************************/
>
> #ifndef JK_LOGGER_H
> @@ -81,20 +81,22 @@
>
> };
>
> -#define JK_LOG_DEBUG_LEVEL 0
> -#define JK_LOG_INFO_LEVEL 1
> -#define JK_LOG_ERROR_LEVEL 2
> -#define JK_LOG_EMERG_LEVEL 3
> +#define JK_LOG_DEBUG_LEVEL 0
> +#define JK_LOG_INFO_LEVEL 1
> +#define JK_LOG_ERROR_LEVEL 2
> +#define JK_LOG_EMERG_LEVEL 3
> +#define JK_LOG_REQUEST_LEVEL 4
>
> #define JK_LOG_DEBUG_VERB "debug"
> #define JK_LOG_INFO_VERB "info"
> #define JK_LOG_ERROR_VERB "error"
> #define JK_LOG_EMERG_VERB "emerg"
>
> -#define JK_LOG_DEBUG __FILE__,__LINE__,JK_LOG_DEBUG_LEVEL
> -#define JK_LOG_INFO __FILE__,__LINE__,JK_LOG_INFO_LEVEL
> -#define JK_LOG_ERROR __FILE__,__LINE__,JK_LOG_ERROR_LEVEL
> -#define JK_LOG_EMERG __FILE__,__LINE__,JK_LOG_EMERG_LEVEL
> +#define JK_LOG_DEBUG __FILE__,__LINE__,JK_LOG_DEBUG_LEVEL
> +#define JK_LOG_INFO __FILE__,__LINE__,JK_LOG_INFO_LEVEL
> +#define JK_LOG_ERROR __FILE__,__LINE__,JK_LOG_ERROR_LEVEL
> +#define JK_LOG_EMERG __FILE__,__LINE__,JK_LOG_EMERG_LEVEL
> +#define JK_LOG_REQUEST __FILE__,NULL,JK_LOG_REQUEST_LEVEL
>
> #ifdef __cplusplus
> }
>
>
>
> 1.14 +31 -2 jakarta-tomcat-connectors/jk/native/common/jk_uri_worker_map.c
>
> Index: jk_uri_worker_map.c
> ===================================================================
> RCS file:
>/home/cvs/jakarta-tomcat-connectors/jk/native/common/jk_uri_worker_map.c,v
> retrieving revision 1.13
> retrieving revision 1.14
> diff -u -r1.13 -r1.14
> --- jk_uri_worker_map.c 7 Dec 2001 00:57:16 -0000 1.13
> +++ jk_uri_worker_map.c 21 Apr 2002 22:57:11 -0000 1.14
> @@ -67,7 +67,7 @@
> * servlet container. *
> * *
> * Author: Gal Shachor <[EMAIL PROTECTED]> *
> - * Version: $Revision: 1.13 $ *
> + * Version: $Revision: 1.14 $ *
> ***************************************************************************/
>
> #include "jk_pool.h"
> @@ -78,6 +78,8 @@
> #define MATCH_TYPE_CONTEXT (1)
> #define MATCH_TYPE_SUFFIX (2)
> #define MATCH_TYPE_GENERAL_SUFFIX (3) /* match all URIs of the form *ext */
> +/* match all context path URIs with a path component suffix */
> +#define MATCH_TYPE_CONTEXT_PATH (4)
>
> struct uri_worker_record {
> /* Original uri for logging */
> @@ -275,7 +277,18 @@
> */
> asterisk--;
> if ('/' == asterisk[0]) {
> - if ('.' == asterisk[2]) {
> + if ( 0 == strncmp("/*/",uri,3) ) {
> + /* general context path */
> + asterisk[1] = '\0';
> + uwr->worker_name = worker;
> + uwr->context = uri;
> + uwr->suffix = asterisk + 2;
> + uwr->match_type = MATCH_TYPE_CONTEXT_PATH;
> + jk_log(l, JK_LOG_DEBUG,
> + "Into jk_uri_worker_map_t::uri_worker_map_open, "
> + "general context path rule %s*%s=%s was added\n",
> + uri, asterisk + 2, worker);
> + } else if ('.' == asterisk[2]) {
> /* suffix rule */
> asterisk[1] =
> asterisk[2] = '\0';
> @@ -507,6 +520,22 @@
> longest_match = uwr->ctxt_len;
> best_match = i;
> }
> + }
> + } else if(MATCH_TYPE_CONTEXT_PATH == uwr->match_type) {
> + char *suffix_path = NULL;
> + if (strlen(uri) > 1 && (suffix_path = strchr(uri+1,'/')) !=
>NULL) {
> + if (0 ==
>strncmp(suffix_path,uwr->suffix,strlen(uwr->suffix))) {
> + if(uwr->ctxt_len >= longest_match) {
> + jk_log(l,
> + JK_LOG_DEBUG,
> + "jk_uri_worker_map_t::map_uri_to_worker, "
> + "Found a general context path match %s ->
>*%s\n",
> + uwr->worker_name,
> + uwr->suffix );
> + longest_match = uwr->ctxt_len;
> + best_match = i;
> + }
> + }
> }
> } else /* suffix match */ {
> int suffix_start;
>
>
>
> 1.13 +11 -6 jakarta-tomcat-connectors/jk/native/common/jk_util.c
>
> Index: jk_util.c
> ===================================================================
> RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native/common/jk_util.c,v
> retrieving revision 1.12
> retrieving revision 1.13
> diff -u -r1.12 -r1.13
> --- jk_util.c 6 Feb 2002 19:11:23 -0000 1.12
> +++ jk_util.c 21 Apr 2002 22:57:11 -0000 1.13
> @@ -59,7 +59,7 @@
> * Description: Utility functions (mainly configuration) *
> * Author: Gal Shachor <[EMAIL PROTECTED]> *
> * Author: Henri Gomez <[EMAIL PROTECTED]> *
> - * Version: $Revision: 1.12 $ *
> + * Version: $Revision: 1.13 $ *
> ***************************************************************************/
>
>
> @@ -127,7 +127,9 @@
> int level,
> const char *what)
> {
> - if(l && l->level <= level && l->logger_private && what) {
> + if( l &&
> + (l->level <= level || level == JK_LOG_REQUEST_LEVEL) &&
> + l->logger_private && what) {
> unsigned sz = strlen(what);
> if(sz) {
> file_logger_t *p = l->logger_private;
> @@ -214,7 +216,7 @@
> return -1;
> }
>
> - if(l->level <= level) {
> + if((l->level <= level) || (level == JK_LOG_REQUEST_LEVEL)) {
> #ifdef NETWARE
> /* On NetWare, this can get called on a thread that has a limited stack so */
> /* we will allocate and free the temporary buffer in this function */
> @@ -236,7 +238,8 @@
> #ifdef WIN32
> set_time_str(buf, HUGE_BUFFER_SIZE);
> used = strlen(buf);
> - used += _snprintf(&buf[used], HUGE_BUFFER_SIZE, " [%s (%d)]: ", f, line);
>
> + if(line)
> + used += _snprintf(&buf[used], HUGE_BUFFER_SIZE, " [%s (%d)]: ", f,
>line);
> #elif defined(NETWARE) /* until we get a snprintf function */
> buf = (char *) malloc(HUGE_BUFFER_SIZE);
> if (NULL == buf)
> @@ -244,11 +247,13 @@
>
> set_time_str(buf, HUGE_BUFFER_SIZE);
> used = strlen(buf);
> - used += sprintf(&buf[used], " [%s (%d)]: ", f, line);
> + if(line)
> + used += sprintf(&buf[used], " [%s (%d)]: ", f, line);
> #else
> set_time_str(buf, HUGE_BUFFER_SIZE);
> used = strlen(buf);
> - used += snprintf(&buf[used], HUGE_BUFFER_SIZE, " [%s (%d)]: ", f, line);
>
> + if(line)
> + used += snprintf(&buf[used], HUGE_BUFFER_SIZE, " [%s (%d)]: ", f,
>line);
> #endif
> if(used < 0) {
> return 0; /* [V] not sure what to return... */
>
>
>
> 1.4 +76 -9 jakarta-tomcat-connectors/jk/doc/mod_jk-howto.html
>
> Index: mod_jk-howto.html
> ===================================================================
> RCS file: /home/cvs/jakarta-tomcat-connectors/jk/doc/mod_jk-howto.html,v
> retrieving revision 1.3
> retrieving revision 1.4
> diff -u -r1.3 -r1.4
> --- mod_jk-howto.html 22 Jun 2001 14:44:52 -0000 1.3
> +++ mod_jk-howto.html 21 Apr 2002 22:57:11 -0000 1.4
> @@ -71,6 +71,7 @@
> <li><a href="#s71">Removing mod_jserv directives</a></li>
> <li><a href="#s72">Configuring Apache to use mod_jk</a></li>
> <li><a href="#s73">Assigning URLs to be redirected to Tomcat</a></li>
> +<li><a href="#s74">Configuring Apache to serve static web application
>files</a></li>
> </ul></li>
> <li><a href="#s8">Configuring Tomcat</a>
> <ul>
> @@ -507,11 +508,35 @@
> <li>You should specify a location where mod_jk is going to place its log file
> and a log level to be used. Use the <tt>JkLogFile</tt> and
><tt>JkLogLevel</tt>
> configuration directives. Possible log levels are <i>debug</i>, <i>info</i>,
> - <i>error</i> and <i>emerg</i>, but <i>info</i> should be your default
> - selection.</li>
> + <i>error</i>, and <i>emerg</i>, but <i>info</i> should be your
> + default selection.</li>
> <li>The directive <tt>JkLogStampFormat</tt> will configure the date/time format
> found on mod_jk logfile. Using <tt>strftime()</tt> format string it's set by
> default to "[%a %b %d %H:%M:%S %Y] "</li>
> + <li>The directive <tt>JkRequestLogFormat</tt> will configure the format of mod_jk
> + individual request logging. Request logging is configured and enabled on a
>per
> + virtual host basis. To enable request logging for a virtual host just add
> + a JkRequestLogFormat config.
> + The syntax of the format string is similiar to the Apache LogFormat command,
> + here is a list of the avaialbe request log format options:
> + <ul>
> + <li>%b - Bytes sent, excluding HTTP headers. In CLF format</li>
> + <li>%B - Bytes sent, excluding HTTP headers.</li>
> + <li>%H - The request protocol</li>
> + <li>%m - The request method</li>
> + <li>%p - The canonical Port of the server serving the request</li>
> + <li>%q - The query string (prepended with a ? if a query string exists,
> + otherwise an empty string)</li>
> + <li>%r - First line of request</li>
> + <li>%s - request HTTP status code</li>
> + <li>%T - Requset duration, elapsed time to handle request in seconds '.'
> + micro seconds</li>
> + <li>%U - The URL path requested, not including any query string.</li>
> + <li>%v - The canonical ServerName of the server serving the request.</li>
> + <li>%V - The server name according to the UseCanonicalName setting.</li>
> + <li>%w - Tomcat worker name</li>
> + </ul>
> + </li>
> </ul>
> A simple example would be to include the following lines in your
><tt>httpd.conf</tt> file:
> <blockquote><pre>
> @@ -537,18 +562,59 @@
> </pre>
>
> <p>For example the following directives will send all requests ending in
> -<tt>.jsp</tt> or beginning with <tt>/servlet</tt> to the
>"<tt>ajp13</tt>" worker,
> -but jsp requests to files located in /otherworker will go to
>"<tt>remoteworker</tt>".
> +<tt>.jsp</tt> or with <tt>/servlet</tt> as the second path componenet to
> +the "<tt>ajp13</tt>" worker, but jsp requests to files located
> +in /otherworker will go to "<tt>remoteworker</tt>".
>
> <blockquote><pre>
> JkMount /*.jsp ajp13
> -JkMount /servlet/* ajp13
> +JkMount /*/servlet/ ajp13
> JkMount /otherworker/*.jsp remoteworker
> </pre></blockquote>
> You can use the <tt>JkMount</tt> directive at the top level or inside
><tt><VirtualHost></tt>
> sections of your httpd.conf file.
> </div>
>
> +<h3><a name="s74">Configuring Apache to serve static web application
>files</a></h3>
> +<div class=subsection>
> +<p>If the Tomcat Host appBase (webapps) directory is accessible by the Apache
> +web server, Apache can be configured to serve web application context directory
> +static files instead of passing the request to Tomcat.</p>
> +
> +<p><b>Caution:</b> If Apache is configured to serve static pages for a web
> +application it bypasses any security contraints you may have configured in
> +your web application web.xml config file.</p>
> +
> +<p>Use Apache's Alias directive to map a single web application context directory
> +into Apache's document space for a VirtualHost:
> +
> +<pre>
> +# Static files in the examples webapp are served by apache
> +Alias /examples /export/home/web/host1/webapps/examples
> +
> +JkMount /*.jsp ajp13
> +JkMount /*/servlet/ ajp13
> +</pre>
> +</p>
> +
> +<p>Use the mod_jk JkAutoAlias directive to map all web application context
> +directories into Apache's document space. Attempts to access the
><code>WEB-INF</code>
> +or <code>META-INF</code> directories within a web application context or a
> +Web Archive <code>*.war</code> within the Tomcat Host appBase (webapps) directory
> +will fail with an HTTP 403, Access Forbidden.</p>
> +<p>
> +Example configuration for an Apache VirtualHost:
> +
> +<pre>
> +# Static files in all Tomcat webapp context directories are served by apache
> +JkAutoAlias /export/home/web/host2/webapps
> +
> +JkMount /*.jsp ajp13
> +JkMount /*/servlet/ ajp13
> +</pre>
> +</p>
> +</div>
> +
> <hr>
> <h2><a name="s8">Configuring Tomcat</a></h2>
>
> @@ -741,13 +807,14 @@
> JkLogFile /usr/local/apache/logs/mod_jk.log
> JkLogLevel info
>
> -# First Virtual Host.
> +# First Virtual Host. Request logging is enabled.
> #
> <VirtualHost 10.0.0.1:80>
> DocumentRoot /web/host1
> ServerName host1.apache.org
> + JkRequestLogFormat "%w \"%r\" %s %T"
> JkMount /*.jsp ajp13
> - JkMount /servlet/* ajp13
> + JkMount /*/servlet/ ajp13
> </VirtualHost>
>
> # Second Virtual Host. Also accessible via HTTPS
> @@ -756,7 +823,7 @@
> DocumentRoot /web/host2
> ServerName host2.apache.org
> JkMount /*.jsp ajp13
> - JkMount /servlet/* ajp13
> + JkMount /*/servlet/ ajp13
> </VirtualHost>
>
> <VirtualHost 10.0.0.2:443>
> @@ -764,7 +831,7 @@
> ServerName host2.apache.org
> SSLEngine On
> JkMount /*.jsp ajp13
> - JkMount /servlet/* ajp13
> + JkMount /*/servlet/ ajp13
> </VirtualHost>
>
> </pre></blockquote>
>
>
>
>
> --
> To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
>
>
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>