⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_mime.c

📁 Apache官方在今天放出产品系列2.2的最新版本2.2.11的源码包 最流行的HTTP服务器软件之一
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 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    8typedef 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){    const extension_info *overlay_info = (const extension_info *)overlay_val;    const extension_info *base_info = (const extension_info *)base_val;    extension_info *new_info = apr_pmemdup(p, 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 "NegotiatedOnly is incompatible with Any, "                   "Filters and Handlers";        }        m->multimatch |= MULTIMATCH_NEGOTIATED;    }    else if (strcasecmp(include, "Filters") == 0) {        if (m->multimatch && (m->multimatch & (MULTIMATCH_NEGOTIATED

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -