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 "" }