This fragment is about to be reported (you'll remain on this page):

You can enter a comment to clarify the mistake if you would like to:

Stop rewriting easy stuff or Why use Apache MultiViews

Stop rewriting easy stuff or Why use Apache MultiViews

In this post I want to talk about a feature that somehow has slipped through my «mental fingers» until recently – Apache MultiViews mechanism, which is part of Content Negotiation module (mod_negotiation).

Useful documentation pages:

Let me give a short overview of what content negotiation is before I proceed to MultiViews themselves (though there's not much to tell about the latter, really).

Apache can serve content in two ways: directly based on its exact URL given by the client or indirectly based on the URL and, possibly, some other headers. The first way is part of the webserver core while the second is provided by mod_negotiation and other modules.

When content is served directly it's plain and simple – if the given URL unambiguously maps to a file or directory it's served, otherwise a HTTP 404 error occurs. However, when the URL doesn't map to a local resource Apache can try to guess what content the client wants – and here comes mod_negotiate.

More info can be found on this doc page but in a nutshell mod_negotiate takes the passed URL as a base path and uses browser's Accept-Language and other Accept-… headers to determine most appropriate document media type (plain text, HTML, graphic, etc.), language (English, Russian, etc.), encoding (GZIP-compressed or plain) or charset (CP1251, UTF-8 and so on).

For example, if you create 2 files: index.html and index.html.jp and a client requests the directory where you've put those files Apache will check its Accept-Language header and serve either Japanese or default (without extension, presumably English) version of the index document.

This mechanism can be made more flexible using type-maps – these are files linking URIs with certain requirments (client headers) that, when matched, will make that local document be served instead of others residing on the same «generic» URI.

MultiViews are part of the same mechanism – when enabled, resources (like PHP scripts) can be requested by their path-prefix – i.e. without extension and with optional trailing path information. For example, if the server has path/script.php residing under its document root then the URI http://my.host/path/script/query-path/goest/here will trigger it and additionally pass everything after its base name as its path info (available through $_SERVER['PATH_INFO'] in PHP) – this would be /query-path/goest/here in our example.

Of course, you can pass normal GET/POST variables this way too: /dir/script/path/info?query=var. To get it working you only have to enable MultiViews in your .htaccess or httpd.conf (it can be set inside <Directory>, <Location> or <Files> directives as well):

confOptions +MultiViews

After this all requests on that directory and its subdirectories will be served using MultiViews, if possible. Note that, as it was said before, it's only enabled for URIs not mapping to a local file so it's possible to have script.php and script.zip and request the first using MultiViews (/script/pathinfo) while requesting the second using a regular URL (/script.zip).

Now we've reached the point of this article: you don't have to use mod_rewrite just to get clean URLs. I personally had a habit of putting these or very similar lines to most .htaccess'es of the engines I was writing:

confRewriteEngine on
RewriteRule ^(page|second|third)(/.*)?$ serve.php?page=$1&path=$2 [L,QSA]

# or this:
RewriteCond %{REQUEST_FILENAME}.php !-f
RewriteRule ^.+$ $0.php [L]

…which had some issues that were growing along with the complexity of rewrite rules; however, with MultiViews many things are just made much more simple – since I have control over my scripts I can instruct them to parse the URL or rely completely on GET query strings and just have cleaner URLs without script file extensions.

Of course, mod_rewrite is still highly useful but each tool has its purpose… it's just that for me MultiViews turned out to be much better for rewriting easy stuff. And probably much faster for the server too.

Comments RSS20

Your name: Your homepage:

Text & signature markup:You can use UverseWiki markup. In short: **bold**, //italic//, %%code%%, ((URL link)), >inline quote, <[ multiline quote ]>.

Humans! Please enter "J" here: (or turn JavaScript on for automatic verification)
Subscribe by e-mail (manage):
Ctrl+Enter »