Files
kjol/httputil/useragent.go

139 lines
3.2 KiB
Go

package httputil
import (
"regexp"
"strings"
)
func ParseUserAgent(ua string) string {
if ua == "" {
return "Unknown"
}
browser := parseBrowser(ua)
os := parseOS(ua)
if browser == "" && os == "" {
return "Unknown"
}
if browser == "" {
return os
}
if os == "" {
return browser
}
return browser + " on " + os
}
func parseBrowser(ua string) string {
if match := regexp.MustCompile(`Edg(?:e|A|iOS)?/(\d+)`).FindStringSubmatch(ua); match != nil {
return "Edge " + match[1]
}
if match := regexp.MustCompile(`(?:OPR|Opera)[/ ](\d+)`).FindStringSubmatch(ua); match != nil {
return "Opera " + match[1]
}
if match := regexp.MustCompile(`SamsungBrowser/(\d+)`).FindStringSubmatch(ua); match != nil {
return "Samsung Browser " + match[1]
}
if strings.Contains(ua, "Chrome") && !strings.Contains(ua, "Chromium") {
if match := regexp.MustCompile(`Chrome/(\d+)`).FindStringSubmatch(ua); match != nil {
return "Chrome " + match[1]
}
}
if match := regexp.MustCompile(`Chromium/(\d+)`).FindStringSubmatch(ua); match != nil {
return "Chromium " + match[1]
}
if match := regexp.MustCompile(`Firefox/(\d+)`).FindStringSubmatch(ua); match != nil {
return "Firefox " + match[1]
}
if strings.Contains(ua, "Safari") && !strings.Contains(ua, "Chrome") {
if match := regexp.MustCompile(`Version/(\d+)`).FindStringSubmatch(ua); match != nil {
return "Safari " + match[1]
}
return "Safari"
}
if match := regexp.MustCompile(`MSIE (\d+)`).FindStringSubmatch(ua); match != nil {
return "Internet Explorer " + match[1]
}
if strings.Contains(ua, "Trident/") {
if match := regexp.MustCompile(`rv:(\d+)`).FindStringSubmatch(ua); match != nil {
return "Internet Explorer " + match[1]
}
return "Internet Explorer"
}
return ""
}
func parseOS(ua string) string {
if strings.Contains(ua, "iPhone") {
if match := regexp.MustCompile(`iPhone OS (\d+)[_\d]*`).FindStringSubmatch(ua); match != nil {
return "iOS " + match[1]
}
return "iOS"
}
if strings.Contains(ua, "iPad") {
if match := regexp.MustCompile(`CPU OS (\d+)[_\d]*`).FindStringSubmatch(ua); match != nil {
return "iPadOS " + match[1]
}
return "iPadOS"
}
if match := regexp.MustCompile(`Android (\d+)`).FindStringSubmatch(ua); match != nil {
return "Android " + match[1]
}
if strings.Contains(ua, "Windows") {
if strings.Contains(ua, "Windows NT 10.0") {
return "Windows 10/11"
}
if strings.Contains(ua, "Windows NT 6.3") {
return "Windows 8.1"
}
if strings.Contains(ua, "Windows NT 6.2") {
return "Windows 8"
}
if strings.Contains(ua, "Windows NT 6.1") {
return "Windows 7"
}
if strings.Contains(ua, "Windows NT 6.0") {
return "Windows Vista"
}
if strings.Contains(ua, "Windows NT 5.1") {
return "Windows XP"
}
return "Windows"
}
if strings.Contains(ua, "Mac OS X") || strings.Contains(ua, "Macintosh") {
if match := regexp.MustCompile(`Mac OS X (\d+)[_.](\d+)`).FindStringSubmatch(ua); match != nil {
return "macOS " + match[1] + "." + match[2]
}
return "macOS"
}
if strings.Contains(ua, "Ubuntu") {
return "Ubuntu"
}
if strings.Contains(ua, "Fedora") {
return "Fedora"
}
if strings.Contains(ua, "Linux") {
return "Linux"
}
if strings.Contains(ua, "CrOS") {
return "Chrome OS"
}
return ""
}