summaryrefslogtreecommitdiff
path: root/modules/http
diff options
context:
space:
mode:
authorEric Covener <covener@apache.org>2019-03-13 18:41:30 +0000
committerEric Covener <covener@apache.org>2019-03-13 18:41:30 +0000
commit6a84f21f3a82dbc68d85b03a3ff921d3a6b76621 (patch)
tree13aa8dcbd0bc556aeb3d0d65a7d9b7074a45b61a /modules/http
parentb444a8e5795999b718f9c852af6c68dd63177a2a (diff)
downloadhttpd-6a84f21f3a82dbc68d85b03a3ff921d3a6b76621.tar.gz
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
Diffstat (limited to 'modules/http')
-rw-r--r--modules/http/mod_mime.c55
1 files changed, 53 insertions, 2 deletions
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;
}