From b84736e9b6401df0c6eeab9950bef09458a6aefd Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Fri, 29 Sep 2017 12:46:30 -0700 Subject: Updating server dependancies. (#7538) --- .../mssola/user_agent/operating_systems.go | 107 ++++++++++++++++++++- 1 file changed, 102 insertions(+), 5 deletions(-) (limited to 'vendor/github.com/mssola/user_agent/operating_systems.go') diff --git a/vendor/github.com/mssola/user_agent/operating_systems.go b/vendor/github.com/mssola/user_agent/operating_systems.go index 0b1e93d29..aebd8b394 100644 --- a/vendor/github.com/mssola/user_agent/operating_systems.go +++ b/vendor/github.com/mssola/user_agent/operating_systems.go @@ -1,4 +1,4 @@ -// Copyright (C) 2012-2014 Miquel Sabaté Solà +// Copyright (C) 2012-2017 Miquel Sabaté Solà // This file is licensed under the MIT license. // See the LICENSE file. @@ -6,13 +6,26 @@ 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. +// 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 { + if len(sp) != 3 || sp[1] != "NT" { return name } @@ -33,7 +46,7 @@ func normalizeOS(name string) string { return "Windows 8" case "6.3": return "Windows 8.1" - case "6.4": + case "10.0": return "Windows 10" } return name @@ -126,7 +139,9 @@ func gecko(p *UserAgent, comment []string) { } } } - if len(comment) > 3 { + // 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] } } @@ -193,6 +208,23 @@ func opera(p *UserAgent, comment []string) { } } +// 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 { @@ -238,6 +270,10 @@ func (p *UserAgent) detectOS(s section) { 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 @@ -258,3 +294,64 @@ func (p *UserAgent) OS() string { 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, + } +} -- cgit v1.2.3-1-g7c22