vendor dependencies with dep
This commit is contained in:
parent
93d8310491
commit
1384296a47
2712 changed files with 965742 additions and 0 deletions
10
vendor/github.com/mssola/user_agent/.travis.yml
generated
vendored
Normal file
10
vendor/github.com/mssola/user_agent/.travis.yml
generated
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
language: go
|
||||
go:
|
||||
- 1.0
|
||||
- 1.1
|
||||
- 1.2
|
||||
- 1.3
|
||||
- tip
|
||||
matrix:
|
||||
allow_failures:
|
||||
- go: tip
|
||||
20
vendor/github.com/mssola/user_agent/LICENSE
generated
vendored
Normal file
20
vendor/github.com/mssola/user_agent/LICENSE
generated
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
Copyright (c) 2012-2014 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
Normal file
51
vendor/github.com/mssola/user_agent/README.md
generated
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
|
||||
# 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-2014 Miquel Sabaté Solà, released under the MIT License.
|
||||
257
vendor/github.com/mssola/user_agent/all_test.go
generated
vendored
Normal file
257
vendor/github.com/mssola/user_agent/all_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
// Copyright (C) 2012-2014 Miquel Sabaté Solà <mikisabate@gmail.com>
|
||||
// This file is licensed under the MIT license.
|
||||
// See the LICENSE file.
|
||||
|
||||
package user_agent
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Slice that contains all the tests. Each test is contained in a struct
|
||||
// that groups the name of the test and the User-Agent string to be tested.
|
||||
var uastrings = []struct {
|
||||
name string
|
||||
ua string
|
||||
}{
|
||||
// Bots
|
||||
{"GoogleBot", "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"},
|
||||
{"GoogleBotSmartphone", "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)"},
|
||||
{"BingBot", "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"},
|
||||
{"BaiduBot", "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"},
|
||||
{"Twitterbot", "Twitterbot"},
|
||||
{"YahooBot", "Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)"},
|
||||
{"FacebookExternalHit", "facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)"},
|
||||
{"FacebookPlatform", "facebookplatform/1.0 (+http://developers.facebook.com)"},
|
||||
{"FaceBot", "Facebot"},
|
||||
|
||||
// Internet Explorer
|
||||
{"IE10", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)"},
|
||||
{"Tablet", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; ARM; Trident/6.0; Touch; .NET4.0E; .NET4.0C; Tablet PC 2.0)"},
|
||||
{"Touch", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; ARM; Trident/6.0; Touch)"},
|
||||
{"Phone", "Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0; SAMSUNG; SGH-i917)"},
|
||||
{"IE6", "Mozilla/4.0 (compatible; MSIE6.0; Windows NT 5.0; .NET CLR 1.1.4322)"},
|
||||
{"IE8Compatibility", "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)"},
|
||||
{"IE10Compatibility", "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)"},
|
||||
{"IE11Win81", "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"},
|
||||
{"IE11Win7", "Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko"},
|
||||
{"IE11b32Win7b64", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"},
|
||||
{"IE11b32Win7b64MDDRJS", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; MDDRJS; rv:11.0) like Gecko"},
|
||||
{"IE11Compatibility", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.3; Trident/7.0)"},
|
||||
|
||||
// Gecko
|
||||
{"FirefoxMac", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0b8) Gecko/20100101 Firefox/4.0b8"},
|
||||
{"FirefoxMacLoc", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13"},
|
||||
{"FirefoxLinux", "Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20100101 Firefox/17.0"},
|
||||
{"FirefoxWin", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14"},
|
||||
{"Firefox29Win7", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0"},
|
||||
{"CaminoMac", "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)"},
|
||||
{"Iceweasel", "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1) Gecko/20061024 Iceweasel/2.0 (Debian-2.0+dfsg-1)"},
|
||||
{"SeaMonkey", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.1.4) Gecko/20091017 SeaMonkey/2.0"},
|
||||
{"AndroidFirefox", "Mozilla/5.0 (Android; Mobile; rv:17.0) Gecko/17.0 Firefox/17.0"},
|
||||
{"AndroidFirefoxTablet", "Mozilla/5.0 (Android; Tablet; rv:26.0) Gecko/26.0 Firefox/26.0"},
|
||||
{"FirefoxOS", "Mozilla/5.0 (Mobile; rv:26.0) Gecko/26.0 Firefox/26.0"},
|
||||
{"FirefoxOSTablet", "Mozilla/5.0 (Tablet; rv:26.0) Gecko/26.0 Firefox/26.0"},
|
||||
{"FirefoxWinXP", "Mozilla/5.0 (Windows NT 5.2; rv:31.0) Gecko/20100101 Firefox/31.0"},
|
||||
{"FirefoxMRA", "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)"},
|
||||
|
||||
// Opera
|
||||
{"OperaMac", "Opera/9.27 (Macintosh; Intel Mac OS X; U; en)"},
|
||||
{"OperaWin", "Opera/9.27 (Windows NT 5.1; U; en)"},
|
||||
{"OperaWinNoLocale", "Opera/9.80 (Windows NT 5.1) Presto/2.12.388 Version/12.10"},
|
||||
{"OperaWin2Comment", "Opera/9.80 (Windows NT 6.0; WOW64) Presto/2.12.388 Version/12.15"},
|
||||
{"OperaMinimal", "Opera/9.80"},
|
||||
{"OperaFull", "Opera/9.80 (Windows NT 6.0; U; en) Presto/2.2.15 Version/10.10"},
|
||||
{"OperaLinux", "Opera/9.80 (X11; Linux x86_64) Presto/2.12.388 Version/12.10"},
|
||||
{"OperaAndroid", "Opera/9.80 (Android 4.2.1; Linux; Opera Mobi/ADR-1212030829) Presto/2.11.355 Version/12.10"},
|
||||
{"OperaNested", "Opera/9.80 (Windows NT 5.1; MRA 6.0 (build 5831)) Presto/2.12.388 Version/12.10"},
|
||||
{"OperaMRA", "Opera/9.80 (Windows NT 6.1; U; MRA 5.8 (build 4139); en) Presto/2.9.168 Version/11.50"},
|
||||
|
||||
// Other
|
||||
{"Empty", ""},
|
||||
{"Nil", "nil"},
|
||||
{"Compatible", "Mozilla/4.0 (compatible)"},
|
||||
{"Mozilla", "Mozilla/5.0"},
|
||||
{"Amaya", "amaya/9.51 libwww/5.4.0"},
|
||||
{"Rails", "Rails Testing"},
|
||||
{"Python", "Python-urllib/2.7"},
|
||||
{"Curl", "curl/7.28.1"},
|
||||
|
||||
// WebKit
|
||||
{"ChromeLinux", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11"},
|
||||
{"ChromeWin7", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.168 Safari/535.19"},
|
||||
{"ChromeMinimal", "Mozilla/5.0 AppleWebKit/534.10 Chrome/8.0.552.215 Safari/534.10"},
|
||||
{"ChromeMac", "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"},
|
||||
{"SafariMac", "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"},
|
||||
{"SafariWin", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en) AppleWebKit/526.9 (KHTML, like Gecko) Version/4.0dp1 Safari/526.8"},
|
||||
{"iPhone7", "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"},
|
||||
{"iPhone", "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/4A102 Safari/419"},
|
||||
{"iPod", "Mozilla/5.0 (iPod; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/4A102 Safari/419"},
|
||||
{"iPad", "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"},
|
||||
{"webOS", "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"},
|
||||
{"Android", "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"},
|
||||
{"BlackBerry", "Mozilla/5.0 (BlackBerry; U; BlackBerry 9800; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/6.0.0.141 Mobile Safari/534.1+"},
|
||||
{"BB10", "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.3+ (KHTML, like Gecko) Version/10.0.9.388 Mobile Safari/537.3+"},
|
||||
{"Ericsson", "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"},
|
||||
{"ChromeAndroid", "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"},
|
||||
{"WebkitNoPlatform", "Mozilla/5.0 (en-us) AppleWebKit/525.13 (KHTML, like Gecko; Google Web Preview) Version/3.1 Safari/525.13"},
|
||||
{"OperaWebkitMobile", "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"},
|
||||
{"OperaWebkitDesktop", "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"},
|
||||
{"ChromeNothingAfterU", "Mozilla/5.0 (Linux; U) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.79 Safari/537.4"},
|
||||
{"SafariOnSymbian", "Mozilla/5.0 (SymbianOS/9.1; U; [en-us]) AppleWebKit/413 (KHTML, like Gecko) Safari/413"},
|
||||
}
|
||||
|
||||
// Slice of the expected results from the previous slice.
|
||||
var expected = []string{
|
||||
// Bots
|
||||
"Mozilla:5.0 Browser:Googlebot-2.1 Bot:true Mobile:false",
|
||||
"Mozilla:5.0 Browser:Googlebot-2.1 Bot:true Mobile:true",
|
||||
"Mozilla:5.0 Browser:bingbot-2.0 Bot:true Mobile:false",
|
||||
"Mozilla:5.0 Browser:Baiduspider-2.0 Bot:true Mobile:false",
|
||||
"Browser:Twitterbot Bot:true Mobile:false",
|
||||
"Mozilla:5.0 Browser:Yahoo! Slurp Bot:true Mobile:false",
|
||||
"Browser:facebookexternalhit-1.1 Bot:true Mobile:false",
|
||||
"Browser:facebookplatform-1.0 Bot:true Mobile:false",
|
||||
"Browser:Facebot Bot:true Mobile:false",
|
||||
|
||||
// Internet Explorer
|
||||
"Mozilla:5.0 Platform:Windows OS:Windows 8 Browser:Internet Explorer-10.0 Engine:Trident Bot:false Mobile:false",
|
||||
"Mozilla:4.0 Platform:Windows OS:Windows 8 Browser:Internet Explorer-10.0 Engine:Trident Bot:false Mobile:false",
|
||||
"Mozilla:5.0 Platform:Windows OS:Windows 8 Browser:Internet Explorer-10.0 Engine:Trident Bot:false Mobile:false",
|
||||
"Mozilla:4.0 Platform:Windows OS:Windows Phone OS 7.0 Browser:Internet Explorer-7.0 Engine:Trident Bot:false Mobile:true",
|
||||
"Mozilla:4.0 Platform:Windows OS:Windows 2000 Browser:Internet Explorer-6.0 Engine:Trident Bot:false Mobile:false",
|
||||
"Mozilla:4.0 Platform:Windows OS:Windows 7 Browser:Internet Explorer-8.0 Engine:Trident Bot:false Mobile:false",
|
||||
"Mozilla:4.0 Platform:Windows OS:Windows 7 Browser:Internet Explorer-10.0 Engine:Trident Bot:false Mobile:false",
|
||||
"Mozilla:5.0 Platform:Windows OS:Windows 8.1 Browser:Internet Explorer-11.0 Engine:Trident Bot:false Mobile:false",
|
||||
"Mozilla:5.0 Platform:Windows OS:Windows 7 Browser:Internet Explorer-11.0 Engine:Trident Bot:false Mobile:false",
|
||||
"Mozilla:5.0 Platform:Windows OS:Windows 7 Browser:Internet Explorer-11.0 Engine:Trident Bot:false Mobile:false",
|
||||
"Mozilla:5.0 Platform:Windows OS:Windows 7 Browser:Internet Explorer-11.0 Engine:Trident Bot:false Mobile:false",
|
||||
"Mozilla:4.0 Platform:Windows OS:Windows 8.1 Browser:Internet Explorer-7.0 Engine:Trident Bot:false Mobile:false",
|
||||
|
||||
// Gecko
|
||||
"Mozilla:5.0 Platform:Macintosh OS:Intel Mac OS X 10.6 Browser:Firefox-4.0b8 Engine:Gecko-20100101 Bot:false Mobile:false",
|
||||
"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",
|
||||
"Mozilla:5.0 Platform:X11 OS:Linux x86_64 Browser:Firefox-17.0 Engine:Gecko-20100101 Bot:false Mobile:false",
|
||||
"Mozilla:5.0 Platform:Windows OS:Windows XP Localization:en-US Browser:Firefox-2.0.0.14 Engine:Gecko-20080404 Bot:false Mobile:false",
|
||||
"Mozilla:5.0 Platform:Windows OS:Windows 7 Browser:Firefox-29.0 Engine:Gecko-20100101 Bot:false Mobile:false",
|
||||
"Mozilla:5.0 Platform:Macintosh OS:Intel Mac OS X Localization:en Browser:Camino-1.6 Engine:Gecko-20080409 Bot:false Mobile:false",
|
||||
"Mozilla:5.0 Platform:X11 OS:Linux i686 Localization:en-US Browser:Iceweasel-2.0 Engine:Gecko-20061024 Bot:false Mobile:false",
|
||||
"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",
|
||||
"Mozilla:5.0 Platform:Mobile OS:Android Browser:Firefox-17.0 Engine:Gecko-17.0 Bot:false Mobile:true",
|
||||
"Mozilla:5.0 Platform:Tablet OS:Android Browser:Firefox-26.0 Engine:Gecko-26.0 Bot:false Mobile:true",
|
||||
"Mozilla:5.0 Platform:Mobile OS:FirefoxOS Browser:Firefox-26.0 Engine:Gecko-26.0 Bot:false Mobile:true",
|
||||
"Mozilla:5.0 Platform:Tablet OS:FirefoxOS Browser:Firefox-26.0 Engine:Gecko-26.0 Bot:false Mobile:true",
|
||||
"Mozilla:5.0 Platform:Windows OS:Windows XP x64 Edition Browser:Firefox-31.0 Engine:Gecko-20100101 Bot:false Mobile:false",
|
||||
"Mozilla:5.0 Platform:Windows OS:Windows XP Localization:en-US Browser:Firefox-24.0 Engine:Gecko-20130405 Bot:false Mobile:false",
|
||||
|
||||
// Opera
|
||||
"Platform:Macintosh OS:Intel Mac OS X Localization:en Browser:Opera-9.27 Engine:Presto Bot:false Mobile:false",
|
||||
"Platform:Windows OS:Windows XP Localization:en Browser:Opera-9.27 Engine:Presto Bot:false Mobile:false",
|
||||
"Platform:Windows OS:Windows XP Browser:Opera-9.80 Engine:Presto-2.12.388 Bot:false Mobile:false",
|
||||
"Platform:Windows OS:Windows Vista Browser:Opera-9.80 Engine:Presto-2.12.388 Bot:false Mobile:false",
|
||||
"Browser:Opera-9.80 Engine:Presto Bot:false Mobile:false",
|
||||
"Platform:Windows OS:Windows Vista Localization:en Browser:Opera-9.80 Engine:Presto-2.2.15 Bot:false Mobile:false",
|
||||
"Platform:X11 OS:Linux x86_64 Browser:Opera-9.80 Engine:Presto-2.12.388 Bot:false Mobile:false",
|
||||
"Platform:Android 4.2.1 OS:Linux Browser:Opera-9.80 Engine:Presto-2.11.355 Bot:false Mobile:true",
|
||||
"Platform:Windows OS:Windows XP Browser:Opera-9.80 Engine:Presto-2.12.388 Bot:false Mobile:false",
|
||||
"Platform:Windows OS:Windows 7 Localization:en Browser:Opera-9.80 Engine:Presto-2.9.168 Bot:false Mobile:false",
|
||||
|
||||
// Other
|
||||
"Bot:false Mobile:false",
|
||||
"Browser:nil Bot:false Mobile:false",
|
||||
"Browser:Mozilla-4.0 Bot:false Mobile:false",
|
||||
"Browser:Mozilla-5.0 Bot:false Mobile:false",
|
||||
"Browser:amaya-9.51 Engine:libwww-5.4.0 Bot:false Mobile:false",
|
||||
"Browser:Rails Engine:Testing Bot:false Mobile:false",
|
||||
"Browser:Python-urllib-2.7 Bot:false Mobile:false",
|
||||
"Browser:curl-7.28.1 Bot:false Mobile:false",
|
||||
|
||||
// WebKit
|
||||
"Mozilla:5.0 Platform:X11 OS:Linux x86_64 Browser:Chrome-23.0.1271.97 Engine:AppleWebKit-537.11 Bot:false Mobile:false",
|
||||
"Mozilla:5.0 Platform:Windows OS:Windows 7 Browser:Chrome-18.0.1025.168 Engine:AppleWebKit-535.19 Bot:false Mobile:false",
|
||||
"Mozilla:5.0 Browser:Chrome-8.0.552.215 Engine:AppleWebKit-534.10 Bot:false Mobile:false",
|
||||
"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",
|
||||
"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",
|
||||
"Mozilla:5.0 Platform:Windows OS:Windows XP Localization:en Browser:Safari-4.0dp1 Engine:AppleWebKit-526.9 Bot:false Mobile:false",
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
"Mozilla:5.0 Platform:webOS OS:Palm Localization:en-US Browser:webOS-1.0 Engine:AppleWebKit-532.2 Bot:false Mobile:true",
|
||||
"Mozilla:5.0 Platform:Linux OS:Android 1.5 Localization:de- Browser:Android-3.1.2 Engine:AppleWebKit-528.5+ Bot:false Mobile:true",
|
||||
"Mozilla:5.0 Platform:BlackBerry OS:BlackBerry 9800 Localization:en Browser:BlackBerry-6.0.0.141 Engine:AppleWebKit-534.1+ Bot:false Mobile:true",
|
||||
"Mozilla:5.0 Platform:BlackBerry OS:BlackBerry Browser:BlackBerry-10.0.9.388 Engine:AppleWebKit-537.3+ Bot:false Mobile:true",
|
||||
"Mozilla:5.0 Platform:Symbian OS:SymbianOS/9.4 Browser:Symbian-3.0 Engine:AppleWebKit-525 Bot:false Mobile:true",
|
||||
"Mozilla:5.0 Platform:Linux OS:Android 4.2.1 Browser:Chrome-18.0.1025.166 Engine:AppleWebKit-535.19 Bot:false Mobile:true",
|
||||
"Mozilla:5.0 Platform:en-us Localization:en-us Browser:Safari-3.1 Engine:AppleWebKit-525.13 Bot:false Mobile:false",
|
||||
"Mozilla:5.0 Platform:Linux OS:Android 4.2.2 Browser:Opera-14.0.1074.57453 Engine:AppleWebKit-537.31 Bot:false Mobile:true",
|
||||
"Mozilla:5.0 Platform:X11 OS:Linux x86_64 Browser:Opera-14.0.1074.57453 Engine:AppleWebKit-537.31 Bot:false Mobile:false",
|
||||
"Mozilla:5.0 Platform:Linux OS:Linux Browser:Chrome-22.0.1229.79 Engine:AppleWebKit-537.4 Bot:false Mobile:false",
|
||||
"Mozilla:5.0 Platform:Symbian OS:SymbianOS/9.1 Browser:Symbian-413 Engine:AppleWebKit-413 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 i, tt := range uastrings {
|
||||
ua := New(tt.ua)
|
||||
got := beautify(ua)
|
||||
if expected[i] != got {
|
||||
t.Errorf("Test %v => %q, expected %q", tt.name, got, expected[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
121
vendor/github.com/mssola/user_agent/bot.go
generated
vendored
Normal file
121
vendor/github.com/mssola/user_agent/bot.go
generated
vendored
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
// Copyright (C) 2014 Miquel Sabaté Solà <mikisabate@gmail.com>
|
||||
// This file is licensed under the MIT license.
|
||||
// See the LICENSE file.
|
||||
|
||||
package user_agent
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 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.
|
||||
re := regexp.MustCompile("http://.+\\.\\w+")
|
||||
results := re.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 = ""
|
||||
}
|
||||
}
|
||||
|
||||
// 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" in his name.
|
||||
reg, _ := regexp.Compile("(?i)bot")
|
||||
if reg.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)
|
||||
}
|
||||
}
|
||||
120
vendor/github.com/mssola/user_agent/browser.go
generated
vendored
Normal file
120
vendor/github.com/mssola/user_agent/browser.go
generated
vendored
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
// Copyright (C) 2012-2014 Miquel Sabaté Solà <mikisabate@gmail.com>
|
||||
// This file is licensed under the MIT license.
|
||||
// See the LICENSE file.
|
||||
|
||||
package user_agent
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 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.mozilla = ""
|
||||
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 slen > 1 {
|
||||
engine := sections[1]
|
||||
p.browser.Engine = engine.name
|
||||
p.browser.EngineVersion = engine.version
|
||||
if slen > 2 {
|
||||
p.browser.Version = sections[2].version
|
||||
if engine.name == "AppleWebKit" {
|
||||
if sections[slen-1].name == "OPR" {
|
||||
p.browser.Name = "Opera"
|
||||
p.browser.Version = sections[slen-1].version
|
||||
} else if sections[2].name == "Chrome" {
|
||||
p.browser.Name = "Chrome"
|
||||
} 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"
|
||||
reg, _ := regexp.Compile("^rv:(.+)$")
|
||||
for _, c := range sections[0].comment {
|
||||
version := reg.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
|
||||
}
|
||||
260
vendor/github.com/mssola/user_agent/operating_systems.go
generated
vendored
Normal file
260
vendor/github.com/mssola/user_agent/operating_systems.go
generated
vendored
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
// Copyright (C) 2012-2014 Miquel Sabaté Solà <mikisabate@gmail.com>
|
||||
// This file is licensed under the MIT license.
|
||||
// See the LICENSE file.
|
||||
|
||||
package user_agent
|
||||
|
||||
import "strings"
|
||||
|
||||
// Normalize the name of the operating system. By now, this just
|
||||
// affects to Windows.
|
||||
//
|
||||
// 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 {
|
||||
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 "6.4":
|
||||
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) > 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])
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(comment) > 3 {
|
||||
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]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// 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
|
||||
}
|
||||
169
vendor/github.com/mssola/user_agent/user_agent.go
generated
vendored
Normal file
169
vendor/github.com/mssola/user_agent/user_agent.go
generated
vendored
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
// Copyright (C) 2012-2014 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 {
|
||||
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
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue