mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
Removed mssola/user_agent library (#8417)
* Removed mssola/user_agent library * Changed user agent tests to use t.Run
This commit is contained in:
13
vendor/github.com/mssola/user_agent/.travis.yml
generated
vendored
13
vendor/github.com/mssola/user_agent/.travis.yml
generated
vendored
@@ -1,13 +0,0 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.4.x
|
||||
- 1.5.x
|
||||
- 1.6.x
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- 1.x
|
||||
- tip
|
||||
matrix:
|
||||
allow_failures:
|
||||
- go: tip
|
||||
20
vendor/github.com/mssola/user_agent/LICENSE
generated
vendored
20
vendor/github.com/mssola/user_agent/LICENSE
generated
vendored
@@ -1,20 +0,0 @@
|
||||
Copyright (c) 2012-2018 Miquel Sabaté Solà
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
51
vendor/github.com/mssola/user_agent/README.md
generated
vendored
51
vendor/github.com/mssola/user_agent/README.md
generated
vendored
@@ -1,51 +0,0 @@
|
||||
|
||||
# UserAgent [](https://travis-ci.org/mssola/user_agent) [](http://godoc.org/github.com/mssola/user_agent)
|
||||
|
||||
|
||||
UserAgent is a Go library that parses HTTP User Agents.
|
||||
|
||||
## Usage
|
||||
|
||||
~~~ go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/mssola/user_agent"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// The "New" function will create a new UserAgent object and it will parse
|
||||
// the given string. If you need to parse more strings, you can re-use
|
||||
// this object and call: ua.Parse("another string")
|
||||
ua := user_agent.New("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11")
|
||||
|
||||
fmt.Printf("%v\n", ua.Mobile()) // => false
|
||||
fmt.Printf("%v\n", ua.Bot()) // => false
|
||||
fmt.Printf("%v\n", ua.Mozilla()) // => "5.0"
|
||||
|
||||
fmt.Printf("%v\n", ua.Platform()) // => "X11"
|
||||
fmt.Printf("%v\n", ua.OS()) // => "Linux x86_64"
|
||||
|
||||
name, version := ua.Engine()
|
||||
fmt.Printf("%v\n", name) // => "AppleWebKit"
|
||||
fmt.Printf("%v\n", version) // => "537.11"
|
||||
|
||||
name, version = ua.Browser()
|
||||
fmt.Printf("%v\n", name) // => "Chrome"
|
||||
fmt.Printf("%v\n", version) // => "23.0.1271.97"
|
||||
|
||||
// Let's see an example with a bot.
|
||||
|
||||
ua.Parse("Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)")
|
||||
|
||||
fmt.Printf("%v\n", ua.Bot()) // => true
|
||||
|
||||
name, version = ua.Browser()
|
||||
fmt.Printf("%v\n", name) // => Googlebot
|
||||
fmt.Printf("%v\n", version) // => 2.1
|
||||
}
|
||||
~~~
|
||||
|
||||
Copyright © 2012-2018 Miquel Sabaté Solà, released under the MIT License.
|
||||
594
vendor/github.com/mssola/user_agent/all_test.go
generated
vendored
594
vendor/github.com/mssola/user_agent/all_test.go
generated
vendored
@@ -1,594 +0,0 @@
|
||||
// Copyright (C) 2012-2018 Miquel Sabaté Solà <mikisabate@gmail.com>
|
||||
// This file is licensed under the MIT license.
|
||||
// See the LICENSE file.
|
||||
|
||||
package user_agent
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Slice that contains all the tests. Each test is contained in a struct
|
||||
// that groups the title of the test, the User-Agent string to be tested and the expected value.
|
||||
var uastrings = []struct {
|
||||
title string
|
||||
ua string
|
||||
expected string
|
||||
expectedOS *OSInfo
|
||||
}{
|
||||
// Bots
|
||||
{
|
||||
title: "GoogleBot",
|
||||
ua: "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)",
|
||||
expected: "Mozilla:5.0 Browser:Googlebot-2.1 Bot:true Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "GoogleBotSmartphone (iPhone)",
|
||||
ua: "Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)",
|
||||
expected: "Mozilla:5.0 Browser:Googlebot-2.1 Bot:true Mobile:true",
|
||||
},
|
||||
{
|
||||
title: "GoogleBotSmartphone (Android)",
|
||||
ua: "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)",
|
||||
expected: "Mozilla:5.0 Browser:Googlebot-2.1 Bot:true Mobile:true",
|
||||
},
|
||||
{
|
||||
title: "BingBot",
|
||||
ua: "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)",
|
||||
expected: "Mozilla:5.0 Browser:bingbot-2.0 Bot:true Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "BaiduBot",
|
||||
ua: "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)",
|
||||
expected: "Mozilla:5.0 Browser:Baiduspider-2.0 Bot:true Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "Twitterbot",
|
||||
ua: "Twitterbot",
|
||||
expected: "Browser:Twitterbot Bot:true Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "YahooBot",
|
||||
ua: "Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)",
|
||||
expected: "Mozilla:5.0 Browser:Yahoo! Slurp Bot:true Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "FacebookExternalHit",
|
||||
ua: "facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)",
|
||||
expected: "Browser:facebookexternalhit-1.1 Bot:true Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "FacebookPlatform",
|
||||
ua: "facebookplatform/1.0 (+http://developers.facebook.com)",
|
||||
expected: "Browser:facebookplatform-1.0 Bot:true Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "FaceBot",
|
||||
ua: "Facebot",
|
||||
expected: "Browser:Facebot Bot:true Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "NutchCVS",
|
||||
ua: "NutchCVS/0.8-dev (Nutch; http://lucene.apache.org/nutch/bot.html; nutch-agent@lucene.apache.org)",
|
||||
expected: "Browser:NutchCVS Bot:true Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "MJ12bot",
|
||||
ua: "Mozilla/5.0 (compatible; MJ12bot/v1.2.4; http://www.majestic12.co.uk/bot.php?+)",
|
||||
expected: "Mozilla:5.0 Browser:MJ12bot-v1.2.4 Bot:true Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "MJ12bot",
|
||||
ua: "MJ12bot/v1.0.8 (http://majestic12.co.uk/bot.php?+)",
|
||||
expected: "Browser:MJ12bot Bot:true Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "AhrefsBot",
|
||||
ua: "Mozilla/5.0 (compatible; AhrefsBot/4.0; +http://ahrefs.com/robot/)",
|
||||
expected: "Mozilla:5.0 Browser:AhrefsBot-4.0 Bot:true Mobile:false",
|
||||
},
|
||||
|
||||
// Internet Explorer
|
||||
{
|
||||
title: "IE10",
|
||||
ua: "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)",
|
||||
expected: "Mozilla:5.0 Platform:Windows OS:Windows 8 Browser:Internet Explorer-10.0 Engine:Trident Bot:false Mobile:false",
|
||||
expectedOS: &OSInfo{"Windows 8", "Windows", "8"},
|
||||
},
|
||||
{
|
||||
title: "Tablet",
|
||||
ua: "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; ARM; Trident/6.0; Touch; .NET4.0E; .NET4.0C; Tablet PC 2.0)",
|
||||
expected: "Mozilla:4.0 Platform:Windows OS:Windows 8 Browser:Internet Explorer-10.0 Engine:Trident Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "Touch",
|
||||
ua: "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; ARM; Trident/6.0; Touch)",
|
||||
expected: "Mozilla:5.0 Platform:Windows OS:Windows 8 Browser:Internet Explorer-10.0 Engine:Trident Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "Phone",
|
||||
ua: "Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0; SAMSUNG; SGH-i917)",
|
||||
expected: "Mozilla:4.0 Platform:Windows OS:Windows Phone OS 7.0 Browser:Internet Explorer-7.0 Engine:Trident Bot:false Mobile:true",
|
||||
expectedOS: &OSInfo{"Windows Phone OS 7.0", "Windows Phone OS", "7.0"},
|
||||
},
|
||||
{
|
||||
title: "IE6",
|
||||
ua: "Mozilla/4.0 (compatible; MSIE6.0; Windows NT 5.0; .NET CLR 1.1.4322)",
|
||||
expected: "Mozilla:4.0 Platform:Windows OS:Windows 2000 Browser:Internet Explorer-6.0 Engine:Trident Bot:false Mobile:false",
|
||||
expectedOS: &OSInfo{"Windows 2000", "Windows", "2000"},
|
||||
},
|
||||
{
|
||||
title: "IE8Compatibility",
|
||||
ua: "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; InfoPath.3; MS-RTC LM 8)",
|
||||
expected: "Mozilla:4.0 Platform:Windows OS:Windows 7 Browser:Internet Explorer-8.0 Engine:Trident Bot:false Mobile:false",
|
||||
expectedOS: &OSInfo{"Windows 7", "Windows", "7"},
|
||||
},
|
||||
{
|
||||
title: "IE10Compatibility",
|
||||
ua: "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; InfoPath.3; MS-RTC LM 8)",
|
||||
expected: "Mozilla:4.0 Platform:Windows OS:Windows 7 Browser:Internet Explorer-10.0 Engine:Trident Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "IE11Win81",
|
||||
ua: "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko",
|
||||
expected: "Mozilla:5.0 Platform:Windows OS:Windows 8.1 Browser:Internet Explorer-11.0 Engine:Trident Bot:false Mobile:false",
|
||||
expectedOS: &OSInfo{"Windows 8.1", "Windows", "8.1"},
|
||||
},
|
||||
{
|
||||
title: "IE11Win7",
|
||||
ua: "Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko",
|
||||
expected: "Mozilla:5.0 Platform:Windows OS:Windows 7 Browser:Internet Explorer-11.0 Engine:Trident Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "IE11b32Win7b64",
|
||||
ua: "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
|
||||
expected: "Mozilla:5.0 Platform:Windows OS:Windows 7 Browser:Internet Explorer-11.0 Engine:Trident Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "IE11b32Win7b64MDDRJS",
|
||||
ua: "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; MDDRJS; rv:11.0) like Gecko",
|
||||
expected: "Mozilla:5.0 Platform:Windows OS:Windows 7 Browser:Internet Explorer-11.0 Engine:Trident Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "IE11Compatibility",
|
||||
ua: "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.3; Trident/7.0)",
|
||||
expected: "Mozilla:4.0 Platform:Windows OS:Windows 8.1 Browser:Internet Explorer-7.0 Engine:Trident Bot:false Mobile:false",
|
||||
},
|
||||
|
||||
// Microsoft Edge
|
||||
{
|
||||
title: "EdgeDesktop",
|
||||
ua: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240",
|
||||
expected: "Mozilla:5.0 Platform:Windows OS:Windows 10 Browser:Edge-12.10240 Engine:EdgeHTML Bot:false Mobile:false",
|
||||
expectedOS: &OSInfo{"Windows 10", "Windows", "10"},
|
||||
},
|
||||
{
|
||||
title: "EdgeMobile",
|
||||
ua: "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; DEVICE INFO) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Mobile Safari/537.36 Edge/12.10240",
|
||||
expected: "Mozilla:5.0 Platform:Windows OS:Windows Phone 10.0 Browser:Edge-12.10240 Engine:EdgeHTML Bot:false Mobile:true",
|
||||
},
|
||||
|
||||
// Gecko
|
||||
{
|
||||
title: "FirefoxMac",
|
||||
ua: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0b8) Gecko/20100101 Firefox/4.0b8",
|
||||
expected: "Mozilla:5.0 Platform:Macintosh OS:Intel Mac OS X 10.6 Browser:Firefox-4.0b8 Engine:Gecko-20100101 Bot:false Mobile:false",
|
||||
expectedOS: &OSInfo{"Intel Mac OS X 10.6", "Mac OS X", "10.6"},
|
||||
},
|
||||
{
|
||||
title: "FirefoxMacLoc",
|
||||
ua: "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13",
|
||||
expected: "Mozilla:5.0 Platform:Macintosh OS:Intel Mac OS X 10.6 Localization:en-US Browser:Firefox-3.6.13 Engine:Gecko-20101203 Bot:false Mobile:false",
|
||||
expectedOS: &OSInfo{"Intel Mac OS X 10.6", "Mac OS X", "10.6"},
|
||||
},
|
||||
{
|
||||
title: "FirefoxLinux",
|
||||
ua: "Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20100101 Firefox/17.0",
|
||||
expected: "Mozilla:5.0 Platform:X11 OS:Linux x86_64 Browser:Firefox-17.0 Engine:Gecko-20100101 Bot:false Mobile:false",
|
||||
expectedOS: &OSInfo{"Linux x86_64", "Linux", ""},
|
||||
},
|
||||
{
|
||||
title: "FirefoxLinux - Ubuntu V50",
|
||||
ua: "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0",
|
||||
expected: "Mozilla:5.0 Platform:X11 OS:Ubuntu Browser:Firefox-50.0 Engine:Gecko-20100101 Bot:false Mobile:false",
|
||||
expectedOS: &OSInfo{"Ubuntu", "Ubuntu", ""},
|
||||
},
|
||||
{
|
||||
title: "FirefoxWin",
|
||||
ua: "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14",
|
||||
expected: "Mozilla:5.0 Platform:Windows OS:Windows XP Localization:en-US Browser:Firefox-2.0.0.14 Engine:Gecko-20080404 Bot:false Mobile:false",
|
||||
expectedOS: &OSInfo{"Windows XP", "Windows", "XP"},
|
||||
},
|
||||
{
|
||||
title: "Firefox29Win7",
|
||||
ua: "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0",
|
||||
expected: "Mozilla:5.0 Platform:Windows OS:Windows 7 Browser:Firefox-29.0 Engine:Gecko-20100101 Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "CaminoMac",
|
||||
ua: "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en; rv:1.8.1.14) Gecko/20080409 Camino/1.6 (like Firefox/2.0.0.14)",
|
||||
expected: "Mozilla:5.0 Platform:Macintosh OS:Intel Mac OS X Localization:en Browser:Camino-1.6 Engine:Gecko-20080409 Bot:false Mobile:false",
|
||||
expectedOS: &OSInfo{"Intel Mac OS X", "Mac OS X", ""},
|
||||
},
|
||||
{
|
||||
title: "Iceweasel",
|
||||
ua: "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1) Gecko/20061024 Iceweasel/2.0 (Debian-2.0+dfsg-1)",
|
||||
expected: "Mozilla:5.0 Platform:X11 OS:Linux i686 Localization:en-US Browser:Iceweasel-2.0 Engine:Gecko-20061024 Bot:false Mobile:false",
|
||||
expectedOS: &OSInfo{"Linux i686", "Linux", ""},
|
||||
},
|
||||
{
|
||||
title: "SeaMonkey",
|
||||
ua: "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.1.4) Gecko/20091017 SeaMonkey/2.0",
|
||||
expected: "Mozilla:5.0 Platform:Macintosh OS:Intel Mac OS X 10.6 Localization:en-US Browser:SeaMonkey-2.0 Engine:Gecko-20091017 Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "AndroidFirefox",
|
||||
ua: "Mozilla/5.0 (Android; Mobile; rv:17.0) Gecko/17.0 Firefox/17.0",
|
||||
expected: "Mozilla:5.0 Platform:Mobile OS:Android Browser:Firefox-17.0 Engine:Gecko-17.0 Bot:false Mobile:true",
|
||||
},
|
||||
{
|
||||
title: "AndroidFirefoxTablet",
|
||||
ua: "Mozilla/5.0 (Android; Tablet; rv:26.0) Gecko/26.0 Firefox/26.0",
|
||||
expected: "Mozilla:5.0 Platform:Tablet OS:Android Browser:Firefox-26.0 Engine:Gecko-26.0 Bot:false Mobile:true",
|
||||
expectedOS: &OSInfo{"Android", "Android", ""},
|
||||
},
|
||||
{
|
||||
title: "FirefoxOS",
|
||||
ua: "Mozilla/5.0 (Mobile; rv:26.0) Gecko/26.0 Firefox/26.0",
|
||||
expected: "Mozilla:5.0 Platform:Mobile OS:FirefoxOS Browser:Firefox-26.0 Engine:Gecko-26.0 Bot:false Mobile:true",
|
||||
expectedOS: &OSInfo{"FirefoxOS", "FirefoxOS", ""},
|
||||
},
|
||||
{
|
||||
title: "FirefoxOSTablet",
|
||||
ua: "Mozilla/5.0 (Tablet; rv:26.0) Gecko/26.0 Firefox/26.0",
|
||||
expected: "Mozilla:5.0 Platform:Tablet OS:FirefoxOS Browser:Firefox-26.0 Engine:Gecko-26.0 Bot:false Mobile:true",
|
||||
},
|
||||
{
|
||||
title: "FirefoxWinXP",
|
||||
ua: "Mozilla/5.0 (Windows NT 5.2; rv:31.0) Gecko/20100101 Firefox/31.0",
|
||||
expected: "Mozilla:5.0 Platform:Windows OS:Windows XP x64 Edition Browser:Firefox-31.0 Engine:Gecko-20100101 Bot:false Mobile:false",
|
||||
expectedOS: &OSInfo{"Windows XP x64 Edition", "Windows", "XP"},
|
||||
},
|
||||
{
|
||||
title: "FirefoxMRA",
|
||||
ua: "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:24.0) Gecko/20130405 MRA 5.5 (build 02842) Firefox/24.0 (.NET CLR 3.5.30729)",
|
||||
expected: "Mozilla:5.0 Platform:Windows OS:Windows XP Localization:en-US Browser:Firefox-24.0 Engine:Gecko-20130405 Bot:false Mobile:false",
|
||||
},
|
||||
|
||||
// Opera
|
||||
{
|
||||
title: "OperaMac",
|
||||
ua: "Opera/9.27 (Macintosh; Intel Mac OS X; U; en)",
|
||||
expected: "Platform:Macintosh OS:Intel Mac OS X Localization:en Browser:Opera-9.27 Engine:Presto Bot:false Mobile:false",
|
||||
expectedOS: &OSInfo{"Intel Mac OS X", "Mac OS X", ""},
|
||||
},
|
||||
{
|
||||
title: "OperaWin",
|
||||
ua: "Opera/9.27 (Windows NT 5.1; U; en)",
|
||||
expected: "Platform:Windows OS:Windows XP Localization:en Browser:Opera-9.27 Engine:Presto Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "OperaWinNoLocale",
|
||||
ua: "Opera/9.80 (Windows NT 5.1) Presto/2.12.388 Version/12.10",
|
||||
expected: "Platform:Windows OS:Windows XP Browser:Opera-9.80 Engine:Presto-2.12.388 Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "OperaWin2Comment",
|
||||
ua: "Opera/9.80 (Windows NT 6.0; WOW64) Presto/2.12.388 Version/12.15",
|
||||
expected: "Platform:Windows OS:Windows Vista Browser:Opera-9.80 Engine:Presto-2.12.388 Bot:false Mobile:false",
|
||||
expectedOS: &OSInfo{"Windows Vista", "Windows", "Vista"},
|
||||
},
|
||||
{
|
||||
title: "OperaMinimal",
|
||||
ua: "Opera/9.80",
|
||||
expected: "Browser:Opera-9.80 Engine:Presto Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "OperaFull",
|
||||
ua: "Opera/9.80 (Windows NT 6.0; U; en) Presto/2.2.15 Version/10.10",
|
||||
expected: "Platform:Windows OS:Windows Vista Localization:en Browser:Opera-9.80 Engine:Presto-2.2.15 Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "OperaLinux",
|
||||
ua: "Opera/9.80 (X11; Linux x86_64) Presto/2.12.388 Version/12.10",
|
||||
expected: "Platform:X11 OS:Linux x86_64 Browser:Opera-9.80 Engine:Presto-2.12.388 Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "OperaLinux - Ubuntu V41",
|
||||
ua: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36 OPR/41.0.2353.69",
|
||||
expected: "Mozilla:5.0 Platform:X11 OS:Linux x86_64 Browser:Opera-41.0.2353.69 Engine:AppleWebKit-537.36 Bot:false Mobile:false",
|
||||
expectedOS: &OSInfo{"Linux x86_64", "Linux", ""},
|
||||
},
|
||||
{
|
||||
title: "OperaAndroid",
|
||||
ua: "Opera/9.80 (Android 4.2.1; Linux; Opera Mobi/ADR-1212030829) Presto/2.11.355 Version/12.10",
|
||||
expected: "Platform:Android 4.2.1 OS:Linux Browser:Opera-9.80 Engine:Presto-2.11.355 Bot:false Mobile:true",
|
||||
expectedOS: &OSInfo{"Linux", "Linux", ""},
|
||||
},
|
||||
{
|
||||
title: "OperaNested",
|
||||
ua: "Opera/9.80 (Windows NT 5.1; MRA 6.0 (build 5831)) Presto/2.12.388 Version/12.10",
|
||||
expected: "Platform:Windows OS:Windows XP Browser:Opera-9.80 Engine:Presto-2.12.388 Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "OperaMRA",
|
||||
ua: "Opera/9.80 (Windows NT 6.1; U; MRA 5.8 (build 4139); en) Presto/2.9.168 Version/11.50",
|
||||
expected: "Platform:Windows OS:Windows 7 Localization:en Browser:Opera-9.80 Engine:Presto-2.9.168 Bot:false Mobile:false",
|
||||
},
|
||||
|
||||
// Other
|
||||
{
|
||||
title: "Empty",
|
||||
ua: "",
|
||||
expected: "Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "Nil",
|
||||
ua: "nil",
|
||||
expected: "Browser:nil Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "Compatible",
|
||||
ua: "Mozilla/4.0 (compatible)",
|
||||
expected: "Browser:Mozilla-4.0 Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "Mozilla",
|
||||
ua: "Mozilla/5.0",
|
||||
expected: "Browser:Mozilla-5.0 Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "Amaya",
|
||||
ua: "amaya/9.51 libwww/5.4.0",
|
||||
expected: "Browser:amaya-9.51 Engine:libwww-5.4.0 Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "Rails",
|
||||
ua: "Rails Testing",
|
||||
expected: "Browser:Rails Engine:Testing Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "Python",
|
||||
ua: "Python-urllib/2.7",
|
||||
expected: "Browser:Python-urllib-2.7 Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "Curl",
|
||||
ua: "curl/7.28.1",
|
||||
expected: "Browser:curl-7.28.1 Bot:false Mobile:false",
|
||||
},
|
||||
|
||||
// WebKit
|
||||
{
|
||||
title: "ChromeLinux",
|
||||
ua: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11",
|
||||
expected: "Mozilla:5.0 Platform:X11 OS:Linux x86_64 Browser:Chrome-23.0.1271.97 Engine:AppleWebKit-537.11 Bot:false Mobile:false",
|
||||
expectedOS: &OSInfo{"Linux x86_64", "Linux", ""},
|
||||
},
|
||||
{
|
||||
title: "ChromeLinux - Ubuntu V55",
|
||||
ua: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36",
|
||||
expected: "Mozilla:5.0 Platform:X11 OS:Linux x86_64 Browser:Chrome-55.0.2883.75 Engine:AppleWebKit-537.36 Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "ChromeWin7",
|
||||
ua: "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.168 Safari/535.19",
|
||||
expected: "Mozilla:5.0 Platform:Windows OS:Windows 7 Browser:Chrome-18.0.1025.168 Engine:AppleWebKit-535.19 Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "ChromeMinimal",
|
||||
ua: "Mozilla/5.0 AppleWebKit/534.10 Chrome/8.0.552.215 Safari/534.10",
|
||||
expected: "Mozilla:5.0 Browser:Chrome-8.0.552.215 Engine:AppleWebKit-534.10 Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "ChromeMac",
|
||||
ua: "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.231 Safari/534.10",
|
||||
expected: "Mozilla:5.0 Platform:Macintosh OS:Intel Mac OS X 10_6_5 Localization:en-US Browser:Chrome-8.0.552.231 Engine:AppleWebKit-534.10 Bot:false Mobile:false",
|
||||
expectedOS: &OSInfo{"Intel Mac OS X 10_6_5", "Mac OS X", "10.6.5"},
|
||||
},
|
||||
{
|
||||
title: "SafariMac",
|
||||
ua: "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16",
|
||||
expected: "Mozilla:5.0 Platform:Macintosh OS:Intel Mac OS X 10_6_3 Localization:en-us Browser:Safari-5.0 Engine:AppleWebKit-533.16 Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "SafariWin",
|
||||
ua: "Mozilla/5.0 (Windows; U; Windows NT 5.1; en) AppleWebKit/526.9 (KHTML, like Gecko) Version/4.0dp1 Safari/526.8",
|
||||
expected: "Mozilla:5.0 Platform:Windows OS:Windows XP Localization:en Browser:Safari-4.0dp1 Engine:AppleWebKit-526.9 Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "iPhone7",
|
||||
ua: "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0_3 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11B511 Safari/9537.53",
|
||||
expected: "Mozilla:5.0 Platform:iPhone OS:CPU iPhone OS 7_0_3 like Mac OS X Browser:Safari-7.0 Engine:AppleWebKit-537.51.1 Bot:false Mobile:true",
|
||||
expectedOS: &OSInfo{"CPU iPhone OS 7_0_3 like Mac OS X", "iPhone OS", "7.0.3"},
|
||||
},
|
||||
{
|
||||
title: "iPhone",
|
||||
ua: "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/4A102 Safari/419",
|
||||
expected: "Mozilla:5.0 Platform:iPhone OS:CPU like Mac OS X Localization:en Browser:Safari-3.0 Engine:AppleWebKit-420.1 Bot:false Mobile:true",
|
||||
},
|
||||
{
|
||||
title: "iPod",
|
||||
ua: "Mozilla/5.0 (iPod; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/4A102 Safari/419",
|
||||
expected: "Mozilla:5.0 Platform:iPod OS:CPU like Mac OS X Localization:en Browser:Safari-3.0 Engine:AppleWebKit-420.1 Bot:false Mobile:true",
|
||||
},
|
||||
{
|
||||
title: "iPad",
|
||||
ua: "Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10",
|
||||
expected: "Mozilla:5.0 Platform:iPad OS:CPU OS 3_2 like Mac OS X Localization:en-us Browser:Safari-4.0.4 Engine:AppleWebKit-531.21.10 Bot:false Mobile:true",
|
||||
},
|
||||
{
|
||||
title: "webOS",
|
||||
ua: "Mozilla/5.0 (webOS/1.4.0; U; en-US) AppleWebKit/532.2 (KHTML, like Gecko) Version/1.0 Safari/532.2 Pre/1.1",
|
||||
expected: "Mozilla:5.0 Platform:webOS OS:Palm Localization:en-US Browser:webOS-1.0 Engine:AppleWebKit-532.2 Bot:false Mobile:true",
|
||||
},
|
||||
{
|
||||
title: "Android",
|
||||
ua: "Mozilla/5.0 (Linux; U; Android 1.5; de-; HTC Magic Build/PLAT-RC33) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1",
|
||||
expected: "Mozilla:5.0 Platform:Linux OS:Android 1.5 Localization:de- Browser:Android-3.1.2 Engine:AppleWebKit-528.5+ Bot:false Mobile:true",
|
||||
},
|
||||
{
|
||||
title: "BlackBerry",
|
||||
ua: "Mozilla/5.0 (BlackBerry; U; BlackBerry 9800; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/6.0.0.141 Mobile Safari/534.1+",
|
||||
expected: "Mozilla:5.0 Platform:BlackBerry OS:BlackBerry 9800 Localization:en Browser:BlackBerry-6.0.0.141 Engine:AppleWebKit-534.1+ Bot:false Mobile:true",
|
||||
expectedOS: &OSInfo{"BlackBerry 9800", "BlackBerry", "9800"},
|
||||
},
|
||||
{
|
||||
title: "BB10",
|
||||
ua: "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.3+ (KHTML, like Gecko) Version/10.0.9.388 Mobile Safari/537.3+",
|
||||
expected: "Mozilla:5.0 Platform:BlackBerry OS:BlackBerry Browser:BlackBerry-10.0.9.388 Engine:AppleWebKit-537.3+ Bot:false Mobile:true",
|
||||
},
|
||||
{
|
||||
title: "Ericsson",
|
||||
ua: "Mozilla/5.0 (SymbianOS/9.4; U; Series60/5.0 Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebKit/525 (KHTML, like Gecko) Version/3.0 Safari/525",
|
||||
expected: "Mozilla:5.0 Platform:Symbian OS:SymbianOS/9.4 Browser:Symbian-3.0 Engine:AppleWebKit-525 Bot:false Mobile:true",
|
||||
expectedOS: &OSInfo{"SymbianOS/9.4", "SymbianOS", "9.4"},
|
||||
},
|
||||
{
|
||||
title: "ChromeAndroid",
|
||||
ua: "Mozilla/5.0 (Linux; Android 4.2.1; Galaxy Nexus Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19",
|
||||
expected: "Mozilla:5.0 Platform:Linux OS:Android 4.2.1 Browser:Chrome-18.0.1025.166 Engine:AppleWebKit-535.19 Bot:false Mobile:true",
|
||||
},
|
||||
{
|
||||
title: "WebkitNoPlatform",
|
||||
ua: "Mozilla/5.0 (en-us) AppleWebKit/525.13 (KHTML, like Gecko; Google Web Preview) Version/3.1 Safari/525.13",
|
||||
expected: "Mozilla:5.0 Platform:en-us Localization:en-us Browser:Safari-3.1 Engine:AppleWebKit-525.13 Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "OperaWebkitMobile",
|
||||
ua: "Mozilla/5.0 (Linux; Android 4.2.2; Galaxy Nexus Build/JDQ39) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.58 Mobile Safari/537.31 OPR/14.0.1074.57453",
|
||||
expected: "Mozilla:5.0 Platform:Linux OS:Android 4.2.2 Browser:Opera-14.0.1074.57453 Engine:AppleWebKit-537.31 Bot:false Mobile:true",
|
||||
},
|
||||
{
|
||||
title: "OperaWebkitDesktop",
|
||||
ua: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.58 Safari/537.31 OPR/14.0.1074.57453",
|
||||
expected: "Mozilla:5.0 Platform:X11 OS:Linux x86_64 Browser:Opera-14.0.1074.57453 Engine:AppleWebKit-537.31 Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "ChromeNothingAfterU",
|
||||
ua: "Mozilla/5.0 (Linux; U) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.79 Safari/537.4",
|
||||
expected: "Mozilla:5.0 Platform:Linux OS:Linux Browser:Chrome-22.0.1229.79 Engine:AppleWebKit-537.4 Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "SafariOnSymbian",
|
||||
ua: "Mozilla/5.0 (SymbianOS/9.1; U; [en-us]) AppleWebKit/413 (KHTML, like Gecko) Safari/413",
|
||||
expected: "Mozilla:5.0 Platform:Symbian OS:SymbianOS/9.1 Browser:Symbian-413 Engine:AppleWebKit-413 Bot:false Mobile:true",
|
||||
},
|
||||
{
|
||||
title: "Chromium - Ubuntu V49",
|
||||
ua: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/49.0.2623.108 Chrome/49.0.2623.108 Safari/537.36",
|
||||
expected: "Mozilla:5.0 Platform:X11 OS:Linux x86_64 Browser:Chromium-49.0.2623.108 Engine:AppleWebKit-537.36 Bot:false Mobile:false",
|
||||
},
|
||||
{
|
||||
title: "Chromium - Ubuntu V55",
|
||||
ua: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36",
|
||||
expected: "Mozilla:5.0 Platform:X11 OS:Linux x86_64 Browser:Chromium-53.0.2785.143 Engine:AppleWebKit-537.36 Bot:false Mobile:false",
|
||||
},
|
||||
|
||||
// Dalvik
|
||||
{
|
||||
title: "Dalvik - Dell:001DL",
|
||||
ua: "Dalvik/1.2.0 (Linux; U; Android 2.2.2; 001DL Build/FRG83G)",
|
||||
expected: "Mozilla:5.0 Platform:Linux OS:Android 2.2.2 Bot:false Mobile:true",
|
||||
},
|
||||
{
|
||||
title: "Dalvik - HTC:001HT",
|
||||
ua: "Dalvik/1.4.0 (Linux; U; Android 2.3.3; 001HT Build/GRI40)",
|
||||
expected: "Mozilla:5.0 Platform:Linux OS:Android 2.3.3 Bot:false Mobile:true",
|
||||
},
|
||||
{
|
||||
title: "Dalvik - ZTE:009Z",
|
||||
ua: "Dalvik/1.4.0 (Linux; U; Android 2.3.4; 009Z Build/GINGERBREAD)",
|
||||
expected: "Mozilla:5.0 Platform:Linux OS:Android 2.3.4 Bot:false Mobile:true",
|
||||
},
|
||||
{
|
||||
title: "Dalvik - A850",
|
||||
ua: "Dalvik/1.6.0 (Linux; U; Android 4.2.2; A850 Build/JDQ39) Configuration/CLDC-1.1; Opera Mini/att/4.2",
|
||||
expected: "Mozilla:5.0 Platform:Linux OS:Android 4.2.2 Bot:false Mobile:true",
|
||||
},
|
||||
{
|
||||
title: "Dalvik - Asus:T00Q",
|
||||
ua: "Dalvik/1.6.0 (Linux; U; Android 4.4.2; ASUS_T00Q Build/KVT49L)/CLDC-1.1",
|
||||
expected: "Mozilla:5.0 Platform:Linux OS:Android 4.4.2 Bot:false Mobile:true",
|
||||
expectedOS: &OSInfo{"Android 4.4.2", "Android", "4.4.2"},
|
||||
},
|
||||
{
|
||||
title: "Dalvik - W2430",
|
||||
ua: "Dalvik/1.6.0 (Linux; U; Android 4.0.4; W2430 Build/IMM76D)014; Profile/MIDP-2.1 Configuration/CLDC-1",
|
||||
expected: "Mozilla:5.0 Platform:Linux OS:Android 4.0.4 Bot:false Mobile:true",
|
||||
},
|
||||
}
|
||||
|
||||
// Internal: beautify the UserAgent reference into a string so it can be
|
||||
// tested later on.
|
||||
//
|
||||
// ua - a UserAgent reference.
|
||||
//
|
||||
// Returns a string that contains the beautified representation.
|
||||
func beautify(ua *UserAgent) (s string) {
|
||||
if len(ua.Mozilla()) > 0 {
|
||||
s += "Mozilla:" + ua.Mozilla() + " "
|
||||
}
|
||||
if len(ua.Platform()) > 0 {
|
||||
s += "Platform:" + ua.Platform() + " "
|
||||
}
|
||||
if len(ua.OS()) > 0 {
|
||||
s += "OS:" + ua.OS() + " "
|
||||
}
|
||||
if len(ua.Localization()) > 0 {
|
||||
s += "Localization:" + ua.Localization() + " "
|
||||
}
|
||||
str1, str2 := ua.Browser()
|
||||
if len(str1) > 0 {
|
||||
s += "Browser:" + str1
|
||||
if len(str2) > 0 {
|
||||
s += "-" + str2 + " "
|
||||
} else {
|
||||
s += " "
|
||||
}
|
||||
}
|
||||
str1, str2 = ua.Engine()
|
||||
if len(str1) > 0 {
|
||||
s += "Engine:" + str1
|
||||
if len(str2) > 0 {
|
||||
s += "-" + str2 + " "
|
||||
} else {
|
||||
s += " "
|
||||
}
|
||||
}
|
||||
s += "Bot:" + fmt.Sprintf("%v", ua.Bot()) + " "
|
||||
s += "Mobile:" + fmt.Sprintf("%v", ua.Mobile())
|
||||
return s
|
||||
}
|
||||
|
||||
// The test suite.
|
||||
func TestUserAgent(t *testing.T) {
|
||||
for _, tt := range uastrings {
|
||||
ua := New(tt.ua)
|
||||
got := beautify(ua)
|
||||
if tt.expected != got {
|
||||
t.Errorf("\nTest %v\ngot: %q\nexpected %q\n", tt.title, got, tt.expected)
|
||||
}
|
||||
|
||||
if tt.expectedOS != nil {
|
||||
gotOSInfo := ua.OSInfo()
|
||||
if !reflect.DeepEqual(tt.expectedOS, &gotOSInfo) {
|
||||
t.Errorf("\nTest %v\ngot: %#v\nexpected %#v\n", tt.title, gotOSInfo, tt.expectedOS)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmark: it parses each User-Agent string on the uastrings slice b.N times.
|
||||
func BenchmarkUserAgent(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
b.StopTimer()
|
||||
for _, tt := range uastrings {
|
||||
ua := new(UserAgent)
|
||||
b.StartTimer()
|
||||
ua.Parse(tt.ua)
|
||||
}
|
||||
}
|
||||
}
|
||||
123
vendor/github.com/mssola/user_agent/bot.go
generated
vendored
123
vendor/github.com/mssola/user_agent/bot.go
generated
vendored
@@ -1,123 +0,0 @@
|
||||
// Copyright (C) 2014-2018 Miquel Sabaté Solà <mikisabate@gmail.com>
|
||||
// This file is licensed under the MIT license.
|
||||
// See the LICENSE file.
|
||||
|
||||
package user_agent
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var botFromSiteRegexp = regexp.MustCompile("http://.+\\.\\w+")
|
||||
|
||||
// Get the name of the bot from the website that may be in the given comment. If
|
||||
// there is no website in the comment, then an empty string is returned.
|
||||
func getFromSite(comment []string) string {
|
||||
if len(comment) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Where we should check the website.
|
||||
idx := 2
|
||||
if len(comment) < 3 {
|
||||
idx = 0
|
||||
}
|
||||
|
||||
// Pick the site.
|
||||
results := botFromSiteRegexp.FindStringSubmatch(comment[idx])
|
||||
if len(results) == 1 {
|
||||
// If it's a simple comment, just return the name of the site.
|
||||
if idx == 0 {
|
||||
return results[0]
|
||||
}
|
||||
|
||||
// This is a large comment, usually the name will be in the previous
|
||||
// field of the comment.
|
||||
return strings.TrimSpace(comment[1])
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Returns true if the info that we currently have corresponds to the Google
|
||||
// mobile bot. This function also modifies some attributes in the receiver
|
||||
// accordingly.
|
||||
func (p *UserAgent) googleBot() bool {
|
||||
// This is a hackish way to detect Google's mobile bot.
|
||||
if strings.Index(p.ua, "Googlebot") != -1 {
|
||||
p.platform = ""
|
||||
p.undecided = true
|
||||
}
|
||||
return p.undecided
|
||||
}
|
||||
|
||||
// Set the attributes of the receiver as given by the parameters. All the other
|
||||
// parameters are set to empty.
|
||||
func (p *UserAgent) setSimple(name, version string, bot bool) {
|
||||
p.bot = bot
|
||||
if !bot {
|
||||
p.mozilla = ""
|
||||
}
|
||||
p.browser.Name = name
|
||||
p.browser.Version = version
|
||||
p.browser.Engine = ""
|
||||
p.browser.EngineVersion = ""
|
||||
p.os = ""
|
||||
p.localization = ""
|
||||
}
|
||||
|
||||
// Fix some values for some weird browsers.
|
||||
func (p *UserAgent) fixOther(sections []section) {
|
||||
if len(sections) > 0 {
|
||||
p.browser.Name = sections[0].name
|
||||
p.browser.Version = sections[0].version
|
||||
p.mozilla = ""
|
||||
}
|
||||
}
|
||||
|
||||
var botRegex = regexp.MustCompile("(?i)(bot|crawler|sp(i|y)der|search|worm|fetch|nutch)")
|
||||
|
||||
// Check if we're dealing with a bot or with some weird browser. If that is the
|
||||
// case, the receiver will be modified accordingly.
|
||||
func (p *UserAgent) checkBot(sections []section) {
|
||||
// If there's only one element, and it's doesn't have the Mozilla string,
|
||||
// check whether this is a bot or not.
|
||||
if len(sections) == 1 && sections[0].name != "Mozilla" {
|
||||
p.mozilla = ""
|
||||
|
||||
// Check whether the name has some suspicious "bot" or "crawler" in his name.
|
||||
if botRegex.Match([]byte(sections[0].name)) {
|
||||
p.setSimple(sections[0].name, "", true)
|
||||
return
|
||||
}
|
||||
|
||||
// Tough luck, let's try to see if it has a website in his comment.
|
||||
if name := getFromSite(sections[0].comment); name != "" {
|
||||
// First of all, this is a bot. Moreover, since it doesn't have the
|
||||
// Mozilla string, we can assume that the name and the version are
|
||||
// the ones from the first section.
|
||||
p.setSimple(sections[0].name, sections[0].version, true)
|
||||
return
|
||||
}
|
||||
|
||||
// At this point we are sure that this is not a bot, but some weirdo.
|
||||
p.setSimple(sections[0].name, sections[0].version, false)
|
||||
} else {
|
||||
// Let's iterate over the available comments and check for a website.
|
||||
for _, v := range sections {
|
||||
if name := getFromSite(v.comment); name != "" {
|
||||
// Ok, we've got a bot name.
|
||||
results := strings.SplitN(name, "/", 2)
|
||||
version := ""
|
||||
if len(results) == 2 {
|
||||
version = results[1]
|
||||
}
|
||||
p.setSimple(results[0], version, true)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// We will assume that this is some other weird browser.
|
||||
p.fixOther(sections)
|
||||
}
|
||||
}
|
||||
140
vendor/github.com/mssola/user_agent/browser.go
generated
vendored
140
vendor/github.com/mssola/user_agent/browser.go
generated
vendored
@@ -1,140 +0,0 @@
|
||||
// Copyright (C) 2012-2018 Miquel Sabaté Solà <mikisabate@gmail.com>
|
||||
// This file is licensed under the MIT license.
|
||||
// See the LICENSE file.
|
||||
|
||||
package user_agent
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var ie11Regexp = regexp.MustCompile("^rv:(.+)$")
|
||||
|
||||
// A struct containing all the information that we might be
|
||||
// interested from the browser.
|
||||
type Browser struct {
|
||||
// The name of the browser's engine.
|
||||
Engine string
|
||||
|
||||
// The version of the browser's engine.
|
||||
EngineVersion string
|
||||
|
||||
// The name of the browser.
|
||||
Name string
|
||||
|
||||
// The version of the browser.
|
||||
Version string
|
||||
}
|
||||
|
||||
// Extract all the information that we can get from the User-Agent string
|
||||
// about the browser and update the receiver with this information.
|
||||
//
|
||||
// The function receives just one argument "sections", that contains the
|
||||
// sections from the User-Agent string after being parsed.
|
||||
func (p *UserAgent) detectBrowser(sections []section) {
|
||||
slen := len(sections)
|
||||
|
||||
if sections[0].name == "Opera" {
|
||||
p.browser.Name = "Opera"
|
||||
p.browser.Version = sections[0].version
|
||||
p.browser.Engine = "Presto"
|
||||
if slen > 1 {
|
||||
p.browser.EngineVersion = sections[1].version
|
||||
}
|
||||
} else if sections[0].name == "Dalvik" {
|
||||
// When Dalvik VM is in use, there is no browser info attached to ua.
|
||||
// Although browser is still a Mozilla/5.0 compatible.
|
||||
p.mozilla = "5.0"
|
||||
} else if slen > 1 {
|
||||
engine := sections[1]
|
||||
p.browser.Engine = engine.name
|
||||
p.browser.EngineVersion = engine.version
|
||||
if slen > 2 {
|
||||
sectionIndex := 2
|
||||
// The version after the engine comment is empty on e.g. Ubuntu
|
||||
// platforms so if this is the case, let's use the next in line.
|
||||
if sections[2].version == "" && slen > 3 {
|
||||
sectionIndex = 3
|
||||
}
|
||||
p.browser.Version = sections[sectionIndex].version
|
||||
if engine.name == "AppleWebKit" {
|
||||
switch sections[slen-1].name {
|
||||
case "Edge":
|
||||
p.browser.Name = "Edge"
|
||||
p.browser.Version = sections[slen-1].version
|
||||
p.browser.Engine = "EdgeHTML"
|
||||
p.browser.EngineVersion = ""
|
||||
case "OPR":
|
||||
p.browser.Name = "Opera"
|
||||
p.browser.Version = sections[slen-1].version
|
||||
default:
|
||||
if sections[sectionIndex].name == "Chrome" {
|
||||
p.browser.Name = "Chrome"
|
||||
} else if sections[sectionIndex].name == "Chromium" {
|
||||
p.browser.Name = "Chromium"
|
||||
} else {
|
||||
p.browser.Name = "Safari"
|
||||
}
|
||||
}
|
||||
} else if engine.name == "Gecko" {
|
||||
name := sections[2].name
|
||||
if name == "MRA" && slen > 4 {
|
||||
name = sections[4].name
|
||||
p.browser.Version = sections[4].version
|
||||
}
|
||||
p.browser.Name = name
|
||||
} else if engine.name == "like" && sections[2].name == "Gecko" {
|
||||
// This is the new user agent from Internet Explorer 11.
|
||||
p.browser.Engine = "Trident"
|
||||
p.browser.Name = "Internet Explorer"
|
||||
for _, c := range sections[0].comment {
|
||||
version := ie11Regexp.FindStringSubmatch(c)
|
||||
if len(version) > 0 {
|
||||
p.browser.Version = version[1]
|
||||
return
|
||||
}
|
||||
}
|
||||
p.browser.Version = ""
|
||||
}
|
||||
}
|
||||
} else if slen == 1 && len(sections[0].comment) > 1 {
|
||||
comment := sections[0].comment
|
||||
if comment[0] == "compatible" && strings.HasPrefix(comment[1], "MSIE") {
|
||||
p.browser.Engine = "Trident"
|
||||
p.browser.Name = "Internet Explorer"
|
||||
// The MSIE version may be reported as the compatibility version.
|
||||
// For IE 8 through 10, the Trident token is more accurate.
|
||||
// http://msdn.microsoft.com/en-us/library/ie/ms537503(v=vs.85).aspx#VerToken
|
||||
for _, v := range comment {
|
||||
if strings.HasPrefix(v, "Trident/") {
|
||||
switch v[8:] {
|
||||
case "4.0":
|
||||
p.browser.Version = "8.0"
|
||||
case "5.0":
|
||||
p.browser.Version = "9.0"
|
||||
case "6.0":
|
||||
p.browser.Version = "10.0"
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
// If the Trident token is not provided, fall back to MSIE token.
|
||||
if p.browser.Version == "" {
|
||||
p.browser.Version = strings.TrimSpace(comment[1][4:])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns two strings. The first string is the name of the engine and the
|
||||
// second one is the version of the engine.
|
||||
func (p *UserAgent) Engine() (string, string) {
|
||||
return p.browser.Engine, p.browser.EngineVersion
|
||||
}
|
||||
|
||||
// Returns two strings. The first string is the name of the browser and the
|
||||
// second one is the version of the browser.
|
||||
func (p *UserAgent) Browser() (string, string) {
|
||||
return p.browser.Name, p.browser.Version
|
||||
}
|
||||
359
vendor/github.com/mssola/user_agent/operating_systems.go
generated
vendored
359
vendor/github.com/mssola/user_agent/operating_systems.go
generated
vendored
@@ -1,359 +0,0 @@
|
||||
// Copyright (C) 2012-2018 Miquel Sabaté Solà <mikisabate@gmail.com>
|
||||
// This file is licensed under the MIT license.
|
||||
// See the LICENSE file.
|
||||
|
||||
package user_agent
|
||||
|
||||
import "strings"
|
||||
|
||||
// Represents full information on the operating system extracted from the user agent.
|
||||
type OSInfo struct {
|
||||
// Full name of the operating system. This is identical to the output of ua.OS()
|
||||
FullName string
|
||||
|
||||
// Name of the operating system. This is sometimes a shorter version of the
|
||||
// operating system name, e.g. "Mac OS X" instead of "Intel Mac OS X"
|
||||
Name string
|
||||
|
||||
// Operating system version, e.g. 7 for Windows 7 or 10.8 for Max OS X Mountain Lion
|
||||
Version string
|
||||
}
|
||||
|
||||
// Normalize the name of the operating system. By now, this just
|
||||
// affects to Windows NT.
|
||||
//
|
||||
// Returns a string containing the normalized name for the Operating System.
|
||||
func normalizeOS(name string) string {
|
||||
sp := strings.SplitN(name, " ", 3)
|
||||
if len(sp) != 3 || sp[1] != "NT" {
|
||||
return name
|
||||
}
|
||||
|
||||
switch sp[2] {
|
||||
case "5.0":
|
||||
return "Windows 2000"
|
||||
case "5.01":
|
||||
return "Windows 2000, Service Pack 1 (SP1)"
|
||||
case "5.1":
|
||||
return "Windows XP"
|
||||
case "5.2":
|
||||
return "Windows XP x64 Edition"
|
||||
case "6.0":
|
||||
return "Windows Vista"
|
||||
case "6.1":
|
||||
return "Windows 7"
|
||||
case "6.2":
|
||||
return "Windows 8"
|
||||
case "6.3":
|
||||
return "Windows 8.1"
|
||||
case "10.0":
|
||||
return "Windows 10"
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
// Guess the OS, the localization and if this is a mobile device for a
|
||||
// Webkit-powered browser.
|
||||
//
|
||||
// The first argument p is a reference to the current UserAgent and the second
|
||||
// argument is a slice of strings containing the comment.
|
||||
func webkit(p *UserAgent, comment []string) {
|
||||
if p.platform == "webOS" {
|
||||
p.browser.Name = p.platform
|
||||
p.os = "Palm"
|
||||
if len(comment) > 2 {
|
||||
p.localization = comment[2]
|
||||
}
|
||||
p.mobile = true
|
||||
} else if p.platform == "Symbian" {
|
||||
p.mobile = true
|
||||
p.browser.Name = p.platform
|
||||
p.os = comment[0]
|
||||
} else if p.platform == "Linux" {
|
||||
p.mobile = true
|
||||
if p.browser.Name == "Safari" {
|
||||
p.browser.Name = "Android"
|
||||
}
|
||||
if len(comment) > 1 {
|
||||
if comment[1] == "U" {
|
||||
if len(comment) > 2 {
|
||||
p.os = comment[2]
|
||||
} else {
|
||||
p.mobile = false
|
||||
p.os = comment[0]
|
||||
}
|
||||
} else {
|
||||
p.os = comment[1]
|
||||
}
|
||||
}
|
||||
if len(comment) > 3 {
|
||||
p.localization = comment[3]
|
||||
} else if len(comment) == 3 {
|
||||
_ = p.googleBot()
|
||||
}
|
||||
} else if len(comment) > 0 {
|
||||
if len(comment) > 3 {
|
||||
p.localization = comment[3]
|
||||
}
|
||||
if strings.HasPrefix(comment[0], "Windows NT") {
|
||||
p.os = normalizeOS(comment[0])
|
||||
} else if len(comment) < 2 {
|
||||
p.localization = comment[0]
|
||||
} else if len(comment) < 3 {
|
||||
if !p.googleBot() {
|
||||
p.os = normalizeOS(comment[1])
|
||||
}
|
||||
} else {
|
||||
p.os = normalizeOS(comment[2])
|
||||
}
|
||||
if p.platform == "BlackBerry" {
|
||||
p.browser.Name = p.platform
|
||||
if p.os == "Touch" {
|
||||
p.os = p.platform
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Guess the OS, the localization and if this is a mobile device
|
||||
// for a Gecko-powered browser.
|
||||
//
|
||||
// The first argument p is a reference to the current UserAgent and the second
|
||||
// argument is a slice of strings containing the comment.
|
||||
func gecko(p *UserAgent, comment []string) {
|
||||
if len(comment) > 1 {
|
||||
if comment[1] == "U" {
|
||||
if len(comment) > 2 {
|
||||
p.os = normalizeOS(comment[2])
|
||||
} else {
|
||||
p.os = normalizeOS(comment[1])
|
||||
}
|
||||
} else {
|
||||
if p.platform == "Android" {
|
||||
p.mobile = true
|
||||
p.platform, p.os = normalizeOS(comment[1]), p.platform
|
||||
} else if comment[0] == "Mobile" || comment[0] == "Tablet" {
|
||||
p.mobile = true
|
||||
p.os = "FirefoxOS"
|
||||
} else {
|
||||
if p.os == "" {
|
||||
p.os = normalizeOS(comment[1])
|
||||
}
|
||||
}
|
||||
}
|
||||
// Only parse 4th comment as localization if it doesn't start with rv:.
|
||||
// For example Firefox on Ubuntu contains "rv:XX.X" in this field.
|
||||
if len(comment) > 3 && !strings.HasPrefix(comment[3], "rv:") {
|
||||
p.localization = comment[3]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Guess the OS, the localization and if this is a mobile device
|
||||
// for Internet Explorer.
|
||||
//
|
||||
// The first argument p is a reference to the current UserAgent and the second
|
||||
// argument is a slice of strings containing the comment.
|
||||
func trident(p *UserAgent, comment []string) {
|
||||
// Internet Explorer only runs on Windows.
|
||||
p.platform = "Windows"
|
||||
|
||||
// The OS can be set before to handle a new case in IE11.
|
||||
if p.os == "" {
|
||||
if len(comment) > 2 {
|
||||
p.os = normalizeOS(comment[2])
|
||||
} else {
|
||||
p.os = "Windows NT 4.0"
|
||||
}
|
||||
}
|
||||
|
||||
// Last but not least, let's detect if it comes from a mobile device.
|
||||
for _, v := range comment {
|
||||
if strings.HasPrefix(v, "IEMobile") {
|
||||
p.mobile = true
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Guess the OS, the localization and if this is a mobile device
|
||||
// for Opera.
|
||||
//
|
||||
// The first argument p is a reference to the current UserAgent and the second
|
||||
// argument is a slice of strings containing the comment.
|
||||
func opera(p *UserAgent, comment []string) {
|
||||
slen := len(comment)
|
||||
|
||||
if strings.HasPrefix(comment[0], "Windows") {
|
||||
p.platform = "Windows"
|
||||
p.os = normalizeOS(comment[0])
|
||||
if slen > 2 {
|
||||
if slen > 3 && strings.HasPrefix(comment[2], "MRA") {
|
||||
p.localization = comment[3]
|
||||
} else {
|
||||
p.localization = comment[2]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if strings.HasPrefix(comment[0], "Android") {
|
||||
p.mobile = true
|
||||
}
|
||||
p.platform = comment[0]
|
||||
if slen > 1 {
|
||||
p.os = comment[1]
|
||||
if slen > 3 {
|
||||
p.localization = comment[3]
|
||||
}
|
||||
} else {
|
||||
p.os = comment[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Guess the OS. Android browsers send Dalvik as the user agent in the
|
||||
// request header.
|
||||
//
|
||||
// The first argument p is a reference to the current UserAgent and the second
|
||||
// argument is a slice of strings containing the comment.
|
||||
func dalvik(p *UserAgent, comment []string) {
|
||||
slen := len(comment)
|
||||
|
||||
if strings.HasPrefix(comment[0], "Linux") {
|
||||
p.platform = comment[0]
|
||||
if slen > 2 {
|
||||
p.os = comment[2]
|
||||
}
|
||||
p.mobile = true
|
||||
}
|
||||
}
|
||||
|
||||
// Given the comment of the first section of the UserAgent string,
|
||||
// get the platform.
|
||||
func getPlatform(comment []string) string {
|
||||
if len(comment) > 0 {
|
||||
if comment[0] != "compatible" {
|
||||
if strings.HasPrefix(comment[0], "Windows") {
|
||||
return "Windows"
|
||||
} else if strings.HasPrefix(comment[0], "Symbian") {
|
||||
return "Symbian"
|
||||
} else if strings.HasPrefix(comment[0], "webOS") {
|
||||
return "webOS"
|
||||
} else if comment[0] == "BB10" {
|
||||
return "BlackBerry"
|
||||
}
|
||||
return comment[0]
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Detect some properties of the OS from the given section.
|
||||
func (p *UserAgent) detectOS(s section) {
|
||||
if s.name == "Mozilla" {
|
||||
// Get the platform here. Be aware that IE11 provides a new format
|
||||
// that is not backwards-compatible with previous versions of IE.
|
||||
p.platform = getPlatform(s.comment)
|
||||
if p.platform == "Windows" && len(s.comment) > 0 {
|
||||
p.os = normalizeOS(s.comment[0])
|
||||
}
|
||||
|
||||
// And finally get the OS depending on the engine.
|
||||
switch p.browser.Engine {
|
||||
case "":
|
||||
p.undecided = true
|
||||
case "Gecko":
|
||||
gecko(p, s.comment)
|
||||
case "AppleWebKit":
|
||||
webkit(p, s.comment)
|
||||
case "Trident":
|
||||
trident(p, s.comment)
|
||||
}
|
||||
} else if s.name == "Opera" {
|
||||
if len(s.comment) > 0 {
|
||||
opera(p, s.comment)
|
||||
}
|
||||
} else if s.name == "Dalvik" {
|
||||
if len(s.comment) > 0 {
|
||||
dalvik(p, s.comment)
|
||||
}
|
||||
} else {
|
||||
// Check whether this is a bot or just a weird browser.
|
||||
p.undecided = true
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a string containing the platform..
|
||||
func (p *UserAgent) Platform() string {
|
||||
return p.platform
|
||||
}
|
||||
|
||||
// Returns a string containing the name of the Operating System.
|
||||
func (p *UserAgent) OS() string {
|
||||
return p.os
|
||||
}
|
||||
|
||||
// Returns a string containing the localization.
|
||||
func (p *UserAgent) Localization() string {
|
||||
return p.localization
|
||||
}
|
||||
|
||||
// Return OS name and version from a slice of strings created from the full name of the OS.
|
||||
func osName(osSplit []string) (name, version string) {
|
||||
if len(osSplit) == 1 {
|
||||
name = osSplit[0]
|
||||
version = ""
|
||||
} else {
|
||||
// Assume version is stored in the last part of the array.
|
||||
nameSplit := osSplit[:len(osSplit)-1]
|
||||
version = osSplit[len(osSplit)-1]
|
||||
|
||||
// Nicer looking Mac OS X
|
||||
if len(nameSplit) >= 2 && nameSplit[0] == "Intel" && nameSplit[1] == "Mac" {
|
||||
nameSplit = nameSplit[1:]
|
||||
}
|
||||
name = strings.Join(nameSplit, " ")
|
||||
|
||||
if strings.Contains(version, "x86") || strings.Contains(version, "i686") {
|
||||
// x86_64 and i868 are not Linux versions but architectures
|
||||
version = ""
|
||||
} else if version == "X" && name == "Mac OS" {
|
||||
// X is not a version for Mac OS.
|
||||
name = name + " " + version
|
||||
version = ""
|
||||
}
|
||||
}
|
||||
return name, version
|
||||
}
|
||||
|
||||
// Returns combined information for the operating system.
|
||||
func (p *UserAgent) OSInfo() OSInfo {
|
||||
// Special case for iPhone weirdness
|
||||
os := strings.Replace(p.os, "like Mac OS X", "", 1)
|
||||
os = strings.Replace(os, "CPU", "", 1)
|
||||
os = strings.Trim(os, " ")
|
||||
|
||||
osSplit := strings.Split(os, " ")
|
||||
|
||||
// Special case for x64 edition of Windows
|
||||
if os == "Windows XP x64 Edition" {
|
||||
osSplit = osSplit[:len(osSplit)-2]
|
||||
}
|
||||
|
||||
name, version := osName(osSplit)
|
||||
|
||||
// Special case for names that contain a forward slash version separator.
|
||||
if strings.Contains(name, "/") {
|
||||
s := strings.Split(name, "/")
|
||||
name = s[0]
|
||||
version = s[1]
|
||||
}
|
||||
|
||||
// Special case for versions that use underscores
|
||||
version = strings.Replace(version, "_", ".", -1)
|
||||
|
||||
return OSInfo{
|
||||
FullName: p.os,
|
||||
Name: name,
|
||||
Version: version,
|
||||
}
|
||||
}
|
||||
174
vendor/github.com/mssola/user_agent/user_agent.go
generated
vendored
174
vendor/github.com/mssola/user_agent/user_agent.go
generated
vendored
@@ -1,174 +0,0 @@
|
||||
// Copyright (C) 2012-2018 Miquel Sabaté Solà <mikisabate@gmail.com>
|
||||
// This file is licensed under the MIT license.
|
||||
// See the LICENSE file.
|
||||
|
||||
// Package user_agent implements an HTTP User Agent string parser. It defines
|
||||
// the type UserAgent that contains all the information from the parsed string.
|
||||
// It also implements the Parse function and getters for all the relevant
|
||||
// information that has been extracted from a parsed User Agent string.
|
||||
package user_agent
|
||||
|
||||
import "strings"
|
||||
|
||||
// A section contains the name of the product, its version and
|
||||
// an optional comment.
|
||||
type section struct {
|
||||
name string
|
||||
version string
|
||||
comment []string
|
||||
}
|
||||
|
||||
// The UserAgent struct contains all the info that can be extracted
|
||||
// from the User-Agent string.
|
||||
type UserAgent struct {
|
||||
ua string
|
||||
mozilla string
|
||||
platform string
|
||||
os string
|
||||
localization string
|
||||
browser Browser
|
||||
bot bool
|
||||
mobile bool
|
||||
undecided bool
|
||||
}
|
||||
|
||||
// Read from the given string until the given delimiter or the
|
||||
// end of the string have been reached.
|
||||
//
|
||||
// The first argument is the user agent string being parsed. The second
|
||||
// argument is a reference pointing to the current index of the user agent
|
||||
// string. The delimiter argument specifies which character is the delimiter
|
||||
// and the cat argument determines whether nested '(' should be ignored or not.
|
||||
//
|
||||
// Returns an array of bytes containing what has been read.
|
||||
func readUntil(ua string, index *int, delimiter byte, cat bool) []byte {
|
||||
var buffer []byte
|
||||
|
||||
i := *index
|
||||
catalan := 0
|
||||
for ; i < len(ua); i = i + 1 {
|
||||
if ua[i] == delimiter {
|
||||
if catalan == 0 {
|
||||
*index = i + 1
|
||||
return buffer
|
||||
}
|
||||
catalan--
|
||||
} else if cat && ua[i] == '(' {
|
||||
catalan++
|
||||
}
|
||||
buffer = append(buffer, ua[i])
|
||||
}
|
||||
*index = i + 1
|
||||
return buffer
|
||||
}
|
||||
|
||||
// Parse the given product, that is, just a name or a string
|
||||
// formatted as Name/Version.
|
||||
//
|
||||
// It returns two strings. The first string is the name of the product and the
|
||||
// second string contains the version of the product.
|
||||
func parseProduct(product []byte) (string, string) {
|
||||
prod := strings.SplitN(string(product), "/", 2)
|
||||
if len(prod) == 2 {
|
||||
return prod[0], prod[1]
|
||||
}
|
||||
return string(product), ""
|
||||
}
|
||||
|
||||
// Parse a section. A section is typically formatted as follows
|
||||
// "Name/Version (comment)". Both, the comment and the version are optional.
|
||||
//
|
||||
// The first argument is the user agent string being parsed. The second
|
||||
// argument is a reference pointing to the current index of the user agent
|
||||
// string.
|
||||
//
|
||||
// Returns a section containing the information that we could extract
|
||||
// from the last parsed section.
|
||||
func parseSection(ua string, index *int) (s section) {
|
||||
buffer := readUntil(ua, index, ' ', false)
|
||||
|
||||
s.name, s.version = parseProduct(buffer)
|
||||
if *index < len(ua) && ua[*index] == '(' {
|
||||
*index++
|
||||
buffer = readUntil(ua, index, ')', true)
|
||||
s.comment = strings.Split(string(buffer), "; ")
|
||||
*index++
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Initialize the parser.
|
||||
func (p *UserAgent) initialize() {
|
||||
p.ua = ""
|
||||
p.mozilla = ""
|
||||
p.platform = ""
|
||||
p.os = ""
|
||||
p.localization = ""
|
||||
p.browser.Engine = ""
|
||||
p.browser.EngineVersion = ""
|
||||
p.browser.Name = ""
|
||||
p.browser.Version = ""
|
||||
p.bot = false
|
||||
p.mobile = false
|
||||
p.undecided = false
|
||||
}
|
||||
|
||||
// Parse the given User-Agent string and get the resulting UserAgent object.
|
||||
//
|
||||
// Returns an UserAgent object that has been initialized after parsing
|
||||
// the given User-Agent string.
|
||||
func New(ua string) *UserAgent {
|
||||
o := &UserAgent{}
|
||||
o.Parse(ua)
|
||||
return o
|
||||
}
|
||||
|
||||
// Parse the given User-Agent string. After calling this function, the
|
||||
// receiver will be setted up with all the information that we've extracted.
|
||||
func (p *UserAgent) Parse(ua string) {
|
||||
var sections []section
|
||||
|
||||
p.initialize()
|
||||
p.ua = ua
|
||||
for index, limit := 0, len(ua); index < limit; {
|
||||
s := parseSection(ua, &index)
|
||||
if !p.mobile && s.name == "Mobile" {
|
||||
p.mobile = true
|
||||
}
|
||||
sections = append(sections, s)
|
||||
}
|
||||
|
||||
if len(sections) > 0 {
|
||||
if sections[0].name == "Mozilla" {
|
||||
p.mozilla = sections[0].version
|
||||
}
|
||||
|
||||
p.detectBrowser(sections)
|
||||
p.detectOS(sections[0])
|
||||
|
||||
if p.undecided {
|
||||
p.checkBot(sections)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the mozilla version (it's how the User Agent string begins:
|
||||
// "Mozilla/5.0 ...", unless we're dealing with Opera, of course).
|
||||
func (p *UserAgent) Mozilla() string {
|
||||
return p.mozilla
|
||||
}
|
||||
|
||||
// Returns true if it's a bot, false otherwise.
|
||||
func (p *UserAgent) Bot() bool {
|
||||
return p.bot
|
||||
}
|
||||
|
||||
// Returns true if it's a mobile device, false otherwise.
|
||||
func (p *UserAgent) Mobile() bool {
|
||||
return p.mobile
|
||||
}
|
||||
|
||||
// Returns the original given user agent.
|
||||
func (p *UserAgent) UA() string {
|
||||
return p.ua
|
||||
}
|
||||
Reference in New Issue
Block a user