Type Checker
int module_type_checker(request_rec *pReq)
At this stage, we have almost finished
processing the request. All that is left to decide is who actually
handles it. This is done in two stages: first, by converting the URL
or filename into a MIME type or handler string, language, and
encoding; and second, by calling the appropriate function for the
type. This hook deals with the first part. If it generates a MIME
type, it should be stored in
pReq->content_type
. Alternatively, if it
generates a handler string, it should be stored in
pReq->handler
. The languages go in
pReq->content_languages
, and the encoding in
pReq->content_encoding
. Note that there is no
defined way of generating a unique handler string. Furthermore,
handler strings and MIME types are matched to the request handler
through the same table, so the handler string should probably not be
a MIME type.[7]
One obvious place that this must go on is in mod_mime.c. See Example 21-20.
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.