mod_mime.c revision 853a0c44563b056e40e9cffe911190f554e63ec3
93fa7e4374de6e37328e752991a698bf03032c75Christian Maeder/* ====================================================================
93fa7e4374de6e37328e752991a698bf03032c75Christian Maeder * The Apache Software License, Version 1.1
93fa7e4374de6e37328e752991a698bf03032c75Christian Maeder *
93fa7e4374de6e37328e752991a698bf03032c75Christian Maeder * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
93fa7e4374de6e37328e752991a698bf03032c75Christian Maeder * reserved.
93fa7e4374de6e37328e752991a698bf03032c75Christian Maeder *
93fa7e4374de6e37328e752991a698bf03032c75Christian Maeder * Redistribution and use in source and binary forms, with or without
93fa7e4374de6e37328e752991a698bf03032c75Christian Maeder * modification, are permitted provided that the following conditions
93fa7e4374de6e37328e752991a698bf03032c75Christian Maeder * are met:
d697755cce49a436e1170e8e158c19f79b0389b8Christian Maeder *
d697755cce49a436e1170e8e158c19f79b0389b8Christian Maeder * 1. Redistributions of source code must retain the above copyright
d697755cce49a436e1170e8e158c19f79b0389b8Christian Maeder * notice, this list of conditions and the following disclaimer.
d697755cce49a436e1170e8e158c19f79b0389b8Christian Maeder *
d697755cce49a436e1170e8e158c19f79b0389b8Christian Maeder * 2. Redistributions in binary form must reproduce the above copyright
d697755cce49a436e1170e8e158c19f79b0389b8Christian Maeder * notice, this list of conditions and the following disclaimer in
e4eed2389ec1b1bfa03c662c71e8165e93df43c4Christian Maeder * the documentation and/or other materials provided with the
e4eed2389ec1b1bfa03c662c71e8165e93df43c4Christian Maeder * distribution.
fd40e201b7277427113c89724d8a2389c18e9cbdChristian Maeder *
fd40e201b7277427113c89724d8a2389c18e9cbdChristian Maeder * 3. The end-user documentation included with the redistribution,
d697755cce49a436e1170e8e158c19f79b0389b8Christian Maeder * if any, must include the following acknowledgment:
9987d35a267440c71e1e8b21c2ee6081a6390643Christian Maeder * "This product includes software developed by the
93fa7e4374de6e37328e752991a698bf03032c75Christian Maeder * Apache Software Foundation (http://www.apache.org/)."
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder * Alternately, this acknowledgment may appear in the software itself,
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder * if and wherever such third-party acknowledgments normally appear.
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder *
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder * 4. The names "Apache" and "Apache Software Foundation" must
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder * not be used to endorse or promote products derived from this
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder * software without prior written permission. For written
e69bfc714e534d71322f504dde433941142e1c05Christian Maeder * permission, please contact apache@apache.org.
e69bfc714e534d71322f504dde433941142e1c05Christian Maeder *
e69bfc714e534d71322f504dde433941142e1c05Christian Maeder * 5. Products derived from this software may not be called "Apache",
e69bfc714e534d71322f504dde433941142e1c05Christian Maeder * nor may "Apache" appear in their name, without prior written
b26211de8c1e50efbabbb95497e7508c4d852634Christian Maeder * permission of the Apache Software Foundation.
b26211de8c1e50efbabbb95497e7508c4d852634Christian Maeder *
b26211de8c1e50efbabbb95497e7508c4d852634Christian Maeder * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
b26211de8c1e50efbabbb95497e7508c4d852634Christian Maeder * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
b26211de8c1e50efbabbb95497e7508c4d852634Christian Maeder * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
b26211de8c1e50efbabbb95497e7508c4d852634Christian Maeder * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
b26211de8c1e50efbabbb95497e7508c4d852634Christian Maeder * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
b26211de8c1e50efbabbb95497e7508c4d852634Christian Maeder * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
b26211de8c1e50efbabbb95497e7508c4d852634Christian Maeder * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
b26211de8c1e50efbabbb95497e7508c4d852634Christian Maeder * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
b26211de8c1e50efbabbb95497e7508c4d852634Christian Maeder * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
b26211de8c1e50efbabbb95497e7508c4d852634Christian Maeder * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
b26211de8c1e50efbabbb95497e7508c4d852634Christian Maeder * SUCH DAMAGE.
b26211de8c1e50efbabbb95497e7508c4d852634Christian Maeder * ====================================================================
c8bf82bdb27dfa58f7f05045c639c14276be3333Christian Maeder *
b26211de8c1e50efbabbb95497e7508c4d852634Christian Maeder * This software consists of voluntary contributions made by many
93fa7e4374de6e37328e752991a698bf03032c75Christian Maeder * individuals on behalf of the Apache Software Foundation. For more
e4eed2389ec1b1bfa03c662c71e8165e93df43c4Christian Maeder * information on the Apache Software Foundation, please see
e4eed2389ec1b1bfa03c662c71e8165e93df43c4Christian Maeder * <http://www.apache.org/>.
70ca840c8a6cf3591d5f9aa9a3de6fae42d696e8Christian Maeder *
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder * Portions of this software are based upon public domain software
e4eed2389ec1b1bfa03c662c71e8165e93df43c4Christian Maeder * originally written at the National Center for Supercomputing Applications,
e4eed2389ec1b1bfa03c662c71e8165e93df43c4Christian Maeder * University of Illinois, Urbana-Champaign.
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder */
9987d35a267440c71e1e8b21c2ee6081a6390643Christian Maeder
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder/*
e4eed2389ec1b1bfa03c662c71e8165e93df43c4Christian Maeder * http_mime.c: Sends/gets MIME headers for requests
93fa7e4374de6e37328e752991a698bf03032c75Christian Maeder *
9987d35a267440c71e1e8b21c2ee6081a6390643Christian Maeder * Rob McCool
e4eed2389ec1b1bfa03c662c71e8165e93df43c4Christian Maeder *
9987d35a267440c71e1e8b21c2ee6081a6390643Christian Maeder */
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder#include "apr.h"
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder#include "apr_strings.h"
9987d35a267440c71e1e8b21c2ee6081a6390643Christian Maeder#include "apr_lib.h"
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder
9987d35a267440c71e1e8b21c2ee6081a6390643Christian Maeder#define APR_WANT_STRFUNC
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder#include "apr_want.h"
9987d35a267440c71e1e8b21c2ee6081a6390643Christian Maeder
9987d35a267440c71e1e8b21c2ee6081a6390643Christian Maeder#include "ap_config.h"
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder#include "httpd.h"
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder#include "http_config.h"
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder#include "http_log.h"
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder#include "http_request.h"
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder/* XXXX - fix me / EBCDIC
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder * there was a cludge here which would use its
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder * own version apr_isascii(). Indicating that
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder * on some platforms that might be needed.
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder *
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder * #define OS_ASC(c) (c) -- for mere mortals
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder * or
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder * #define OS_ASC(c) (ebcdic2ascii[c]) -- for dino's
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder *
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder * #define apr_isascii(c) ((OS_ASC(c) & 0x80) == 0)
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder */
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder/* XXXXX - fix me - See note with NOT_PROXY
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder */
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maedertypedef struct attrib_info {
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder char *name;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder} attrib_info;
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maedertypedef struct {
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder apr_table_t *forced_types; /* Additional AddTyped stuff */
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder apr_table_t *encoding_types; /* Added with AddEncoding... */
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder apr_table_t *language_types; /* Added with AddLanguage... */
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder apr_table_t *handlers; /* Added with AddHandler... */
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder apr_table_t *charset_types; /* Added with AddCharset... */
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder apr_array_header_t *handlers_remove; /* List of handlers to remove */
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder apr_array_header_t *types_remove; /* List of MIME types to remove */
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder apr_array_header_t *encodings_remove; /* List of encodings to remove */
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder char *type; /* Type forced with ForceType */
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder char *handler; /* Handler forced with SetHandler */
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder char *default_language; /* Language if no AddLanguage ext found */
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder /* Due to the FUD about JS and charsets
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder * default_charset is actually in src/main */
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder} mime_dir_config;
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maedertypedef struct param_s {
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder char *attr;
93fa7e4374de6e37328e752991a698bf03032c75Christian Maeder char *val;
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder struct param_s *next;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder} param;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maedertypedef struct {
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder char *type;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder char *subtype;
93fa7e4374de6e37328e752991a698bf03032c75Christian Maeder param *param;
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder} content_type;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder
6fb319833285f714693d58e9620d67ab21ddebe4Christian Maederstatic char tspecial[] = {
6fb319833285f714693d58e9620d67ab21ddebe4Christian Maeder '(', ')', '<', '>', '@', ',', ';', ':',
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder '\\', '"', '/', '[', ']', '?', '=',
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder '\0'
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder};
6fb319833285f714693d58e9620d67ab21ddebe4Christian Maeder
6fb319833285f714693d58e9620d67ab21ddebe4Christian Maedermodule AP_MODULE_DECLARE_DATA mime_module;
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder
6fb319833285f714693d58e9620d67ab21ddebe4Christian Maederstatic void *create_mime_dir_config(apr_pool_t *p, char *dummy)
6eed7cde6b75d63ec6b8f7e31caac6919558a676Christian Maeder{
6eed7cde6b75d63ec6b8f7e31caac6919558a676Christian Maeder mime_dir_config *new =
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder (mime_dir_config *) apr_palloc(p, sizeof(mime_dir_config));
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder new->forced_types = apr_table_make(p, 4);
6eed7cde6b75d63ec6b8f7e31caac6919558a676Christian Maeder new->encoding_types = apr_table_make(p, 4);
6fb319833285f714693d58e9620d67ab21ddebe4Christian Maeder new->charset_types = apr_table_make(p, 4);
6eed7cde6b75d63ec6b8f7e31caac6919558a676Christian Maeder new->language_types = apr_table_make(p, 4);
6eed7cde6b75d63ec6b8f7e31caac6919558a676Christian Maeder new->handlers = apr_table_make(p, 4);
6eed7cde6b75d63ec6b8f7e31caac6919558a676Christian Maeder new->handlers_remove = apr_array_make(p, 4, sizeof(attrib_info));
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder new->types_remove = apr_array_make(p, 4, sizeof(attrib_info));
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder new->encodings_remove = apr_array_make(p, 4, sizeof(attrib_info));
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder new->type = NULL;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder new->handler = NULL;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder new->default_language = NULL;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder return new;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder}
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maederstatic void *merge_mime_dir_configs(apr_pool_t *p, void *basev, void *addv)
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder{
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder mime_dir_config *base = (mime_dir_config *) basev;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder mime_dir_config *add = (mime_dir_config *) addv;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder mime_dir_config *new =
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder (mime_dir_config *) apr_palloc(p, sizeof(mime_dir_config));
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder int i;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder attrib_info *suffix;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder new->forced_types = apr_table_overlay(p, add->forced_types,
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder base->forced_types);
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder new->encoding_types = apr_table_overlay(p, add->encoding_types,
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder base->encoding_types);
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder new->charset_types = apr_table_overlay(p, add->charset_types,
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder base->charset_types);
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder new->language_types = apr_table_overlay(p, add->language_types,
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder base->language_types);
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder new->handlers = apr_table_overlay(p, add->handlers,
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder base->handlers);
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder suffix = (attrib_info *) add->handlers_remove->elts;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder for (i = 0; i < add->handlers_remove->nelts; i++) {
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder apr_table_unset(new->handlers, suffix[i].name);
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder }
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder
70ca840c8a6cf3591d5f9aa9a3de6fae42d696e8Christian Maeder suffix = (attrib_info *) add->types_remove->elts;
6fb319833285f714693d58e9620d67ab21ddebe4Christian Maeder for (i = 0; i < add->types_remove->nelts; i++) {
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder apr_table_unset(new->forced_types, suffix[i].name);
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder }
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder suffix = (attrib_info *) add->encodings_remove->elts;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder for (i = 0; i < add->encodings_remove->nelts; i++) {
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder apr_table_unset(new->encoding_types, suffix[i].name);
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder }
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder new->type = add->type ? add->type : base->type;
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder new->handler = add->handler ? add->handler : base->handler;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder new->default_language = add->default_language ?
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder add->default_language : base->default_language;
70ca840c8a6cf3591d5f9aa9a3de6fae42d696e8Christian Maeder
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder return new;
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder}
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maederstatic const char *add_type(cmd_parms *cmd, void *m_, const char *ct_,
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder const char *ext)
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder{
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder mime_dir_config *m=m_;
e69bfc714e534d71322f504dde433941142e1c05Christian Maeder char *ct=apr_pstrdup(cmd->pool,ct_);
6fb319833285f714693d58e9620d67ab21ddebe4Christian Maeder
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder if (*ext == '.')
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder ++ext;
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder
6fb319833285f714693d58e9620d67ab21ddebe4Christian Maeder ap_str_tolower(ct);
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder apr_table_setn(m->forced_types, ext, ct);
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder return NULL;
9987d35a267440c71e1e8b21c2ee6081a6390643Christian Maeder}
e69bfc714e534d71322f504dde433941142e1c05Christian Maeder
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maederstatic const char *add_encoding(cmd_parms *cmd, void *m_, const char *enc_,
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder const char *ext)
b26211de8c1e50efbabbb95497e7508c4d852634Christian Maeder{
6fb319833285f714693d58e9620d67ab21ddebe4Christian Maeder mime_dir_config *m=m_;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder char *enc=apr_pstrdup(cmd->pool,enc_);
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder
6fb319833285f714693d58e9620d67ab21ddebe4Christian Maeder if (*ext == '.')
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder ++ext;
6fb319833285f714693d58e9620d67ab21ddebe4Christian Maeder ap_str_tolower(enc);
6fb319833285f714693d58e9620d67ab21ddebe4Christian Maeder apr_table_setn(m->encoding_types, ext, enc);
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder return NULL;
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder}
6fb319833285f714693d58e9620d67ab21ddebe4Christian Maeder
6fb319833285f714693d58e9620d67ab21ddebe4Christian Maederstatic const char *add_charset(cmd_parms *cmd, void *m_, const char *charset_,
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder const char *ext)
6fb319833285f714693d58e9620d67ab21ddebe4Christian Maeder{
6fb319833285f714693d58e9620d67ab21ddebe4Christian Maeder mime_dir_config *m=m_;
6fb319833285f714693d58e9620d67ab21ddebe4Christian Maeder char *charset=apr_pstrdup(cmd->pool,charset_);
c8bf82bdb27dfa58f7f05045c639c14276be3333Christian Maeder
c8bf82bdb27dfa58f7f05045c639c14276be3333Christian Maeder if (*ext == '.') {
c8bf82bdb27dfa58f7f05045c639c14276be3333Christian Maeder ++ext;
c8bf82bdb27dfa58f7f05045c639c14276be3333Christian Maeder }
c8bf82bdb27dfa58f7f05045c639c14276be3333Christian Maeder ap_str_tolower(charset);
c8bf82bdb27dfa58f7f05045c639c14276be3333Christian Maeder apr_table_setn(m->charset_types, ext, charset);
c8bf82bdb27dfa58f7f05045c639c14276be3333Christian Maeder return NULL;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder}
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maederstatic const char *add_language(cmd_parms *cmd, void *m_, const char *lang_,
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder const char *ext)
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder{
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder mime_dir_config *m=m_;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder char *lang=apr_pstrdup(cmd->pool,lang_);
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder if (*ext == '.') {
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder ++ext;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder }
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder ap_str_tolower(lang);
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder apr_table_setn(m->language_types, ext, lang);
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder return NULL;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder}
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maederstatic const char *add_handler(cmd_parms *cmd, void *m_, const char *hdlr_,
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder const char *ext)
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder{
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder mime_dir_config *m=m_;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder char *hdlr=apr_pstrdup(cmd->pool,hdlr_);
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder if (*ext == '.')
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder ++ext;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder ap_str_tolower(hdlr);
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder apr_table_setn(m->handlers, ext, hdlr);
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder return NULL;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder}
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder/*
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder * Note handler names that should be un-added for this location. This
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder * will keep the association from being inherited, as well, but not
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder * from being re-added at a subordinate level.
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder */
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maederstatic const char *remove_handler(cmd_parms *cmd, void *m, const char *ext)
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder{
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder mime_dir_config *mcfg = (mime_dir_config *) m;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder attrib_info *suffix;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder if (*ext == '.') {
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder ++ext;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder }
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder suffix = (attrib_info *) apr_array_push(mcfg->handlers_remove);
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder suffix->name = apr_pstrdup(cmd->pool, ext);
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder return NULL;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder}
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder/*
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder * Just like the previous function, except that it records encoding
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder * associations to be undone.
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder */
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maederstatic const char *remove_encoding(cmd_parms *cmd, void *m, const char *ext)
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder{
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder mime_dir_config *mcfg = (mime_dir_config *) m;
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder attrib_info *suffix;
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder if (*ext == '.') {
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder ++ext;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder }
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder suffix = (attrib_info *) apr_array_push(mcfg->encodings_remove);
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder suffix->name = apr_pstrdup(cmd->pool, ext);
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder return NULL;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder}
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder/*
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder * Similar to the previous functions, except that it deals with filename
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder * suffix/MIME-type associations.
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder */
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maederstatic const char *remove_type(cmd_parms *cmd, void *m, const char *ext)
9987d35a267440c71e1e8b21c2ee6081a6390643Christian Maeder{
9987d35a267440c71e1e8b21c2ee6081a6390643Christian Maeder mime_dir_config *mcfg = (mime_dir_config *) m;
9987d35a267440c71e1e8b21c2ee6081a6390643Christian Maeder attrib_info *suffix;
9987d35a267440c71e1e8b21c2ee6081a6390643Christian Maeder
9987d35a267440c71e1e8b21c2ee6081a6390643Christian Maeder if (*ext == '.') {
9987d35a267440c71e1e8b21c2ee6081a6390643Christian Maeder ++ext;
9987d35a267440c71e1e8b21c2ee6081a6390643Christian Maeder }
9987d35a267440c71e1e8b21c2ee6081a6390643Christian Maeder suffix = (attrib_info *) apr_array_push(mcfg->types_remove);
9987d35a267440c71e1e8b21c2ee6081a6390643Christian Maeder suffix->name = apr_pstrdup(cmd->pool, ext);
9987d35a267440c71e1e8b21c2ee6081a6390643Christian Maeder return NULL;
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder}
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder/* The sole bit of server configuration that the MIME module has is
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder * the name of its config file, so...
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder */
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maederstatic const char *set_types_config(cmd_parms *cmd, void *dummy,
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder const char *arg)
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder{
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder ap_set_module_config(cmd->server->module_config, &mime_module,
3004ea619754fb657d87ecad1d9a8b6b8ed0f9d1Christian Maeder (void *)arg);
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder return NULL;
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder}
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maederstatic const command_rec mime_cmds[] =
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder{
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian MaederAP_INIT_ITERATE2("AddType", add_type, NULL, OR_FILEINFO,
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder "a mime type followed by one or more file extensions"),
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian MaederAP_INIT_ITERATE2("AddEncoding", add_encoding, NULL, OR_FILEINFO,
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder "an encoding (e.g., gzip), followed by one or more file extensions"),
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian MaederAP_INIT_ITERATE2("AddCharset", add_charset, NULL, OR_FILEINFO,
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder "a charset (e.g., iso-2022-jp), followed by one or more file extensions"),
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian MaederAP_INIT_ITERATE2("AddLanguage", add_language, NULL, OR_FILEINFO,
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder "a language (e.g., fr), followed by one or more file extensions"),
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian MaederAP_INIT_ITERATE2("AddHandler", add_handler, NULL, OR_FILEINFO,
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder "a handler name followed by one or more file extensions"),
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian MaederAP_INIT_TAKE1("ForceType", ap_set_string_slot_lower,
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder (void *)XtOffsetOf(mime_dir_config, type), OR_FILEINFO,
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder "a media type"),
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian MaederAP_INIT_ITERATE("RemoveHandler", remove_handler, NULL, OR_FILEINFO,
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder "one or more file extensions"),
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian MaederAP_INIT_ITERATE("RemoveEncoding", remove_encoding, NULL, OR_FILEINFO,
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder "one or more file extensions"),
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian MaederAP_INIT_ITERATE("RemoveType", remove_type, NULL, OR_FILEINFO,
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder "one or more file extensions"),
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian MaederAP_INIT_TAKE1("SetHandler", ap_set_string_slot_lower,
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder (void *)XtOffsetOf(mime_dir_config, handler), OR_FILEINFO,
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder "a handler name"),
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian MaederAP_INIT_TAKE1("TypesConfig", set_types_config, NULL, RSRC_CONF,
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder "the MIME types config file"),
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian MaederAP_INIT_TAKE1("DefaultLanguage", ap_set_string_slot,
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder (void*)XtOffsetOf(mime_dir_config, default_language), OR_FILEINFO,
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder "language to use for documents with no other language file extension"),
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder {NULL}
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder};
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder/* Hash apr_table_t --- only one of these per daemon; virtual hosts can
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder * get private versions through AddType...
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder */
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder#define MIME_HASHSIZE (32)
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder#define hash(i) (apr_tolower(i) % MIME_HASHSIZE)
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maederstatic apr_table_t *hash_buckets[MIME_HASHSIZE];
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maederstatic void mime_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder{
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder ap_configfile_t *f;
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder char l[MAX_STRING_LEN];
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder int x;
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder const char *types_confname = ap_get_module_config(s->module_config, &mime_module);
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder apr_status_t status;
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder if (!types_confname)
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder types_confname = AP_TYPES_CONFIG_FILE;
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder types_confname = ap_server_root_relative(p, types_confname);
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder if ((status = ap_pcfg_openfile(&f, p, types_confname)) != APR_SUCCESS) {
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder ap_log_error(APLOG_MARK, APLOG_ERR, status, s,
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder "could not open mime types config file %s.", types_confname);
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder exit(1);
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder }
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder for (x = 0; x < MIME_HASHSIZE; x++)
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder hash_buckets[x] = apr_table_make(p, 10);
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder const char *ll = l, *ct;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder if (l[0] == '#')
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder continue;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder ct = ap_getword_conf(p, &ll);
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder while (ll[0]) {
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder char *ext = ap_getword_conf(p, &ll);
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder ap_str_tolower(ext); /* ??? */
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder apr_table_setn(hash_buckets[hash(ext[0])], ext, ct);
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder }
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder }
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder ap_cfg_closefile(f);
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder}
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maederstatic char *zap_sp(char *s)
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder{
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder char *tp;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder if (s == NULL) {
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder return (NULL);
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder }
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder if (*s == '\0') {
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder return (s);
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder }
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder /* delete prefixed white space */
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder for (; *s == ' ' || *s == '\t' || *s == '\n'; s++);
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder /* delete postfixed white space */
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder for (tp = s; *tp != '\0'; tp++);
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder for (tp--; tp != s && (*tp == ' ' || *tp == '\t' || *tp == '\n'); tp--) {
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder *tp = '\0';
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder }
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder return (s);
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder}
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maederstatic int is_token(char c)
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder{
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder int res;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder res = (apr_isascii(c) && apr_isgraph(c)
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder && (strchr(tspecial, c) == NULL)) ? 1 : -1;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder return res;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder}
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maederstatic int is_qtext(char c)
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder{
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder int res;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder res = (apr_isascii(c) && (c != '"') && (c != '\\') && (c != '\n'))
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder ? 1 : -1;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder return res;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder}
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maederstatic int is_quoted_pair(char *s)
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder{
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder int res = -1;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder int c;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder if (((s + 1) != NULL) && (*s == '\\')) {
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder c = (int) *(s + 1);
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder if (apr_isascii(c)) {
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder res = 1;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder }
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder }
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder return (res);
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder}
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maederstatic content_type *analyze_ct(request_rec *r, char *s)
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder{
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder char *tp, *mp, *cp;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder char *attribute, *value;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder int quoted = 0;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder server_rec * ss = r->server;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder apr_pool_t * p = r->pool;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder content_type *ctp;
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder param *pp, *npp;
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder /* initialize ctp */
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder ctp = (content_type *) apr_palloc(p, sizeof(content_type));
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder ctp->type = NULL;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder ctp->subtype = NULL;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder ctp->param = NULL;
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder tp = apr_pstrdup(p, s);
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder mp = tp;
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder cp = mp;
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder
5d05fc7110bca98e897a726d60dd5f67c4100814Christian Maeder /* getting a type */
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder if (!(cp = strchr(mp, '/'))) {
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
ab7a0615fceecfe401c3229ce7147d2bafc80287Christian Maeder "mod_mime: analyze_ct: cannot get media type from '%s'",
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder (const char *) mp);
6eed7cde6b75d63ec6b8f7e31caac6919558a676Christian Maeder return (NULL);
190828a6ce12ff8c502e3d7303dcc0d70db49b6cChristian Maeder }
70ca840c8a6cf3591d5f9aa9a3de6fae42d696e8Christian Maeder ctp->type = apr_pstrndup(p, mp, cp - mp);
93fa7e4374de6e37328e752991a698bf03032c75Christian Maeder ctp->type = zap_sp(ctp->type);
93fa7e4374de6e37328e752991a698bf03032c75Christian Maeder if (ctp->type == NULL || *(ctp->type) == '\0' ||
93fa7e4374de6e37328e752991a698bf03032c75Christian Maeder strchr(ctp->type, ';') || strchr(ctp->type, ' ') ||
d697755cce49a436e1170e8e158c19f79b0389b8Christian Maeder strchr(ctp->type, '\t')) {
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder "Cannot get media subtype.");
fd40e201b7277427113c89724d8a2389c18e9cbdChristian Maeder return (NULL);
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder }
fd40e201b7277427113c89724d8a2389c18e9cbdChristian Maeder
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder /* getting a subtype */
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder cp++;
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder mp = cp;
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder for (; *cp != ';' && *cp != '\0'; cp++)
fd40e201b7277427113c89724d8a2389c18e9cbdChristian Maeder continue;
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder ctp->subtype = apr_pstrndup(p, mp, cp - mp);
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder ctp->subtype = zap_sp(ctp->subtype);
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder if ((ctp->subtype == NULL) || (*(ctp->subtype) == '\0') ||
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder strchr(ctp->subtype, ' ') || strchr(ctp->subtype, '\t')) {
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder "Cannot get media subtype.");
fd40e201b7277427113c89724d8a2389c18e9cbdChristian Maeder return (NULL);
fd40e201b7277427113c89724d8a2389c18e9cbdChristian Maeder }
fd40e201b7277427113c89724d8a2389c18e9cbdChristian Maeder cp = zap_sp(cp);
3f0cd3e73a8aa47bb586b69fe5f7fa450000ecfdChristian Maeder if (cp == NULL || *cp == '\0') {
fd40e201b7277427113c89724d8a2389c18e9cbdChristian Maeder return (ctp);
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder }
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder /* getting parameters */
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder cp++;
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder cp = zap_sp(cp);
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder if (cp == NULL || *cp == '\0') {
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder "Cannot get media parameter.");
7bdf8f2044ee1bb844ec460e7d96fbdee69feda4Christian Maeder return (NULL);
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder }
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder mp = cp;
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder attribute = NULL;
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder value = NULL;
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder while (cp != NULL && *cp != '\0') {
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder if (attribute == NULL) {
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder if (is_token(*cp) > 0) {
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder cp++;
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder continue;
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder }
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder else if (*cp == ' ' || *cp == '\t' || *cp == '\n') {
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder cp++;
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder continue;
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder }
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder else if (*cp == '=') {
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder attribute = apr_pstrndup(p, mp, cp - mp);
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder attribute = zap_sp(attribute);
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder if (attribute == NULL || *attribute == '\0') {
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder "Cannot get media parameter.");
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder return (NULL);
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder }
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder cp++;
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder cp = zap_sp(cp);
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder if (cp == NULL || *cp == '\0') {
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder "Cannot get media parameter.");
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder return (NULL);
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder }
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder mp = cp;
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder continue;
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder }
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder else {
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder "Cannot get media parameter.");
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder return (NULL);
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder }
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder }
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder else {
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder if (mp == cp) {
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder if (*cp == '"') {
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder quoted = 1;
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder cp++;
fd40e201b7277427113c89724d8a2389c18e9cbdChristian Maeder }
fd40e201b7277427113c89724d8a2389c18e9cbdChristian Maeder else {
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder quoted = 0;
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder }
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder }
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder if (quoted > 0) {
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder while (quoted && *cp != '\0') {
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder if (is_qtext(*cp) > 0) {
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder cp++;
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder }
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder else if (is_quoted_pair(cp) > 0) {
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder cp += 2;
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder }
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder else if (*cp == '"') {
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder cp++;
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder while (*cp == ' ' || *cp == '\t' || *cp == '\n') {
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder cp++;
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder }
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder if (*cp != ';' && *cp != '\0') {
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
9256f871e7dd915ccfb5969e2117f054306cd366Christian Maeder "Cannot get media parameter.");
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder return(NULL);
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder }
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder quoted = 0;
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder }
e31c7e91ecb4b23aac070f64fa1b099c05aadd0dChristian Maeder 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 = apr_pstrndup(p, mp, cp - mp);
value = zap_sp(value);
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);
}
static int find_ct(request_rec *r)
{
const char *fn = strrchr(r->filename, '/');
mime_dir_config *conf =
(mime_dir_config *) ap_get_module_config(r->per_dir_config, &mime_module);
char *ext;
const char *orighandler = r->handler;
const char *type;
const char *charset = NULL;
if (r->finfo.filetype == APR_DIR) {
r->content_type = DIR_MAGIC_TYPE;
return OK;
}
/* TM -- FIXME
* if r->filename does not contain a '/', the following passes a null
* pointer to getword, causing a SEGV ..
*/
if (fn == NULL) {
fn = r->filename;
}
/* Parse filename extensions, which can be in any order */
while ((ext = ap_getword(r->pool, &fn, '.')) && *ext) {
int found = 0;
/* Check for Content-Type */
if ((type = apr_table_get(conf->forced_types, ext))
|| (type = apr_table_get(hash_buckets[hash(*ext)], ext))) {
r->content_type = type;
found = 1;
}
/* Add charset to Content-Type */
if ((type = apr_table_get(conf->charset_types, ext))) {
charset = type;
found = 1;
}
/* Check for Content-Language */
if ((type = apr_table_get(conf->language_types, ext))) {
const char **new;
r->content_language = type; /* back compat. only */
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 = type;
found = 1;
}
/* Check for Content-Encoding */
if ((type = apr_table_get(conf->encoding_types, ext))) {
if (!r->content_encoding)
r->content_encoding = type;
else
r->content_encoding = apr_pstrcat(r->pool, r->content_encoding,
", ", type, NULL);
found = 1;
}
/* Check for a special handler, but not for proxy request */
if ((type = apr_table_get(conf->handlers, ext))
&& (PROXYREQ_NONE == r->proxyreq)
) {
r->handler = type;
found = 1;
}
/* This is to deal with cases such as foo.gif.bak, which we want
* to not have a type. So if we find an unknown extension, we
* zap the type/language/encoding and reset the handler
*/
if (!found) {
r->content_type = NULL;
r->content_language = NULL;
r->content_languages = NULL;
r->content_encoding = NULL;
r->handler = orighandler;
charset = NULL;
}
}
if (r->content_type) {
content_type *ctp;
char *ct;
int override = 0;
ct = (char *) apr_palloc(r->pool,
sizeof(char) * (strlen(r->content_type) + 1));
strcpy(ct, r->content_type);
if ((ctp = analyze_ct(r, ct))) {
param *pp = ctp->param;
r->content_type = apr_pstrcat(r->pool, ctp->type, "/",
ctp->subtype, NULL);
while (pp != NULL) {
if (charset && !strcmp(pp->attr, "charset")) {
if (!override) {
r->content_type = apr_pstrcat(r->pool, r->content_type,
"; charset=", charset,
NULL);
override = 1;
}
}
else {
r->content_type = apr_pstrcat(r->pool, r->content_type,
"; ", pp->attr,
"=", pp->val,
NULL);
}
pp = pp->next;
}
if (charset && !override) {
r->content_type = 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;
r->content_language = conf->default_language; /* back compat. only */
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;
}
/* Check for overrides with ForceType/SetHandler */
if (conf->type && strcmp(conf->type, "none"))
r->content_type = conf->type;
if (conf->handler && strcmp(conf->handler, "none"))
r->handler = conf->handler;
if (!r->content_type)
return DECLINED;
return OK;
}
static void register_hooks(apr_pool_t *p)
{
ap_hook_type_checker(find_ct,NULL,NULL,APR_HOOK_MIDDLE);
ap_hook_post_config(mime_post_config,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 */
};