<seealso><module>mod_mime_magic</module></seealso>
</directivesynopsis>
+<directivesynopsis>
+<name>MimeOptions</name>
+<description>Configures mod_mime behavior</description>
+<syntax>MimeOptions<var>option</var> [<var>option</var>] ...</syntax>
+<contextlist><context>server config</context>
+<context>virtual host</context><context>directory</context>
+<context>.htaccess</context>
+<compatibility>IBM HTTP Server 9.0.0.12 and later</compatibility>
+</contextlist>
+<override>FileInfo</override>
+
+<usage>
+ <p>The <directive>MimeOptions</directive> directive configures certain
+ behaviors of <module>mod_mime</module>. <var>Option</var> can
+ be one of</p>
+
+ <dl>
+ <dt><code>TypesLastExtension</code></dt>
+ <dd>This option only consider the last (right-most) filename extension
+ when determining a files Content-Type.</dd>
+ <dt><code>NoTypesLastExtension</code></dt>
+ <dd>This option can be used to revert to the default behavior of testing
+ every filename extension when determining a files Content-Type.</dd>
+ <dt><code>AllLastExtension</code></dt>
+ <dd>This option only consider the last (right-most) filename extension
+ when determining any response metadata (Content-Type, language, encoding,
+ etc.) .</dd>
+ <dt><code>NoAllLastExtension</code></dt>
+ <dd>This option can be used to revert to the default behavior of testing
+ every filename extension when determining any response metadata
+ (Content-Type, language, encoding, etc.) .</dd>
+ </dl>
+</usage>
+</directivesynopsis>
</modulesynopsis>
* If set to 2, this value is unset and is
* effectively 0.
*/
+ /* Only use the final extension for Content-Type */
+ enum {CT_LAST_INIT, CT_LAST_ON, CT_LAST_OFF} ct_last_ext;
+ /* Only use the final extension for anything */
+ enum {ALL_LAST_INIT, ALL_LAST_ON, ALL_LAST_OFF} all_last_ext;
} mime_dir_config;
typedef struct param_s {
new->multimatch = MULTIMATCH_UNSET;
new->use_path_info = 2;
+ new->ct_last_ext = CT_LAST_INIT;
+ new->all_last_ext = ALL_LAST_INIT;
return new;
}
new->use_path_info = base->use_path_info;
}
+ new->ct_last_ext = (add->ct_last_ext != CT_LAST_INIT)
+ ? add->ct_last_ext
+ : base->ct_last_ext;
+ new->all_last_ext = (add->all_last_ext != ALL_LAST_INIT)
+ ? add->all_last_ext
+ : base->all_last_ext;
+
return new;
}
return NULL;
}
+static const char *add_mime_options(cmd_parms *cmd, void *in_dc,
+ const char *flag)
+{
+ mime_dir_config *dc = in_dc;
+
+ if (!strcasecmp(flag, "TypesLastExtension")) {
+ dc->ct_last_ext = CT_LAST_ON;
+ }
+ else if (!strcasecmp(flag, "NoTypesLastExtension")) {
+ dc->ct_last_ext = CT_LAST_OFF;
+ }
+ else if (!strcasecmp(flag, "AllLastExtension")) {
+ dc->all_last_ext = ALL_LAST_ON;
+ }
+ else if (!strcasecmp(flag, "AllLastExtension")) {
+ dc->all_last_ext = ALL_LAST_OFF;
+ }
+ else {
+ return apr_pstrcat(cmd->temp_pool,
+ "Invalid MimeOptions option: ",
+ flag,
+ NULL);
+ }
+
+ return NULL;
+}
+
static const command_rec mime_cmds[] =
{
AP_INIT_ITERATE2("AddCharset", add_extension_info,
AP_INIT_FLAG("ModMimeUsePathInfo", ap_set_flag_slot,
(void *)APR_OFFSETOF(mime_dir_config, use_path_info), ACCESS_CONF,
"Set to 'yes' to allow mod_mime to use path info for type checking"),
+ AP_INIT_ITERATE("MimeOptions",
+ add_mime_options,
+ NULL,
+ OR_FILEINFO,
+ "valid options: [No]TypesLastExtension, [No]AllLastExtension"),
{NULL}
};
const extension_info *exinfo = NULL;
int found;
char *extcase;
+ int skipct = (conf->ct_last_ext == CT_LAST_ON) && (*fn);
+ int skipall = (conf->all_last_ext == ALL_LAST_ON) && (*fn);
if (*ext == '\0') { /* ignore empty extensions "bad..html" */
continue;
}
+ if (skipall) {
+ continue;
+ }
+
found = 0;
/* Save the ext in extcase before converting it to lower case.
ext, APR_HASH_KEY_STRING);
}
- if (exinfo == NULL || !exinfo->forced_type) {
+ if ((exinfo == NULL || !exinfo->forced_type) && !skipct) {
if ((type = apr_hash_get(mime_type_extensions, ext,
APR_HASH_KEY_STRING)) != NULL) {
ap_set_content_type(r, (char*) type);
if (exinfo != NULL) {
/* empty string is treated as special case for RemoveType */
- if (exinfo->forced_type && *exinfo->forced_type) {
+ if ((exinfo->forced_type && *exinfo->forced_type) && !skipct) {
ap_set_content_type(r, exinfo->forced_type);
found = 1;
}