Skip to content


Content Negotiation for WAP Browsers

After trying several times over the past several years to have one URL work for both desktop browsers and mobile phone browsers—using the HTTP content negotiation first defined in 1992 and again in 1997 and 1998—and failing because the WAP browsers are broken, I finally stumbled upon a hack that actually works.

The root problem is that almost every WAP browser claims support for both HTML and WAP content in its HTTP Accept header, without specifying a preference for one. Combined with a server that is properly configured to favor HTML over WAP content unless the browser says otherwise, this results in a WAP browser being sent the HTML page.

On some phones, this kinda-sorta works, if the phone can actually parse HTML and has enough memory to handle the typically large Web page. But on most phones, where the limit is something like 1.5K for source, the phone simply barfs and spits out a mostly useless error message.

This hack exploits a currious aspect of Apache’s content negotiation algorithm that is still being investigated. At first glance, it looks just like a couple of standard MIME type definitions that are often found in the .htaccess file:

Options +Multiviews
DirectoryIndex index
AddType text/html;charset=utf-8;qs=1.000;level=4 .html #old-fashioned HTML 4.x source
AddType text/vnd.wap.wml;qs=0.800 .wml #WML 1.x source

The Options +Multiviews line enables content negotiation based on file extensions, the DirectoryIndex index line tells Apache to serve index.anything as the index page when given a URL that ends in a directory, and the qs=n.nnn parameter tells Apache what the quality of each type is, so that it can send the content with the highest quality that the browser claims to handle.

Of course, you then need to remove the .html and .wml extensions from the URLs you publish and link to, but that is how content negotiation is supposed to work anyway.

The magic part of this is the level parameter. Although it really should have no effect since I am only offering one level of HTML, it tricks Apache into not sending HTML files to browsers that claim support for both types of negotiated content. If you do the clever thing, though, and add a level=1 to the WAP MIME type definition as well, this little hack stops working.

This is not an ideal solution, since the phone vendors still need to fix their browsers, but it is a decent workaround that doesn’t require user-agent sniffing or publishing a different URL just for mobile phones.

Posted in Web.


No Responses (yet)

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

You must be logged in to post a comment.