]> granicus.if.org Git - apache/commitdiff
Introduces mod_mime AddInputFilter and AddOutputFilter filter ext syntax.
authorWilliam A. Rowe Jr <wrowe@apache.org>
Tue, 28 Aug 2001 15:07:11 +0000 (15:07 +0000)
committerWilliam A. Rowe Jr <wrowe@apache.org>
Tue, 28 Aug 2001 15:07:11 +0000 (15:07 +0000)
  Significantly refactored the code to maintain single functions for the
  add_extension_info hash and remove_extension_info table processing.

  The AddInputFilter/AddOutputFilter could have been plural, as they accept
  a semicolon delimited list of filters (e.g. you need to stack two different
  filters based on a single extension.)  I expect that the plural could
  confuse users, though, as they might expect AddInputFilters foo bar var
  to add foo and bar to the extension var, which it definately doesn't do!

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@90756 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/http/mod_mime.c

diff --git a/CHANGES b/CHANGES
index 76606e3d3392b924059dbd9dbed2253f9972b523..1fd88c638b7e2a402b8694c5c38ead6d0368322f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,10 @@
 Changes with Apache 2.0.25-dev
 
+  *) Introduce the AddInputFilter filter[;filter...] ext [ext...]
+     and corresponding AddOutputFilter syntax, to insert one or more 
+     filters by mod_mime filename extension processing.
+     [William Rowe]
+
   *) Fix a growing connection pool in core_output_filter() for 
      keepalive requests.  [Jeff Trawick]
 
index 29ae4be42908422b9b59abf9b257914906ea564a..d7060a3fb38d5c286cb5273fb78ee226efcdbb70 100644 (file)
@@ -95,6 +95,7 @@
 
 typedef struct attrib_info {
     char *name;
+    int   offset;
 } attrib_info;
 
 /* Information to which an extension can be mapped
@@ -105,17 +106,15 @@ typedef struct extension_info {
     char *language_type;              /* Added with AddLanguage... */
     char *handler;                    /* Added with AddHandler... */
     char *charset_type;               /* Added with AddCharset... */
+    char *input_filters;              /* Added with AddInputFilter... */
+    char *output_filters;             /* Added with AddOutputFilter... */
 } extension_info;
 
 typedef struct {
     apr_hash_t  *extension_mappings;  /* Map from extension name to
                                        * extension_info structure */
 
-    apr_array_header_t *charsets_remove;  /* List of charsets to remove */
-    apr_array_header_t *encodings_remove; /* List of encodings to remove */
-    apr_array_header_t *handlers_remove;  /* List of handlers to remove */
-    apr_array_header_t *languages_remove; /* List of languages to remove */
-    apr_array_header_t *types_remove;     /* List of MIME types to remove */
+    apr_array_header_t *remove_mappings; /* A simple list, walked once */
 
     char *type;                 /* Type forced with ForceType  */
     char *handler;              /* Handler forced with SetHandler */
@@ -150,12 +149,7 @@ static void *create_mime_dir_config(apr_pool_t *p, char *dummy)
     (mime_dir_config *) apr_palloc(p, sizeof(mime_dir_config));
 
     new->extension_mappings = NULL;
-
-    new->charsets_remove = NULL;
-    new->encodings_remove = NULL;
-    new->handlers_remove = NULL;
-    new->languages_remove = NULL;
-    new->types_remove = NULL;
+    new->remove_mappings = NULL;
 
     new->type = NULL;
     new->handler = NULL;
@@ -211,7 +205,7 @@ static void overlay_extension_mappings(apr_pool_t *p,
 /* Member is the offset within an extension_info of the pointer to reset 
  */
 static void remove_items(apr_pool_t *p, apr_array_header_t *remove, 
-                         apr_hash_t *mappings, void *member)
+                         apr_hash_t *mappings)
 {
     attrib_info *suffix = (attrib_info *) remove->elts;
     int i;
@@ -220,13 +214,13 @@ static void remove_items(apr_pool_t *p, apr_array_header_t *remove,
             (extension_info*)apr_hash_get(mappings,
                                           suffix[i].name,
                                           APR_HASH_KEY_STRING);
-        if (exinfo && *((void **)((char*)&exinfo + (apr_size_t)member))) {
+        if (exinfo && *(const char**)((char *)exinfo + suffix[i].offset)) {
             extension_info *copyinfo = exinfo;
             exinfo = (extension_info*)apr_palloc(p, sizeof(*exinfo));
             apr_hash_set(mappings, suffix[i].name, 
                          APR_HASH_KEY_STRING, exinfo);
             memcpy(exinfo, copyinfo, sizeof(*exinfo));
-            *(void **)((char*)exinfo + (apr_size_t)member) = NULL;
+            *(const char**)((char *)exinfo + suffix[i].offset) = NULL;
         }
     }
 }
@@ -255,11 +249,7 @@ static void *merge_mime_dir_configs(apr_pool_t *p, void *basev, void *addv)
          * an exinfo member, then we are about to trounce it anyways.
          * We must have a copy for safety.
          */
-        if (new->extension_mappings && (add->charsets_remove
-                                     || add->encodings_remove
-                                     || add->handlers_remove 
-                                     || add->languages_remove 
-                                     || add->types_remove)) {
+        if (new->extension_mappings && add->remove_mappings) {
             apr_hash_t *copyhash = new->extension_mappings;
             new->extension_mappings = apr_hash_make(p);
             overlay_extension_mappings(p, copyhash, new->extension_mappings);
@@ -267,33 +257,10 @@ static void *merge_mime_dir_configs(apr_pool_t *p, void *basev, void *addv)
     }
 
     if (new->extension_mappings) {
-        if (add->charsets_remove)
-            remove_items(p, add->charsets_remove, new->extension_mappings,
-                         &(*(extension_info*)NULL).charset_type);
-
-        if (add->encodings_remove)
-            remove_items(p, add->encodings_remove, new->extension_mappings,
-                         &(*(extension_info*)NULL).encoding_type);
-
-        if (add->languages_remove)
-            remove_items(p, add->languages_remove, new->extension_mappings,
-                         &(*(extension_info*)NULL).language_type);
-
-        if (add->handlers_remove)
-            remove_items(p, add->handlers_remove, new->extension_mappings,
-                         &(*(extension_info*)NULL).handler);
-
-        if (add->types_remove)
-            remove_items(p, add->types_remove, new->extension_mappings,
-                         &(*(extension_info*)NULL).forced_type);
-
+        if (add->remove_mappings)
+            remove_items(p, add->remove_mappings, new->extension_mappings);
     }
-
-    new->charsets_remove = NULL;
-    new->encodings_remove = NULL;
-    new->handlers_remove = NULL;
-    new->languages_remove = NULL;
-    new->types_remove = NULL;
+    new->remove_mappings = NULL;
 
     new->type = add->type ? add->type : base->type;
     new->handler = add->handler ? add->handler : base->handler;
@@ -303,13 +270,15 @@ static void *merge_mime_dir_configs(apr_pool_t *p, void *basev, void *addv)
     return new;
 }
 
-static extension_info *add_extension_info(cmd_parms *cmd, void *m_, 
-                                          const char* ext)
+static const char *add_extension_info(cmd_parms *cmd, void *m_, 
+                                      const char *value_, const char* ext)
 {
     mime_dir_config *m=m_;
     extension_info *exinfo;
+    int offset = (int) (long) cmd->info;
     char *key = apr_pstrdup(cmd->temp_pool, ext);
-
+    char *value = apr_pstrdup(cmd->pool, value_);
+    ap_str_tolower(value);
 #ifdef CASE_BLIND_FILESYSTEM
     ap_str_tolower(key);
 #endif
@@ -328,114 +297,31 @@ static extension_info *add_extension_info(cmd_parms *cmd, void *m_,
         apr_hash_set(m->extension_mappings, key,
                      APR_HASH_KEY_STRING, exinfo);
     }
-    return exinfo;
-}
-static const char *add_charset(cmd_parms *cmd, void *m, const char *value,
-                              const char *ext)
-{
-    extension_info* exinfo = add_extension_info(cmd, m, ext);
-    char *charset = apr_pstrdup(cmd->pool, value);
-    ap_str_tolower(charset);
-    exinfo->charset_type = charset;
-    return NULL;
-}
-
-static const char *add_encoding(cmd_parms *cmd, void *m, const char *value,
-                               const char *ext)
-{
-    extension_info* exinfo = add_extension_info(cmd, m, ext);
-    char *enc = apr_pstrdup(cmd->pool, value);
-    ap_str_tolower(enc);
-    exinfo->encoding_type = enc;
-    return NULL;
-}
-
-static const char *add_handler(cmd_parms *cmd, void *m, const char *value,
-                               const char *ext)
-{
-    extension_info* exinfo = add_extension_info(cmd, m, ext);
-    char *hdlr = apr_pstrdup(cmd->pool, value);
-    ap_str_tolower(hdlr);
-    exinfo->handler = hdlr;
-    return NULL;
-}
-
-static const char *add_language(cmd_parms *cmd, void *m, const char *value,
-                                const char *ext)
-{
-    extension_info* exinfo = add_extension_info(cmd, m, ext);
-    char *lang = apr_pstrdup(cmd->pool, value);
-    ap_str_tolower(lang);
-    exinfo->language_type = lang;
-    return NULL;
-}
-
-static const char *add_type(cmd_parms *cmd, void *m, const char *value,
-                            const char *ext)
-{
-    extension_info* exinfo = add_extension_info(cmd, m, ext);
-    char *ct = apr_pstrdup(cmd->pool, value);
-    ap_str_tolower(ct);
-    exinfo->forced_type = ct;
+    *(const char**)((char *)exinfo + offset) = value;
     return NULL;
 }
 
 /*
- * Note handler names that should be un-added for this location.  This
- * will keep the association from being inherited, as well, but not
+ * Note handler names are un-added with each per_dir_config merge.
+ * This keeps the association from being inherited, but not
  * from being re-added at a subordinate level.
  */
-static void remove_extension_info(cmd_parms *cmd, 
-                                  apr_array_header_t **m_array,
-                                  const char* ext)
+static const char *remove_extension_info(cmd_parms *cmd, void *m_, 
+                                         const char *ext)
 {
+    mime_dir_config *m = (mime_dir_config *) m_;
     attrib_info *suffix;
-
     if (*ext == '.')
         ++ext;
-    if (*m_array == NULL) {
-        *m_array = apr_array_make(cmd->pool, 4, sizeof(*suffix));
+    if (!m->remove_mappings) {
+        m->remove_mappings = apr_array_make(cmd->pool, 4, sizeof(*suffix));
     }
-    suffix = (attrib_info *) apr_array_push(*m_array);
+    suffix = (attrib_info *) apr_array_push(m->remove_mappings);
     suffix->name = apr_pstrdup(cmd->pool, ext);
 #ifdef CASE_BLIND_FILESYSTEM
     ap_str_tolower(suffix->name);
 #endif
-}
-
-static const char *remove_charset(cmd_parms *cmd, void *m_, const char *ext)
-{
-    mime_dir_config *m = (mime_dir_config *) m_;
-    remove_extension_info(cmd, &m->charsets_remove, ext);
-    return NULL;
-}
-
-static const char *remove_encoding(cmd_parms *cmd, void *m_, const char *ext)
-{
-    mime_dir_config *m = (mime_dir_config *) m_;
-    remove_extension_info(cmd, &m->encodings_remove, ext);
-    return NULL;
-}
-
-static const char *remove_handler(cmd_parms *cmd, void *m_, const char *ext)
-{
-    mime_dir_config *m = (mime_dir_config *) m_;
-    remove_extension_info(cmd, &m->handlers_remove, ext);
-    return NULL;
-}
-
-static const char *remove_language(cmd_parms *cmd, void *m_, const char *ext)
-{
-    mime_dir_config *m = (mime_dir_config *) m_;
-    remove_extension_info(cmd, &m->languages_remove, ext);
-    return NULL;
-}
-
-static const char *remove_type(cmd_parms *cmd, void *m_, const char *ext)
-{
-    mime_dir_config *m = (mime_dir_config *) m_;
-    remove_extension_info(cmd, &m->types_remove, ext);
+    suffix->offset = (int) (long) cmd->info;
     return NULL;
 }
 
@@ -453,34 +339,56 @@ static const char *set_types_config(cmd_parms *cmd, void *dummy,
 
 static const command_rec mime_cmds[] =
 {
-AP_INIT_ITERATE2("AddCharset", add_charset, NULL, OR_FILEINFO,
+AP_INIT_ITERATE2("AddCharset", add_extension_info, 
+         (void *)APR_XtOffsetOf(extension_info, charset_type), OR_FILEINFO,
      "a charset (e.g., iso-2022-jp), followed by one or more file extensions"),
-AP_INIT_ITERATE2("AddEncoding", add_encoding, NULL, OR_FILEINFO,
+AP_INIT_ITERATE2("AddEncoding", add_extension_info, 
+         (void *)APR_XtOffsetOf(extension_info, encoding_type), OR_FILEINFO,
      "an encoding (e.g., gzip), followed by one or more file extensions"),
-AP_INIT_ITERATE2("AddHandler", add_handler, NULL, OR_FILEINFO,
+AP_INIT_ITERATE2("AddHandler", add_extension_info, 
+         (void *)APR_XtOffsetOf(extension_info, handler), OR_FILEINFO,
      "a handler name followed by one or more file extensions"),
-AP_INIT_ITERATE2("AddLanguage", add_language, NULL, OR_FILEINFO,
+AP_INIT_ITERATE2("AddInputFilter", add_extension_info, 
+         (void *)APR_XtOffsetOf(extension_info, input_filters), OR_FILEINFO,
+     "a handler name followed by one or more file extensions"),
+AP_INIT_ITERATE2("AddLanguage", add_extension_info, 
+         (void *)APR_XtOffsetOf(extension_info, language_type), OR_FILEINFO,
      "a language (e.g., fr), followed by one or more file extensions"),
-AP_INIT_ITERATE2("AddType", add_type, NULL, OR_FILEINFO, 
+AP_INIT_ITERATE2("AddOutputFilter", add_extension_info, 
+         (void *)APR_XtOffsetOf(extension_info, output_filters), OR_FILEINFO, 
+     "a mime type followed by one or more file extensions"),
+AP_INIT_ITERATE2("AddType", add_extension_info, 
+         (void *)APR_XtOffsetOf(extension_info, forced_type), OR_FILEINFO, 
      "a mime type followed by one or more file extensions"),
 AP_INIT_TAKE1("DefaultLanguage", ap_set_string_slot,
-     (void*)APR_XtOffsetOf(mime_dir_config, default_language), OR_FILEINFO,
+       (void*)APR_XtOffsetOf(mime_dir_config, default_language), OR_FILEINFO,
      "language to use for documents with no other language file extension"),
 AP_INIT_TAKE1("ForceType", ap_set_string_slot_lower, 
-     (void *)APR_XtOffsetOf(mime_dir_config, type), OR_FILEINFO,
+       (void *)APR_XtOffsetOf(mime_dir_config, type), OR_FILEINFO,
      "a media type"),
-AP_INIT_ITERATE("RemoveCharset", remove_charset, NULL, OR_FILEINFO,
+AP_INIT_ITERATE("RemoveCharset", remove_extension_info, 
+        (void *)APR_XtOffsetOf(extension_info, charset_type), OR_FILEINFO,
+     "one or more file extensions"),
+AP_INIT_ITERATE("RemoveEncoding", remove_extension_info, 
+        (void *)APR_XtOffsetOf(extension_info, encoding_type), OR_FILEINFO,
+     "one or more file extensions"),
+AP_INIT_ITERATE("RemoveHandler", remove_extension_info, 
+        (void *)APR_XtOffsetOf(extension_info, handler), OR_FILEINFO,
      "one or more file extensions"),
-AP_INIT_ITERATE("RemoveEncoding", remove_encoding, NULL, OR_FILEINFO,
+AP_INIT_ITERATE("RemoveInputFilter", remove_extension_info, 
+        (void *)APR_XtOffsetOf(extension_info, input_filters), OR_FILEINFO,
      "one or more file extensions"),
-AP_INIT_ITERATE("RemoveHandler", remove_handler, NULL, OR_FILEINFO,
+AP_INIT_ITERATE("RemoveLanguage", remove_extension_info, 
+        (void *)APR_XtOffsetOf(extension_info, language_type), OR_FILEINFO,
      "one or more file extensions"),
-AP_INIT_ITERATE("RemoveLanguage", remove_language, NULL, OR_FILEINFO,
+AP_INIT_ITERATE("RemoveOutputFilter", remove_extension_info, 
+        (void *)APR_XtOffsetOf(extension_info, output_filters), OR_FILEINFO,
      "one or more file extensions"),
-AP_INIT_ITERATE("RemoveType", remove_type, NULL, OR_FILEINFO,
+AP_INIT_ITERATE("RemoveType", remove_extension_info, 
+        (void *)APR_XtOffsetOf(extension_info, forced_type), OR_FILEINFO,
      "one or more file extensions"),
 AP_INIT_TAKE1("SetHandler", ap_set_string_slot_lower, 
-     (void *)APR_XtOffsetOf(mime_dir_config, handler), OR_FILEINFO,
+       (void *)APR_XtOffsetOf(mime_dir_config, handler), OR_FILEINFO,
      "a handler name"),
 AP_INIT_TAKE1("TypesConfig", set_types_config, NULL, RSRC_CONF,
      "the MIME types config file"),
@@ -871,9 +779,30 @@ static int find_ct(request_rec *r)
                 }
                 found = 1;
             }
+            /* The following extensions are not 'Found'.  That is, they don't
+             * make any contribution to metadata negotation, so they must have
+             * been explicitly requested by name.
+             */
             if (exinfo->handler && r->proxyreq == PROXYREQ_NONE) {
                 r->handler = exinfo->handler;
-                found = 1;
+            }
+            /* XXX Two significant problems; 1, we don't check to see if we are
+             * setting redundant filters.    2, we insert these in the types config
+             * hook, which may be too early (dunno.)
+             */
+            if (exinfo->input_filters && r->proxyreq == PROXYREQ_NONE) {
+                const char *filter, *filters = exinfo->input_filters;
+                while (*filters 
+                    && (filter = ap_getword(r->pool, &filters, ';'))) {
+                    ap_add_input_filter(filter, NULL, r, r->connection);
+                }
+            }
+            if (exinfo->output_filters && r->proxyreq == PROXYREQ_NONE) {
+                const char *filter, *filters = exinfo->output_filters;
+                while (*filters 
+                    && (filter = ap_getword(r->pool, &filters, ';'))) {
+                    ap_add_output_filter(filter, NULL, r, r->connection);
+                }
             }
         }
 
@@ -960,8 +889,14 @@ static int find_ct(request_rec *r)
 
 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);
+    ap_hook_type_checker(find_ct,NULL,NULL,APR_HOOK_MIDDLE);
+ /* 
+  * this hook seems redundant ... is there any reason a type checker isn't
+  * allowed to do this already?  I'd think that fixups in general would be
+  * the last opportunity to get the filters right.
+  * ap_hook_insert_filter(mime_insert_filters,NULL,NULL,APR_HOOK_MIDDLE);
+  */
 }
 
 module AP_MODULE_DECLARE_DATA mime_module = {