/* 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.
 */

/*
 * http_mime.c: Sends/gets MIME headers for requests
 * 
 * Rob McCool
 * 
 */

#include "apr.h"
#include "apr_strings.h"
#include "apr_lib.h"
#include "apr_hash.h"

#define APR_WANT_STRFUNC
#include "apr_want.h"

#include "ap_config.h"
#include "httpd.h"
#include "http_config.h"
#include "http_log.h"
#include "http_request.h"
#include "http_protocol.h"

/* XXXX - fix me / EBCDIC
 *        there was a cludge here which would use its
 *        own version apr_isascii(). Indicating that
 *        on some platforms that might be needed. 
 *
 *        #define OS_ASC(c) (c)             -- for mere mortals 
 *     or
 *        #define OS_ASC(c) (ebcdic2ascii[c]) -- for dino's
 *
 *        #define apr_isascii(c) ((OS_ASC(c) & 0x80) == 0)
 */

/* XXXXX - fix me - See note with NOT_PROXY 
 */

typedef struct attrib_info {
    char *name;
    int   offset;
} attrib_info;

/* Information to which an extension can be mapped
 */
typedef struct extension_info {
    char *forced_type;                /* Additional AddTyped stuff */
    char *encoding_type;              /* Added with AddEncoding... */
    char *language_type;              /* Added with AddLanguage... */
    char *handler;                    /* Added with AddHandler... */
    char *charset_type;               /* Added with AddCharset... */
    char *input_filters;              /* Added with AddInputFilter... */
    char *output_filters;             /* Added with AddOutputFilter... */
} extension_info;

#define MULTIMATCH_UNSET      0
#define MULTIMATCH_ANY        1
#define MULTIMATCH_NEGOTIATED 2
#define MULTIMATCH_HANDLERS   4
#define MULTIMATCH_FILTERS    8

typedef struct {
    apr_hash_t *extension_mappings;  /* Map from extension name to
                                      * extension_info structure */

    apr_array_header_t *remove_mappings; /* A simple list, walked once */

    char *default_language;     /* Language if no AddLanguage ext found */

    int multimatch;       /* Extensions to include in multiview matching
                           * for filenames, e.g. Filters and Handlers 
                           */
    int use_path_info;    /* If set to 0, only use filename.
                           * If set to 1, append PATH_INFO to filename for
                           *   lookups.
                           * If set to 2, this value is unset and is
                           *   effectively 0.  
                           */
} mime_dir_config;

typedef struct param_s {
    char *attr;
    char *val;
    struct param_s *next;
} param;

typedef struct {
    const char *type;
    apr_size_t type_len;
    const char *subtype;
    apr_size_t subtype_len;
    param *param;
} content_type;

static char tspecial[] = {
    '(', ')', '<', '>', '@', ',', ';', ':',
    '\\', '"', '/', '[', ']', '?', '=',
    '\0'
};

module AP_MODULE_DECLARE_DATA mime_module;

static void *create_mime_dir_config(apr_pool_t *p, char *dummy)
{
    mime_dir_config *new = apr_palloc(p, sizeof(mime_dir_config));

    new->extension_mappings = NULL;
    new->remove_mappings = NULL;

    new->default_language = NULL;

    new->multimatch = MULTIMATCH_UNSET;

    new->use_path_info = 2;

    return new;
}
/*
 * Overlay one hash table of extension_mappings onto another
 */
static void *overlay_extension_mappings(apr_pool_t *p,
                                        const void *key,
                                        apr_ssize_t klen,
                                        const void *overlay_val,
                                        const void *base_val,
                                        const void *data)
{
    extension_info *new_info = apr_palloc(p, sizeof(extension_info));
    const extension_info *overlay_info = (const extension_info *)overlay_val;
    const extension_info *base_info = (const extension_info *)base_val;

    memcpy(new_info, base_info, sizeof(extension_info));
    if (overlay_info->forced_type) {
        new_info->forced_type = overlay_info->forced_type;
    }
    if (overlay_info->encoding_type) {
        new_info->encoding_type = overlay_info->encoding_type;
    }
    if (overlay_info->language_type) {
        new_info->language_type = overlay_info->language_type;
    }
    if (overlay_info->handler) {
        new_info->handler = overlay_info->handler;
    }
    if (overlay_info->charset_type) {
        new_info->charset_type = overlay_info->charset_type;
    }
    if (overlay_info->input_filters) {
        new_info->input_filters = overlay_info->input_filters;
    }
    if (overlay_info->output_filters) {
        new_info->output_filters = overlay_info->output_filters;
    }

    return new_info;
}

/* Member is the offset within an extension_info of the pointer to reset 
 */
static void remove_items(apr_pool_t *p, apr_array_header_t *remove, 
                         apr_hash_t *mappings)
{
    attrib_info *suffix = (attrib_info *) remove->elts;
    int i;
    for (i = 0; i < remove->nelts; i++) {
        extension_info *exinfo = apr_hash_get(mappings,
                                              suffix[i].name,
                                              APR_HASH_KEY_STRING);
        if (exinfo && *(const char**)((char *)exinfo + suffix[i].offset)) {
            extension_info *copyinfo = exinfo;
            exinfo = (extension_info*)apr_palloc(p, sizeof(*exinfo));
            apr_hash_set(mappings, suffix[i].name, 
                         APR_HASH_KEY_STRING, exinfo);
            memcpy(exinfo, copyinfo, sizeof(*exinfo));
            *(const char**)((char *)exinfo + suffix[i].offset) = NULL;
        }
    }
}

static void *merge_mime_dir_configs(apr_pool_t *p, void *basev, void *addv)
{
    mime_dir_config *base = (mime_dir_config *)basev;
    mime_dir_config *add = (mime_dir_config *)addv;
    mime_dir_config *new = apr_palloc(p, sizeof(mime_dir_config));

    if (base->extension_mappings && add->extension_mappings) {
        new->extension_mappings = apr_hash_merge(p, add->extension_mappings,
                                                 base->extension_mappings,
                                                 overlay_extension_mappings,
                                                 NULL);
    }
    else {
        if (base->extension_mappings == NULL) {
            new->extension_mappings = add->extension_mappings;
        }
        else {
            new->extension_mappings = base->extension_mappings;
        }
        /* We may not be merging the tables, but if we potentially will change
         * an exinfo member, then we are about to trounce it anyways.
         * We must have a copy for safety.
         */
        if (new->extension_mappings && add->remove_mappings) {
            new->extension_mappings =
                apr_hash_copy(p, new->extension_mappings);
        }
    }

    if (new->extension_mappings) {
        if (add->remove_mappings)
            remove_items(p, add->remove_mappings, new->extension_mappings);
    }
    new->remove_mappings = NULL;

    new->default_language = add->default_language ?
        add->default_language : base->default_language;

    new->multimatch = (add->multimatch != MULTIMATCH_UNSET) ?
        add->multimatch : base->multimatch;

    if ((add->use_path_info & 2) == 0) {
        new->use_path_info = add->use_path_info;
    }
    else {
        new->use_path_info = base->use_path_info;
    }

    return new;
}

static const char *add_extension_info(cmd_parms *cmd, void *m_, 
                                      const char *value_, const char* ext)
{
    mime_dir_config *m=m_;
    extension_info *exinfo;
    int offset = (int) (long) cmd->info;
    char *key = apr_pstrdup(cmd->temp_pool, ext);
    char *value = apr_pstrdup(cmd->pool, value_);
    ap_str_tolower(value);
    ap_str_tolower(key);

    if (*key == '.') {
        ++key;
    }
    if (!m->extension_mappings) {
        m->extension_mappings = apr_hash_make(cmd->pool);
        exinfo = NULL;
    }
    else {
        exinfo = (extension_info*)apr_hash_get(m->extension_mappings, key,
                                               APR_HASH_KEY_STRING);
    }
    if (!exinfo) {
        exinfo = apr_pcalloc(cmd->pool, sizeof(extension_info));
        key = apr_pstrdup(cmd->pool, key);
        apr_hash_set(m->extension_mappings, key, APR_HASH_KEY_STRING, exinfo);
    }
    *(const char**)((char *)exinfo + offset) = value;
    return NULL;
}

/*
 * Note handler names are un-added with each per_dir_config merge.
 * This keeps the association from being inherited, but not
 * from being re-added at a subordinate level.
 */
static const char *remove_extension_info(cmd_parms *cmd, void *m_, 
                                         const char *ext)
{
    mime_dir_config *m = (mime_dir_config *) m_;
    attrib_info *suffix;
    if (*ext == '.') {
        ++ext;
    }
    if (!m->remove_mappings) {
        m->remove_mappings = apr_array_make(cmd->pool, 4, sizeof(*suffix));
    }
    suffix = (attrib_info *)apr_array_push(m->remove_mappings);
    suffix->name = apr_pstrdup(cmd->pool, ext);
    ap_str_tolower(suffix->name);
    suffix->offset = (int) (long) cmd->info;
    return NULL;
}

/* The sole bit of server configuration that the MIME module has is
 * the name of its config file, so...
 */

static const char *set_types_config(cmd_parms *cmd, void *dummy,
                                    const char *arg)
{
    ap_set_module_config(cmd->server->module_config, &mime_module,
                         (void *)arg);
    return NULL;
}

static const char *multiviews_match(cmd_parms *cmd, void *m_, 
                                    const char *include)
{
    mime_dir_config *m = (mime_dir_config *) m_;

    if (strcasecmp(include, "Any") == 0) {
        if (m->multimatch && (m->multimatch & ~MULTIMATCH_ANY)) {
            return "Any is incompatible with NegotiatedOnly, "
                   "Filters and Handlers";
        }
        m->multimatch |= MULTIMATCH_ANY;
    }
    else if (strcasecmp(include, "NegotiatedOnly") == 0) {
        if (m->multimatch && (m->multimatch & ~MULTIMATCH_NEGOTIATED)) {
            return "Any is incompatible with NegotiatedOnly, "
                   "Filters and Handlers";
        }
        m->multimatch |= MULTIMATCH_NEGOTIATED;
    }
    else if (strcasecmp(include, "Filters") == 0) {
        if (m->multimatch && (m->multimatch & (MULTIMATCH_NEGOTIATED 
                                             | MULTIMATCH_ANY))) {
            return "Filters is incompatible with Any and NegotiatedOnly";
        }
        m->multimatch |= MULTIMATCH_FILTERS;
    }
    else if (strcasecmp(include, "Handlers") == 0) {
        if (m->multimatch && (m->multimatch & (MULTIMATCH_NEGOTIATED 
                                             | MULTIMATCH_ANY))) {
            return "Handlers is incompatible with Any and NegotiatedOnly";
        }
        m->multimatch |= MULTIMATCH_HANDLERS;
    }
    else {
        return "Unrecognized option";
    }

    return NULL;
}

static const command_rec mime_cmds[] =
{
    AP_INIT_ITERATE2("AddCharset", add_extension_info, 
        (void *)APR_OFFSETOF(extension_info, charset_type), OR_FILEINFO,
        "a charset (e.g., iso-2022-jp), followed by one or more "
        "file extensions"),
    AP_INIT_ITERATE2("AddEncoding", add_extension_info, 
        (void *)APR_OFFSETOF(extension_info, encoding_type), OR_FILEINFO,
        "an encoding (e.g., gzip), followed by one or more file extensions"),
    AP_INIT_ITERATE2("AddHandler", add_extension_info, 
        (void *)APR_OFFSETOF(extension_info, handler), OR_FILEINFO,
        "a handler name followed by one or more file extensions"),
    AP_INIT_ITERATE2("AddInputFilter", add_extension_info, 
        (void *)APR_OFFSETOF(extension_info, input_filters), OR_FILEINFO,
        "input filter name (or ; delimited names) followed by one or "
        "more file extensions"),
    AP_INIT_ITERATE2("AddLanguage", add_extension_info, 
        (void *)APR_OFFSETOF(extension_info, language_type), OR_FILEINFO,
        "a language (e.g., fr), followed by one or more file extensions"),
    AP_INIT_ITERATE2("AddOutputFilter", add_extension_info, 
        (void *)APR_OFFSETOF(extension_info, output_filters), OR_FILEINFO, 
        "output filter name (or ; delimited names) followed by one or "
        "more file extensions"),
    AP_INIT_ITERATE2("AddType", add_extension_info, 
        (void *)APR_OFFSETOF(extension_info, forced_type), OR_FILEINFO, 
        "a mime type followed by one or more file extensions"),
    AP_INIT_TAKE1("DefaultLanguage", ap_set_string_slot,
        (void*)APR_OFFSETOF(mime_dir_config, default_language), OR_FILEINFO,
        "language to use for documents with no other language file extension"),
    AP_INIT_ITERATE("MultiviewsMatch", multiviews_match, NULL, OR_FILEINFO,
        "NegotiatedOnly (default), Handlers and/or Filters, or Any"),
    AP_INIT_ITERATE("RemoveCharset", remove_extension_info, 
        (void *)APR_OFFSETOF(extension_info, charset_type), OR_FILEINFO,
        "one or more file extensions"),
    AP_INIT_ITERATE("RemoveEncoding", remove_extension_info, 
        (void *)APR_OFFSETOF(extension_info, encoding_type), OR_FILEINFO,
        "one or more file extensions"),
    AP_INIT_ITERATE("RemoveHandler", remove_extension_info, 
        (void *)APR_OFFSETOF(extension_info, handler), OR_FILEINFO,
        "one or more file extensions"),
    AP_INIT_ITERATE("RemoveInputFilter", remove_extension_info, 
        (void *)APR_OFFSETOF(extension_info, input_filters), OR_FILEINFO,
        "one or more file extensions"),
    AP_INIT_ITERATE("RemoveLanguage", remove_extension_info, 
        (void *)APR_OFFSETOF(extension_info, language_type), OR_FILEINFO,
        "one or more file extensions"),
    AP_INIT_ITERATE("RemoveOutputFilter", remove_extension_info, 
        (void *)APR_OFFSETOF(extension_info, output_filters), OR_FILEINFO,
        "one or more file extensions"),
    AP_INIT_ITERATE("RemoveType", remove_extension_info, 
        (void *)APR_OFFSETOF(extension_info, forced_type), OR_FILEINFO,
        "one or more file extensions"),
    AP_INIT_TAKE1("TypesConfig", set_types_config, NULL, RSRC_CONF,
        "the MIME types config file"),
    AP_INIT_FLAG("ModMimeUsePathInfo", ap_set_flag_slot,
        (void *)APR_OFFSETOF(mime_dir_config, use_path_info), ACCESS_CONF,
        "Set to 'yes' to allow mod_mime to use path info for type checking"),
    {NULL}
};

static apr_hash_t *mime_type_extensions;

static int mime_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
{
    ap_configfile_t *f;
    char l[MAX_STRING_LEN];
    const char *types_confname = ap_get_module_config(s->module_config,
                                                      &mime_module);
    apr_status_t status;

    if (!types_confname) {
        types_confname = AP_TYPES_CONFIG_FILE;
    }

    types_confname = ap_server_root_relative(p, types_confname);
    if (!types_confname) {
        ap_log_error(APLOG_MARK, APLOG_ERR, APR_EBADPATH, s,
                     "Invalid mime types config path %s", 
                     (const char *)ap_get_module_config(s->module_config,
                                                        &mime_module));
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    if ((status = ap_pcfg_openfile(&f, ptemp, types_confname)) 
                != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, status, s,
                     "could not open mime types config file %s.", 
                     types_confname);
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    mime_type_extensions = apr_hash_make(p);

    while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
        const char *ll = l, *ct;

        if (l[0] == '#') {
            continue;
        }
        ct = ap_getword_conf(p, &ll);

        while (ll[0]) {
            char *ext = ap_getword_conf(p, &ll);
            ap_str_tolower(ext);
            apr_hash_set(mime_type_extensions, ext, APR_HASH_KEY_STRING, ct);
        }
    }
    ap_cfg_closefile(f);
    return OK;
}

static const char *zap_sp(const char *s)
{
    if (s == NULL) {
        return (NULL);
    }
    if (*s == '\0') {
        return (s);
    }

    /* skip prefixed white space */
    for (; *s == ' ' || *s == '\t' || *s == '\n'; s++)
        ;

    return (s);
}

static char *zap_sp_and_dup(apr_pool_t *p, const char *start,
                            const char *end, apr_size_t *len)
{
    while ((start < end) && apr_isspace(*start)) {
        start++;
    }
    while ((end > start) && apr_isspace(*(end - 1))) {
        end--;
    }
    if (len) {
        *len = end - start;
    }
    return apr_pstrmemdup(p, start, end - start);
}

static int is_token(char c)
{
    int res;

    res = (apr_isascii(c) && apr_isgraph(c)
           && (strchr(tspecial, c) == NULL)) ? 1 : -1;
    return res;
}

static int is_qtext(char c)
{
    int res;

    res = (apr_isascii(c) && (c != '"') && (c != '\\') && (c != '\n'))
        ? 1 : -1;
    return res;
}

static int is_quoted_pair(const char *s)
{
    int res = -1;
    int c;

    if (((s + 1) != NULL) && (*s == '\\')) {
        c = (int) *(s + 1);
        if (apr_isascii(c)) {
            res = 1;
        }
    }
    return (res);
}

static content_type *analyze_ct(request_rec *r, const char *s)
{
    const char *cp, *mp;
    char *attribute, *value;
    int quoted = 0;
    server_rec * ss = r->server;
    apr_pool_t * p = r->pool;

    content_type *ctp;
    param *pp, *npp;

    /* initialize ctp */
    ctp = (content_type *)apr_palloc(p, sizeof(content_type));
    ctp->type = NULL;
    ctp->subtype = NULL;
    ctp->param = NULL;

    mp = s;

    /* getting a type */
    cp = mp;
    while (apr_isspace(*cp)) {
        cp++;
    }
    if (!*cp) {
        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
                     "mod_mime: analyze_ct: cannot get media type from '%s'",
                     (const char *) mp);
        return (NULL);
    }
    ctp->type = cp;
    do {
        cp++;
    } while (*cp && (*cp != '/') && !apr_isspace(*cp) && (*cp != ';'));
    if (!*cp || (*cp == ';')) {
        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
                     "Cannot get media type from '%s'",
                     (const char *) mp);
        return (NULL);
    }
    while (apr_isspace(*cp)) {
        cp++;
    }
    if (*cp != '/') {
        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
                     "mod_mime: analyze_ct: cannot get media type from '%s'",
                     (const char *) mp);
        return (NULL);
    }
    ctp->type_len = cp - ctp->type;

    cp++; /* skip the '/' */

    /* getting a subtype */
    while (apr_isspace(*cp)) {
        cp++;
    }
    if (!*cp) {
        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
                     "Cannot get media subtype.");
        return (NULL);
    }
    ctp->subtype = cp;
    do {
        cp++;
    } while (*cp && !apr_isspace(*cp) && (*cp != ';'));
    ctp->subtype_len = cp - ctp->subtype;
    while (apr_isspace(*cp)) {
        cp++;
    }

    if (*cp == '\0') {
        return (ctp);
    }

    /* getting parameters */
    cp++; /* skip the ';' */
    cp = zap_sp(cp);
    if (cp == NULL || *cp == '\0') {
        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
                     "Cannot get media parameter.");
        return (NULL);
    }
    mp = cp;
    attribute = NULL;
    value = NULL;

    while (cp != NULL && *cp != '\0') {
        if (attribute == NULL) {
            if (is_token(*cp) > 0) {
                cp++;
                continue;
            }
            else if (*cp == ' ' || *cp == '\t' || *cp == '\n') {
                cp++;
                continue;
            }
            else if (*cp == '=') {
                attribute = zap_sp_and_dup(p, mp, cp, NULL);
                if (attribute == NULL || *attribute == '\0') {
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
                                 "Cannot get media parameter.");
                    return (NULL);
                }
                cp++;
                cp = zap_sp(cp);
                if (cp == NULL || *cp == '\0') {
                    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
                                 "Cannot get media parameter.");
                    return (NULL);
                }
                mp = cp;
                continue;
            }
            else {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
                             "Cannot get media parameter.");
                return (NULL);
            }
        }
        else {
            if (mp == cp) {
                if (*cp == '"') {
                    quoted = 1;
                    cp++;
                }
                else {
                    quoted = 0;
                }
            }
            if (quoted > 0) {
                while (quoted && *cp != '\0') {
                    if (is_qtext(*cp) > 0) {
                        cp++;
                    }
                    else if (is_quoted_pair(cp) > 0) {
                        cp += 2;
                    }
                    else if (*cp == '"') {
                        cp++;
                        while (*cp == ' ' || *cp == '\t' || *cp == '\n') {
                            cp++;
                        }
                        if (*cp != ';' && *cp != '\0') {
                            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
                                         "Cannot get media parameter.");
                            return(NULL);
                        }
                        quoted = 0;
                    }
                    else {
                        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
                                     "Cannot get media parameter.");
                        return (NULL);
                    }
                }
            }
            else {
                while (1) {
                    if (is_token(*cp) > 0) {
                        cp++;
                    }
                    else if (*cp == '\0' || *cp == ';') {
                        break;
                    }
                    else {
                        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
                                     "Cannot get media parameter.");
                        return (NULL);
                    }
                }
            }
            value = zap_sp_and_dup(p, mp, cp, NULL);
            if (value == NULL || *value == '\0') {
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
                             "Cannot get media parameter.");
                return (NULL);
            }

            pp = apr_palloc(p, sizeof(param));
            pp->attr = attribute;
            pp->val = value;
            pp->next = NULL;

            if (ctp->param == NULL) {
                ctp->param = pp;
            }
            else {
                npp = ctp->param;
                while (npp->next) {
                    npp = npp->next;
                }
                npp->next = pp;
            }
            quoted = 0;
            attribute = NULL;
            value = NULL;
            if (*cp == '\0') {
                break;
            }
            cp++;
            mp = cp;
        }
    }
    return (ctp);
}

/*
 * find_ct is the hook routine for determining content-type and other
 * MIME-related metadata.  It assumes that r->filename has already been
 * set and stat has been called for r->finfo.  It also assumes that the
 * non-path base file name is not the empty string unless it is a dir.
 */
static int find_ct(request_rec *r)
{
    mime_dir_config *conf;
    apr_array_header_t *exception_list;
    char *ext;
    const char *fn, *type, *charset = NULL, *resource_name;
    int found_metadata = 0;

    if (r->finfo.filetype == APR_DIR) {
        ap_set_content_type(r, DIR_MAGIC_TYPE);
        return OK;
    }

    if (!r->filename) {
        return DECLINED;
    }

    conf = (mime_dir_config *)ap_get_module_config(r->per_dir_config,
                                                   &mime_module);
    exception_list = apr_array_make(r->pool, 2, sizeof(char *));

    /* If use_path_info is explicitly set to on (value & 1 == 1), append. */
    if (conf->use_path_info & 1) {
        resource_name = apr_pstrcat(r->pool, r->filename, r->path_info, NULL);
    }
    else {
        resource_name = r->filename;
    }

    /* Always drop the path leading up to the file name.
     */
    if ((fn = ap_strrchr_c(resource_name, '/')) == NULL) {
        fn = resource_name;
    }
    else {
        ++fn;
    }

    /* The exception list keeps track of those filename components that
     * are not associated with extensions indicating metadata.
     * The base name is always the first exception (i.e., "txt.html" has
     * a basename of "txt" even though it might look like an extension).
     */
    ext = ap_getword(r->pool, &fn, '.');
    *((const char **)apr_array_push(exception_list)) = ext;

    /* Parse filename extensions which can be in any order 
     */
    while (*fn && (ext = ap_getword(r->pool, &fn, '.'))) {
        const extension_info *exinfo = NULL;
        int found;

        if (*ext == '\0') {  /* ignore empty extensions "bad..html" */
            continue;
        }

        found = 0;

        ap_str_tolower(ext);

        if (conf->extension_mappings != NULL) {
            exinfo = (extension_info*)apr_hash_get(conf->extension_mappings,
                                                   ext, APR_HASH_KEY_STRING);
        }

        if (exinfo == NULL || !exinfo->forced_type) {
            if ((type = apr_hash_get(mime_type_extensions, ext,
                                     APR_HASH_KEY_STRING)) != NULL) {
                ap_set_content_type(r, (char*) type);
                found = 1;
            }
        }

        if (exinfo != NULL) {

            if (exinfo->forced_type) {
                ap_set_content_type(r, exinfo->forced_type);
                found = 1;
            }

            if (exinfo->charset_type) {
                charset = exinfo->charset_type;
                found = 1;
            }
            if (exinfo->language_type) {
                if (!r->content_languages) {
                    r->content_languages = apr_array_make(r->pool, 2,
                                                          sizeof(char *));
                }
                *((const char **)apr_array_push(r->content_languages))
                    = exinfo->language_type;
                found = 1;
            }
            if (exinfo->encoding_type) {
                if (!r->content_encoding) {
                    r->content_encoding = exinfo->encoding_type;
                }
                else {
                    /* XXX should eliminate duplicate entities */
                    r->content_encoding = apr_pstrcat(r->pool,
                                                      r->content_encoding,
                                                      ", ",
                                                      exinfo->encoding_type,
                                                      NULL);
                }
                found = 1;
            }
            /* The following extensions are not 'Found'.  That is, they don't
             * make any contribution to metadata negotation, so they must have
             * been explicitly requested by name. 
             */
            if (exinfo->handler && r->proxyreq == PROXYREQ_NONE) {
                r->handler = exinfo->handler;
                if (conf->multimatch & MULTIMATCH_HANDLERS) {
                    found = 1;
                }
            }
            /* XXX Two significant problems; 1, we don't check to see if we are
             * setting redundant filters.    2, we insert these in the types config
             * hook, which may be too early (dunno.)
             */
            if (exinfo->input_filters && r->proxyreq == PROXYREQ_NONE) {
                const char *filter, *filters = exinfo->input_filters;
                while (*filters 
                    && (filter = ap_getword(r->pool, &filters, ';'))) {
                    ap_add_input_filter(filter, NULL, r, r->connection);
                }
                if (conf->multimatch & MULTIMATCH_FILTERS) {
                    found = 1;
                }
            }
            if (exinfo->output_filters && r->proxyreq == PROXYREQ_NONE) {
                const char *filter, *filters = exinfo->output_filters;
                while (*filters 
                    && (filter = ap_getword(r->pool, &filters, ';'))) {
                    ap_add_output_filter(filter, NULL, r, r->connection);
                }
                if (conf->multimatch & MULTIMATCH_FILTERS) {
                    found = 1;
                }
            }
        }

        if (found || (conf->multimatch & MULTIMATCH_ANY)) {
            found_metadata = 1;
        }
        else {
            *((const char **) apr_array_push(exception_list)) = ext;
        }
    }

    /*
     * Need to set a notes entry on r for unrecognized elements.
     * Somebody better claim them!  If we did absolutely nothing,
     * skip the notes to alert mod_negotiation we are clueless.
     */
    if (found_metadata) {
        apr_table_setn(r->notes, "ap-mime-exceptions-list", 
                       (void *)exception_list);
    }

    if (r->content_type) {
        content_type *ctp;
        int override = 0;

        if ((ctp = analyze_ct(r, r->content_type))) {
            param *pp = ctp->param;
            char *base_content_type = apr_palloc(r->pool, ctp->type_len +
                                                 ctp->subtype_len +
                                                 sizeof("/"));
            char *tmp = base_content_type;
            memcpy(tmp, ctp->type, ctp->type_len);
            tmp += ctp->type_len;
            *tmp++ = '/';
            memcpy(tmp, ctp->subtype, ctp->subtype_len);
            tmp += ctp->subtype_len;
            *tmp = 0;
            ap_set_content_type(r, base_content_type);
            while (pp != NULL) {
                if (charset && !strcmp(pp->attr, "charset")) {
                    if (!override) {
                        ap_set_content_type(r,
                                            apr_pstrcat(r->pool,
                                                        r->content_type,
                                                        "; charset=",
                                                        charset,
                                                        NULL));
                        override = 1;
                    }
                }
                else {
                    ap_set_content_type(r,
                                        apr_pstrcat(r->pool,
                                                    r->content_type,
                                                    "; ", pp->attr,
                                                    "=", pp->val,
                                                    NULL));
                }
                pp = pp->next;
            }
            if (charset && !override) {
                ap_set_content_type(r, apr_pstrcat(r->pool, r->content_type,
                                                   "; charset=", charset,
                                                   NULL));
            }
        }
    }

    /* Set default language, if none was specified by the extensions
     * and we have a DefaultLanguage setting in force
     */

    if (!r->content_languages && conf->default_language) {
        const char **new;

        if (!r->content_languages) {
            r->content_languages = apr_array_make(r->pool, 2, sizeof(char *));
        }
        new = (const char **)apr_array_push(r->content_languages);
        *new = conf->default_language;
    }

    if (!r->content_type) {
        return DECLINED;
    }

    return OK;
}

static void register_hooks(apr_pool_t *p)
{
    ap_hook_post_config(mime_post_config,NULL,NULL,APR_HOOK_MIDDLE);
    ap_hook_type_checker(find_ct,NULL,NULL,APR_HOOK_MIDDLE);
    /* 
     * this hook seems redundant ... is there any reason a type checker isn't
     * allowed to do this already?  I'd think that fixups in general would be
     * the last opportunity to get the filters right.
     * ap_hook_insert_filter(mime_insert_filters,NULL,NULL,APR_HOOK_MIDDLE);
     */
}

module AP_MODULE_DECLARE_DATA mime_module = {
    STANDARD20_MODULE_STUFF,
    create_mime_dir_config,     /* create per-directory config structure */
    merge_mime_dir_configs,     /* merge per-directory config structures */
    NULL,                       /* create per-server config structure */
    NULL,                       /* merge per-server config structures */
    mime_cmds,                  /* command apr_table_t */
    register_hooks              /* register hooks */
};
