Tags:
Mobile Domino Redirect
Whilst preparing sessions for Lotusphere I considered whether or not to include a section about redirecting mobile users based on their User-Agent and other headers. I prepared lots of slides but they didn't make it into either presentation. Despite this it's worth discussing and since I haven't posted anything technical for a while here goes....
If you visit http://news.bbc.co.uk or YouTube with a micro-browser the chances are you'll be offered the chance to use the corresponding mobile site. Both will be using some kind of device detection using headers (name-value pairs) sent by the device or gateway with the request. If a mobile device is detected then a redirection allows the user to easily access device appropriate content.
In an ideal world the redirection would be performed on the server
1. The mobile client requests page http://host.yourdomain.com
2. The Web Server considers the request and the headers provided and tries to work out if the client is constrained (micro-browser)
3. If the server can be sure it's a micro-browser then it issues a 301 or 302 (see http://www.somacon.com/p145.php) response with details of the new page location
4. The Micro-Browser follows the redirect and requests the new page with minimal download of additional data
Using this method the client doesn't need to download a whole page only to be redirected to something more appropriate. Unfortunately without resorting to a complicated IBM HTTP Server, PHP and Websphere Plug-in setup I can't think of a way to do this natively with Domino. If you do please let me know.....
If we accept then, that we have to perform the redirect on the device we have a couple of options:
Option One: Recognising the User-Agent string using the WURFL resource file
Option Two: Sniffing the client using the User-Agent string and other headers with a relatively simple formula
Option One: Using the WURFL resource:
The WURFL (http://wurfl.sourceforge.net/) is a big configuration file (XML) recording in varying detail the capabilities of more than 9000 devices. Although I'm talking about using the file to match the User-Agent string, the potential uses of the file go beyond that.
Because we're Notes people and we understand Views Documents and Fields the attached database wurfl.nsf contains the data in the XML file in documents presented in a view. It also has an agent to import the main file. I haven't got round to writing something to import the patches yet, they look more complicated. I may improve the database but for now the important design elements are the (luUserAgent) view which indexes all documents by User-Agent, and the documents themselves which contain an info about the capabilities of each device.
Having imported the data and created the view what we need now is a little form or page to capture the User-Agent string when user points a browser at the db, do a lookup on the view and redirect the client if necessary. For simplicity I've made the form part of wurfl.nsf. I've chosen to do this with a Navigator (which is left deliberately blank) and a $$NavigatorTemplateDefault form.
The $$Navigator form has a field called "HTTP_USER_AGENT" which is computed and has a default value of the USER-AGENT header. The field isMobile uses the HTTP_USER_AGENT value to perform a lookup on the luUserAgent view and return 0 for not matched and 1 for matched.
The redirect is performed in the HTML Head of the form:
@If(isMobile=1;"";"")
If we detected a mobile we use a META tag to redirect the user. We could use JavaScript too (belt and braces) but we can't rely on it being enabled so we'll stick with the META tag.
Just in case the refresh doesn't work we provide a link to the mobile version of the site:
Finally we implement the $$NavigatorTemplate using the database properties. First we turn off the "Use JavaScript" flag and then in the database launch option choose Navigator and home.
In the attached database the page we redirect to (mobile.html) is a little form that we ask the user to submit:
When submitting the form action "posts" to an agent which captures the answer plus the headers submitted with the form. After submission we present a little thank you page.
If you want to see it in action: http://www/opencod.org/opencod/test/wurfl.nsf
Option Two: Using the User-Agent string and other headers:
This solution though similar to the previous solution replaces the WURFL information with a simple formula in the isMobile field. The formula has it's roots in work published by Andy Moore (www.andymoore.info) which is mentioned in Cameron Moll's book: http://mobilewebbook.com/
The Navigator and $$Template method is identical and I copied the original elements. The new Navigator in WURFL.nsf is called home1 and the "$$NavigatorTemplate For home1" is used.
If you want to see it in action: http://www/opencod.org/opencod/test/wurfl.nsf/home1?opennavigator
The $$NavigatorTemplate for home1 form captures a few extra headers, the values of which are used in the isMobile formula.
Here's the formula for the isMobile field:
FirstFourList :=
"acs-":"alav":"alca":"amoi":"audi":"aste":"avan":"benq":"bird":"blac":"blaz":"brew":"cell":"cldc":"cmd-":"dang":"doco":"eric":"hipt":
"inno":"ipaq":"ipho":"java":"jigs":"kddi":"keji":"leno":"lg-c":"lg-d":"lge-":"maui":"maxo":"midp":"mits":"mmef":"mobi":"mot-":"moto":"mwbp":
"nec-":"newt":"noki":"opwv":"palm":"pana":"pant":"pdxg":"phil":"play":"pluc":"port":"prox":"qtek":"qwap":"sage":"sams":"sany":"sch-":
"sec-":"send":"seri":"sgh-":"shar":"sie-":"siem":"smal":"smar":"sony":"sph-":"symb":"t-mo":"teli":"tim-":"tosh":"tsm-":"upg1":"upsi":
"vk-v":"voda":"w3c":"wap-":"wapa":"wapi":"wapp":"wapr":"webc":"winw":"xda":"xda-";
FirstFour := @Left(@LowerCase(HTTP_USER_AGENT);4);
@If(@Contains(@LowerCase(HTTP_User_Agent);"windows ce");
@Return("Mobile");
@If(@Contains(@LowerCase(HTTP_User_Agent);"iphone");
@Return("Mobile");
@Contains(HTTP_ACCEPT;"application/vnd.wap.xhtml+xml");
@Return("Mobile");
@Contains(HTTP_ACCEPT;"text/vnd.wap.wml");
@Return("Mobile");
@Trim(HTTP_X_WAP_PROFILE)!="";
@Return("Mobile");
@Trim(HTTP_PROFILE)!="";
@Return("Mobile");
@Trim(HTTP_X_OPERAMINI_FEATURES)!="";
@Return("Mobile");
@IsMember(FirstFour;FirstFourList);
@Return("Mobile");
@Return("Desktop")))
Once again we use the HTML Head to perform a redirect if necessary:
@If(@LowerCase(isMobile)="mobile";"";"")
The rest of the workflow is the same as the previous approach.
Testing the options:
It would be nice to test both options to see which works best. Over the next week I hope register a short domain and point it at WURFL.NSF which will then present links to the two methods of detection. At that point I'll invite people to visit with their devices and we'll see how each holds up and what kind of devices are in use.
If you want to play in the meantime you can use these two URLs:
http://www.opencod.org/opencod/test/wurfl.nsf
http://www.opencod.org/opencod/test/wurfl.nsf/home1?opennavigator
If you are using a desktop browser like Firefox you can still play with the USER-AGENT header. To do that first download the User Agent switcher Addon:
https://addons.mozilla.org/en-US/firefox/addon/59
Once installed you can add and then switch between USER-AGENT strings. To get the strings you can either copy from the database or search on the web for sites that offer lists of them.
Alternatively you can use one of the many desktop tools out there including iPhoney, BlackBerry, Symbian and Nokia emulators or a real device
Using WURFL.nsf:
The database is zipped and is close to 3MB and you can download it from this URL:
http://weblog.jasonhookonline.com/jho/blog.nsf/downloads/JHOK-7MBHAF/$file/wurfl.nsf.zip
It contains documents created using the importer agent and data from the WURFL file which you can get from http://wurfl.sourceforge.net. I used the ExportFieldNames agent to help me generate tables of fields which I could use to build a DXL form to view the device definitions.
The main form was created using DXL and imported using Andre Guirard's agent which appears in the Db as DXLImporter.
If you put the database on the server please review the ACL agent code and sign it.
TODO TO DO:
If I were to do more work on this database I'd be inclined to:
Look at the forms and style with some CSS;
Provide a 'home' page with links to both types of detection;
Have the "Thank You" form return some statistics about results and browsers used;
Have an agent that can import WURFL patches.
That's it then. If you find any bugs, or have any comments I be glad to hear from you.