WURFL InFuze for golang is a GO language module wrapping the WURFL C API and encapsulating it in two golang types to provide a fast and intuitive
interface. It is compatible on Linux and macOS platforms for golang 1.7
or higher.
In order for the Module to work it is ESSENTIAL that the libwurfl
library is installed on your system.
libwurfl
is provided in your Customer Vault/FileX.
If you have not already installed libwurfl, instructions can be found here. Release notes for each API can be found here.
InFuze for golang is available as a binary package. To install it, untar the contents in your GOPATH folder. For example:
# cd $GOPATH
# tar xvzf golang-src-wurfl-1.12.10.0.tar.gz
To perform lookups, you will need a copy of your WURFL data snapshot (also referred to as the wurfl.xml
). While there is one included in the release package, it is intended to be a sample and will not contain all of your licensed capabilities. Your licensed WURFL data snapshot can be accessed by following these directions.
Here is an example to get started:
package main
import (
"fmt"
"html"
"net/http"
"scientiamobile/wurfl"
)
func main() {
var wengine *wurfl.Wurfl
var device *wurfl.Device
wengine, err := wurfl.Create("/usr/share/wurfl/wurfl.zip", nil, nil, -1, wurfl.WurflCacheProviderLru, "100000")
if err != nil {
fmt.Println(err)
}
ua := "Dalvik/1.6.0 (Linux; U; Android 4.3; SM-N900T Build/JSS15J)"
device, err = wengine.LookupUserAgent(ua)
deviceid, err := device.GetDeviceID()
fmt.Println(deviceid)
fmt.Println(device.GetCapability("device_os"))
fmt.Println(device.GetVirtualCapability("is_android"))
device.Destroy()
wengine.Destroy()
}
Create the WURFL Engine once, then lookup UserAgent and get the static and virtual capabilities needed in your implementation (NOTE: virtual capabilities are calculated at runtime).
If you already have a HTTP request, you can directly pass it to the WURFL API by using wengine.LookupRequest()
. Alternately you can test passing a HTTP request to the WURFL API by creating a mock request, stuffing it with the desired test headers and passing them to the WURFL API as mentioned in the previous sentence. This is particularly useful for detecting requests with User-Agent Client Hints. In either case you can retrieve the resolved device as shown below. The static and virtual capabilities can then be requested as shown in the first snippet.
req, _ := http.NewRequest("GET", "http://example.com", nil)
UserAgent := "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/10.0.0.0 Mobile Safari/537.36"
req.Header.Add("User-Agent", UserAgent)
req.Header.Add("Sec-CH-UA", "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"110\", \"Google Chrome\";v=\"110\"")
req.Header.Add("Sec-CH-UA-Full-Version", "110.0.4430.91")
req.Header.Add("Sec-CH-UA-Platform", "Android")
req.Header.Add("Sec-CH-UA-Platform-Version", "11")
req.Header.Add("Sec-CH-UA-Model", "SM-M315F")
device, err = wengine.LookupRequest(req)
Additional documentation on User-Agent Client Hints and how to collect them is available here.
If you want to keep your wurfl.zip
uptodate with the ScientiaMobile data release schedule, then you might want to use the Updater features.
After creating your WURFL Engine, set your personal WURFL Snapshot URL (in the form https://data.scientiamobile.com/xxxxx/wurfl.zip, with xxxxx replaced with your personal access token, located in your customer vault):
uerr := wengine.SetUpdaterDataURL(Url)
if uerr != nil {
fmt.Printf("SetUpdaterDataUrl returned : %s\n", uerr.Error())
}
Specify the periodicity you would like for update checks:
_ = wengine.SetUpdaterDataFrequency(wurfl.WurflUpdaterFrequencyDaily)
Do note that a wurfl.zip file must already be present in a writable path in order for the updater to check the file and determine whether or not it needs to update the file. You can either manually download this file by going to your WURFL Snapshot URL or by following these directions.
Start the updater:
uerr = wengine.UpdaterStart()
if uerr != nil {
fmt.Printf("UpdaterStart returned : %s\n", uerr.Error())
}
Updater will run a daily check for the latest release of the wurfl.zip
file, download it, and update the running engine to the latest version - all during normal application operations.
Starting from version 1.12.5.0 the Wurfl
struct provides two new methods: IsUserAgentFrozen()
, GetHeaderQuality()
.
IsUserAgentFrozen(ua string)
returns a boolean value which, if true, means that the input User-Agent string won't be updated by the sender browser.
GetHeaderQuality()
returns an enumeration value that describes the HTTP headers quality. It has three possible values:
EngineTarget (DEPRECATED as of 1.9.5.0)
const (
WurflEngineTargetHighAccuray = C.WURFL_ENGINE_TARGET_HIGH_ACCURACY
WurflEngineTargetHighPerformance = C.WURFL_ENGINE_TARGET_HIGH_PERFORMANCE
WurflEngineTargetDefault = C.WURFL_ENGINE_TARGET_DEFAULT
WurflEngineTargetFastDesktopBrowserMatch = C.WURFL_ENGINE_TARGET_FAST_DESKTOP_BROWSER_MATCH
)
UserAgentPriority (DEPRECATED as of 1.9.5.0)
const (
WurflUserAgentPriorityOverrideSideloadedBrowserUserAgent = C.WURFL_USERAGENT_PRIORITY_OVERRIDE_SIDELOADED_BROWSER_USERAGENT
WurflUserAgentPriorityUsePlainUserAgent = C.WURFL_USERAGENT_PRIORITY_USE_PLAIN_USERAGENT
)
WurflCacheProvider (DEPRECATED as of 1.9.5.0)
const (
WurflCacheProviderDefault = -1
WurflCacheProviderNone = C.WURFL_CACHE_PROVIDER_NONE
WurflCacheProviderLru = C.WURFL_CACHE_PROVIDER_LRU
// Deprecated: use WurflCacheProviderLru instead
WurflCacheProviderDoubleLru = C.WURFL_CACHE_PROVIDER_DOUBLE_LRU
)
WurflMatchType
const (
WurflMatchTypeExact = C.WURFL_MATCH_TYPE_EXACT
WurflMatchTypeConclusive = C.WURFL_MATCH_TYPE_CONCLUSIVE
WurflMatchTypeRecovery = C.WURFL_MATCH_TYPE_RECOVERY
WurflMatchTypeCatchall = C.WURFL_MATCH_TYPE_CATCHALL
WurflMatchTypeHighPerformance = C.WURFL_MATCH_TYPE_HIGHPERFORMANCE
WurflMatchTypeNone = C.WURFL_MATCH_TYPE_NONE
WurflMatchTypeCached = C.WURFL_MATCH_TYPE_CACHED
)
WurflEnum
const (
WurflEnumStaticCapabilities = C.WURFL_ENUM_STATIC_CAPABILITIES
WurflEnumVirtualCapabilities = C.WURFL_ENUM_VIRTUAL_CAPABILITIES
WurflEnumMandatoryCapabilities = C.WURFL_ENUM_MANDATORY_CAPABILITIES
WurflEnumWurflID = C.WURFL_ENUM_WURFLID
)
WurflUpdaterFrequency
const (
WurflUpdaterFrequencyDaily = C.WURFL_UPDATER_FREQ_DAILY
WurflUpdaterFrequencyWeekly = C.WURFL_UPDATER_FREQ_WEEKLY
)
WURFL Extra Headers (DEPRECATED as of 1.9.5.0)
const (
WurflAttrExtraHeadersExperimental = C.WURFL_ATTR_EXTRA_HEADERS_EXPERIMENTAL
)
Returns version of internal InFuze API without needing an initialized engine
func APIVersion() string
Represents the internal matched device handle
type Device struct {
Device C.wurfl_device_handle
Wurfl C.wurfl_handle
}
Destroys the device handle. This should be called when when device attributes are not needed anymore.
func (d *Device) Destroy()
Get the capability values for a list of static capabilities
func (d *Device) GetCapabilities(caps []string) map[string]string
Get the capability values for a single static capability
func (d *Device) GetCapability(cap string) string
Gets the device ID (WURFL ID) from the device handle
func (d *Device) GetDeviceID() (string, error)
Returns the matchtype from the device lookup
func (d *Device) GetMatchType() int
Gets the normalized (processed by the WURFL API) User-Agent
func (d *Device) GetNormalizedUserAgent() (string, error)
Gets the original User-Agent (the one that was passed for the lookup)
func (d *Device) GetOriginalUserAgent() (string, error)
Gets the root WURFL ID for the current device
func (d *Device) GetRootID() string
Gets default User-Agent of matched device from the WURFL snapshot (might be different from the one passed for the lookup)
func (d *Device) GetUserAgent() (string, error)
Get the capability values for a list of virtual capabilities
func (d *Device) GetVirtualCapabilities(caps []string) map[string]string
Get the capability values for a single virtual capability
func (d *Device) GetVirtualCapability(vcap string) string
Returns true
if the looked up device is a device root
func (d *Device) IsRoot() bool
Defines API methods for the Wurfl Device handle
type DeviceHandler interface {
GetMatchType() int
GetVirtualCapabilities(caps []string) map[string]string
GetVirtualCapability(vcap string) string
GetCapabilities(caps []string) map[string]string
GetCapability(cap string) string
IsRoot() bool
GetRootID() string
GetDeviceID() (string, error)
GetNormalizedUserAgent() (string, error)
GetOriginalUserAgent() (string, error)
GetUserAgent() (string, error)
Destroy()
}
Gets the header quality value
type HeaderQuality int
Converts a header quality to a string
func (hq HeaderQuality) String() string
The various header quality values are listed below:
const (
// HeaderQualityNone no User Agent Client Hints are present.
HeaderQualityNone HeaderQuality = C.WURFL_ENUM_UACH_NONE
// HeaderQualityBasic only some of the headers needed for a successful WURFL detection are present.
HeaderQualityBasic HeaderQuality = C.WURFL_ENUM_UACH_BASIC
// HeaderQualityFull all the headers needed for a successful WURFL detection are present.
HeaderQualityFull HeaderQuality = C.WURFL_ENUM_UACH_FULL
)
Defines the API methods for the Updater
type Updater interface {
SetUpdaterDataURL(DataURL string) error
SetUpdaterDataFrequency(Frequency int) error
SetUpdaterDataURLTimeout(ConnectionTimeout int, DataTransferTimeout int) error
SetUpdaterLogPath(LogFile string) error
UpdaterRunonce() error
UpdaterStart() error
UpdaterStop() error
}
Represents internal WURFL Infuze handle
type Wurfl struct {
Wurfl C.wurfl_handle
ImportantHeaderNames []string
// contains filtered or unexported fields
}
Creates the WURFL engine parameters:
func Create(Wurflxml string, Patches []string, CapFilter []string, EngineTarget int, CacheProvider int, CacheExtraConfig string) (*Wurfl, error)
Destroys the WURFL engine
func (w *Wurfl) Destroy()
Gets the version of underlying WURFL InFuze API
func (w *Wurfl) GetAPIVersion() string
Returns all the names of the static capabilities present in the loaded WURFL snapshot
func (w *Wurfl) GetAllCaps() []string
Returns a slice containing all device IDs (WURFL IDs) present in the loaded WURFL snapshot
func (w *Wurfl) GetAllDeviceIds() []string
Returns all the names of the virtual capabilities present in the loaded WURFL snapshot
func (w *Wurfl) GetAllVCaps() []string
Gets the WURFL engine attributes
func (w *Wurfl) GetAttr(attr int) (int, error)
(DEPRECATED as of 1.9.5.0) Returns a string representing the currently set WURFL Engine Target. Possible values are:
func (w *Wurfl) GetEngineTarget() string
Gets the header quality of the request
func (w *Wurfl) GetHeaderQuality(r *http.Request) (HeaderQuality, error)
Gets the information about the wurfl.xml file (WURFL snapshot)
func (w *Wurfl) GetInfo() string
Gets the time the wurfl.xml was last loaded
func (w *Wurfl) GetLastLoadTime() string
DEPRECATED Tells if WURFL is using the plain User-Agent or the sideloaded browser User-Agent for device detection
func (w *Wurfl) GetUserAgentPriority() string
Returns true
if the static capability exists
func (w *Wurfl) HasCapability(cap string) bool
Returns true
if the virtual capability exists
func (w *Wurfl) HasVirtualCapability(vcap string) bool
Returns true if the User-Agent is frozen
func (w *Wurfl) IsUserAgentFrozen(ua string) bool
Performs a lookup by device ID (WURFL ID) and returns a device handle
func (w *Wurfl) LookupDeviceID(DeviceID string) (*Device, error)
Performs a lookup using the device ID (WURFL ID) and the header values found in a ImportantHeaderMap (IHMap), and returns a device handle. The IHMap must be filled with values from Wurfl.ImportantHeaderNames
.
func (w *Wurfl) LookupDeviceIDWithImportantHeaderMap(DeviceID string, IHMap map[string]string) (*Device, error)
Performs a lookup using the device ID (WURFL ID) and request headers, and returns a device handle
func (w *Wurfl) LookupDeviceIDWithRequest(DeviceID string, r *http.Request) (*Device, error)
Performs a lookup using request headers and returns a device handle
func (w *Wurfl) LookupRequest(r *http.Request) (*Device, error)
Performs a lookup using User-Agent and returns a device handle
func (w *Wurfl) LookupUserAgent(ua string) (*Device, error)
Performs a lookup using the header values found in a ImportantHeaderMap (IHMap) and returns a device handle. The IHMap must be filled with values from Wurfl.ImportantHeaderNames
.
func (w *Wurfl) LookupWithImportantHeaderMap(IHMap map[string]string) (*Device, error)
Sets WURFL engine attributes
func (w *Wurfl) SetAttr(attr int, value int) error
Sets the interval of WURFL updater checks
func (w *Wurfl) SetUpdaterDataFrequency(Frequency int) error
Sets the interval of WURFL updater checks. Typically your https
updater URL from your ScientiaMobile vault.
func (w *Wurfl) SetUpdaterDataURL(DataURL string) error
Sets the connection and data transfer timeouts (in millisecs) for the WURFL updater HTTP call. 0
for no timeout, -1
for the default value.
func (w *Wurfl) SetUpdaterDataURLTimeout(ConnectionTimeout int, DataTransferTimeout int) error
Sets the path of WURFL updater log file
func (w *Wurfl) SetUpdaterLogPath(LogFile string) error
(DEPRECATED as of 1.9.5.0) Tells WURFL to use either the plain User-Agent or the sideloaded browser User-Agent for device detection
func (w *Wurfl) SetUserAgentPriority(prio int)
Runs the WURFL updater process once and waits for termination
func (w *Wurfl) UpdaterRunonce() error
Starts the updater thread
func (w *Wurfl) UpdaterStart() error
Stop the updater thread
func (w *Wurfl) UpdaterStop() error
© 2024 ScientiaMobile Inc.
All Rights Reserved.
NOTICE: All information contained herein is, and remains the property of ScientiaMobile Incorporated and its suppliers, if any. The intellectual and technical concepts contained herein are proprietary to ScientiaMobile Incorporated and its suppliers and may be covered by U.S. and Foreign Patents, patents in process, and are protected by trade secret or copyright law. Dissemination of this information or reproduction of this material is strictly forbidden unless prior written permission is obtained from ScientiaMobile Incorporated.