diff options
author | Eric Covener <covener@apache.org> | 2019-03-13 19:41:30 +0100 |
---|---|---|
committer | Eric Covener <covener@apache.org> | 2019-03-13 19:41:30 +0100 |
commit | 6a84f21f3a82dbc68d85b03a3ff921d3a6b76621 (patch) | |
tree | 13aa8dcbd0bc556aeb3d0d65a7d9b7074a45b61a | |
parent | Make the work-around for C++ style comments causing fatal errors in (diff) | |
download | apache2-6a84f21f3a82dbc68d85b03a3ff921d3a6b76621.tar.xz apache2-6a84f21f3a82dbc68d85b03a3ff921d3a6b76621.zip |
mod_mime: Add `MimeOptions`
mod_mime: Add `MimeOptions` directive to allow Content-Type or all metadata
detection to use only the last (right-most) file extension.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1855449 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | CHANGES | 3 | ||||
-rw-r--r-- | docs/manual/mod/mod_mime.xml | 34 | ||||
-rw-r--r-- | modules/http/mod_mime.c | 55 |
3 files changed, 90 insertions, 2 deletions
@@ -1,6 +1,9 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.1 + *) mod_mime: Add `MimeOptions` directive to allow Content-Type or all metadata + detection to use only the last (right-most) file extension. [Eric Covener] + *) MPMs unix: bind the bucket number of each child to its slot number, for a more efficient per bucket maintenance. [Yann Ylavic] diff --git a/docs/manual/mod/mod_mime.xml b/docs/manual/mod/mod_mime.xml index 422b008080..f50ed8f814 100644 --- a/docs/manual/mod/mod_mime.xml +++ b/docs/manual/mod/mod_mime.xml @@ -1051,4 +1051,38 @@ RemoveType .cgi <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> diff --git a/modules/http/mod_mime.c b/modules/http/mod_mime.c index 03d1c4110b..249f64e8c2 100644 --- a/modules/http/mod_mime.c +++ b/modules/http/mod_mime.c @@ -91,6 +91,10 @@ typedef struct { * 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 { @@ -127,6 +131,8 @@ static void *create_mime_dir_config(apr_pool_t *p, char *dummy) 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; } @@ -239,6 +245,13 @@ static void *merge_mime_dir_configs(apr_pool_t *p, void *basev, void *addv) 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; } @@ -364,6 +377,33 @@ static const char *multiviews_match(cmd_parms *cmd, void *m_, 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, @@ -421,6 +461,11 @@ static const command_rec mime_cmds[] = 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} }; @@ -817,11 +862,17 @@ static int find_ct(request_rec *r) 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. @@ -834,7 +885,7 @@ static int find_ct(request_rec *r) 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); @@ -845,7 +896,7 @@ static int find_ct(request_rec *r) 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; } |