mod_mime.c revision b2c2c8a4bc977c0a6bb937af995efc56dc3879a3
bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* ====================================================================
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainen * The Apache Software License, Version 1.1
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainen * Redistribution and use in source and binary forms, with or without
489301ee88b2174e3171875e979e667de2c4a174Timo Sirainen * modification, are permitted provided that the following conditions
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainen * 1. Redistributions of source code must retain the above copyright
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch * notice, this list of conditions and the following disclaimer.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen * 2. Redistributions in binary form must reproduce the above copyright
52fbebc87d7ae4fc4585863d38cb87f166a6521aTimo Sirainen * notice, this list of conditions and the following disclaimer in
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainen * the documentation and/or other materials provided with the
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainen * distribution.
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen * 3. The end-user documentation included with the redistribution,
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainen * if any, must include the following acknowledgment:
7c3f90095b4168d89a268ac1ec820c5925d48fd3Timo Sirainen * "This product includes software developed by the
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainen * Apache Software Foundation (http://www.apache.org/)."
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainen * Alternately, this acknowledgment may appear in the software itself,
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen * if and wherever such third-party acknowledgments normally appear.
52fbebc87d7ae4fc4585863d38cb87f166a6521aTimo Sirainen * 4. The names "Apache" and "Apache Software Foundation" must
52fbebc87d7ae4fc4585863d38cb87f166a6521aTimo Sirainen * not be used to endorse or promote products derived from this
52fbebc87d7ae4fc4585863d38cb87f166a6521aTimo Sirainen * software without prior written permission. For written
31be5ed1551c98cddeb2295a594f010aaf4b76bcTimo Sirainen * permission, please contact apache@apache.org.
5df33e9ee65eec194105b338c55dedbf8422f695Timo Sirainen * 5. Products derived from this software may not be called "Apache",
5df33e9ee65eec194105b338c55dedbf8422f695Timo Sirainen * nor may "Apache" appear in their name, without prior written
5df33e9ee65eec194105b338c55dedbf8422f695Timo Sirainen * permission of the Apache Software Foundation.
5df33e9ee65eec194105b338c55dedbf8422f695Timo Sirainen * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
5df33e9ee65eec194105b338c55dedbf8422f695Timo Sirainen * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
5df33e9ee65eec194105b338c55dedbf8422f695Timo Sirainen * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
5df33e9ee65eec194105b338c55dedbf8422f695Timo Sirainen * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
5df33e9ee65eec194105b338c55dedbf8422f695Timo Sirainen * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
5df33e9ee65eec194105b338c55dedbf8422f695Timo Sirainen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
5df33e9ee65eec194105b338c55dedbf8422f695Timo Sirainen * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
5df33e9ee65eec194105b338c55dedbf8422f695Timo Sirainen * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
5df33e9ee65eec194105b338c55dedbf8422f695Timo Sirainen * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
5df33e9ee65eec194105b338c55dedbf8422f695Timo Sirainen * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
5df33e9ee65eec194105b338c55dedbf8422f695Timo Sirainen * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5df33e9ee65eec194105b338c55dedbf8422f695Timo Sirainen * SUCH DAMAGE.
5df33e9ee65eec194105b338c55dedbf8422f695Timo Sirainen * ====================================================================
5df33e9ee65eec194105b338c55dedbf8422f695Timo Sirainen * This software consists of voluntary contributions made by many
5df33e9ee65eec194105b338c55dedbf8422f695Timo Sirainen * individuals on behalf of the Apache Software Foundation. For more
5df33e9ee65eec194105b338c55dedbf8422f695Timo Sirainen * information on the Apache Software Foundation, please see
5df33e9ee65eec194105b338c55dedbf8422f695Timo Sirainen * Portions of this software are based upon public domain software
5df33e9ee65eec194105b338c55dedbf8422f695Timo Sirainen * originally written at the National Center for Supercomputing Applications,
147a788fea2a88f7125b27226451271d55cf5b01Timo Sirainen * University of Illinois, Urbana-Champaign.
5df33e9ee65eec194105b338c55dedbf8422f695Timo Sirainen * http_mime.c: Sends/gets MIME headers for requests
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen/* XXXX - fix me / EBCDIC
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen * there was a cludge here which would use its
b0a901f1dbe9e05ac1c92a0974af6bce0274f31aTimo Sirainen * own version apr_isascii(). Indicating that
2d01cc1880cf2afd4fb1c8ad7fa6ce78e562e71eTimo Sirainen * on some platforms that might be needed.
b0a901f1dbe9e05ac1c92a0974af6bce0274f31aTimo Sirainen * #define OS_ASC(c) (c) -- for mere mortals
46114180b41dc7cac5e7b0242ad347b4acdbaa5aTimo Sirainen * #define OS_ASC(c) (ebcdic2ascii[c]) -- for dino's
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen * #define apr_isascii(c) ((OS_ASC(c) & 0x80) == 0)
c147bff818798a979d93537f72f5c1f68f5d5ba8Aki Tuomi/* XXXXX - fix me - See note with NOT_PROXY
46114180b41dc7cac5e7b0242ad347b4acdbaa5aTimo Sirainentypedef struct attrib_info {
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainen/* Information to which an extension can be mapped
46114180b41dc7cac5e7b0242ad347b4acdbaa5aTimo Sirainentypedef struct extension_info {
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen char *forced_type; /* Additional AddTyped stuff */
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen char *encoding_type; /* Added with AddEncoding... */
5f44975ec6c5755dd74bcd4c47a123a7242ecab3Timo Sirainen char *language_type; /* Added with AddLanguage... */
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen char *charset_type; /* Added with AddCharset... */
7522446d6514e5593c9d4d7e4beacd328301cb23Aki Tuomi char *input_filters; /* Added with AddInputFilter... */
46114180b41dc7cac5e7b0242ad347b4acdbaa5aTimo Sirainen char *output_filters; /* Added with AddOutputFilter... */
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainentypedef struct {
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen apr_hash_t *extension_mappings; /* Map from extension name to
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainen * extension_info structure */
884228e5496378bada39a932db67aa3d9478198fTimo Sirainen apr_array_header_t *remove_mappings; /* A simple list, walked once */
884228e5496378bada39a932db67aa3d9478198fTimo Sirainen char *handler; /* Handler forced with SetHandler */
884228e5496378bada39a932db67aa3d9478198fTimo Sirainen char *default_language; /* Language if no AddLanguage ext found */
884228e5496378bada39a932db67aa3d9478198fTimo Sirainen /* Due to the FUD about JS and charsets
884228e5496378bada39a932db67aa3d9478198fTimo Sirainen * default_charset is actually in src/main */
884228e5496378bada39a932db67aa3d9478198fTimo Sirainentypedef struct param_s {
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainentypedef struct {
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainenstatic char tspecial[] = {
6e0054c2e5efc526df6287da368335680a856714Timo Sirainenstatic void *create_mime_dir_config(apr_pool_t *p, char *dummy)
1b4441e3e6f9e78ebeae8218de971959cd55bf60Timo Sirainen (mime_dir_config *) apr_palloc(p, sizeof(mime_dir_config));
489301ee88b2174e3171875e979e667de2c4a174Timo Sirainen * Overlay one hash table of extension_mappings onto another
489301ee88b2174e3171875e979e667de2c4a174Timo Sirainenstatic void overlay_extension_mappings(apr_pool_t *p,
489301ee88b2174e3171875e979e667de2c4a174Timo Sirainen for (index = apr_hash_first(p, overlay); index;
8e361d2906b0e44f7175a20981f8d2280645b58bTimo Sirainen apr_hash_this(index, (const void**)&key, &klen, (void**)&overlay_info);
1171f0abf442638bac1827bb24a0b6b8eb682a82Timo Sirainen base_info = (extension_info*)apr_hash_get(base, key, klen);
8e361d2906b0e44f7175a20981f8d2280645b58bTimo Sirainen base_info = (extension_info*)apr_palloc(p, sizeof(*base_info));
8e361d2906b0e44f7175a20981f8d2280645b58bTimo Sirainen memcpy(base_info, copyinfo, sizeof(*base_info));
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainen base_info->forced_type = overlay_info->forced_type;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen base_info->encoding_type = overlay_info->encoding_type;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen base_info->language_type = overlay_info->language_type;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen base_info->charset_type = overlay_info->charset_type;
0737a4fe0b83a05f335a8ad02e833b62565a36daTimo Sirainen/* Member is the offset within an extension_info of the pointer to reset
0737a4fe0b83a05f335a8ad02e833b62565a36daTimo Sirainenstatic void remove_items(apr_pool_t *p, apr_array_header_t *remove,
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen attrib_info *suffix = (attrib_info *) remove->elts;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen if (exinfo && *(const char**)((char *)exinfo + suffix[i].offset)) {
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen exinfo = (extension_info*)apr_palloc(p, sizeof(*exinfo));
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainen *(const char**)((char *)exinfo + suffix[i].offset) = NULL;
439980f88f421039dea8335e92d3fa82b3f470a1Timo Sirainenstatic void *merge_mime_dir_configs(apr_pool_t *p, void *basev, void *addv)
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen mime_dir_config *base = (mime_dir_config *) basev;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen mime_dir_config *add = (mime_dir_config *) addv;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen mime_dir_config *new = apr_palloc(p, sizeof(mime_dir_config));
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen if (base->extension_mappings && add->extension_mappings) {
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen overlay_extension_mappings(p, base->extension_mappings,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen overlay_extension_mappings(p, add->extension_mappings,
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen new->extension_mappings = add->extension_mappings;
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen new->extension_mappings = base->extension_mappings;
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen /* We may not be merging the tables, but if we potentially will change
cd83124e5d070a016c590bb0b1096d7828c7b6adTimo Sirainen * an exinfo member, then we are about to trounce it anyways.
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen * We must have a copy for safety.
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen if (new->extension_mappings && add->remove_mappings) {
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen apr_hash_t *copyhash = new->extension_mappings;
87490012895b4f371635ded00add04c9107dcfefJosef 'Jeff' Sipek overlay_extension_mappings(p, copyhash, new->extension_mappings);
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen remove_items(p, add->remove_mappings, new->extension_mappings);
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen new->type = add->type ? add->type : base->type;
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen new->handler = add->handler ? add->handler : base->handler;
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen new->default_language = add->default_language ?
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen add->default_language : base->default_language;
87490012895b4f371635ded00add04c9107dcfefJosef 'Jeff' Sipekstatic const char *add_extension_info(cmd_parms *cmd, void *m_,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen m->extension_mappings = apr_hash_make(cmd->pool);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen exinfo = (extension_info*)apr_hash_get(m->extension_mappings, key,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen exinfo = apr_pcalloc(cmd->pool, sizeof(extension_info));
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen *(const char**)((char *)exinfo + offset) = value;
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen * Note handler names are un-added with each per_dir_config merge.
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen * This keeps the association from being inherited, but not
5f44975ec6c5755dd74bcd4c47a123a7242ecab3Timo Sirainen * from being re-added at a subordinate level.
3fe9483b2b412a14493e3120751b0e99ecfe9388Timo Sirainenstatic const char *remove_extension_info(cmd_parms *cmd, void *m_,
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen const char *ext)
87490012895b4f371635ded00add04c9107dcfefJosef 'Jeff' Sipek m->remove_mappings = apr_array_make(cmd->pool, 4, sizeof(*suffix));
645f258ea29afaf09b673fc65d1bd788dfec8db8Timo Sirainen suffix = (attrib_info *) apr_array_push(m->remove_mappings);
02b78558dc03daa2e7da2010b63f247b49936a38Timo Sirainen/* The sole bit of server configuration that the MIME module has is
02b78558dc03daa2e7da2010b63f247b49936a38Timo Sirainen * the name of its config file, so...
96541d31299bb40b5a6efdbf9b4cb3d4f4b4a069Timo Sirainenstatic const char *set_types_config(cmd_parms *cmd, void *dummy,
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen const char *arg)
49f65b7c797515d787bcbc9cbeb78f0c21b1b282Timo Sirainen ap_set_module_config(cmd->server->module_config, &mime_module,
e8a59a1671127f87e2d22f42e84c572f28299d81Timo SirainenAP_INIT_ITERATE2("AddCharset", add_extension_info,
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainen (void *)APR_XtOffsetOf(extension_info, charset_type), OR_FILEINFO,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen "a charset (e.g., iso-2022-jp), followed by one or more file extensions"),
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo SirainenAP_INIT_ITERATE2("AddEncoding", add_extension_info,
87490012895b4f371635ded00add04c9107dcfefJosef 'Jeff' Sipek (void *)APR_XtOffsetOf(extension_info, encoding_type), OR_FILEINFO,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen "an encoding (e.g., gzip), followed by one or more file extensions"),
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo SirainenAP_INIT_ITERATE2("AddHandler", add_extension_info,
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen (void *)APR_XtOffsetOf(extension_info, handler), OR_FILEINFO,
1d5f06e1f3226cf07d1521cee1b6b14744845273Timo Sirainen "a handler name followed by one or more file extensions"),
e192a3b1ca8ae857e7d87298ea507d32977ba570Timo SirainenAP_INIT_ITERATE2("AddInputFilter", add_extension_info,
e192a3b1ca8ae857e7d87298ea507d32977ba570Timo Sirainen (void *)APR_XtOffsetOf(extension_info, input_filters), OR_FILEINFO,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen "a handler name followed by one or more file extensions"),
e192a3b1ca8ae857e7d87298ea507d32977ba570Timo SirainenAP_INIT_ITERATE2("AddLanguage", add_extension_info,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen (void *)APR_XtOffsetOf(extension_info, language_type), OR_FILEINFO,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen "a language (e.g., fr), followed by one or more file extensions"),
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo SirainenAP_INIT_ITERATE2("AddOutputFilter", add_extension_info,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen (void *)APR_XtOffsetOf(extension_info, output_filters), OR_FILEINFO,
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen "a mime type followed by one or more file extensions"),
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo SirainenAP_INIT_ITERATE2("AddType", add_extension_info,
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen (void *)APR_XtOffsetOf(extension_info, forced_type), OR_FILEINFO,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen "a mime type followed by one or more file extensions"),
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo SirainenAP_INIT_TAKE1("DefaultLanguage", ap_set_string_slot,
87490012895b4f371635ded00add04c9107dcfefJosef 'Jeff' Sipek (void*)APR_XtOffsetOf(mime_dir_config, default_language), OR_FILEINFO,
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen "language to use for documents with no other language file extension"),
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo SirainenAP_INIT_TAKE1("ForceType", ap_set_string_slot_lower,
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen (void *)APR_XtOffsetOf(mime_dir_config, type), OR_FILEINFO,
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen "a media type"),
e192a3b1ca8ae857e7d87298ea507d32977ba570Timo SirainenAP_INIT_ITERATE("RemoveCharset", remove_extension_info,
e192a3b1ca8ae857e7d87298ea507d32977ba570Timo Sirainen (void *)APR_XtOffsetOf(extension_info, charset_type), OR_FILEINFO,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen "one or more file extensions"),
83bb013a99f0936995f9c7a1077822662d8fefdbTimo SirainenAP_INIT_ITERATE("RemoveEncoding", remove_extension_info,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen (void *)APR_XtOffsetOf(extension_info, encoding_type), OR_FILEINFO,
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen "one or more file extensions"),
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo SirainenAP_INIT_ITERATE("RemoveHandler", remove_extension_info,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen (void *)APR_XtOffsetOf(extension_info, handler), OR_FILEINFO,
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen "one or more file extensions"),
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo SirainenAP_INIT_ITERATE("RemoveInputFilter", remove_extension_info,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen (void *)APR_XtOffsetOf(extension_info, input_filters), OR_FILEINFO,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen "one or more file extensions"),
7a54d58280aad8a64f266c61273ea1e8dff511a3Timo SirainenAP_INIT_ITERATE("RemoveLanguage", remove_extension_info,
7a54d58280aad8a64f266c61273ea1e8dff511a3Timo Sirainen (void *)APR_XtOffsetOf(extension_info, language_type), OR_FILEINFO,
7a54d58280aad8a64f266c61273ea1e8dff511a3Timo Sirainen "one or more file extensions"),
7a54d58280aad8a64f266c61273ea1e8dff511a3Timo SirainenAP_INIT_ITERATE("RemoveOutputFilter", remove_extension_info,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen (void *)APR_XtOffsetOf(extension_info, output_filters), OR_FILEINFO,
7a54d58280aad8a64f266c61273ea1e8dff511a3Timo Sirainen "one or more file extensions"),
7a54d58280aad8a64f266c61273ea1e8dff511a3Timo SirainenAP_INIT_ITERATE("RemoveType", remove_extension_info,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen (void *)APR_XtOffsetOf(extension_info, forced_type), OR_FILEINFO,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen "one or more file extensions"),
f7f16d4fa869337c15e41becab24fece11620f01Timo SirainenAP_INIT_TAKE1("SetHandler", ap_set_string_slot_lower,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen (void *)APR_XtOffsetOf(mime_dir_config, handler), OR_FILEINFO,
7a54d58280aad8a64f266c61273ea1e8dff511a3Timo Sirainen "a handler name"),
f7f16d4fa869337c15e41becab24fece11620f01Timo SirainenAP_INIT_TAKE1("TypesConfig", set_types_config, NULL, RSRC_CONF,
f7f16d4fa869337c15e41becab24fece11620f01Timo Sirainen "the MIME types config file"),
7a54d58280aad8a64f266c61273ea1e8dff511a3Timo Sirainenstatic void mime_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen const char *types_confname = ap_get_module_config(s->module_config, &mime_module);
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainen types_confname = ap_server_root_relative(p, types_confname);
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainen if ((status = ap_pcfg_openfile(&f, ptemp, types_confname)) != APR_SUCCESS) {
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen ap_log_error(APLOG_MARK, APLOG_ERR, status, s,
e192a3b1ca8ae857e7d87298ea507d32977ba570Timo Sirainen "could not open mime types config file %s.", types_confname);
1a18848722d5d20deee4c8aa099890addc53af90Timo Sirainen while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
6789ed17e7ca4021713507baf0dcf6979bb42e0cTimo Sirainen if (l[0] == '#')
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen while (ll[0]) {
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainen apr_hash_set(mime_type_extensions, ext, APR_HASH_KEY_STRING, ct);
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainenstatic char *zap_sp(char *s)
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainen if (*s == '\0') {
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen /* delete prefixed white space */
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainen for (; *s == ' ' || *s == '\t' || *s == '\n'; s++);
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainen /* delete postfixed white space */
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainen for (tp--; tp != s && (*tp == ' ' || *tp == '\t' || *tp == '\n'); tp--) {
ae2bad232435e5f81f37dd4b8ddb631a564d3dc2Aki Tuomistatic int is_token(char c)
424633d1a1e22139a5ab9345f807a89d0792ead3Timo Sirainenstatic int is_qtext(char c)
424633d1a1e22139a5ab9345f807a89d0792ead3Timo Sirainen res = (apr_isascii(c) && (c != '"') && (c != '\\') && (c != '\n'))
424633d1a1e22139a5ab9345f807a89d0792ead3Timo Sirainenstatic int is_quoted_pair(char *s)
1a18848722d5d20deee4c8aa099890addc53af90Timo Sirainen c = (int) *(s + 1);
6fb3d58f9a801488ddeda687cb9d5ff24d76aee3Timo Sirainenstatic content_type *analyze_ct(request_rec *r, char *s)
ae2bad232435e5f81f37dd4b8ddb631a564d3dc2Aki Tuomi /* initialize ctp */
2b96309988981c4005d59ea41e270c9b55c44de7Aki Tuomi ctp = (content_type *) apr_palloc(p, sizeof(content_type));
6fb3d58f9a801488ddeda687cb9d5ff24d76aee3Timo Sirainen /* getting a type */
6fb3d58f9a801488ddeda687cb9d5ff24d76aee3Timo Sirainen ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
6fb3d58f9a801488ddeda687cb9d5ff24d76aee3Timo Sirainen "mod_mime: analyze_ct: cannot get media type from '%s'",
6fb3d58f9a801488ddeda687cb9d5ff24d76aee3Timo Sirainen (const char *) mp);
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen if (ctp->type == NULL || *(ctp->type) == '\0' ||
6fb3d58f9a801488ddeda687cb9d5ff24d76aee3Timo Sirainen strchr(ctp->type, ';') || strchr(ctp->type, ' ') ||
6fb3d58f9a801488ddeda687cb9d5ff24d76aee3Timo Sirainen ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
6fb3d58f9a801488ddeda687cb9d5ff24d76aee3Timo Sirainen "Cannot get media subtype.");
e9a182196c79b321365dbcd8800790e841e5e890Timo Sirainen /* getting a subtype */
6fb3d58f9a801488ddeda687cb9d5ff24d76aee3Timo Sirainen if ((ctp->subtype == NULL) || (*(ctp->subtype) == '\0') ||
6fb3d58f9a801488ddeda687cb9d5ff24d76aee3Timo Sirainen strchr(ctp->subtype, ' ') || strchr(ctp->subtype, '\t')) {
6fb3d58f9a801488ddeda687cb9d5ff24d76aee3Timo Sirainen ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen "Cannot get media subtype.");
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen /* getting parameters */
02b78558dc03daa2e7da2010b63f247b49936a38Timo Sirainen ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
02b78558dc03daa2e7da2010b63f247b49936a38Timo Sirainen "Cannot get media parameter.");
1a18848722d5d20deee4c8aa099890addc53af90Timo Sirainen else if (*cp == ' ' || *cp == '\t' || *cp == '\n') {
1a18848722d5d20deee4c8aa099890addc53af90Timo Sirainen if (attribute == NULL || *attribute == '\0') {
1a18848722d5d20deee4c8aa099890addc53af90Timo Sirainen ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen "Cannot get media parameter.");
5cda0bfea032000c4a51134c748d9efe6614870bTimo Sirainen ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
97511ac4d7607e1ba64ce151eda3d9b5f9775519Timo Sirainen "Cannot get media parameter.");
5cda0bfea032000c4a51134c748d9efe6614870bTimo Sirainen ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
97511ac4d7607e1ba64ce151eda3d9b5f9775519Timo Sirainen "Cannot get media parameter.");
0a1b1d2e55b19786b42810671e4245c5b8942375Timo Sirainen while (*cp == ' ' || *cp == '\t' || *cp == '\n') {
f760ffed7875afbf37adc93555821caa42eadf82Timo Sirainen ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
f760ffed7875afbf37adc93555821caa42eadf82Timo Sirainen "Cannot get media parameter.");
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen "Cannot get media parameter.");
96541d31299bb40b5a6efdbf9b4cb3d4f4b4a069Timo Sirainen ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen "Cannot get media parameter.");
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen "Cannot get media parameter.");
f760ffed7875afbf37adc93555821caa42eadf82Timo Sirainen * find_ct is the hook routine for determining content-type and other
f760ffed7875afbf37adc93555821caa42eadf82Timo Sirainen * MIME-related metadata. It assumes that r->filename has already been
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen * set and stat has been called for r->finfo. It also assumes that the
f760ffed7875afbf37adc93555821caa42eadf82Timo Sirainen * non-path base file name is not the empty string unless it is a dir.
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen conf = (mime_dir_config *) ap_get_module_config(r->per_dir_config,
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen exception_list = apr_array_make(r->pool, 2, sizeof(char *));
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen /* Always drop the path leading up to the file name.
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen /* The exception list keeps track of those filename components that
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen * are not associated with extensions indicating metadata.
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen * The base name is always the first exception (i.e., "txt.html" has
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen * a basename of "txt" even though it might look like an extension).
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen *((const char **) apr_array_push(exception_list)) = ext;
c147bff818798a979d93537f72f5c1f68f5d5ba8Aki Tuomi /* Parse filename extensions which can be in any order
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen while (*fn && (ext = ap_getword(r->pool, &fn, '.'))) {
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen if (*ext == '\0') /* ignore empty extensions "bad..html" */
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen /* We have a basic problem that folks on case-crippled systems
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen * expect anything and everything to succeed
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen exinfo = (extension_info*)apr_hash_get(conf->extension_mappings,
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen if ((type = apr_hash_get(mime_type_extensions, ext,
31ed25f84a5cb6b6e3608e4cb841760910579aa2Timo Sirainen r->content_language = exinfo->language_type; /* back compat. */
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen r->content_languages = apr_array_make(r->pool, 2,
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen sizeof(char *));
31ed25f84a5cb6b6e3608e4cb841760910579aa2Timo Sirainen *((const char **) apr_array_push(r->content_languages)) =
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen /* XXX should eliminate duplicate entities */
4eebe979f6847b3b22782785dafda6ca1bbf6d9fTimo Sirainen /* The following extensions are not 'Found'. That is, they don't
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen * make any contribution to metadata negotation, so they must have
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen * been explicitly requested by name.
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen if (exinfo->handler && r->proxyreq == PROXYREQ_NONE) {
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen /* XXX Two significant problems; 1, we don't check to see if we are
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen * setting redundant filters. 2, we insert these in the types config
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen * hook, which may be too early (dunno.)
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen if (exinfo->input_filters && r->proxyreq == PROXYREQ_NONE) {
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen const char *filter, *filters = exinfo->input_filters;
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen && (filter = ap_getword(r->pool, &filters, ';'))) {
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen ap_add_input_filter(filter, NULL, r, r->connection);
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen if (exinfo->output_filters && r->proxyreq == PROXYREQ_NONE) {
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen const char *filter, *filters = exinfo->output_filters;
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen && (filter = ap_getword(r->pool, &filters, ';'))) {
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen ap_add_output_filter(filter, NULL, r, r->connection);
4eebe979f6847b3b22782785dafda6ca1bbf6d9fTimo Sirainen *((const char **) apr_array_push(exception_list)) = ext;
bb6a0eeab27569790d58a036f67dcd2a965fc539Timo Sirainen * Need to set a notes entry on r for unrecognized elements.
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen * Somebody better claim them! If we did absolutely nothing,
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen * skip the notes to alert mod_negotiation we are clueless.
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen apr_table_setn(r->notes, "ap-mime-exceptions-list",
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen sizeof(char) * (strlen(r->content_type) + 1));
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen r->content_type = apr_pstrcat(r->pool, ctp->type, "/",
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen if (charset && !strcmp(pp->attr, "charset")) {
52fbebc87d7ae4fc4585863d38cb87f166a6521aTimo Sirainen r->content_type = apr_pstrcat(r->pool, r->content_type,
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen r->content_type = apr_pstrcat(r->pool, r->content_type,
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen r->content_type = apr_pstrcat(r->pool, r->content_type,
52fbebc87d7ae4fc4585863d38cb87f166a6521aTimo Sirainen /* Set default language, if none was specified by the extensions
52fbebc87d7ae4fc4585863d38cb87f166a6521aTimo Sirainen * and we have a DefaultLanguage setting in force
52fbebc87d7ae4fc4585863d38cb87f166a6521aTimo Sirainen if (!r->content_languages && conf->default_language) {
52fbebc87d7ae4fc4585863d38cb87f166a6521aTimo Sirainen const char **new;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen r->content_language = conf->default_language; /* back compat. only */
ae2bad232435e5f81f37dd4b8ddb631a564d3dc2Aki Tuomi r->content_languages = apr_array_make(r->pool, 2, sizeof(char *));
ae2bad232435e5f81f37dd4b8ddb631a564d3dc2Aki Tuomi new = (const char **) apr_array_push(r->content_languages);
7a54d58280aad8a64f266c61273ea1e8dff511a3Timo Sirainen /* Check for overrides with ForceType/SetHandler */
ae2bad232435e5f81f37dd4b8ddb631a564d3dc2Aki Tuomi if (conf->handler && strcmp(conf->handler, "none"))
f977ec781fca91e320535f1562382433a9e63177Aki Tuomi ap_hook_post_config(mime_post_config,NULL,NULL,APR_HOOK_MIDDLE);
ae2bad232435e5f81f37dd4b8ddb631a564d3dc2Aki Tuomi ap_hook_type_checker(find_ct,NULL,NULL,APR_HOOK_MIDDLE);
ae2bad232435e5f81f37dd4b8ddb631a564d3dc2Aki Tuomi * this hook seems redundant ... is there any reason a type checker isn't
ae2bad232435e5f81f37dd4b8ddb631a564d3dc2Aki Tuomi * allowed to do this already? I'd think that fixups in general would be
ae2bad232435e5f81f37dd4b8ddb631a564d3dc2Aki Tuomi * the last opportunity to get the filters right.
f977ec781fca91e320535f1562382433a9e63177Aki Tuomi * ap_hook_insert_filter(mime_insert_filters,NULL,NULL,APR_HOOK_MIDDLE);
ae2bad232435e5f81f37dd4b8ddb631a564d3dc2Aki Tuomi create_mime_dir_config, /* create per-directory config structure */
f977ec781fca91e320535f1562382433a9e63177Aki Tuomi merge_mime_dir_configs, /* merge per-directory config structures */