2. Detecting the Context
We’ve already seen how the network protocol works, and
what information is provided and not provided in a mobile browser
request. Now let’s get some data and information from the
context.
2.1. How to read a header
The specifics depend on the language, but all
server-side platforms offer a way to read the request’s header. Some
languages use the same header as the parameter (for example, Accept-Charset), and others use a larger
version with the syntax HTTP_X, where
X is the header name in all uppercase and
with the - replaced by _HTTP_ACCEPT_CHARSET). (for example,
Note:
Some Nokia devices expose a custom HTTP header that defines
the connection type. The header is x-nokia-musicshop-bearer and the possible
values are WLANGPRS/3G. We can try to read this header
and, if it exists, get more information about the context. or
In Java Servlets or JSP, we read a header using:
request.getHeader("header_key")
In ASP 3, we use this:
Request.ServerVariables("header_key_large")
And in PHP:
$_SERVER["header_key_large"]
In ASP.NET with C# or Visual Basic, we have a Headers collection and public members for
most of the common headers:
// This is the C# version
Request.Headers["header_key"]
' This is the VB version
Request.Headers("header_key")
Note:
These devices also expose a
custom HTTP via header that can
be used to see which browser is being used. For example, if the
value contains an MDS string, the
user may be connected via the BlackBerry Browser through the
corporate server; if it contains BISB the user is using the Internet
Browser connecting through the carrier; and if the value is not
defined, the user may be using the WiFi Hotspot Browser.
2.2. How to read the IP address
The IP address from which the request originated can be read
with the following code:
// In Java
String address = req.getRemoteAddr();
// In PHP
$address = $_SERVER["REMOTE_ADDR"];
// In C#
String address = Request.UserHostAddress;
What we can do with the IP address? We need to get an updated list of the IP ranges
assigned to each carrier. The carriers distribute this information to
their partners, and it can also be found in forums and communities or
through commercial services.
Note:
Massive’s Operator Identification Platform is a
community-based database service that allows us to determine
visitors’ countries and network operators, if detected, using a
simple HTTP service request. You can request an account at http://www.werwar.com. It is free for noncommercial
sites, and commercial licenses start at $10 per month.
2.3. Opera Mini
As mentioned earlier, there are some proxied browsers on
the market (Opera Mini is the most widely installed), and we need to
take care of differences in the headers in such browsers. Even on a
well-known device, such as a BlackBerry or a Nokia N97, if Opera Mini
is in use the requests we receive on our servers will come from the
Opera Mini proxy and not from the device itself. So, the client IP
address will be Opera’s server address, and the user-agent string will
be the proxy’s one. On any device, the Opera Mini 5 user-agent string
looks like this:
Opera/9.80 (J2ME/MIDP; Opera Mini/5.0.16823/1126; U; en) Presto/2.2.0
Fortunately, Opera Mini offers the original IP address and the
original user-agent string, along with other information, in new
headers (listed in Table 10-2) that we can read
using the techniques we have already seen.
Warning:
Opera Mini has a developer site at http://www.opera.com/mini/developer that offers tips
and technical information about Opera Mini website development.
Other intermediates are not as developer-friendly as Opera Mini and
remove all the original headers, so we are blind in detecting the
device and its origin.
Table 2. Opera Mini additional HTTP headers
Header | Description |
---|
X-OperaMini-Phone-UA | Provides the user-agent
string identifying the device that downloaded the Opera Mini
client (or the current device’s user-agent string if not
available). |
X-OperaMini-Phone | Provides the device’s
brand and model, separated by a hash
(<brand>#<model>). |
X-Forwarded-For | Provides a CSV list of
all the proxy servers in the chain that have forwarded the
request from the device to Opera Mini’s proxy. Opera
recommends using the last IP address listed for geolocation
purposes. |
X-OperaMini-Features | Provides a CSV list of
phone features, from the following list: basic (Java
MIDP 1.0 device, low resources) advanced (Java
MIDP 2.0 device, high resources) camera (camera
detected, so we can provide a file upload input for
pictures) file_system
(Java filesystem support detected, so the user can
download and upload files) folding
(content folding option is enabled) secure
(connection between phone and proxy is encrypted)
|
Note:
Content folding in Opera Mini
refers to the ability of the browser to group a series of links into
a menu that can be closed and opened to gain space on the
screen.
2.4. Mobile detection
If you only want to know whether the user is browsing
from a desktop or a mobile device (perhaps for doing a redirection),
the quickest way to find out is to check for some different well-known
strings (iPhone, iPod, Nokia, etc.) inside the User-Agent header.
Based on their presence or absence, you can make an educated guess
about whether or not the user is on a mobile device.
Note:
There is an excellent collection of mobile-specific User-Agent headers at http://mobiforge.com/developing/blog/useful-x-headers.
Andy Moore has developed a very simple but powerful PHP
script for detecting mobile user agents and browsers. The latest version (free for non-profit purposes) can be
downloaded from http://detectmobilebrowsers.mobi.
You can find similar scripts in different languages at http://www.mobilexweb.com/go/detection.
Note:
Some devices support multipart document delivery. A multipart
document includes XHTML and resources (images, CSS) in the same HTTP
response, enhancing the download performance. To determine whether a
device supports multipart documents, check for the multipart/mixed or application/vnd.wap.multipart MIME type in
the Accept header. Visit http://www.mobilexweb.com/go/multipart for more
information.