/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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.
 */

/***************************************************************************
 * Description: Apache 2 plugin for Tomcat                                 *
 * Author:      Gal Shachor <shachor@il.ibm.com>                           *
 *              Henri Gomez <hgomez@apache.org>                            *
 * Version:     $Revision$                                          *
 ***************************************************************************/

/*
 * mod_jk: keeps all servlet related ramblings together.
 */

#include "ap_config.h"
#include "apr_lib.h"
#include "apr_date.h"
#include "apr_file_info.h"
#include "apr_file_io.h"
#include "httpd.h"
#include "http_config.h"
#include "http_request.h"
#include "http_core.h"
#include "http_protocol.h"
#include "http_main.h"
#include "http_log.h"
#include "util_script.h"
#include "ap_mpm.h"

#if defined(AS400) && !defined(AS400_UTF8)
#include "ap_charset.h"
#include "util_charset.h"       /* ap_hdrs_from_ascii */
#endif

/* moved to apr since http-2.0.19-dev */
#if (MODULE_MAGIC_NUMBER_MAJOR < 20010523)
#define apr_date_parse_http ap_parseHTTPdate
#include "util_date.h"
#endif

/* deprecated with apr 0.9.3 */

#include "apr_version.h"
#if (APR_MAJOR_VERSION == 0) && \
    (APR_MINOR_VERSION <= 9) && \
    (APR_PATCH_VERSION < 3)
#define apr_filepath_name_get apr_filename_of_pathname
#endif

#include "apr_strings.h"

/* Yes; sorta sucks - with luck we will clean this up before httpd-2.2
 * ships, leaving AP_NEED_SET_MUTEX_PERMS def'd as 1 or 0 on all platforms.
 */
#ifdef AP_NEED_SET_MUTEX_PERMS
# define JK_NEED_SET_MUTEX_PERMS AP_NEED_SET_MUTEX_PERMS
#else
  /* A special case for httpd-2.0 */
# if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) && !defined(AS400)
#  define JK_NEED_SET_MUTEX_PERMS 1
# else
#  define JK_NEED_SET_MUTEX_PERMS 0
# endif
#endif

#if JK_NEED_SET_MUTEX_PERMS
#include "unixd.h"      /* for unixd_set_global_mutex_perms */
#endif
/*
 * jk_ include files
 */
#ifdef NETWARE
#define __sys_types_h__
#define __sys_socket_h__
#define __netdb_h__
#define __netinet_in_h__
#define __arpa_inet_h__
#define __sys_timeval_h__
#endif

#include "jk_global.h"
#include "jk_ajp13.h"
#include "jk_logger.h"
#include "jk_map.h"
#include "jk_pool.h"
#include "jk_service.h"
#include "jk_uri_worker_map.h"
#include "jk_util.h"
#include "jk_worker.h"
#include "jk_shm.h"
#include "jk_url.h"

#define JK_LOG_DEF_FILE             ("logs/mod_jk.log")
#define JK_SHM_DEF_FILE             ("logs/jk-runtime-status")
#define JK_ENV_HTTPS                ("HTTPS")
#define JK_ENV_CERTS                ("SSL_CLIENT_CERT")
#define JK_ENV_CIPHER               ("SSL_CIPHER")
#define JK_ENV_SESSION              ("SSL_SESSION_ID")
#define JK_ENV_KEY_SIZE             ("SSL_CIPHER_USEKEYSIZE")
#define JK_ENV_CERTCHAIN_PREFIX     ("SSL_CLIENT_CERT_CHAIN_")
#define JK_ENV_WORKER_NAME          ("JK_WORKER_NAME")
#define JK_NOTE_WORKER_NAME         ("JK_WORKER_NAME")
#define JK_NOTE_WORKER_TYPE         ("JK_WORKER_TYPE")
#define JK_NOTE_REQUEST_DURATION    ("JK_REQUEST_DURATION")
#define JK_NOTE_WORKER_ROUTE        ("JK_WORKER_ROUTE")
#define JK_HANDLER          ("jakarta-servlet")
#define JK_MAGIC_TYPE       ("application/x-jakarta-servlet")
#define NULL_FOR_EMPTY(x)   ((x && !strlen(x)) ? NULL : x)
#define STRNULL_FOR_NULL(x) ((x) ? (x) : "(null)")
/*
 * If you are not using SSL, comment out the following line. It will make
 * apache run faster.
 *
 * Personally, I (DM), think this may be a lie.
 */
#define ADD_SSL_INFO

/* module MODULE_VAR_EXPORT jk_module; */
AP_MODULE_DECLARE_DATA module jk_module;

/*
 * Environment variable forward object
 */
typedef struct
{
    int has_default;
    char *name;
    char *value;
} envvar_item;

/*
 * Configuration object for the mod_jk module.
 */
typedef struct
{

    /*
     * Log stuff
     */
    char *log_file;
    int log_level;
    jk_logger_t *log;
    apr_file_t *jklogfp;

    /*
     * Worker stuff
     */
    jk_map_t *worker_properties;
    char *worker_file;
    char *mount_file;
    int mount_file_reload;
    jk_map_t *uri_to_context;

    int mountcopy;
    char *secret_key;
    jk_map_t *automount;

    jk_uri_worker_map_t *uw_map;

    int was_initialized;

    /*
     * Automatic context path apache alias
     */
    char *alias_dir;

    /*
     * Request Logging
     */

    char *stamp_format_string;
    char *format_string;
    apr_array_header_t *format;

    /*
     * Setting target worker via environment
     */
    char *worker_indicator;

    /*
     * SSL Support
     */
    int ssl_enable;
    char *https_indicator;
    char *certs_indicator;
    char *cipher_indicator;
    char *session_indicator;    /* Servlet API 2.3 requirement */
    char *key_size_indicator;   /* Servlet API 2.3 requirement */
    char *certchain_prefix;     /* Client certificate chain prefix */

    /*
     * Jk Options
     */
    int options;
    int exclude_options;

    int strip_session;
    /*
     * Environment variables support
     */
    int envvars_in_use;
    apr_table_t *envvars;
    apr_table_t *envvars_def;
    apr_array_header_t *envvar_items;

    server_rec *s;
} jk_server_conf_t;

struct apache_private_data
{
    jk_pool_t p;

    int response_started;
    int read_body_started;
    request_rec *r;
};
typedef struct apache_private_data apache_private_data_t;

static jk_logger_t *main_log = NULL;
static apr_hash_t *jk_log_fps = NULL;
static jk_worker_env_t worker_env;
static apr_global_mutex_t *jk_log_lock = NULL;
static char *jk_shm_file = NULL;
static size_t jk_shm_size = JK_SHM_DEF_SIZE;

static int JK_METHOD ws_start_response(jk_ws_service_t *s,
                                       int status,
                                       const char *reason,
                                       const char *const *header_names,
                                       const char *const *header_values,
                                       unsigned num_of_headers);

static int JK_METHOD ws_read(jk_ws_service_t *s,
                             void *b, unsigned len, unsigned *actually_read);

static int init_jk(apr_pool_t * pconf, jk_server_conf_t * conf,
                    server_rec * s);

static int JK_METHOD ws_write(jk_ws_service_t *s, const void *b, unsigned l);

static void JK_METHOD ws_add_log_items(jk_ws_service_t *s,
                                       const char *const *log_names,
                                       const char *const *log_values,
                                       unsigned num_of_log_items);

/* ========================================================================= */
/* JK Service step callbacks                                                 */
/* ========================================================================= */

static int JK_METHOD ws_start_response(jk_ws_service_t *s,
                                       int status,
                                       const char *reason,
                                       const char *const *header_names,
                                       const char *const *header_values,
                                       unsigned num_of_headers)
{
    unsigned h;
    apache_private_data_t *p = s->ws_private;
    request_rec *r = p->r;

    if (!reason) {
        reason = "";
    }
    r->status = status;
    r->status_line = apr_psprintf(r->pool, "%d %s", status, reason);

    for (h = 0; h < num_of_headers; h++) {
        if (!strcasecmp(header_names[h], "Content-type")) {
            char *tmp = apr_pstrdup(r->pool, header_values[h]);
            ap_content_type_tolower(tmp);
            /* It should be done like this in Apache 2.0 */
            /* This way, Apache 2.0 will be able to set the output filter */
            /* and it make jk useable with deflate using */
            /* AddOutputFilterByType DEFLATE text/html */
            ap_set_content_type(r, tmp);
        }
        else if (!strcasecmp(header_names[h], "Location")) {
#if defined(AS400) && !defined(AS400_UTF8)
            /* Fix escapes in Location Header URL */
            ap_fixup_escapes((char *)header_values[h],
                             strlen(header_values[h]), ap_hdrs_from_ascii);
#endif
            apr_table_set(r->headers_out, header_names[h], header_values[h]);
        }
        else if (!strcasecmp(header_names[h], "Content-Length")) {
            apr_table_set(r->headers_out, header_names[h], header_values[h]);
        }
        else if (!strcasecmp(header_names[h], "Transfer-Encoding")) {
            apr_table_set(r->headers_out, header_names[h], header_values[h]);
        }
        else if (!strcasecmp(header_names[h], "Last-Modified")) {
            /*
             * If the script gave us a Last-Modified header, we can't just
             * pass it on blindly because of restrictions on future values.
             */
            ap_update_mtime(r, apr_date_parse_http(header_values[h]));
            ap_set_last_modified(r);
        }
        else {
            apr_table_add(r->headers_out, header_names[h], header_values[h]);
        }
    }

    /* this NOP function was removed in apache 2.0 alpha14 */
    /* ap_send_http_header(r); */
    p->response_started = JK_TRUE;

	/* hgomez@20070516: under i5/OS this flag is not set correctly */
	/* We should check with Rochester Labs what could be the problem */
#ifdef AS400
        r->sent_bodyct = 1;
#endif

    return JK_TRUE;
}

/*
 * Read a chunk of the request body into a buffer.  Attempt to read len
 * bytes into the buffer.  Write the number of bytes actually read into
 * actually_read.
 *
 * Think of this function as a method of the apache1.3-specific subclass of
 * the jk_ws_service class.  Think of the *s param as a "this" or "self"
 * pointer.
 */
static int JK_METHOD ws_read(jk_ws_service_t *s,
                             void *b, unsigned len, unsigned *actually_read)
{
    if (s && s->ws_private && b && actually_read) {
        apache_private_data_t *p = s->ws_private;
        if (!p->read_body_started) {
            if (ap_should_client_block(p->r)) {
                p->read_body_started = JK_TRUE;
            }
        }

        if (p->read_body_started) {
#if defined(AS400) && !defined(AS400_UTF8)
            int long rv = OK;
            if (rv = ap_change_request_body_xlate(p->r, 65535, 65535)) {        /* turn off request body translation */
                ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_CRIT, 0, NULL,
                             "mod_jk: Error on ap_change_request_body_xlate, rc=%d",
                             rv);
                return JK_FALSE;
            }
#else
            long rv;
#endif

            if ((rv = ap_get_client_block(p->r, b, len)) < 0) {
                *actually_read = 0;
            }
            else {
                *actually_read = (unsigned)rv;
            }
            return JK_TRUE;
        }
    }
    return JK_FALSE;
}

static void JK_METHOD ws_flush(jk_ws_service_t *s)
{
#if defined(AS400) && !defined(AS400_UTF8)
    if (s && s->ws_private) {
        apache_private_data_t *p = s->ws_private;
        ap_rflush(p->r);
    }
#endif
}

/*
 * Write a chunk of response data back to the browser.  If the headers
 * haven't yet been sent over, send over default header values (Status =
 * 200, basically).
 *
 * Write len bytes from buffer b.
 *
 * Think of this function as a method of the apache1.3-specific subclass of
 * the jk_ws_service class.  Think of the *s param as a "this" or "self"
 * pointer.
 */
/* Works with 4096, fails with 8192 */
#ifndef CHUNK_SIZE
#define CHUNK_SIZE 4096
#endif

static int JK_METHOD ws_write(jk_ws_service_t *s, const void *b, unsigned int l)
{
#if defined(AS400) && !defined(AS400_UTF8)
    int rc;
#endif

    if (s && s->ws_private && b) {
        apache_private_data_t *p = s->ws_private;

        if (l) {
            /* BUFF *bf = p->r->connection->client; */
            int r = 0;
            int ll = l;
            const char *bb = (const char *)b;

            if (!p->response_started) {
                if (main_log)
                    jk_log(main_log, JK_LOG_INFO,
                           "Write without start, starting with defaults");
                if (!s->start_response(s, 200, NULL, NULL, NULL, 0)) {
                    return JK_FALSE;
                }
            }
            if (p->r->header_only) {
#if defined(AS400) && !defined(AS400_UTF8)
                ap_rflush(p->r);
#endif
                return JK_TRUE;
            }
#if defined(AS400) && !defined(AS400_UTF8)
            /* turn off response body translation */
            rc = ap_change_response_body_xlate(p->r, 65535, 65535);
            if (rc) {
                ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_CRIT, 0, NULL,
                             "mod_jk: Error on ap_change_response_body_xlate, rc=%d",
                             rc);
                return JK_FALSE;
            }
#endif

            while (ll > 0 && !p->r->connection->aborted) {
#if 0
                /* Apache 2 output filter does not write
                 * directly to the wire.
                 */
                int toSend = (ll > CHUNK_SIZE) ? CHUNK_SIZE : ll;
                r = ap_rwrite(bb, toSend, p->r);
#else
                r = ap_rwrite(bb, ll, p->r);
#endif
                if (JK_IS_DEBUG_LEVEL(main_log))
                    jk_log(main_log, JK_LOG_DEBUG,
                           "written %d out of %d", r, ll);

                if (r < 0)
                    return JK_FALSE;
                ll -= r;
                bb += r;
            }
            if (ll && p->r->connection->aborted) {
                /* Fail if there is something left to send and
                 * the connection was aborted by the client
                 */
                return JK_FALSE;
            }
        }

        return JK_TRUE;
    }
    return JK_FALSE;
}

static void JK_METHOD ws_add_log_items(jk_ws_service_t *s,
                                       const char *const *log_names,
                                       const char *const *log_values,
                                       unsigned num_of_log_items)
{
    unsigned h;
    apache_private_data_t *p = s->ws_private;
    request_rec *r = p->r;

    for (h = 0; h < num_of_log_items; h++) {
        if (log_names[h] && log_values[h]) {
            apr_table_setn(r->notes, log_names[h], log_values[h]);
        }
    }
}

/* ========================================================================= */
/* Utility functions                                                         */
/* ========================================================================= */

/* ========================================================================= */
/* Log something to Jk log file then exit */
static void jk_error_exit(const char *file,
                          int line,
                          int level,
                          const server_rec * s,
                          apr_pool_t * p, const char *fmt, ...)
{
    va_list ap;
    char *res;

    va_start(ap, fmt);
    res = apr_pvsprintf(s->process->pool, fmt, ap);
    va_end(ap);

    ap_log_error(file, line, level, 0, s, res);
    if ( s ) {
        ap_log_error(file, line, level, 0, NULL, res);
    }

    /* Exit process */
    exit(1);
}

static int get_content_length(request_rec * r)
{
    if (r->clength > 0) {
        return (int)r->clength;
    }
    else if (r->main == NULL || r->main == r) {
        char *lenp = (char *)apr_table_get(r->headers_in, "Content-Length");

        if (lenp) {
            int rc = atoi(lenp);
            if (rc > 0) {
                return rc;
            }
        }
    }

    return 0;
}

static int init_ws_service(apache_private_data_t * private_data,
                           jk_ws_service_t *s, jk_server_conf_t * conf)
{
    request_rec *r = private_data->r;

    char *ssl_temp = NULL;
    int size;
    s->route = NULL;        /* Used for sticky session routing */

    /* Copy in function pointers (which are really methods) */
    s->start_response = ws_start_response;
    s->read = ws_read;
    s->write = ws_write;
    s->flush = ws_flush;
    s->add_log_items = ws_add_log_items;

    /* Clear RECO status */
    s->reco_status = RECO_NONE;

    s->auth_type = NULL_FOR_EMPTY(r->ap_auth_type);
    s->remote_user = NULL_FOR_EMPTY(r->user);

    s->protocol = r->protocol;
    s->remote_host = (char *)ap_get_remote_host(r->connection,
                                                r->per_dir_config,
                                                REMOTE_HOST, NULL);
    s->remote_host = NULL_FOR_EMPTY(s->remote_host);
    if (conf->options & JK_OPT_FWDLOCAL)
        s->remote_addr = NULL_FOR_EMPTY(r->connection->local_ip);
    else
        s->remote_addr = NULL_FOR_EMPTY(r->connection->remote_ip);
    if (conf->options & JK_OPT_FLUSHPACKETS)
        s->flush_packets = 1;
    else
        s->flush_packets = 0;
    if (conf->options & JK_OPT_FLUSHEADER)
        s->flush_header = 1;
    else
        s->flush_header = 0;

    if (conf->options & JK_OPT_DISABLEREUSE)
        s->disable_reuse = 1;
    else
        s->disable_reuse = 0;

    /* get server name */
    s->server_name = (char *)ap_get_server_name(r);

    /* get the real port (otherwise redirect failed) */
    /* XXX: use apache API for getting server port
     *
     * Pre 1.2.7 versions used:
     * s->server_port = r->connection->local_addr->port;
     */
    s->server_port  = ap_get_server_port(r);

#if (AP_MODULE_MAGIC_AT_LEAST(20060905,0))
    s->server_software = (char *)ap_get_server_description();
#else
    s->server_software = (char *)ap_get_server_version();
#endif
    s->method = (char *)r->method;
    s->content_length = get_content_length(r);
    s->is_chunked = r->read_chunked;
    s->no_more_chunks = 0;
#if defined(AS400) && !defined(AS400_UTF8)
    /* Get the query string that is not translated to EBCDIC  */
    s->query_string = ap_get_original_query_string(r);
#else
    s->query_string = r->args;
#endif

    /* Dump all connection param so we can trace what's going to
     * the remote tomcat
     */
    if (JK_IS_DEBUG_LEVEL(conf->log)) {
        jk_log(conf->log, JK_LOG_DEBUG,
               "Service protocol=%s method=%s host=%s addr=%s name=%s port=%d auth=%s user=%s laddr=%s raddr=%s",
               STRNULL_FOR_NULL(s->protocol),
               STRNULL_FOR_NULL(s->method),
               STRNULL_FOR_NULL(s->remote_host),
               STRNULL_FOR_NULL(s->remote_addr),
               STRNULL_FOR_NULL(s->server_name),
               s->server_port,
               STRNULL_FOR_NULL(s->auth_type),
               STRNULL_FOR_NULL(s->remote_user),
               STRNULL_FOR_NULL(r->connection->local_ip),
               STRNULL_FOR_NULL(r->connection->remote_ip));
    }

    /*
     * The 2.2 servlet spec errata says the uri from
     * HttpServletRequest.getRequestURI() should remain encoded.
     * [http://java.sun.com/products/servlet/errata_042700.html]
     *
     * We use JkOptions to determine which method to be used
     *
     * ap_escape_uri is the latest recommanded but require
     *               some java decoding (in TC 3.3 rc2)
     *
     * unparsed_uri is used for strict compliance with spec and
     *              old Tomcat (3.2.3 for example)
     *
     * uri is use for compatibilty with mod_rewrite with old Tomcats
     */

    switch (conf->options & JK_OPT_FWDURIMASK) {

    case JK_OPT_FWDURICOMPATUNPARSED:
        s->req_uri = r->unparsed_uri;
        if (s->req_uri != NULL) {
            char *query_str = strchr(s->req_uri, '?');
            if (query_str != NULL) {
                *query_str = 0;
            }
        }

        break;

    case JK_OPT_FWDURICOMPAT:
        s->req_uri = r->uri;
        break;

    case JK_OPT_FWDURIPROXY:
        size = strlen(r->uri);
        s->req_uri = apr_palloc(r->pool, size * 3 + 1);
        jk_canonenc(s->req_uri, r->uri, size, enc_path, 0, 
                    JK_PROXYREQ_REVERSE);
        break;

    case JK_OPT_FWDURIESCAPED:
        s->req_uri = ap_escape_uri(r->pool, r->uri);
        break;

    default:
        return JK_FALSE;
    }

    s->is_ssl = JK_FALSE;
    s->ssl_cert = NULL;
    s->ssl_cert_len = 0;
    s->ssl_cipher = NULL;       /* required by Servlet 2.3 Api,
                                   allready in original ajp13 */
    s->ssl_session = NULL;
    s->ssl_key_size = -1;       /* required by Servlet 2.3 Api, added in jtc */

    if (conf->ssl_enable || conf->envvars_in_use) {
        ap_add_common_vars(r);

        if (conf->ssl_enable) {
            ssl_temp =
                (char *)apr_table_get(r->subprocess_env,
                                      conf->https_indicator);
            if (ssl_temp && !strcasecmp(ssl_temp, "on")) {
                s->is_ssl = JK_TRUE;
                s->ssl_cert =
                    (char *)apr_table_get(r->subprocess_env,
                                          conf->certs_indicator);

                if (conf->options & JK_OPT_FWDCERTCHAIN) {
                    const apr_array_header_t *t = apr_table_elts(r->subprocess_env);
                    if (t && t->nelts) {
                        int i;
                        const apr_table_entry_t *elts = (const apr_table_entry_t *) t->elts;
                        apr_array_header_t *certs = apr_array_make(r->pool, 1, sizeof(char *));
                        *(const char **)apr_array_push(certs) = s->ssl_cert;
                        for (i = 0; i < t->nelts; i++) {
                            if (!elts[i].key)
                                continue;
                            if (!strncasecmp(elts[i].key, conf->certchain_prefix,
                                             strlen(conf->certchain_prefix)))
                                *(const char **)apr_array_push(certs) = elts[i].val;
                        }
                        s->ssl_cert = apr_array_pstrcat(r->pool, certs, '\0');
                    }
                }

                if (s->ssl_cert) {
                    s->ssl_cert_len = strlen(s->ssl_cert);
                    if (JK_IS_DEBUG_LEVEL(conf->log)) {
                        jk_log(conf->log, JK_LOG_DEBUG,
                               "SSL client certificate (%d bytes): %s",
                               s->ssl_cert_len, s->ssl_cert);
                    }
                }
                /* Servlet 2.3 API */
                s->ssl_cipher =
                    (char *)apr_table_get(r->subprocess_env,
                                          conf->cipher_indicator);
                s->ssl_session =
                    (char *)apr_table_get(r->subprocess_env,
                                          conf->session_indicator);

                if (conf->options & JK_OPT_FWDKEYSIZE) {
                    /* Servlet 2.3 API */
                    ssl_temp = (char *)apr_table_get(r->subprocess_env,
                                                     conf->
                                                     key_size_indicator);
                    if (ssl_temp)
                        s->ssl_key_size = atoi(ssl_temp);
                }


            }
        }

        if (conf->envvars_in_use) {
            const apr_array_header_t *t = conf->envvar_items;
            if (t && t->nelts) {
                int i;
                int j = 0;
                envvar_item *elts = (envvar_item *) t->elts;
                s->attributes_names = apr_palloc(r->pool,
                                                 sizeof(char *) * t->nelts);
                s->attributes_values = apr_palloc(r->pool,
                                                  sizeof(char *) * t->nelts);

                for (i = 0; i < t->nelts; i++) {
                    s->attributes_names[i - j] = elts[i].name;
                    s->attributes_values[i - j] =
                        (char *)apr_table_get(r->subprocess_env, elts[i].name);
                    if (!s->attributes_values[i - j]) {
                        if (elts[i].has_default) {
                            s->attributes_values[i - j] = elts[i].value;
                        }
                        else {
                            s->attributes_values[i - j] = "";
                            s->attributes_names[i - j] = "";
                            j++;
                        }
                    }
                }

                s->num_attributes = t->nelts - j;
            }
        }
    }

    s->headers_names = NULL;
    s->headers_values = NULL;
    s->num_headers = 0;
    if (r->headers_in && apr_table_elts(r->headers_in)) {
        int need_content_length_header = (!s->is_chunked
                                          && s->content_length ==
                                          0) ? JK_TRUE : JK_FALSE;
        const apr_array_header_t *t = apr_table_elts(r->headers_in);
        if (t && t->nelts) {
            int i;
            apr_table_entry_t *elts = (apr_table_entry_t *) t->elts;
            s->num_headers = t->nelts;
            /* allocate an extra header slot in case we need to add a content-length header */
            s->headers_names =
                apr_palloc(r->pool, sizeof(char *) * (t->nelts + 1));
            s->headers_values =
                apr_palloc(r->pool, sizeof(char *) * (t->nelts + 1));
            if (!s->headers_names || !s->headers_values)
                return JK_FALSE;
            for (i = 0; i < t->nelts; i++) {
                char *hname = apr_pstrdup(r->pool, elts[i].key);
                s->headers_values[i] = apr_pstrdup(r->pool, elts[i].val);
                s->headers_names[i] = hname;
                if (need_content_length_header &&
                    !strcasecmp(s->headers_names[i], "content-length")) {
                    need_content_length_header = JK_FALSE;
                }
            }
            /* Add a content-length = 0 header if needed.
             * Ajp13 assumes an absent content-length header means an unknown,
             * but non-zero length body.
             */
            if (need_content_length_header) {
                s->headers_names[s->num_headers] = "content-length";
                s->headers_values[s->num_headers] = "0";
                s->num_headers++;
            }
        }
        /* Add a content-length = 0 header if needed. */
        else if (need_content_length_header) {
            s->headers_names = apr_palloc(r->pool, sizeof(char *));
            s->headers_values = apr_palloc(r->pool, sizeof(char *));
            if (!s->headers_names || !s->headers_values)
                return JK_FALSE;
            s->headers_names[0] = "content-length";
            s->headers_values[0] = "0";
            s->num_headers++;
        }
    }
    s->uw_map = conf->uw_map;
    return JK_TRUE;
}

/*
 * The JK module command processors
 *
 * The below are all installed so that Apache calls them while it is
 * processing its config files.  This allows configuration info to be
 * copied into a jk_server_conf_t object, which is then used for request
 * filtering/processing.
 *
 * See jk_cmds definition below for explanations of these options.
 */

/*
 * JkMountCopy directive handling
 *
 * JkMountCopy On/Off
 */

static const char *jk_set_mountcopy(cmd_parms * cmd, void *dummy, int flag)
{
    server_rec *s = cmd->server;
    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);

    /* Set up our value */
    conf->mountcopy = flag ? JK_TRUE : JK_FALSE;

    return NULL;
}

/*
 * JkMount directive handling
 *
 * JkMount URI(context) worker
 */

static const char *jk_mount_context(cmd_parms * cmd,
                                    void *dummy,
                                    const char *context,
                                    const char *worker)
{
    server_rec *s = cmd->server;
    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);
    const char *c, *w;

    if (worker != NULL && cmd->path == NULL ) {
        c = context;
        w = worker;
    }
    else if (worker == NULL && cmd->path != NULL) {
        c = cmd->path;
        w = context;
    }
    else {
        if (worker == NULL)
            return "JkMount needs a path when not defined in a location";
        else
            return "JkMount can not have a path when defined in a location";
    }

    if (c[0] != '/')
        return "JkMount context should start with /";

    /*
     * Add the new worker to the alias map.
     */
    jk_map_put(conf->uri_to_context, c, w, NULL);
    return NULL;
}

/*
 * JkUnMount directive handling
 *
 * JkUnMount URI(context) worker
 */

static const char *jk_unmount_context(cmd_parms * cmd,
                                      void *dummy,
                                      const char *context,
                                      const char *worker)
{
    server_rec *s = cmd->server;
    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);
    char *uri;
    const char *c, *w;

    if (worker != NULL && cmd->path == NULL ) {
        c = context;
        w = worker;
    }
    else if (worker == NULL && cmd->path != NULL) {
        c = cmd->path;
        w = context;
    }
    else {
        if (worker == NULL)
            return "JkUnMount needs a path when not defined in a location";
        else
            return "JkUnMount can not have a path when defined in a location";
    }

    if (c[0] != '/')
        return "JkUnMount context should start with /";

    uri = apr_pstrcat(cmd->temp_pool, "!", c, NULL);
    /*
     * Add the new worker to the alias map.
     */
    jk_map_put(conf->uri_to_context, uri, w, NULL);
    return NULL;
}


/*
 * JkAutoMount directive handling
 *
 * JkAutoMount worker [virtualhost]
 * This is an experimental and undocumented extension made in j-t-c/jk.
 */
static const char *jk_automount_context(cmd_parms * cmd,
                                        void *dummy,
                                        const char *worker,
                                        const char *virtualhost)
{
    server_rec *s = cmd->server;
    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);

    /*
     * Add the new automount to the auto map.
     */
    jk_map_put(conf->automount, worker, virtualhost, NULL);
    return NULL;
}

/*
 * JkWorkersFile Directive Handling
 *
 * JkWorkersFile file
 */

static const char *jk_set_worker_file(cmd_parms * cmd,
                                      void *dummy, const char *worker_file)
{
    server_rec *s = cmd->server;
    struct stat statbuf;

    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);

    const char *err_string = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    if (err_string != NULL) {
        return err_string;
    }

    /* we need an absolute path (ap_server_root_relative does the ap_pstrdup) */
    conf->worker_file = ap_server_root_relative(cmd->pool, worker_file);

    if (conf->worker_file == NULL)
        return "JkWorkersFile file name invalid";

    if (jk_file_exists(conf->worker_file) != JK_TRUE)
        return "Can't find the workers file specified";

    return NULL;
}

/*
 * JkMountFile Directive Handling
 *
 * JkMountFile file
 */

static const char *jk_set_mount_file(cmd_parms * cmd,
                                     void *dummy, const char *mount_file)
{
    server_rec *s = cmd->server;
    struct stat statbuf;

    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);

    /* we need an absolute path (ap_server_root_relative does the ap_pstrdup) */
    conf->mount_file = ap_server_root_relative(cmd->pool, mount_file);

    if (conf->mount_file == NULL)
        return "JkMountFile file name invalid";

    if (jk_file_exists(conf->mount_file) != JK_TRUE)
        return "Can't find the mount file specified";

    return NULL;
}

/*
 * JkMountFileReload Directive Handling
 *
 * JkMountFileReload seconds
 */

static const char *jk_set_mount_file_reload(cmd_parms * cmd,
                                            void *dummy, const char *mount_file_reload)
{
    server_rec *s = cmd->server;
    int interval;

    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);

    interval = atoi(mount_file_reload);
    if (interval < 0) {
        interval = 0;
    }

    conf->mount_file_reload = interval;

    return NULL;
}

/*
 * JkLogFile Directive Handling
 *
 * JkLogFile file
 */

static const char *jk_set_log_file(cmd_parms * cmd,
                                   void *dummy, const char *log_file)
{
    server_rec *s = cmd->server;
    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);

    /* we need an absolute path */
    if (*log_file != '|')
        conf->log_file = ap_server_root_relative(cmd->pool, log_file);
    else
        conf->log_file = apr_pstrdup(cmd->pool, log_file);

    if (conf->log_file == NULL)
        return "JkLogFile file name invalid";

    return NULL;
}

/*
 * JkShmFile Directive Handling
 *
 * JkShmFile file
 */

static const char *jk_set_shm_file(cmd_parms * cmd,
                                   void *dummy, const char *shm_file)
{
    const char *err_string = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    if (err_string != NULL) {
        return err_string;
    }

    /* we need an absolute path */
    jk_shm_file = ap_server_root_relative(cmd->pool, shm_file);
    if (jk_shm_file == NULL)
        return "JkShmFile file name invalid";

    return NULL;
}

/*
 * JkShmSize Directive Handling
 *
 * JkShmSize size in kilobytes
 */

static const char *jk_set_shm_size(cmd_parms * cmd,
                                   void *dummy, const char *shm_size)
{
    int sz = 0;
    const char *err_string = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    if (err_string != NULL) {
        return err_string;
    }

    sz = atoi(shm_size) * 1024;
    if (sz < JK_SHM_DEF_SIZE)
        sz = JK_SHM_DEF_SIZE;
    else
        sz = JK_SHM_ALIGN(sz);
    jk_shm_size = (size_t)sz;
    return NULL;
}

/*
 * JkLogLevel Directive Handling
 *
 * JkLogLevel debug/info/error/emerg
 */

static const char *jk_set_log_level(cmd_parms * cmd,
                                    void *dummy, const char *log_level)
{
    server_rec *s = cmd->server;
    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);

    conf->log_level = jk_parse_log_level(log_level);

    return NULL;
}

/*
 * JkLogStampFormat Directive Handling
 *
 * JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
 */

static const char *jk_set_log_fmt(cmd_parms * cmd,
                                  void *dummy, const char *log_format)
{
    server_rec *s = cmd->server;
    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);

    conf->stamp_format_string = apr_pstrdup(cmd->pool, log_format);

    return NULL;
}


/*
 * JkAutoAlias Directive Handling
 *
 * JkAutoAlias application directory
 */

static const char *jk_set_auto_alias(cmd_parms * cmd,
                                     void *dummy, const 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 = apr_pstrdup(cmd->pool, directory);

    if (conf->alias_dir == NULL)
        return "JkAutoAlias directory invalid";

    return NULL;
}

/*
 * JkStripSession directive handling
 *
 * JkStripSession On/Off
 */

static const char *jk_set_strip_session(cmd_parms * cmd, void *dummy, int flag)
{
    server_rec *s = cmd->server;
    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);

    /* Set up our value */
    conf->strip_session = flag ? JK_TRUE : JK_FALSE;

    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 void 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;
    apr_array_header_t *format = conf->format;

    strs = apr_palloc(r->pool, sizeof(char *) * (format->nelts));
    strl = apr_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 = apr_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, JK_LOG_REQUEST, "%s", str);

}

/*****************************************************************
 *
 * Parsing the log format string
 */

static char *format_integer(apr_pool_t * p, int i)
{
    return apr_psprintf(p, "%d", i);
}

static char *pfmt(apr_pool_t * 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 apr_table_get(r->notes, JK_NOTE_WORKER_NAME);
}

static const char *log_worker_route(request_rec * r, char *a)
{
    return apr_table_get(r->notes, JK_NOTE_WORKER_ROUTE);
}


static const char *log_request_duration(request_rec * r, char *a)
{
    return apr_table_get(r->notes, JK_NOTE_REQUEST_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) ? apr_pstrcat(r->pool, r->method, " ",
                                                  apr_uri_unparse(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 apr_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) ? apr_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 {
        return apr_off_t_toa(r->pool, r->bytes_sent);
    }
}

static const char *log_bytes_sent(request_rec * r, char *a)
{
    if (!r->sent_bodyct) {
        return "0";
    }
    else {
        return apr_psprintf(r->pool, "%" APR_OFF_T_FMT, r->bytes_sent);
    }
}

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}, {
    'R', log_worker_route}, {
    '\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(apr_pool_t * 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 = apr_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(apr_pool_t * p,
                                    request_log_format_item * it,
                                    const char **sa)
{
    const char *s = *sa;
    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 apr_pstrcat(p, "Unrecognized JkRequestLogFormat directive %",
                           dummy, NULL);
    }
    it->func = l->func;
    *sa = s;
    return NULL;
}

static apr_array_header_t *parse_request_log_string(apr_pool_t * p,
                                                    const char *s,
                                                    const char **err)
{
    apr_array_header_t *a =
        apr_array_make(p, 15, sizeof(request_log_format_item));
    char *res;

    while (*s) {
        if ((res =
             parse_request_log_item(p,
                                    (request_log_format_item *)
                                    apr_array_push(a), &s))) {
            *err = res;
            return NULL;
        }
    }

    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, const char *format)
{
    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 = apr_pstrdup(cmd->pool, format);

    return NULL;
}


/*
 * JkWorkerIndicator Directive Handling
 *
 * JkWorkerIndicator JkWorker
 */

static const char *jk_set_worker_indicator(cmd_parms * cmd,
                                           void *dummy, const char *indicator)
{
    server_rec *s = cmd->server;
    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);

    conf->worker_indicator = apr_pstrdup(cmd->pool, indicator);

    return NULL;
}

/*
 * JkExtractSSL Directive Handling
 *
 * JkExtractSSL On/Off
 */

static const char *jk_set_enable_ssl(cmd_parms * cmd, void *dummy, int flag)
{
    server_rec *s = cmd->server;
    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);

    /* Set up our value */
    conf->ssl_enable = flag ? JK_TRUE : JK_FALSE;

    return NULL;
}

/*
 * JkHTTPSIndicator Directive Handling
 *
 * JkHTTPSIndicator HTTPS
 */

static const char *jk_set_https_indicator(cmd_parms * cmd,
                                          void *dummy, const char *indicator)
{
    server_rec *s = cmd->server;
    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);

    conf->https_indicator = apr_pstrdup(cmd->pool, indicator);

    return NULL;
}

/*
 * JkCERTSIndicator Directive Handling
 *
 * JkCERTSIndicator SSL_CLIENT_CERT
 */

static const char *jk_set_certs_indicator(cmd_parms * cmd,
                                          void *dummy, const char *indicator)
{
    server_rec *s = cmd->server;
    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);

    conf->certs_indicator = apr_pstrdup(cmd->pool, indicator);

    return NULL;
}

/*
 * JkCIPHERIndicator Directive Handling
 *
 * JkCIPHERIndicator SSL_CIPHER
 */

static const char *jk_set_cipher_indicator(cmd_parms * cmd,
                                           void *dummy, const char *indicator)
{
    server_rec *s = cmd->server;
    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);

    conf->cipher_indicator = apr_pstrdup(cmd->pool, indicator);

    return NULL;
}

/*
 * JkCERTCHAINPrefix Directive Handling
 *
 * JkCERTCHAINPrefix SSL_CLIENT_CERT_CHAIN_
 */

static const char *jk_set_certchain_prefix(cmd_parms * cmd,
                                           void *dummy, const char *prefix)
{
    server_rec *s = cmd->server;
    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);

    conf->certchain_prefix = apr_pstrdup(cmd->pool, prefix);

    return NULL;
}

/*
 * JkSESSIONIndicator Directive Handling
 *
 * JkSESSIONIndicator SSL_SESSION_ID
 */

static const char *jk_set_session_indicator(cmd_parms * cmd,
                                            void *dummy,
                                            const char *indicator)
{
    server_rec *s = cmd->server;
    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);

    conf->session_indicator = apr_pstrdup(cmd->pool, indicator);

    return NULL;
}

/*
 * JkKEYSIZEIndicator Directive Handling
 *
 * JkKEYSIZEIndicator SSL_CIPHER_USEKEYSIZE
 */

static const char *jk_set_key_size_indicator(cmd_parms * cmd,
                                             void *dummy,
                                             const char *indicator)
{
    server_rec *s = cmd->server;
    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);

    conf->key_size_indicator = apr_pstrdup(cmd->pool, indicator);

    return NULL;
}

/*
 * JkOptions Directive Handling
 *
 *
 * +ForwardSSLKeySize        => Forward SSL Key Size, to follow 2.3 specs but may broke old TC 3.2
 * -ForwardSSLKeySize        => Don't Forward SSL Key Size, will make mod_jk works with all TC release
 *  ForwardURICompat         => Forward URI normally, less spec compliant but mod_rewrite compatible (old TC)
 *  ForwardURICompatUnparsed => Forward URI as unparsed, spec compliant but broke mod_rewrite (old TC)
 *  ForwardURIEscaped        => Forward URI escaped and Tomcat (3.3 rc2) stuff will do the decoding part
 *  ForwardDirectories       => Forward all directory requests with no index files to Tomcat
 * +ForwardSSLCertChain      => Forward SSL Cert Chain
 * -ForwardSSLCertChain      => Don't Forward SSL Cert Chain (default)
 */

static const char *jk_set_options(cmd_parms * cmd, void *dummy,
                                  const char *line)
{
    int opt = 0;
    int mask = 0;
    char action;
    char *w;

    server_rec *s = cmd->server;
    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);

    while (line[0] != 0) {
        w = ap_getword_conf(cmd->pool, &line);
        action = 0;

        if (*w == '+' || *w == '-') {
            action = *(w++);
        }

        mask = 0;

        if (action == '-' && !strncasecmp(w, "ForwardURI", strlen("ForwardURI")))
            return apr_pstrcat(cmd->pool, "JkOptions: Illegal option '-", w,
                               "': ForwardURI* options can not be disabled", NULL);

        if (!strcasecmp(w, "ForwardKeySize")) {
            opt = JK_OPT_FWDKEYSIZE;
        }
        else if (!strcasecmp(w, "ForwardURICompat")) {
            opt = JK_OPT_FWDURICOMPAT;
            mask = JK_OPT_FWDURIMASK;
        }
        else if (!strcasecmp(w, "ForwardURICompatUnparsed")) {
            opt = JK_OPT_FWDURICOMPATUNPARSED;
            mask = JK_OPT_FWDURIMASK;
        }
        else if (!strcasecmp(w, "ForwardURIEscaped")) {
            opt = JK_OPT_FWDURIESCAPED;
            mask = JK_OPT_FWDURIMASK;
        }
        else if (!strcasecmp(w, "ForwardURIProxy")) {
            opt = JK_OPT_FWDURIPROXY;
            mask = JK_OPT_FWDURIMASK;
        }
        else if (!strcasecmp(w, "ForwardDirectories")) {
            opt = JK_OPT_FWDDIRS;
        }
        else if (!strcasecmp(w, "ForwardLocalAddress")) {
            opt = JK_OPT_FWDLOCAL;
        }
        else if (!strcasecmp(w, "FlushPackets")) {
            opt = JK_OPT_FLUSHPACKETS;
        }
        else if (!strcasecmp(w, "FlushHeader")) {
            opt = JK_OPT_FLUSHEADER;
        }
        else if (!strcasecmp(w, "DisableReuse")) {
            opt = JK_OPT_DISABLEREUSE;
        }
        else if (!strcasecmp(w, "ForwardSSLCertChain")) {
            opt = JK_OPT_FWDCERTCHAIN;
        }
        else
            return apr_pstrcat(cmd->pool, "JkOptions: Illegal option '", w,
                               "'", NULL);

        conf->options &= ~mask;

        if (action == '-') {
            conf->exclude_options |= opt;
        }
        else if (action == '+') {
            conf->options |= opt;
        }
        else {                  /* for now +Opt == Opt */
            conf->options |= opt;
        }
    }
    return NULL;
}

/*
 * JkEnvVar Directive Handling
 *
 * JkEnvVar MYOWNDIR
 */

static const char *jk_add_env_var(cmd_parms * cmd,
                                  void *dummy,
                                  const char *env_name,
                                  const char *default_value)
{
    server_rec *s = cmd->server;
    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);

    conf->envvars_in_use = JK_TRUE;

    /* env_name is mandatory, default_value is optional.
     * No value means send the attribute only, if the env var is set during runtime.
     */
    apr_table_setn(conf->envvars, env_name, default_value ? default_value : "");
    apr_table_setn(conf->envvars_def, env_name, default_value ? "1" : "0");

    return NULL;
}

/*
 * JkWorkerProperty Directive Handling
 *
 * JkWorkerProperty name=value
 */

static const char *jk_set_worker_property(cmd_parms * cmd,
                                          void *dummy,
                                          const char *line)
{
    server_rec *s = cmd->server;
    jk_server_conf_t *conf =
        (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                  &jk_module);

    const char *err_string = ap_check_cmd_context(cmd, GLOBAL_ONLY);
    if (err_string != NULL) {
        return err_string;
    }

    if (jk_map_read_property(conf->worker_properties, line, 1, conf->log) == JK_FALSE)
        return apr_pstrcat(cmd->temp_pool, "Invalid JkWorkerProperty ", line, NULL);

    return NULL;
}

static const command_rec jk_cmds[] = {
    /*
     * JkWorkersFile specifies a full path to the location of the worker
     * properties file.
     *
     * This file defines the different workers used by apache to redirect
     * servlet requests.
     */
    AP_INIT_TAKE1("JkWorkersFile", jk_set_worker_file, NULL, RSRC_CONF,
                  "the name of a worker file for the Tomcat servlet containers"),

    /*
     * JkMountFile specifies a full path to the location of the
     * uriworker properties file.
     *
     * This file defines the different mapping for workers used by apache
     * to redirect servlet requests.
     */
    AP_INIT_TAKE1("JkMountFile", jk_set_mount_file, NULL, RSRC_CONF,
                  "the name of a mount file for the Tomcat servlet uri mapping"),

    /*
     * JkMountFileReload specifies the reload check interval for the
     * uriworker properties file.
     *
     * Default value is: JK_URIMAP_DEF_RELOAD
     */
    AP_INIT_TAKE1("JkMountFileReload", jk_set_mount_file_reload, NULL, RSRC_CONF,
                  "the reload check interval of the mount file"),

    /*
     * JkAutoMount specifies that the list of handled URLs must be
     * asked to the servlet engine (autoconf feature)
     */
    AP_INIT_TAKE12("JkAutoMount", jk_automount_context, NULL, RSRC_CONF,
                   "automatic mount points to a Tomcat worker"),

    /*
     * JkMount mounts a url prefix to a worker (the worker need to be
     * defined in the worker properties file.
     */
    AP_INIT_TAKE12("JkMount", jk_mount_context, NULL, RSRC_CONF|ACCESS_CONF,
                   "A mount point from a context to a Tomcat worker"),

    /*
     * JkUnMount unmounts a url prefix to a worker (the worker need to be
     * defined in the worker properties file.
     */
    AP_INIT_TAKE12("JkUnMount", jk_unmount_context, NULL, RSRC_CONF|ACCESS_CONF,
                   "A no mount point from a context to a Tomcat worker"),

    /*
     * JkMountCopy specifies if mod_jk should copy the mount points
     * from the main server to the virtual servers.
     */
    AP_INIT_FLAG("JkMountCopy", jk_set_mountcopy, NULL, RSRC_CONF,
                 "Should the base server mounts be copied to the virtual server"),

    /*
     * JkStripSession specifies if mod_jk should strip the ;jsessionid
     * from the unmapped urls
     */
    AP_INIT_FLAG("JkStripSession", jk_set_strip_session, NULL, RSRC_CONF,
                 "Should the server strip the jsessionid from unmapped URLs"),

    /*
     * JkLogFile & JkLogLevel specifies to where should the plugin log
     * its information and how much.
     * JkLogStampFormat specify the time-stamp to be used on log
     */
    AP_INIT_TAKE1("JkLogFile", jk_set_log_file, NULL, RSRC_CONF,
                  "Full path to the Tomcat module log file"),

    AP_INIT_TAKE1("JkShmFile", jk_set_shm_file, NULL, RSRC_CONF,
                  "Full path to the Tomcat module shared memory file"),

    AP_INIT_TAKE1("JkShmSize", jk_set_shm_size, NULL, RSRC_CONF,
                  "Size of the shared memory file in KBytes"),

    AP_INIT_TAKE1("JkLogLevel", jk_set_log_level, NULL, RSRC_CONF,
                  "The Tomcat module log level, can be debug, "
                  "info, error or emerg"),
    AP_INIT_TAKE1("JkLogStampFormat", jk_set_log_fmt, NULL, RSRC_CONF,
                  "The Tomcat module log format, follow strftime synthax"),
    AP_INIT_TAKE1("JkRequestLogFormat", jk_set_request_log_format, NULL,
                  RSRC_CONF,
                  "The mod_jk module request log format string"),

    /*
     * Automatically Alias webapp context directories into the Apache
     * document space.
     */
    AP_INIT_TAKE1("JkAutoAlias", jk_set_auto_alias, NULL, RSRC_CONF,
                  "The mod_jk module automatic context apache alias directory"),

    /*
     * Enable worker name to be set in an environment variable.
     * this way one can use LocationMatch together with mod_end,
     * mod_setenvif and mod_rewrite to set the target worker.
     * Use this in combination with SetHandler jakarta-servlet to
     * make mod_jk the handler for the request.
     *
     */
    AP_INIT_TAKE1("JkWorkerIndicator", jk_set_worker_indicator, NULL, RSRC_CONF,
                  "Name of the Apache environment that contains the worker name"),

    /*
     * Apache has multiple SSL modules (for example apache_ssl, stronghold
     * IHS ...). Each of these can have a different SSL environment names
     * The following properties let the administrator specify the envoiroment
     * variables names.
     *
     * HTTPS - indication for SSL
     * CERTS - Base64-Der-encoded client certificates.
     * CIPHER - A string specifing the ciphers suite in use.
     * KEYSIZE - Size of Key used in dialogue (#bits are secure)
     * SESSION - A string specifing the current SSL session.
     */
    AP_INIT_TAKE1("JkHTTPSIndicator", jk_set_https_indicator, NULL, RSRC_CONF,
                  "Name of the Apache environment that contains SSL indication"),
    AP_INIT_TAKE1("JkCERTSIndicator", jk_set_certs_indicator, NULL, RSRC_CONF,
                  "Name of the Apache environment that contains SSL client certificates"),
    AP_INIT_TAKE1("JkCIPHERIndicator", jk_set_cipher_indicator, NULL,
                  RSRC_CONF,
                  "Name of the Apache environment that contains SSL client cipher"),
    AP_INIT_TAKE1("JkSESSIONIndicator", jk_set_session_indicator, NULL,
                  RSRC_CONF,
                  "Name of the Apache environment that contains SSL session"),
    AP_INIT_TAKE1("JkKEYSIZEIndicator", jk_set_key_size_indicator, NULL,
                  RSRC_CONF,
                  "Name of the Apache environment that contains SSL key size in use"),
    AP_INIT_TAKE1("JkCERTCHAINPrefix", jk_set_certchain_prefix, NULL, RSRC_CONF,
                  "Name of the Apache environment (prefix) that contains SSL client chain certificates"),
    AP_INIT_FLAG("JkExtractSSL", jk_set_enable_ssl, NULL, RSRC_CONF,
                 "Turns on SSL processing and information gathering by mod_jk"),

    /*
     * Options to tune mod_jk configuration
     * for now we understand :
     * +ForwardSSLKeySize        => Forward SSL Key Size, to follow 2.3 specs but may broke old TC 3.2
     * -ForwardSSLKeySize        => Don't Forward SSL Key Size, will make mod_jk works with all TC release
     *  ForwardURICompat         => Forward URI normally, less spec compliant but mod_rewrite compatible (old TC)
     *  ForwardURICompatUnparsed => Forward URI as unparsed, spec compliant but broke mod_rewrite (old TC)
     *  ForwardURIEscaped        => Forward URI escaped and Tomcat (3.3 rc2) stuff will do the decoding part
     * +ForwardSSLCertChain      => Forward SSL certificate chain
     * -ForwardSSLCertChain      => Don't forward SSL certificate chain
     */
    AP_INIT_RAW_ARGS("JkOptions", jk_set_options, NULL, RSRC_CONF,
                     "Set one of more options to configure the mod_jk module"),

    /*
     * JkEnvVar let user defines envs var passed from WebServer to
     * Servlet Engine
     */
    AP_INIT_TAKE12("JkEnvVar", jk_add_env_var, NULL, RSRC_CONF,
                  "Adds a name of environment variable and an optional value "
                  "that should be sent to servlet-engine"),

    AP_INIT_RAW_ARGS("JkWorkerProperty", jk_set_worker_property,
                     NULL, RSRC_CONF,
                     "Set workers.properties formated directive"),

    {NULL}
};

/* ========================================================================= */
/* The JK module handlers                                                    */
/* ========================================================================= */

/** Util - cleanup shmem.
 */
static apr_status_t jk_cleanup_shmem(void *data)
{
    jk_shm_close();
    return APR_SUCCESS;
}

/** Main service method, called to forward a request to tomcat
 */
static int jk_handler(request_rec * r)
{
    const char *worker_name;
    jk_server_conf_t *xconf;
    int rc, dmt = 1;

    /* We do DIR_MAGIC_TYPE here to make sure TC gets all requests, even
     * if they are directory requests, in case there are no static files
     * visible to Apache and/or DirectoryIndex was not used. This is only
     * used when JkOptions has ForwardDirectories set. */
    /* Not for me, try next handler */
    if (strcmp(r->handler, JK_HANDLER)
        && (dmt = strcmp(r->handler, DIR_MAGIC_TYPE)))
        return DECLINED;

    xconf = (jk_server_conf_t *) ap_get_module_config(r->server->module_config,
                                                      &jk_module);
    JK_TRACE_ENTER(xconf->log);
    if (apr_table_get(r->subprocess_env, "no-jk")) {
        if (JK_IS_DEBUG_LEVEL(xconf->log))
            jk_log(xconf->log, JK_LOG_DEBUG,
                   "Into handler no-jk env var detected for uri=%s, declined",
                   r->uri);

        JK_TRACE_EXIT(xconf->log);
        return DECLINED;
    }

    /* Was the option to forward directories to Tomcat set? */
    if (!dmt && !(xconf->options & JK_OPT_FWDDIRS)) {
        JK_TRACE_EXIT(xconf->log);
        return DECLINED;
    }
    worker_name = apr_table_get(r->notes, JK_NOTE_WORKER_NAME);

    /* Set up r->read_chunked flags for chunked encoding, if present */
    if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) != APR_SUCCESS) {
        JK_TRACE_EXIT(xconf->log);
        return rc;
    }

    if (worker_name == NULL) {
        /* we may be here because of a manual directive ( that overrides
           translate and
           sets the handler directly ). We still need to know the worker.
         */
        worker_name = apr_table_get(r->subprocess_env, xconf->worker_indicator);
        if (worker_name) {
          /* The JkWorkerIndicator environment variable has
           * been used to explicitely set the worker without JkMount.
           * This is useful in combination with LocationMatch or mod_rewrite.
           */
            if (JK_IS_DEBUG_LEVEL(xconf->log))
                jk_log(xconf->log, JK_LOG_DEBUG,
                       "Retrieved worker (%s) from env %s for %s",
                       worker_name, xconf->worker_indicator, r->uri);
        }
        else if (worker_env.num_of_workers == 1) {
          /** We have a single worker ( the common case ).
              ( lb is a bit special, it should count as a single worker but
              I'm not sure how ). We also have a manual config directive that
              explicitely give control to us. */
            worker_name = worker_env.worker_list[0];
            if (JK_IS_DEBUG_LEVEL(xconf->log))
                jk_log(xconf->log, JK_LOG_DEBUG,
                       "Single worker (%s) configuration for %s",
                       worker_name, r->uri);
        }
        else {
            worker_name = map_uri_to_worker(xconf->uw_map, r->uri, xconf->log);
            if (worker_name == NULL && worker_env.num_of_workers) {
                worker_name = worker_env.worker_list[0];
                if (JK_IS_DEBUG_LEVEL(xconf->log))
                    jk_log(xconf->log, JK_LOG_DEBUG,
                           "Using first worker (%s) from %d workers for %s",
                           worker_name, worker_env.num_of_workers, r->uri);
            }
        }
        if (worker_name)
            apr_table_setn(r->notes, JK_NOTE_WORKER_NAME, worker_name);
    }

    if (JK_IS_DEBUG_LEVEL(xconf->log))
       jk_log(xconf->log, JK_LOG_DEBUG, "Into handler %s worker=%s"
              " r->proxyreq=%d",
              r->handler, worker_name, r->proxyreq);

    /* If this is a proxy request, we'll notify an error */
    if (r->proxyreq) {
        jk_log(xconf->log, JK_LOG_INFO, "Proxy request for worker=%s"
              " is not allowed",
              worker_name);
        JK_TRACE_EXIT(xconf->log);
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    if (worker_name) {
        jk_worker_t *worker = wc_get_worker_for_name(worker_name, xconf->log);

        /* If the remote client has aborted, just ignore the request */
        if (r->connection->aborted) {
            jk_log(xconf->log, JK_LOG_INFO, "Client connection aborted for"
                   " worker=%s",
                   worker_name);
            JK_TRACE_EXIT(xconf->log);
            return OK;
        }

        if (worker) {
            apr_time_t request_begin = 0;
            int is_error = HTTP_INTERNAL_SERVER_ERROR;
            int rc = JK_FALSE;
            apache_private_data_t private_data;
            jk_ws_service_t s;
            jk_pool_atom_t buf[SMALL_POOL_SIZE];
            jk_open_pool(&private_data.p, buf, sizeof(buf));

            private_data.response_started = JK_FALSE;
            private_data.read_body_started = JK_FALSE;
            private_data.r = r;

            wc_maintain(xconf->log);

            jk_init_ws_service(&s);
            /* Update retries for this worker */
            s.retries = worker->retries;
            s.ws_private = &private_data;
            s.pool = &private_data.p;
            apr_table_setn(r->notes, JK_NOTE_WORKER_TYPE,
                           wc_get_name_for_type(worker->type, xconf->log));

            if (xconf->format != NULL) {
                request_begin = apr_time_now();
            }

            if (init_ws_service(&private_data, &s, xconf)) {
                jk_endpoint_t *end = NULL;

                /* Use per/thread pool ( or "context" ) to reuse the
                   endpoint. It's a bit faster, but I don't know
                   how to deal with load balancing - but it's usefull for JNI
                 */

                /* worker->get_endpoint might fail if we are out of memory so check */
                /* and handle it */
                if (worker->get_endpoint(worker, &end, xconf->log)) {
                    rc = end->service(end, &s, xconf->log,
                                      &is_error);
                    end->done(&end, xconf->log);
                    if (s.content_read < s.content_length ||
                        (s.is_chunked && !s.no_more_chunks)) {

                        /*
                         * If the servlet engine didn't consume all of the
                         * request data, consume and discard all further
                         * characters left to read from client
                         */
                        char *buff = apr_palloc(r->pool, 2048);
                        if (buff != NULL) {
                            int rd;
                            while ((rd =
                                    ap_get_client_block(r, buff, 2048)) > 0) {
                                s.content_read += rd;
                            }
                        }
                    }
                }
                else {            /* this means we couldn't get an endpoint */
                    jk_log(xconf->log, JK_LOG_ERROR, "Could not get endpoint"
                           " for worker=%s",
                           worker_name);
                    rc = 0;       /* just to make sure that we know we've failed */
                }
            }
            else {
                jk_log(xconf->log, JK_LOG_ERROR, "Could not init service"
                       " for worker=%s",
                       worker_name);
                jk_close_pool(&private_data.p);
                JK_TRACE_EXIT(xconf->log);
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            if (xconf->format != NULL) {
                long micro, seconds;
                char *duration = NULL;
                apr_time_t rd = apr_time_now() - request_begin;
                seconds = (long)apr_time_sec(rd);
                micro = (long)(rd - apr_time_from_sec(seconds));

                duration = apr_psprintf(r->pool, "%.1ld.%.6ld", seconds, micro);
                apr_table_setn(r->notes, JK_NOTE_REQUEST_DURATION, duration);
                if (s.route && *s.route)
                    apr_table_setn(r->notes, JK_NOTE_WORKER_ROUTE, s.route);

                request_log_transaction(r, xconf);
            }

            jk_close_pool(&private_data.p);

            if (rc > 0) {
                /* If tomcat returned no body and the status is not OK,
                   let apache handle the error code */

/* hgomez@20070516 : under i5/OS sent_bodyct is not set correctly */
/*                   check for header_only to see if there was a body */
                if (!r->sent_bodyct && r->status >= HTTP_BAD_REQUEST) {
                    jk_log(xconf->log, JK_LOG_INFO, "No body with status=%d"
                           " for worker=%s",
                           r->status, worker_name);
                    JK_TRACE_EXIT(xconf->log);
                    return r->status;
                }
                if (JK_IS_DEBUG_LEVEL(xconf->log))
                    jk_log(xconf->log, JK_LOG_DEBUG, "Service finished"
                           " with status=%d for worker=%s",
                           r->status, worker_name);
                JK_TRACE_EXIT(xconf->log);
                return OK;      /* NOT r->status, even if it has changed. */
            }
            else if (rc == JK_CLIENT_ERROR) {
                if (is_error != HTTP_REQUEST_ENTITY_TOO_LARGE)
                    r->connection->aborted = 1;
                jk_log(xconf->log, JK_LOG_INFO, "Aborting connection"
                       " for worker=%s",
                       worker_name);
                JK_TRACE_EXIT(xconf->log);
                return is_error;
            }
            else {
                jk_log(xconf->log, JK_LOG_INFO, "Service error=%d"
                       " for worker=%s",
                       rc, worker_name);
                JK_TRACE_EXIT(xconf->log);
                return is_error;
            }
        }
        else {
            jk_log(xconf->log, JK_LOG_INFO, "Could not find a worker"
                   " for worker name=%s",
                   worker_name);
            JK_TRACE_EXIT(xconf->log);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
    }

    JK_TRACE_EXIT(xconf->log);
    return DECLINED;
}

/** Standard apache hook, cleanup jk
 */
static apr_status_t jk_apr_pool_cleanup(void *data)
{
    server_rec *s = data;

    while (NULL != s) {
        jk_server_conf_t *conf =
            (jk_server_conf_t *) ap_get_module_config(s->module_config,
                                                      &jk_module);

        if (conf && conf->worker_properties) {
            /* On pool cleanup pass NULL for the jk_logger to
               prevent segmentation faults on Windows because
               we can't guarantee what order pools get cleaned
               up between APR implementations. */
            if (conf->was_initialized)
                wc_close(NULL);
            if (conf->worker_properties)
                jk_map_free(&conf->worker_properties);
            if (conf->uri_to_context)
                jk_map_free(&conf->uri_to_context);
            if (conf->automount)
                jk_map_free(&conf->automount);
            if (conf->uw_map)
                uri_worker_map_free(&conf->uw_map, NULL);
            conf->was_initialized   = JK_FALSE;
            conf->worker_properties = NULL;
        }
        s = s->next;
    }
    return APR_SUCCESS;
}

/** Create default jk_config. XXX This is mostly server-independent,
    all servers are using something similar - should go to common.
 */
static void *create_jk_config(apr_pool_t * p, server_rec * s)
{
    jk_server_conf_t *c =
        (jk_server_conf_t *) apr_pcalloc(p, sizeof(jk_server_conf_t));

    c->worker_properties = NULL;
    jk_map_alloc(&c->worker_properties);
    c->worker_file = NULL;
    c->mount_file = NULL;
    c->log_file = NULL;
    c->log = NULL;
    c->alias_dir = NULL;
    c->stamp_format_string = NULL;
    c->format_string = NULL;
    c->format = NULL;
    c->mountcopy = JK_FALSE;
    c->exclude_options = 0;
    c->was_initialized = JK_FALSE;

    if (s->is_virtual) {
        c->mount_file_reload = JK_UNSET;
        c->log_level = JK_UNSET;
        c->options = 0;
        c->worker_indicator = NULL;
        c->ssl_enable = JK_UNSET;
        c->https_indicator = NULL;
        c->certs_indicator = NULL;
        c->cipher_indicator = NULL;
        c->certchain_prefix = NULL;
        c->session_indicator = NULL;
        c->key_size_indicator = NULL;
        c->strip_session = JK_UNSET;
    } else {
        c->mount_file_reload = JK_URIMAP_DEF_RELOAD;
        c->log_level = JK_LOG_DEF_LEVEL;
        c->options = JK_OPT_FWDURIDEFAULT;
        c->worker_indicator = JK_ENV_WORKER_NAME;
        /*
         * By default we will try to gather SSL info.
         * Disable this functionality through JkExtractSSL
         */
        c->ssl_enable = JK_TRUE;
        /*
         * The defaults ssl indicators match those in mod_ssl (seems
         * to be in more use).
         */
        c->https_indicator = JK_ENV_HTTPS;
        c->certs_indicator = JK_ENV_CERTS;
        c->cipher_indicator = JK_ENV_CIPHER;
        c->certchain_prefix = JK_ENV_CERTCHAIN_PREFIX;
        c->session_indicator = JK_ENV_SESSION;
        c->key_size_indicator = JK_ENV_KEY_SIZE;
        c->strip_session = JK_FALSE;
    }

    if (!jk_map_alloc(&(c->uri_to_context))) {
        jk_error_exit(APLOG_MARK, APLOG_EMERG, s, p, "Memory error");
    }
    if (!jk_map_alloc(&(c->automount))) {
        jk_error_exit(APLOG_MARK, APLOG_EMERG, s, p, "Memory error");
    }

    c->uw_map = NULL;
    c->secret_key = NULL;

    c->envvars_in_use = JK_FALSE;
    c->envvars = apr_table_make(p, 0);
    c->envvars_def = apr_table_make(p, 0);
    c->envvar_items = apr_array_make(p, 0, sizeof(envvar_item));

    c->s = s;
    jk_map_put(c->worker_properties, "ServerRoot", ap_server_root, NULL);
    apr_pool_cleanup_register(p, s, jk_apr_pool_cleanup, jk_apr_pool_cleanup);
    return c;
}


/** Utility - copy a map . XXX Should move to jk_map, it's generic code.
 */
static void copy_jk_map(apr_pool_t * p, server_rec * s, jk_map_t *src,
                        jk_map_t *dst)
{
    int sz = jk_map_size(src);
    int i;
    for (i = 0; i < sz; i++) {
        const char *name = jk_map_name_at(src, i);
        if (jk_map_get(dst, name, NULL) == NULL) {
            if (!jk_map_put(dst, name,
                            apr_pstrdup(p, jk_map_get_string(src, name, NULL)),
                            NULL)) {
                jk_error_exit(APLOG_MARK, APLOG_EMERG, s, p, "Memory error");
            }
        }
    }
}

/** Standard apache callback, merge jk options specified in <Directory>
    context or <Host>.
 */
static void *merge_jk_config(apr_pool_t * p, void *basev, void *overridesv)
{
    jk_server_conf_t *base = (jk_server_conf_t *) basev;
    jk_server_conf_t *overrides = (jk_server_conf_t *) overridesv;

    if (!overrides->log_file)
        overrides->log_file = base->log_file;
    if (overrides->log_level == JK_UNSET)
        overrides->log_level = base->log_level;

    if (!overrides->stamp_format_string)
        overrides->stamp_format_string = base->stamp_format_string;
    if (!overrides->format_string)
        overrides->format_string = base->format_string;

    if (!overrides->worker_indicator)
        overrides->worker_indicator = base->worker_indicator;

    if (overrides->ssl_enable == JK_UNSET)
        overrides->ssl_enable = base->ssl_enable;
    if (!overrides->https_indicator)
        overrides->https_indicator = base->https_indicator;
    if (!overrides->certs_indicator)
        overrides->certs_indicator = base->certs_indicator;
    if (!overrides->cipher_indicator)
        overrides->cipher_indicator = base->cipher_indicator;
    if (!overrides->certchain_prefix)
        overrides->certchain_prefix = base->certchain_prefix;
    if (!overrides->session_indicator)
        overrides->session_indicator = base->session_indicator;
    if (!overrides->key_size_indicator)
        overrides->key_size_indicator = base->key_size_indicator;

    if (!overrides->secret_key)
        overrides->secret_key = base->secret_key;

    overrides->options |= (base->options & ~base->exclude_options);

    if (base->envvars_in_use) {
        int i;
        const apr_array_header_t *arr;
        const apr_table_entry_t *elts;

        arr = apr_table_elts(base->envvars);
        if (arr) {
            overrides->envvars_in_use = JK_TRUE;
            elts = (const apr_table_entry_t *)arr->elts;
            for (i = 0; i < arr->nelts; ++i) {
                if (!apr_table_get(overrides->envvars, elts[i].key)) {
                    apr_table_setn(overrides->envvars, elts[i].key, elts[i].val);
                }
            }
        }
        arr = apr_table_elts(base->envvars_def);
        if (arr) {
            overrides->envvars_in_use = JK_TRUE;
            elts = (const apr_table_entry_t *)arr->elts;
            for (i = 0; i < arr->nelts; ++i) {
                if (!apr_table_get(overrides->envvars_def, elts[i].key)) {
                    apr_table_setn(overrides->envvars_def, elts[i].key, elts[i].val);
                }
            }
        }
    }

    if (overrides->mount_file_reload == JK_UNSET)
        overrides->mount_file_reload = base->mount_file_reload;
    if (overrides->mountcopy) {
        copy_jk_map(p, overrides->s, base->uri_to_context,
                    overrides->uri_to_context);
        copy_jk_map(p, overrides->s, base->automount, overrides->automount);
        if (!overrides->mount_file)
            overrides->mount_file = base->mount_file;
        if (!overrides->alias_dir)
            overrides->alias_dir = base->alias_dir;
    }
    if (overrides->strip_session == JK_UNSET)
        overrides->strip_session = base->strip_session;

    return overrides;
}

static int JK_METHOD jk_log_to_file(jk_logger_t *l,
                                    int level, const char *what)
{
    if (l &&
        (l->level <= level || level == JK_LOG_REQUEST_LEVEL) &&
        l->logger_private && what) {
        unsigned sz = strlen(what);
        apr_size_t wrote = sz;
        char error[256];
        if (sz) {
            apr_status_t status;
            jk_file_logger_t *p = l->logger_private;
            if (p->jklogfp) {
                apr_status_t rv;
                rv = apr_global_mutex_lock(jk_log_lock);
                if (rv != APR_SUCCESS) {
                    ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL,
                                 "apr_global_mutex_lock(jk_log_lock) failed");
                    /* XXX: Maybe this should be fatal? */
                }
                status = apr_file_write(p->jklogfp, what, &wrote);
                if (status != APR_SUCCESS) {
                    apr_strerror(status, error, 254);
                    ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
                                 "mod_jk: jk_log_to_file %s failed: %s",
                                 what, error);
                }
#if defined(WIN32)
                apr_file_putc('\r', p->jklogfp);
#endif
                apr_file_putc('\n', p->jklogfp);
                rv = apr_global_mutex_unlock(jk_log_lock);
                if (rv != APR_SUCCESS) {
                    ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL,
                                 "apr_global_mutex_unlock(jk_log_lock) failed");
                    /* XXX: Maybe this should be fatal? */
                }
            }
        }

        return JK_TRUE;
    }

    return JK_FALSE;
}

/*
** +-------------------------------------------------------+
** |                                                       |
** |              jk logfile support                       |
** |                                                       |
** +-------------------------------------------------------+
*/

static apr_status_t jklog_cleanup(void *d)
{
    /* hgomez@20070425 */
    /* Clean up pointer content */
    if (d != NULL)
        *(jk_logger_t **)d = NULL;

    return APR_SUCCESS;
}

static int open_jklog(server_rec * s, apr_pool_t * p)
{
    jk_server_conf_t *conf;
    const char *fname;
    apr_status_t rc;
    apr_file_t *jklogfp;
    piped_log *pl;
    jk_logger_t *jkl;
    jk_file_logger_t *flp;
    int jklog_flags = (APR_WRITE | APR_APPEND | APR_CREATE);
    apr_fileperms_t jklog_mode =
        (APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD);

    conf = ap_get_module_config(s->module_config, &jk_module);

    if (conf->log_file == NULL) {
        conf->log_file = ap_server_root_relative(p, JK_LOG_DEF_FILE);
        if (conf->log_file)
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
                         "No JkLogFile defined in httpd.conf. "
                         "Using default %s", conf->log_file);
    }
    if (*(conf->log_file) == '\0') {
        ap_log_error(APLOG_MARK, APLOG_ERR, APR_EBADPATH, s,
                     "mod_jk: Invalid JkLogFile EMPTY");
        conf->log = main_log;
        return 0;
    }

    jklogfp = apr_hash_get(jk_log_fps, conf->log_file, APR_HASH_KEY_STRING);
    if (!jklogfp) {
        if (*conf->log_file == '|') {
            if ((pl = ap_open_piped_log(p, conf->log_file + 1)) == NULL) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                             "mod_jk: could not open reliable pipe "
                             "to jk log %s", conf->log_file + 1);
                return -1;
            }
            jklogfp = (void *)ap_piped_log_write_fd(pl);
        }
        else {
            fname = ap_server_root_relative(p, conf->log_file);
            if (!fname) {
                ap_log_error(APLOG_MARK, APLOG_ERR, APR_EBADPATH, s,
                             "mod_jk: Invalid JkLog " "path %s", conf->log_file);
                return -1;
            }
            if ((rc = apr_file_open(&jklogfp, fname,
                                    jklog_flags, jklog_mode, p))
                != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rc, s,
                             "mod_jk: could not open JkLog " "file %s", fname);
                return -1;
            }
        }
        apr_file_inherit_set(jklogfp);
        apr_hash_set(jk_log_fps, conf->log_file, APR_HASH_KEY_STRING, jklogfp);
    }
    conf->jklogfp = jklogfp;
    jkl = (jk_logger_t *)apr_palloc(p, sizeof(jk_logger_t));
    flp = (jk_file_logger_t *) apr_palloc(p, sizeof(jk_file_logger_t));
    if (jkl && flp) {
        jkl->log = jk_log_to_file;
        jkl->level = conf->log_level;
        jkl->log_fmt = conf->stamp_format_string;
        jkl->logger_private = flp;
        flp->jklogfp = conf->jklogfp;
        conf->log = jkl;
        if (main_log == NULL) {
            main_log = conf->log;

            /* hgomez@20070425 */
            /* Shouldn't we clean both conf->log and main_log ?                   */
            /* Also should we pass pointer (ie: main_log) or handle (*main_log) ? */
            apr_pool_cleanup_register(p, &main_log, jklog_cleanup, jklog_cleanup);
        }

        return 0;
    }

    return -1;
}


/** Standard apache callback, initialize jk.
 */
static void jk_child_init(apr_pool_t * pconf, server_rec * s)
{
    jk_server_conf_t *conf;
    apr_status_t rv;
    int rc;

    conf = ap_get_module_config(s->module_config, &jk_module);

    rv = apr_global_mutex_child_init(&jk_log_lock, NULL, pconf);
    if (rv != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
                     "mod_jk: could not init JK log lock in child");
    }

    JK_TRACE_ENTER(conf->log);

    if ((rc = jk_shm_attach(jk_shm_file, jk_shm_size, conf->log)) == 0) {
        if (JK_IS_DEBUG_LEVEL(conf->log))
            jk_log(conf->log, JK_LOG_DEBUG, "Attached shm:%s",
                   jk_shm_name());
            apr_pool_cleanup_register(pconf, conf->log, jk_cleanup_shmem,
                                     jk_cleanup_shmem);
    }
    else
        jk_log(conf->log, JK_LOG_ERROR, "Attaching shm:%s errno=%d",
               jk_shm_name(), rc);

    if (JK_IS_DEBUG_LEVEL(conf->log))
        jk_log(conf->log, JK_LOG_DEBUG, "Initialized %s", JK_EXPOSED_VERSION);
    JK_TRACE_EXIT(conf->log);
}

/** Initialize jk, using worker.properties.
    We also use apache commands ( JkWorker, etc), but this use is
    deprecated, as we'll try to concentrate all config in
    workers.properties, urimap.properties, and ajp14 autoconf.

    Apache config will only be used for manual override, using
    SetHandler and normal apache directives ( but minimal jk-specific
    stuff )
*/
static int init_jk(apr_pool_t * pconf, jk_server_conf_t * conf,
                    server_rec * s)
{
    int rc;
    int is_threaded;
    int mpm_threads = 1;

    /*     jk_map_t *init_map = NULL; */
    jk_map_t *init_map = conf->worker_properties;

#if !defined(WIN32) && !defined(NETWARE)
    if (!jk_shm_file) {
        jk_shm_file = ap_server_root_relative(pconf, JK_SHM_DEF_FILE);
        if (jk_shm_file)
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
                         "No JkShmFile defined in httpd.conf. "
                         "Using default %s", jk_shm_file);
    }
#endif
    if ((rc = jk_shm_open(jk_shm_file, jk_shm_size, conf->log)) == 0) {
        if (JK_IS_DEBUG_LEVEL(conf->log))
            jk_log(conf->log, JK_LOG_DEBUG, "Initialized shm:%s",
                   jk_shm_name(), rc);
            apr_pool_cleanup_register(pconf, conf->log, jk_cleanup_shmem,
                                      jk_cleanup_shmem);
    }
    else
        jk_log(conf->log, JK_LOG_ERROR,
               "Initializing shm:%s errno=%d. Load balancing workers will not function properly.",
               jk_shm_name(), rc);

    /* Set default connection cache size for multi-threaded MPMs */
    if (ap_mpm_query(AP_MPMQ_IS_THREADED, &is_threaded) == APR_SUCCESS &&
        is_threaded != AP_MPMQ_NOT_SUPPORTED) {
        if (ap_mpm_query(AP_MPMQ_MAX_THREADS, &mpm_threads) != APR_SUCCESS)
            mpm_threads = 1;
    }
    if (JK_IS_DEBUG_LEVEL(conf->log))
        jk_log(conf->log, JK_LOG_DEBUG,
               "Setting default connection pool max size to %d",
               mpm_threads);
    jk_set_worker_def_cache_size(mpm_threads);

    if ((conf->worker_file != NULL) &&
        !jk_map_read_properties(init_map, conf->worker_file, NULL, 1, conf->log)) {
        ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
                     "Error in reading worker properties from '%s'",
                     conf->worker_file);
        return JK_FALSE;
    }

    if (jk_map_resolve_references(init_map, "worker.", 1, 1, conf->log) == JK_FALSE) {
        ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
                     "Error in resolving configuration references");
        return JK_FALSE;
    }

    /* we add the URI->WORKER MAP since workers using AJP14
       will feed it */
    worker_env.uri_to_worker = conf->uw_map;
    worker_env.virtual = "*";   /* for now */
#if (AP_MODULE_MAGIC_AT_LEAST(20060905,0))
    worker_env.server_name = (char *)ap_get_server_description();
#else
    worker_env.server_name = (char *)ap_get_server_version();
#endif

    if (wc_open(init_map, &worker_env, conf->log)) {
        ap_add_version_component(pconf, JK_EXPOSED_VERSION);
        jk_log(conf->log, JK_LOG_INFO,
               "%s initialized",
               JK_EXPOSED_VERSION);
    }
    else {
        ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
                     "Error in creating the workers."
                     " Please consult your mod_jk log file '%s'.", conf->log_file);
        return JK_FALSE;
    }
    return JK_TRUE;
}

static int jk_post_config(apr_pool_t * pconf,
                          apr_pool_t * plog,
                          apr_pool_t * ptemp, server_rec * s)
{
    apr_status_t rv;
    jk_server_conf_t *conf;
    server_rec *srv = s;
    const char *err_string = NULL;

    /* create the jk log lockfiles in the parent */
    if ((rv = apr_global_mutex_create(&jk_log_lock, NULL,
                                      APR_LOCK_DEFAULT,
                                      pconf)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
                     "mod_jk: could not create jk_log_lock");
        return HTTP_INTERNAL_SERVER_ERROR;
    }

#if JK_NEED_SET_MUTEX_PERMS
    rv = unixd_set_global_mutex_perms(jk_log_lock);
    if (rv != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
                     "mod_jk: Could not set permissions on "
                     "jk_log_lock; check User and Group directives");
        return HTTP_INTERNAL_SERVER_ERROR;
    }
#endif

    jk_log_fps = apr_hash_make(pconf);

    if (!s->is_virtual) {
        conf = (jk_server_conf_t *)ap_get_module_config(s->module_config,
                                                        &jk_module);
        if (!conf->was_initialized) {
            conf->was_initialized = JK_TRUE;
            /* step through the servers and open each jk logfile
             * and do additional post config initialization.
             */
            for (; srv; srv = srv->next) {
                jk_server_conf_t *sconf = (jk_server_conf_t *)ap_get_module_config(srv->module_config,
                                                                                   &jk_module);
                if (open_jklog(srv, pconf))
                    return HTTP_INTERNAL_SERVER_ERROR;
                if (sconf) {
                    if (!uri_worker_map_alloc(&(sconf->uw_map),
                                              sconf->uri_to_context, sconf->log))
                        jk_error_exit(APLOG_MARK, APLOG_EMERG, srv,
                                      srv->process->pool, "Memory error");
                    if (sconf->mount_file) {
                        sconf->uw_map->fname = sconf->mount_file;
                        sconf->uw_map->reload = sconf->mount_file_reload;
                        uri_worker_map_load(sconf->uw_map, sconf->log);
                    }
                    if (sconf->format_string) {
                        sconf->format =
                            parse_request_log_string(pconf, sconf->format_string, &err_string);
                        if (sconf->format == NULL)
                            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                                         "JkRequestLogFormat format array NULL");
                    }
                    sconf->options &= ~sconf->exclude_options;
                    if (sconf->envvars_in_use) {
                        int i;
                        const apr_array_header_t *arr;
                        const apr_table_entry_t *elts;
                        envvar_item *item;
                        const char *envvar_def;

                        arr = apr_table_elts(sconf->envvars);
                        if (arr) {
                            elts = (const apr_table_entry_t *)arr->elts;
                            for (i = 0; i < arr->nelts; ++i) {
                                item = (envvar_item *)apr_array_push(sconf->envvar_items);
                                if (!item)
                                    return HTTP_INTERNAL_SERVER_ERROR;
                                item->name = elts[i].key;
                                envvar_def = apr_table_get(sconf->envvars_def, elts[i].key);
                                if (envvar_def && !strcmp("1", envvar_def) ) {
                                    item->value = elts[i].val;
                                    item->has_default = 1;
                                }
                                else {
                                    item->value = "";
                                    item->has_default = 0;
                                }
                            }
                        }
                    }
                }
            }
            if (init_jk(pconf, conf, s) == JK_FALSE)
                return HTTP_INTERNAL_SERVER_ERROR;
        }
    }

    return OK;
}

/** Use the internal mod_jk mappings to find if this is a request for
 *    tomcat and what worker to use.
 */
static int jk_translate(request_rec * r)
{
    if (!r->proxyreq) {
        jk_server_conf_t *conf =
            (jk_server_conf_t *) ap_get_module_config(r->server->
                                                      module_config,
                                                      &jk_module);

        if (conf) {
            const char *worker;
            if ((r->handler != NULL) && (!strcmp(r->handler, JK_HANDLER))) {
                /* Somebody already set the handler, probably manual config
                 * or "native" configuration, no need for extra overhead
                 */
                if (JK_IS_DEBUG_LEVEL(conf->log))
                    jk_log(conf->log, JK_LOG_DEBUG,
                           "Manually mapped, no need to call uri_to_worker");
                return DECLINED;
            }

            if (apr_table_get(r->subprocess_env, "no-jk")) {
                if (JK_IS_DEBUG_LEVEL(conf->log))
                    jk_log(conf->log, JK_LOG_DEBUG,
                           "Into translate no-jk env var detected for uri=%s, declined",
                           r->uri);

                return DECLINED;
            }

            /* Special case to make sure that apache can serve a directory
               listing if there are no matches for the DirectoryIndex and
               Tomcat webapps are mapped into apache using JkAutoAlias. */
            if (r->main != NULL && r->main->handler != NULL &&
                (conf->alias_dir != NULL) &&
                !strcmp(r->main->handler, DIR_MAGIC_TYPE)) {

                /* Append the request uri to the JkAutoAlias directory and
                   determine if the file exists. */
                char *clean_uri;
                apr_finfo_t finfo;
                finfo.filetype = APR_NOFILE;
                clean_uri = apr_pstrdup(r->pool, r->uri);
                ap_no2slash(clean_uri);
                /* Map uri to a context static file */
                if (strlen(clean_uri) > 1) {
                    char *context_path = NULL;

                    context_path = apr_pstrcat(r->pool, conf->alias_dir,
                                               ap_os_escape_path(r->pool,
                                                                 clean_uri,
                                                                 1), NULL);
                    if (context_path != NULL) {
                        apr_stat(&finfo, context_path, APR_FINFO_TYPE,
                                 r->pool);
                    }
                }
                if (finfo.filetype != APR_REG) {
                    if (JK_IS_DEBUG_LEVEL(conf->log))
                        jk_log(conf->log, JK_LOG_DEBUG,
                               "JkAutoAlias, no DirectoryIndex file for URI %s",
                               r->uri);
                    return DECLINED;
                }
            }

            worker = map_uri_to_worker(conf->uw_map, r->uri, conf->log);

            if (worker) {
                r->handler = apr_pstrdup(r->pool, JK_HANDLER);
                apr_table_setn(r->notes, JK_NOTE_WORKER_NAME, worker);

                /* This could be a sub-request, possibly from mod_dir */
                /* Also add the the HANDLER to the main request */
                if (r->main) {
                    r->main->handler = apr_pstrdup(r->main->pool, JK_HANDLER);
                    apr_table_setn(r->main->notes, JK_NOTE_WORKER_NAME, worker);
                }

                return OK;
            }
            else if (conf->alias_dir != NULL) {
                char *clean_uri = apr_pstrdup(r->pool, r->uri);
                ap_no2slash(clean_uri);
                /* Automatically map uri to a context static file */
                if (JK_IS_DEBUG_LEVEL(conf->log))
                    jk_log(conf->log, JK_LOG_DEBUG,
                           "check alias_dir: %s",
                           conf->alias_dir);
                if (strlen(clean_uri) > 1) {
                    /* Get the context directory name */
                    char *context_dir = NULL;
                    char *context_path = NULL;
                    char *child_dir = NULL;
                    char *index = clean_uri;
                    char *suffix = strchr(index + 1, '/');
                    if (suffix != NULL) {
                        int size = suffix - index;
                        context_dir = apr_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 = apr_pstrndup(r->pool, index, size);
                        }
                        else {
                            child_dir = index;
                        }
                        /* Deny access to WEB-INF and META-INF directories */
                        if (child_dir != NULL) {
                            if (JK_IS_DEBUG_LEVEL(conf->log))
                                jk_log(conf->log, JK_LOG_DEBUG,
                                       "AutoAlias child_dir: %s",
                                       child_dir);
                            if (!strcasecmp(child_dir, "WEB-INF")
                                || !strcasecmp(child_dir, "META-INF")) {
                                if (JK_IS_DEBUG_LEVEL(conf->log))
                                    jk_log(conf->log, JK_LOG_DEBUG,
                                           "AutoAlias HTTP_NOT_FOUND for URI: %s",
                                           r->uri);
                                return HTTP_NOT_FOUND;
                            }
                        }
                    }
                    else {
                        context_dir = apr_pstrdup(r->pool, index);
                    }

                    context_path = apr_pstrcat(r->pool, conf->alias_dir,
                                               ap_os_escape_path(r->pool,
                                                                 context_dir,
                                                                 1), NULL);
                    if (context_path != NULL) {
                        apr_finfo_t finfo;
                        finfo.filetype = APR_NOFILE;
                        apr_stat(&finfo, context_path, APR_FINFO_TYPE,
                                 r->pool);
                        if (finfo.filetype == APR_DIR) {
                            char *escurl =
                                ap_os_escape_path(r->pool, clean_uri, 1);
                            char *ret =
                                apr_pstrcat(r->pool, conf->alias_dir, escurl,
                                            NULL);
                            /* Add code to verify real path ap_os_canonical_name */
                            if (ret != NULL) {
                                if (JK_IS_DEBUG_LEVEL(conf->log))
                                    jk_log(conf->log, JK_LOG_DEBUG,
                                           "AutoAlias OK for file: %s",
                                           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")) {
                                if (JK_IS_DEBUG_LEVEL(conf->log))
                                    jk_log(conf->log, JK_LOG_DEBUG,
                                           "AutoAlias HTTP_FORBIDDEN for URI: %s",
                                           r->uri);
                                return HTTP_FORBIDDEN;
                            }
                        }
                    }
                }
            }
        }
    }

    return DECLINED;
}

#if (MODULE_MAGIC_NUMBER_MAJOR > 20010808)
/* bypass the directory_walk and file_walk for non-file requests */
static int jk_map_to_storage(request_rec * r)
{

    if (!r->proxyreq && !apr_table_get(r->notes, JK_NOTE_WORKER_NAME)) {
        jk_server_conf_t *conf =
            (jk_server_conf_t *) ap_get_module_config(r->server->
                                                      module_config,
                                                      &jk_module);

        if (conf) {
            const char *worker;
            if ((r->handler != NULL) && (!strcmp(r->handler, JK_HANDLER))) {
                /* Somebody already set the handler, probably manual config
                 * or "native" configuration, no need for extra overhead
                 */
                if (JK_IS_DEBUG_LEVEL(conf->log))
                    jk_log(conf->log, JK_LOG_DEBUG,
                           "Manually mapped, no need to call uri_to_worker");
                return DECLINED;
            }

            if (apr_table_get(r->subprocess_env, "no-jk")) {
                if (JK_IS_DEBUG_LEVEL(conf->log))
                    jk_log(conf->log, JK_LOG_DEBUG,
                           "Into map_to_storage no-jk env var detected for uri=%s, declined",
                           r->uri);

                return DECLINED;
            }

            worker = map_uri_to_worker(conf->uw_map, r->uri, conf->log);

            if (worker) {
                r->handler = apr_pstrdup(r->pool, JK_HANDLER);
                apr_table_setn(r->notes, JK_NOTE_WORKER_NAME, worker);

                /* This could be a sub-request, possibly from mod_dir */
                if (r->main)
                    apr_table_setn(r->main->notes, JK_NOTE_WORKER_NAME, worker);

            }
            else if (conf->strip_session == JK_TRUE) {
                char *jsessionid;
                if (r->uri) {
                    jsessionid = strstr(r->uri, JK_PATH_SESSION_IDENTIFIER);
                    if (jsessionid) {
                        if (JK_IS_DEBUG_LEVEL(conf->log))
                            jk_log(conf->log, JK_LOG_DEBUG,
                                   "removing session identifier [%s] for non servlet url [%s]",
                                   jsessionid, r->uri);
                        *jsessionid = '\0';
                    }
                }
                if (r->filename) {
                    jsessionid = strstr(r->filename, JK_PATH_SESSION_IDENTIFIER);
                    if (jsessionid)
                        *jsessionid = '\0';
                }
                return DECLINED;
            }
        }
    }

    if (apr_table_get(r->notes, JK_NOTE_WORKER_NAME)) {

        /* First find just the name of the file, no directory */
        r->filename = (char *)apr_filepath_name_get(r->uri);

        /* Only if sub-request for a directory, most likely from mod_dir */
        if (r->main && r->main->filename &&
            (!apr_filepath_name_get(r->main->filename) ||
             !strlen(apr_filepath_name_get(r->main->filename)))) {

            /* The filename from the main request will be set to what should
             * be picked up, aliases included. Tomcat will need to know about
             * those aliases or things won't work for them. Normal files should
             * be fine. */

            /* Need absolute path to stat */
            if (apr_filepath_merge(&r->filename,
                                   r->main->filename, r->filename,
                                   APR_FILEPATH_SECUREROOT |
                                   APR_FILEPATH_TRUENAME, r->pool)
                != APR_SUCCESS) {
                return DECLINED;        /* We should never get here, very bad */
            }

            /* Stat the file so that mod_dir knows it's there */
            apr_stat(&r->finfo, r->filename, APR_FINFO_TYPE, r->pool);
        }

        return OK;
    }
    return DECLINED;
}
#endif

static void jk_register_hooks(apr_pool_t * p)
{
    ap_hook_handler(jk_handler, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_post_config(jk_post_config, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_child_init(jk_child_init, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_translate_name(jk_translate, NULL, NULL, APR_HOOK_MIDDLE);
#if (MODULE_MAGIC_NUMBER_MAJOR > 20010808)
    ap_hook_map_to_storage(jk_map_to_storage, NULL, NULL, APR_HOOK_MIDDLE);
#endif
}

module AP_MODULE_DECLARE_DATA jk_module = {
    STANDARD20_MODULE_STUFF,
    NULL,                       /* dir config creater */
    NULL,                       /* dir merger --- default is to override */
    create_jk_config,           /* server config */
    merge_jk_config,            /* merge server config */
    jk_cmds,                    /* command ap_table_t */
    jk_register_hooks           /* register hooks */
};
