Name

Type Checker

Example

Example 21-20. mod_mime.c

int find_ct(request_rec *r)
{
    char *fn = strrchr(r->filename, '/'.;
    mime_dir_config *conf =
      (mime_dir_config *)ap_get_module_config(r->per_dir_config, &mime_module);
    char *ext, *type, *orighandler = r->handler;

    if (S_ISDIR(r->finfo.st_mode)) {
        r->content_type = DIR_MAGIC_TYPE;
        return OK;
    }

    if(fn == NULL) fn = r->filename;

    /* Parse filename extensions, which can be in any order */
    while ((ext = getword(r->pool, &fn, '.')) && *ext) {
      int found = 0;

      /* Check for Content-Type */
      if ((type = table_get (conf->forced_types, ext))
          || (type = table_get (hash_buckets[hash(*ext)], ext))) {
          r->content_type = type;
          found = 1;
      }

      /* Check for Content-Language */
      if ((type = table_get (conf->language_types, ext))) {
          r->content_language = type;
          found = 1;
      }

      /* Check for Content-Encoding */
      if ((type = table_get (conf->encoding_types, ext))) {
          if (!r->content_encoding)
              r->content_encoding = type;
          else
              r->content_encoding = pstrcat(r->pool, r->content_encoding,
                                            ", ", type, NULL);
          found = 1;
      }

      /* Check for a special handler, but not for proxy request */
      if ((type = table_get (conf->handlers, ext)) && !r->proxyreq) {
          r->handler = type;
          found = 1;
      }

      /* This is to deal with cases such as foo.gif.bak, which we want
       * to not have a type. So if we find an unknown extension, we
       * zap the type/language/encoding and reset the handler.
       */

      if (!found) {
        r->content_type = NULL;
        r->content_language = NULL;
        r->content_encoding = NULL;
        r->handler = orighandler;
      }
    }

    /* Check for overrides with ForceType/SetHandler */

    if (conf->type && strcmp(conf->type, "none"))
        r->content_type = pstrdup(r->pool, conf->type);
    if (conf->handler && strcmp(conf->handler, "none"))
        r->handler = pstrdup(r->pool, conf->handler);

    if (!r->content_type) return DECLINED;

    return OK;
}

Another example can be found in mod_negotiation.c, but it is rather more complicated than is needed to illustrate the point.

Although the 2.0 version of the example is rather different, the differences aren’t really because of changes in the hook and are more concerned with the complication of determining MIME types with filters in place, so we won’t bother to show the 2.0 version here.



[7] Old hands may recall that earlier versions of Apache used “magic”; MIME types to cause certain request handlers to be invoked, such as the CGI handler. Handler strings were invented to remove this kludge.