diff options
Diffstat (limited to 'rubbos/app/httpd-2.0.64/modules/http/mod_mime.c')
-rw-r--r-- | rubbos/app/httpd-2.0.64/modules/http/mod_mime.c | 987 |
1 files changed, 0 insertions, 987 deletions
diff --git a/rubbos/app/httpd-2.0.64/modules/http/mod_mime.c b/rubbos/app/httpd-2.0.64/modules/http/mod_mime.c deleted file mode 100644 index 214cd8bf..00000000 --- a/rubbos/app/httpd-2.0.64/modules/http/mod_mime.c +++ /dev/null @@ -1,987 +0,0 @@ -/* 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 */ -}; |