Device Detection in C Nginx module
Supported Databases | Developer Documention | Available Properties
Need .NET | Java | PHP Script?
In nginx.config, use like...
http {
51D_filePath path/to/51Degrees.dat;
server {
...
location / {
51D_match_all X-Mobile IsMobile;
...
}
}
}
... to turn User-Agent HTTP headers into useful information about physical screen size, device price and type of device.
Use this project to detect device properties using HTTP browser User-Agents as input using the patented pattern detection method.
Two detection methods are supported.
Pattern: Searches for device signatures in a useragent returning metrics about the validity of the results. Does NOT use regular expressions.
Hash Trie: A small binary data file containing User-Agents stored as Hash sequences. Very fast detection time.
All methods use an external data file which can easilly be updated.
- gcc
- make
- Nginx source
- curl
- grep
- ApacheBench dependencies (see Device-Detection/ApacheBench/README.md)
For Ubuntu based distributions gcc can be found on apt, use
$ sudo apt-get install gcc make
and the Nginx source will be automatically downloaded by the make file.
Pre-compiled modules are available in the "modules" sub-directory. The correct version can simply be placed in Nginx's module directory (this is usually /etc/nginx/modules
). The Nginx version, and Nginx's module directory , can be found by running nginx -V
.
This is a good way to build Nginx in a local directory to try out the module if Nginx is not already installed on the system. Just use
$ git clone https://github.com/51Degrees/Device-Detection.git
$ cd Device-Detection/nginx
$ make install pattern
or
$ make install trie
To install to the local directory.
Then run the included tests with:
$ make test
which will all pass if the local installation was successful.
Note: If ApacheBench tests fail even though the dependencies are fulfilled it may need to be recompiled using the correct compiler for your OS. This can be done using Device-Detection/CodeBlocks/ApacheBench.cbp
51Degrees dynamic module can be used in Nginx version 1.9.11 or later. For versions after 1.11.5 It is important to check you have '--with-compat' available within your configure arguments. You can check this by doing nginx -V
. In order to compile dynamic modules before this version you will need to ensure the configure arguments in the Makefile (under the configure
block) are identical to those in your current Nginx installation.
For versions 1.11.5 (R11), 1.11.10 (R12) and 1.13.4 (R13), 1.14.2, 1.15.2 (R16), 1.15.7 (R17) there are pre-built modules in the nginx/modules
directory.
To build the module as ngx_http_51D_module.so for another version, define VERSION
when calling make like:
$ make module pattern VERSION=1.9.11
By default, the module will be built to the build/modules
directory.
To load the module, copy the .so to your modules directory and include the following near the top of the Nginx config file.
load_module modules/ngx_http_51D_module.so;
When calling make install
, the following compile arguments are available.
Argument | Default | Description |
---|---|---|
STATIC_BUILD |
Undefined | To compile as a static module rather than dynamically, set to 1. |
FIFTYONEDEGREES_CACHE_KEY_LENGTH |
500 | The number of characters to use as the cache key string. Only applies to Pattern. |
FIFTYONEDEGREES_VALUE_SEPARATOR |
',' | The separator to use when returning a list of values, e.g. "True,Chrome". |
Before start matching user agents, you may wish to configure the solution to use a different database for example.
These settings are valid in the main configuration block and should only be set once.
-
51D_filePath
(defaults to'51Degrees.dat'
). Sets the location of the data file. -
51D_cache
(defaults to0
). Sets the size of the workset cache. -
51D_valueSeparator
(defaults to','
). Sets the delimiter to separate values with.
These settings are valid in a location, server, or main configuration block.
-
51D_match_single
- Gets device properties using a User-Agent. Takes the name the resultant header will be set as, a comma separated list of properties to return, and optionaly a variable containing the User-Agent to match with. -
51D_match_all
- Gets device properties using multiple HTTP headers. Takes the name the resultant header will be set as, and a comma separated list of properties to return.
An example configuration file is included in this repository. It shows how to pass device information when using Nginx as a reverse proxy, and when passing to a fast-cgi provider.
Within the HTTP block is where the detector settings are set, these should be set like:
http {
51D_filePath data/51Degrees.dat;
51D_cache 10000;
...
}
Within a location block is where the match settings are usually set, though they can be set in a server block to add a header to all locations contained in that server block, and similarly for an HTTP block. They can be set in one of three ways:
To get properties using the device's User-Agent use:
location / {
51D_match_single x-user-agent-match HardwareName,DeviceType,BrowserName;
...
}
To get properties from all the relevant HTTP headers from the device use:
location / {
51D_match_all x-all-headers-match HardwareName,BrowserName,PlatformName;
...
}
A User-Agent other than the request's can also be used for a match by passing the variable which contains a User-Agent string as an argument. For example, for a User-Agent sent as a "ua" parameter in the query string of a request, use:
location / {
51D_match_single x-user-agent-match HardwareName,DeviceType,BrowserName $arg_ua;
...
}
When using the proxy_pass
directive in a location block where a match directive is used, the properties selected are passed as additional HTTP headers with the name specified in the first argument of 51D_match_single
/51D_match_all
.
Using include fastcgi_params;
makes these additional headers available via the $_SERVER
variable.
The value of the header is set to a comma separated list of values (comma delimited is the default behaviour, but the delimiter can be set explicitly with 51D_valueSeparator
), these are in the same order the properties are listed in the config file. So setting a header with the line:
51D_match_all x-device HardwareName,BrowserName,PlatformName;
will give a header named x-device
with a value like Desktop,Firefox,Ubuntu
. Alternatively, headers can be set individually like:
51D_match_all x-hardware HardwareName;
51D_match_all x-browser BrowserName;
51D_match_all x-platform PlatformName;
giving three seperate headers.
If installing to a local directory using make install pattern
/make install trie
, the executable is set up to use the example configuration and can be easily tested. Take example.php
, which just prints all request headers, and place it in apache's web directory (probably /var/www/html).
Now, once Nginx is started by running
$ ./nginx
in the Device-Detection/nginx
directory, accessing localhost:8888/example.php
will display all request headers which will include the device properties:
x-device: Desktop,Firefox,Ubuntu
x-tablet: False
x-smartphone: False
x-metrics: 15364-18118-57666-18092,Exact,0,1538
Alternatively, the line add_header x-mobile http_x_mobile
is included in the example config. This adds the header to the response headers, so can be viewed in the response without a PHP server set up. In a Linux environment, these can be viewed with the command:
$ curl localhost:8888 -I -A [SOME USER-AGENT]
which will give the following response:
HTTP/1.1 200 OK
Server: nginx/1.10.0
...
x-device: Desktop,Firefox,Windows
x-mobile: False
x-tablet: False
x-smartphone: False
x-metrics: 15364-21460-53251-18092,Exact,0,249