“Everything you always wanted to know
about your HTTP Clients, but were afraid to ask.”
I cannot count the times I heard someone wonder why on earth device manufacturers never added an HTTP header that would make it obvious that an HTTP request is coming from a mobile device. I typically had witty answers to that question. ‘The header existed. It was called UAProf. Apple killed it’.
Jokes aside, the answer to that question lies in the economics of the whole thing: mobile stakeholders do not agree on who is entitled to decide what content and what user-experience should be delivered to users, hence the inability to agree on a standard and stick by it.
The point we are making today is not why such a header does not exist, but rather that the ScientiaMobile team is finally launching products that will make that header (and a limitless array of other WURFL-powered headers) available to WURFL adopters. We have made the versions of a set of modules for Apache, HAProxy, NGINX, NGINX Plus, Microsoft IIS, and Varnish-Cache (all based on our WURFL InFuze C++ API) available to commercial customers. This opens a whole range of new possibilities.
Let me proceed, with order. As you know, installing WURFL and managing a WURFL installation takes a certain amount of work and dedication. This is particularly demanding in the case of large organizations, dealing with several data feeds, content repositories, CMSes and geographically dispersed teams. Wouldn’t it be awesome if the HTTP spec already came with headers such as x-wurfl-is-wireless-device, x-wurfl-is-tablet and x-wurfl-ux-full-desktop to indicate the true nature of each device, tablet or desktop browser? This would allow companies to leverage device information within the very frameworks, tools and programming languages they use today.
Thanks to the products that we make available in their beta form today, this is now a reality. In the case of Varnish-Cache, for example, the VCL configuration would look something like:
sub vcl_init {
wurfl.set_root(“/usr/share/wurfl/wurfl.xml”);
wurfl.add_patch(“/usr/share/wurfl/wurfl_patch.xml”);
wurfl.set_engine_target_high_performance();
wurfl.set_cache_provider_double_lru(10000,3000);
wurfl.add_requested_capability(“brand_name”);
wurfl.add_requested_capability(“model_name”);
wurfl.add_requested_capability(“marketing_name”);
wurfl.add_requested_capability(“device_os”);
wurfl.add_requested_capability(“device_os_version”);
wurfl.add_requested_capability(“is_tablet”);
wurfl.add_requested_capability(“is_wireless_device”);
wurfl.load();
if (wurfl.error()) {
panic wurfl.error();
}
}
sub vcl_recv {
set req.http.X-Wurfl-Id = wurfl.get_device_id();
set req.http.X-Wurfl-RootId = wurfl.get_root_id();
set req.http.X-Wurfl-IsDevRoot = wurfl.is_actual_device_root();
set req.http.X-Wurfl-Cap-Brand-Name = wurfl.get_capability(“brand_name”);
set req.http.X-Wurfl-Cap-Device-Os = wurfl.get_capability(“device_os”);
set req.http.X-Wurfl-Cap-Device-Os-Version = wurfl.get_capability(“device_os_version”);
set req.http.X-Wurfl-Cap-Is-Tablet = wurfl.get_capability(“is_tablet”);
set req.http.X-Wurfl-Cap-Is-Wireless-Device = wurfl.get_capability(“is_wireless_device”);
if (wurfl.error()) {
std.syslog(wurfl.error());
}
}
On the other hand, it is way too early to talk about standardization, I think that the ‘X-‘ format still makes sense.
Let’s look at the HTTP request from a Nokia Lumia 900 the moment it passed through Varnish-Cache, enroute to the web server (Apache in our example):
The implication of this is that PHP, Java, .NET programmers and virtually any other programmer on the planet can access the power of WURFL with the simplicity of:
// PHP
if ($_SERVER[‘HTTP_X_WURFL_IS_TABLET’] == ‘true’) {
//Do whatever makes sense for a tablet
}
I guess Apache would be another good example, albeit the reader may object that there is no point in using Apache when you already have Varnish. To this, I counter-object that there is no limit to the technology anti-patterns tucked away inside multi-layered large organizations.
// You can even use it in an Apache rewrite condition
RewriteCond %{HTTP:x-wurfl-is-tablet} =TRUE
RewriteRule ^phone/(.+)$ tablet/$1
The example above referred to Varnish, whose natural job is being a reverse-proxy. But also NGINX and Apache can be set up as reverse proxies. We could show you the same example with NGINX, or show you the configuration of NGINX for a different use-case. For example, we could use NGINX to enrich our environment variables ($_ENV[]) with capability values, effectively making those capabilities available in the most natural way for a variety of uses.
Enriching the Environment Variables
NGINX can be compiled with the WURFL Module and configured as follows:
http {
…
#wurfl root definition (one per config)
wurfl_root /usr/share/wurfl/wurfl.xml;
#wurfl patch definition
wurfl_patch /path/to/patch1.xml;
wurfl_target_performance;
wurfl_cache_double_lru 10000,3000;
# specify all required capabilities
wurfl_request_capability brand_name;
wurfl_request_capability model_name;
wurfl_request_capability is_wireless_device;
wurfl_request_capability is_tablet;
wurfl_request_capability ux_full_desktop;
…
server {
…
location ~ .php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www$fastcgi_script_name;
include fastcgi_params;
# Example to inject Wurfl Capabilities to FastCGI Environments
fastcgi_param WURFL_ID $wurfl_id;
fastcgi_param WURFL_BRAND_NAME $wurfl_cap_brand_name;
fastcgi_param WURFL_MODEL_NAME $wurfl_cap_model_name;
fastcgi_param WURFL_IS_WURELESS_DEVICE $wurfl_cap_is_wireless_device;
fastcgi_param WURFL_IS_TABLET $wurfl_cap_is_tablet;
fastcgi_param WURFL_UX_FULL_DESKTOP $wurfl_cap_ux_full_desktop;
}
…
}
}
Which, in turn, would allow PHP programmers to do things like:
if ($_ENV[‘WURFL_IS_TABLET’] == ‘true‘) {
//Do whatever makes sense for a tablet
}
Of course Perl, Python and everything that can run in a CGI environment can take advantage of the same functionality.
Enriching the HTTP request or the Environment Variables with new headers and values are obvious use cases. This allows organizations to “inject” the value of WURFL without disrupting (or even without redeploying) existing sites and systems. This lowers the burden on application developers and removes the need to maintain a WURFL library dependency in their code base.
But these are not the only use cases that the WURFL Modules enable. Other uses are possible. For example, URL rewriting or routing can be made mobile-aware to preserve URL ‘uniformity’ for end users (i.e. make sure that the same URL leads to the same content but with different user-experiences for mobile users).
Adopting separated caching strategies for mobile and desktop clients is another totally sustainable option. Once WURFL is built-in into your network, the possibilities are endless.
Enterprise
WURFL InFuze represents a quantum leap in terms of ScientiaMobile offerings to the Enterprise. Device detection can now be configured to be a DevOps issue (as opposed to a developer issue). In a world where IT wants to be defined in terms of components that interact with one another (as opposed to the implementation of one’s own personal wheel), InFuze is a giant step exactly in that direction.
Luca Passani
CTO @ScientiaMobile