@@ -70,6 +70,62 @@ public static class HttpUserAgentStatics
7070 new ( CreateDefaultPlatformRegex ( "symbian" ) , "Symbian OS" , HttpUserAgentPlatformType . Symbian ) ,
7171 ] ;
7272
73+ /// <summary>
74+ /// Fast-path platform token rules for zero-allocation Contains checks
75+ /// </summary>
76+ internal static readonly ( string Token , string Name , HttpUserAgentPlatformType PlatformType ) [ ] s_platformRules =
77+ [
78+ ( "windows nt 10.0" , "Windows 10" , HttpUserAgentPlatformType . Windows ) ,
79+ ( "windows nt 6.3" , "Windows 8.1" , HttpUserAgentPlatformType . Windows ) ,
80+ ( "windows nt 6.2" , "Windows 8" , HttpUserAgentPlatformType . Windows ) ,
81+ ( "windows nt 6.1" , "Windows 7" , HttpUserAgentPlatformType . Windows ) ,
82+ ( "windows nt 6.0" , "Windows Vista" , HttpUserAgentPlatformType . Windows ) ,
83+ ( "windows nt 5.2" , "Windows 2003" , HttpUserAgentPlatformType . Windows ) ,
84+ ( "windows nt 5.1" , "Windows XP" , HttpUserAgentPlatformType . Windows ) ,
85+ ( "windows nt 5.0" , "Windows 2000" , HttpUserAgentPlatformType . Windows ) ,
86+ ( "windows nt 4.0" , "Windows NT 4.0" , HttpUserAgentPlatformType . Windows ) ,
87+ ( "winnt4.0" , "Windows NT 4.0" , HttpUserAgentPlatformType . Windows ) ,
88+ ( "winnt 4.0" , "Windows NT" , HttpUserAgentPlatformType . Windows ) ,
89+ ( "winnt" , "Windows NT" , HttpUserAgentPlatformType . Windows ) ,
90+ ( "windows 98" , "Windows 98" , HttpUserAgentPlatformType . Windows ) ,
91+ ( "win98" , "Windows 98" , HttpUserAgentPlatformType . Windows ) ,
92+ ( "windows 95" , "Windows 95" , HttpUserAgentPlatformType . Windows ) ,
93+ ( "win95" , "Windows 95" , HttpUserAgentPlatformType . Windows ) ,
94+ ( "windows phone" , "Windows Phone" , HttpUserAgentPlatformType . Windows ) ,
95+ ( "windows" , "Unknown Windows OS" , HttpUserAgentPlatformType . Windows ) ,
96+ ( "android" , "Android" , HttpUserAgentPlatformType . Android ) ,
97+ ( "blackberry" , "BlackBerry" , HttpUserAgentPlatformType . BlackBerry ) ,
98+ ( "iphone" , "iOS" , HttpUserAgentPlatformType . IOS ) ,
99+ ( "ipad" , "iOS" , HttpUserAgentPlatformType . IOS ) ,
100+ ( "ipod" , "iOS" , HttpUserAgentPlatformType . IOS ) ,
101+ ( "cros" , "ChromeOS" , HttpUserAgentPlatformType . ChromeOS ) ,
102+ ( "os x" , "Mac OS X" , HttpUserAgentPlatformType . MacOS ) ,
103+ ( "ppc mac" , "Power PC Mac" , HttpUserAgentPlatformType . MacOS ) ,
104+ ( "freebsd" , "FreeBSD" , HttpUserAgentPlatformType . Linux ) ,
105+ ( "ppc" , "Macintosh" , HttpUserAgentPlatformType . Linux ) ,
106+ ( "linux" , "Linux" , HttpUserAgentPlatformType . Linux ) ,
107+ ( "debian" , "Debian" , HttpUserAgentPlatformType . Linux ) ,
108+ ( "sunos" , "Sun Solaris" , HttpUserAgentPlatformType . Generic ) ,
109+ ( "beos" , "BeOS" , HttpUserAgentPlatformType . Generic ) ,
110+ ( "apachebench" , "ApacheBench" , HttpUserAgentPlatformType . Generic ) ,
111+ ( "aix" , "AIX" , HttpUserAgentPlatformType . Generic ) ,
112+ ( "irix" , "Irix" , HttpUserAgentPlatformType . Generic ) ,
113+ ( "osf" , "DEC OSF" , HttpUserAgentPlatformType . Generic ) ,
114+ ( "hp-ux" , "HP-UX" , HttpUserAgentPlatformType . Windows ) ,
115+ ( "netbsd" , "NetBSD" , HttpUserAgentPlatformType . Generic ) ,
116+ ( "bsdi" , "BSDi" , HttpUserAgentPlatformType . Generic ) ,
117+ ( "openbsd" , "OpenBSD" , HttpUserAgentPlatformType . Unix ) ,
118+ ( "gnu" , "GNU/Linux" , HttpUserAgentPlatformType . Linux ) ,
119+ ( "unix" , "Unknown Unix OS" , HttpUserAgentPlatformType . Unix ) ,
120+ ( "symbian" , "Symbian OS" , HttpUserAgentPlatformType . Symbian ) ,
121+ ] ;
122+
123+ // Precompiled platform regex map to attach to PlatformInformation without per-call allocations
124+ private static readonly Dictionary < string , Regex > s_platformRegexMap = s_platformRules
125+ . ToDictionary ( p => p . Token , p => CreateDefaultPlatformRegex ( p . Token ) , StringComparer . OrdinalIgnoreCase ) ;
126+
127+ internal static Regex GetPlatformRegexForToken ( string token ) => s_platformRegexMap [ token ] ;
128+
73129 /// <summary>
74130 /// Regex defauls for browser mappings
75131 /// </summary>
@@ -122,6 +178,48 @@ private static Regex CreateDefaultBrowserRegex(string key)
122178 { CreateDefaultBrowserRegex ( "Ubuntu" ) , "Ubuntu Web Browser" } ,
123179 } ;
124180
181+ /// <summary>
182+ /// Fast-path browser token rules. If these fail to extract a version, code will fall back to regex rules.
183+ /// </summary>
184+ internal static readonly ( string Name , string DetectToken , string ? VersionToken ) [ ] s_browserRules =
185+ [
186+ ( "Opera" , "OPR" , null ) ,
187+ ( "Flock" , "Flock" , null ) ,
188+ ( "Edge" , "Edge" , null ) ,
189+ ( "Edge" , "EdgA" , null ) ,
190+ ( "Edge" , "Edg" , null ) ,
191+ ( "Vivaldi" , "Vivaldi" , null ) ,
192+ ( "Brave" , "Brave Chrome" , null ) ,
193+ ( "Chrome" , "Chrome" , null ) ,
194+ ( "Chrome" , "CriOS" , null ) ,
195+ ( "Opera" , "Opera" , "Version/" ) ,
196+ ( "Opera" , "Opera" , null ) ,
197+ ( "Internet Explorer" , "MSIE" , "MSIE " ) ,
198+ ( "Internet Explorer" , "Internet Explorer" , null ) ,
199+ ( "Internet Explorer" , "Trident" , "rv:" ) ,
200+ ( "Shiira" , "Shiira" , null ) ,
201+ ( "Firefox" , "Firefox" , null ) ,
202+ ( "Firefox" , "FxiOS" , null ) ,
203+ ( "Chimera" , "Chimera" , null ) ,
204+ ( "Phoenix" , "Phoenix" , null ) ,
205+ ( "Firebird" , "Firebird" , null ) ,
206+ ( "Camino" , "Camino" , null ) ,
207+ ( "Netscape" , "Netscape" , null ) ,
208+ ( "OmniWeb" , "OmniWeb" , null ) ,
209+ ( "Safari" , "Version/" , "Version/" ) ,
210+ ( "Mozilla" , "Mozilla" , null ) ,
211+ ( "Konqueror" , "Konqueror" , null ) ,
212+ ( "iCab" , "icab" , null ) ,
213+ ( "Lynx" , "Lynx" , null ) ,
214+ ( "Links" , "Links" , null ) ,
215+ ( "HotJava" , "hotjava" , null ) ,
216+ ( "Amaya" , "amaya" , null ) ,
217+ ( "IBrowse" , "IBrowse" , null ) ,
218+ ( "Maxthon" , "Maxthon" , null ) ,
219+ ( "Apple iPod" , "ipod touch" , null ) ,
220+ ( "Ubuntu Web Browser" , "Ubuntu" , null ) ,
221+ ] ;
222+
125223 /// <summary>
126224 /// Mobiles
127225 /// </summary>
0 commit comments