Lasso Soft Inc. > Home

[lp_client_browser]

Linklp_client_browser
AuthorBil Corry
CategoryClient
Version8.x
LicensePublic Domain
Posted20 Jan 2006
Updated26 Feb 2009
More by this author...

Description

Returns the name, version, OS, type and typecode of the client browser in a map.

 

Browser types:
    B = Browser (Desktop)
    C = Link/Bookmark/Server Checker
    D = Download/FTP tool
    E = Email Reader
    F = Feed Reader
    L = Library
    M = Mobile Browser
    O = Offline Browsing
    P = Proxy, Web filter
    R = Robot/Crawler/Spider
    S = Spam Harvester, Bad Bot
    U = Unknown
    V = HTML/CSS/JS Validator
    X = Suspected Robot/Crawler/Spider

Sample Usage

lp_client_browser->(find:'browser');
lp_client_browser->(find:'version');
lp_client_browser->(find:'os');

(lp_client_browser: 'Mozilla/5.0 (X11; U; Linux i586; en-US; rv:1.6) Gecko/20040207 Firefox/0.8')->(find:'browser');

Source Code

Click the "Download" button below to retrieve a copy of this tag, including the complete documentation and sample usage shown on this page. Place the downloaded ".inc" file in your LassoStartup folder, restart Lasso, and you can begin using this tag immediately.

define_tag:'lp_client_browser',
	-description='Returns a map of the browswer name, browser version, browser type, and browser OS',
	-priority='replace',
	-optional='user_agent';

	// http://www.botsvsbrowsers.com/
	// http://www.quirksmode.org/js/detect.html
	// http://en.wikipedia.org/wiki/User_agent
	// http://browsers.garykeith.com/downloads.asp
	// http://www.pgts.com.au/pgtsj/pgtsj0212d.html
	// http://www.pgts.com.au/download/data/robots_list.txt
	// http://www.user-agents.org/index.shtml
	// http://www.robotstxt.org/wc/active/html/contact.html
	// http://www.jafsoft.com/searchengines/webbots.html
	// http://www.useragentstring.com/pages/useragentstring.php

	/* Browser types:
	B = Browser (Desktop)
	C = Link/Bookmark/Server Checker
	D = Download/FTP tool
	E = Email Reader
	F = Feed Reader
	L = Library
	M = Mobile Browser
	O = Offline Browsing
	P = Proxy, Web filter
	R = Robot/Crawler/Spider
	S = Spam Harvester, Bad Bot
	U = Unknown
	V = HTML/CSS/JS Validator
	X = Suspected Robot/Crawler/Spider
	*/

	if: local_defined:'user_agent';
		local:'client_browser' = #user_agent;
	else;
		local:'client_browser' = client_browser;
	/if;
	#client_browser->trim;

	if: #client_browser->size == 0;
		return: (map: 'browser' = 'No User Agent Provided', 'version' = '', 'os' = '', 'type' = 'Suspected Robot/Crawler/Spider', 'typecode' = 'X');
	/if;

	local:'return' = (map: 'browser' = '', 'version' = '', 'os' = '', 'type' = '', 'typecode' = '');


	//-------------------------------------------------------------------
	// browser
	//-------------------------------------------------------------------
	if: #client_browser->(beginswith:'mozilla/');

		iterate: $_lp_client_browser_mozilla, local:'browser';
			if: #client_browser->(contains:#browser->name);
				#return->(insert:'browser' = #browser->value->(get:1));
				#return->(insert:'typecode' = #browser->value->(get:2));
				
				// browser version
				local:'version' = #client_browser->(substring: #client_browser->(find: #browser->name) + #browser->name->size, 255);
				#version = (string_findregexp: #version, -find='\\d[^\\s;()\\]]*');
				if: #version->size;
					#return->(insert: 'version' = #version->(get:1));
				/if;

				// Safari version info for newer versions of Safari
				if: #return->(find:'browser') == 'Safari';
					local:'version' = #client_browser->(find: 'Version/');
					if: #version != 0;
						#version = #client_browser->(substring: #version + 7, 255);
						#version = (string_findregexp: #version, -find='\\d[^\\s;()\\]]*');
						if: #version->size;
							#return->(insert: 'version' = #version->(get:1));
						/if;
					/if;
				/if;

				loop_abort;
			/if;
		/iterate;	

		if: #return->(find:'browser')->size == 0; /// keep trying

			// handle mozilla and old netscape versions, the problem children
			if: !#client_browser->(contains:'compatible') && !#client_browser->(contains:'http') && !#client_browser->(contains:'@') && !#client_browser->(contains:'www');
				local:'mozver' = (string_findregexp: #client_browser, -find='\\d');
				if: #mozver->size;
					#mozver = (integer: #mozver->(get:1));
					if: #mozver < 5 && #client_browser->(contains:'[');
						// old Netscape
						#return->(insert: 'browser' = 'Netscape');
						#return->(insert:'typecode' = 'B');
						
						// browser version
						local:'version' = #client_browser;
						#version = (string_findregexp: #version, -find='\\d[^\\s;()\\]]*');
						if: #version->size;
							#return->(insert: 'version' = #version->(get:1));
						/if;

					else: #mozver == 5 && #client_browser->(contains:'gecko/') && #client_browser->(contains:'rv:');
						if: #client_browser->(split:'gecko/')->last->(split:' ')->size == 1;
							// mozilla
							#return->(insert: 'browser' = 'Mozilla');
							#return->(insert:'typecode' = 'B');
							
							// browser version
							local:'version' = #client_browser->(substring: #client_browser->(find: 'rv:') + 'rv:'->size, 255);;
							#version = (string_findregexp: #version, -find='\\d[^\\s;()\\]]*');
							if: #version->size;
								#return->(insert: 'version' = #version->(get:1));
							/if;

						/if;
						
					/if;

				/if;
			/if;

			// handle msie
			if: #client_browser->(contains:'compatible; MSIE') && !#client_browser->(contains:'http') && !#client_browser->(contains:'@') && !#client_browser->(contains:'www') && !#client_browser->(contains:'.com');
				if: #client_browser->(split:')')->last->size == 0;
					#return->(insert: 'browser' = 'Internet Explorer');
					#return->(insert:'typecode' = 'B');

					// browser version
					local:'version' = #client_browser->(substring: #client_browser->(find: 'MSIE') + 'MSIE'->size, 255);;
					#version = (string_findregexp: #version, -find='\\d[^\\s;()\\]]*');
					if: #version->size;
						#return->(insert: 'version' = #version->(get:1));
					/if;
				/if;
			/if;
		
		/if;

	
	else; // lots of possibilities

		iterate: $_lp_client_browser_other->(find:#client_browser->(get:1)), local:'browser';
			if: #client_browser->(beginswith:#browser->name);
				#return->(insert: 'browser' = #browser->value->(get:1));
				#return->(insert:'typecode' = #browser->value->(get:2));
				// browser version
				local:'version' = #client_browser->(substring: #client_browser->(find: #browser->name) + #browser->name->size, 255);
				#version = (string_findregexp: #version, -find='\\d[^\\s;()\\]]*');
				if: #version->size;
					#return->(insert: 'version' = #version->(get:1));
				/if;
				loop_abort;
			/if;
		/iterate;

	/if;

	//-------------------------------------------------------------------
	// os
	//-------------------------------------------------------------------
	local:'os' = (array:
	
								'android' = 'Android',
								'blackberry' = 'Blackberry',
								'iphone' = 'iPhone',
								'ipod' = 'iPod',
								'palm' = 'PalmOS',
								'symbian' = 'Symbian',
								'windows ce' = 'WinCE',
								
								'windows' = 'Windows',
								'win16' = 'Windows',
								'win32' = 'Windows',
								'win64' = 'Windows',
								'win95' = 'Windows',
								'win98' = 'Windows',
								'winNT' = 'Windows',

								'macintosh' = 'Macintosh',
								'darwin' = 'Macintosh',
								'panther' = 'Macintosh',
								'leopard' = 'Macintosh',
								'osx' = 'Macintosh',
								'os x' = 'Macintosh',
								'powerpc' = 'Macintosh',

								'linux' = 'Linux',
								'kanotix' = 'Linux',
								'ubuntu' = 'Linux',
								'mepis' = 'Linux',
								'debian' = 'Linux',
								'suse' = 'Linux',
								'redhat' = 'Linux',
								'red hat' = 'Linux',
								'slackware' = 'Linux',
								'mandrake' = 'Linux',
								'gentoo' = 'Linux',
								'fedora' = 'Linux',

								'solaris' = 'Unix',
								'unix' = 'Unix',
								'bsd' = 'Unix',
								'sun' = 'Unix',
								'irix' = 'Unix',
								'irix' = 'Unix',
								'hpux' = 'Unix',
								'hp-ux' = 'Unix',
								'aix' = 'Unix',
								'sco' = 'Unix',
								'mpras' = 'Unix',
								'reliant' = 'Unix',
								'dec' = 'Unix',
								'sinix' = 'Unix',

								'nintendo' = 'Nintendo',
								'wii' = 'Nintendo',
								'playstation' = 'PlayStation',
								'risc' = 'RISC OS',
								'amiga' = 'Amiga',
								'beos' = 'BeOS',
								'os2' = 'OS/2',
								'os/2' = 'OS/2',
								'webtv' = 'WebTV',
								'xbox' = 'Xbox',

							);

	iterate: #os, local:'o';
		if: #client_browser->(contains:#o->name);
			#return->(insert: 'os' = #o->value);
			loop_abort;
		/if;
	/iterate;



	//-------------------------------------------------------------------
	// if still unknown, see if it has a bot keyword
	//-------------------------------------------------------------------
	if: #return->(find:'typecode') == 'U' || #return->(find:'typecode') == '';
		local: 'bots' = (array:
							'agent',
							'archive',
							'bot',
							'check',
							'crawl',
							'creep',
							'feed',
							'fetch',
							'find',
							'get',
							'grub',
							'index',
							'info',
							'leech',
							'libwww',
							'link',
							'manage',
							'proxy',
							'robo',
							'search',
							'scrub',
							'seek',
							'siphon',
							'site',
							'slurp',
							'spider',
							'url',
							'valid',
							'worm',
		  				);
	
		iterate: #bots, (local: 'bot');
	    	if: #client_browser->(contains:#bot);
				#return->(insert:'browser' = 'Suspected Bot "'+#bot+'"');
				#return->(insert:'typecode' = 'X');
				loop_abort;
			/if;
		/iterate;
	/if;



	//-------------------------------------------------------------------
	// check if mobile browser
	//-------------------------------------------------------------------
	// http://mobiforge.mobi/developing/story/mobile-sites-with-joomla-cms?dm_switcher=true
	if('Android,Blackberry,iPhone,iPod,PalmOS,Symbian,WinCE' >> #return->find('OS'));
		#return->(insert:'typecode' = 'M');
	else(client_headers >> 'vnd.wap' || client_headers >> 'HTTP_X_WAP_PROFILE' || client_headers >> 'HTTP_PROFILE' || client_headers >> 'UA-pixels' || client_headers >> 'X-OperaMini');
		#return->(insert:'typecode' = 'M');
	/if;



	//-------------------------------------------------------------------
	// assign the type based on the typecode
	//-------------------------------------------------------------------

	select: #return->(find:'typecode');
		case:'B';
			#return->(insert:'type' = 'Browser');
		case:'C';
			#return->(insert:'type' = 'Link/Bookmark/Server Checker');
		case:'D';
			#return->(insert:'type' = 'Download/FTP tool');
		case:'E';
			#return->(insert:'type' = 'Email Reader');
		case:'F';
			#return->(insert:'type' = 'Feed Reader');
		case:'L';
			#return->(insert:'type' = 'Library');
		case:'M';
			#return->(insert:'type' = 'Mobile Browser');
		case:'O';
			#return->(insert:'type' = 'Offline Browsing');
		case:'P';
			#return->(insert:'type' = 'Proxy, Web filter');
		case:'R';
			#return->(insert:'type' = 'Robot/Crawler/Spider');
		case:'S';
			#return->(insert:'type' = 'Spam Harvester, Bad Bot');
		case:'U';
			#return->(insert:'type' = 'Unknown');
		case:'V';
			#return->(insert:'type' = 'HTML/CSS/JS Validator');
		case:'X';
			#return->(insert:'type' = 'Suspected Robot/Crawler/Spider');
		case;
			#return->(insert:'type' = 'Unknown');
			#return->(insert:'typecode' = 'U');
	/select;

	return: #return;
	
/define_tag;


// browsers with user agents that begin with "mozilla/"
!(global_defined:'_lp_client_browser_mozilla') ? (global:'_lp_client_browser_mozilla') = (array:

	// mobile browsers
	'iemobile' = (:'MSIE Mobile','M'),
	'Mobile Safari' = (:'Mobile Safari','M'),
	'Opera Mini' = (:'Opera Mini','M'),
	'Opera Mobi' = (:'Opera Mobi','M'),

	// Other browsers
	'icab' = (:'iCab','B'),
	'oregano' = (:'Oregano','B'),
	'amigavoyager' = (:'AmigaVoyager','B'),
	'ibrowse' = (:'IBrowse','B'),

	// email readers
	'thunderbird' = (:'Thunderbird','E'),
	'Mnenhy' = (:'Mnenhy Thunderbird Plug-in','E'),

	// proxies
	'BorderManager' = (:'Novell BorderManager','P'),	

	// link checkers
	'LinksManager.com' = (:'LinksManager.com','C'),
	'www.euro-directory.com' = (:'www.euro-directory.com','C'),
	'ZyBorg' = (:'ZyBorg','C'),

	// offline
	'MSIECrawler' = (:'MSIE Offline Favorites','O'),

	// robots
	'AbiLogicBot' = (:'AbiLogicBot','R'),
	'AnyApexBot' = (:'AnyApexBot','R'),
	'Arachmo' = (:'Arachmo','R'),
	'Ask Jeeves' = (:'Ask Jeeves','R'),
	'BecomeBot' = (:'BecomeBot','R'),
	'B-l-i-t-z-B-O-T' = (:'BlitzBOT','R'),
	'BlitzBOT' = (:'BlitzBOT','R'),
	'B_L_I_T_Z_B_O_T' = (:'BlitzBOT','R'),
	'Cerberian Drtrs' = (:'Cerberian Drtrs','R'),
	'FDSE robot' = (:'FDSE robot','R'),
	'Fluffy the spider' = (:'www.searchhippo.com','R'),
	'FurlBot' = (:'FurlBot','R'),
	'Girafabot' = (:'Girafabot','R'),
	'Googlebot' = (:'Googlebot','R'),
	'grub-client' = (:'grub.org','R'),
	'HTTrack' = (:'HTTrack offline browser utility','O'),
	'Larbin' = (:'Larbin','R'),
	'MojeekBot' = (:'MojeekBot','R'),
	'MuscatFerret' = (:'MuscatFerret','R'),
	'Paros' = (:'Paros','R'),
	'scan4mail' = (:'scan4mail anti-spam tool','C'),
	'Scrubby' = (:'Scrubby','R'),
	'SEOChat::Bot' = (:'SEOChat::Bot','R'),
	'Shoula robot' = (:'Shoula robot','R'),
	'slurp@inktomi' = (:'inktomi.com','R'),
	'Teoma' = (:'Ask Jeeves','R'),
	'VoilaBot' = (:'VoilaBot','R'),
	'Vonna.com' = (:'Vonna.com','R'),
	'www.galaxy.com'  = (:'Galaxy.com','R'),
	'Yahoo! Slurp' = (:'Yahoo!','R'),
	'YahooSeeker' = (:'Yahoo!','R'),
	'Zealbot' = (:'Zealbot','R'),

	// spam bots
	'Indy Library' = (:'Delphi/C++ library used mostly by Asian spammers','S'),

	// Gecko browsers
	'iceweasel' = (:'Iceweasel','B'),
	'flock' = (:'Flock','B'),
	'epiphany' = (:'Epiphany','B'),
	'beonex' = (:'Beonex','B'),
	'camino' = (:'Camino','B'),
	'chimera' = (:'Chimera','B'),
	'galeon' = (:'Galeon','B'),
	'k-meleon' = (:'K-Meleon','B'),
	'k-ninja' = (:'K-Ninja','B'),
	'kazehakase' = (:'Kazehakase','B'),
	'kapiko' = (:'Kapiko','B'),
	'iceape' = (:'Iceape','B'),
	'multizilla' = (:'MultiZilla','B'),
	'netscape' = (:'Netscape','B'),
	'seamonkey' = (:'SeaMonkey','B'),
	'bonecho' = (:'Firefox','B'),
	'firebird' = (:'Firefox','B'),
	'phoenix' = (:'Firefox','B'),
	'granparadiso' = (:'Firefox','B'),
	'minefield' = (:'Firefox','B'),
	'firefox' = (:'Firefox','B'),
	// netscape and mozilla handled below

	// MSIE browsers
	'america online' = (:'AOL','B'),
	'aol' = (:'AOL','B'),
	'opera' = (:'Opera','B'),
	'avant' = (:'Avant','B'),
	'crazy browser' = (:'Crazy Browser','B'),
	'maxthon' = (:'Maxthon','B'),
	'netcaptor' = (:'NetCaptor','B'),
	'myie2' = (:'MyIE2','B'),
	// msie handled as special case

	// KHTML browsers
	'konqueror' = (:'Konqueror','B'),
	'shiira' = (:'Shiira','B'),
	'omniweb' = (:'OmniWeb','B'),
	'cheshire' = (:'Cheshire','B'),
	'netnewswire' = (:'NetNewsWire','B'),
	'sunrise' = (:'Sunrise','B'),
	'chrome' = (:'Chrome','B'),
	'safari' = (:'Safari','B'),

);


// browsers with user agents that don't begin with "mozilla/"
!(global_defined:'_lp_client_browser_other') ? (global:'_lp_client_browser_other') = (map:
	'!' = (array:
		'!Susie' = (:'!Susie','C'),
		),
	'&' = (array:
		' UnChaosBot' = (:'UnCHAOS search robot','R'),
		'
		

Comments

30 Jan 2008, Johan Solve

Correction

After realizing that the browser config variables should be globals instead of vars or locals (so they don't have to be defined each time), execution time without cache is now 5-6 ms compared to 2-4 ms with cache. In other words, not much to gain with the caching. I'm withdrawing my suggested changes.

30 Jan 2008, Johan Solve

Small adjustments [trying better formatting]

I moved the browser profile config vars into the ctag (and changed them to locals) to make it more self-contained (also seems slightly faster actually), and I also added caching in a global (limited to 10000 entries) so client_browsers we have seen before will have the info returned immediately without further processing. Cached client types are returned in 2-3ms instead of 75-80ms on my MacBook.



Code additions for the cache (it would also need thread locking to be completely safe) --

near the beginning:

if: (global: '_lp_client_browser_cache') >> #client_browser;

return: $_lp_client_browser_cache -> find(#client_browser);

/if;



and near the end:



!(global: '_lp_client_browser_cache') -> isa('map') ? global: '_lp_client_browser_cache' = map;

if: $_lp_client_browser_cache -> size < 10000 && $_lp_client_browser_cache !>> #client_browser;

$_lp_client_browser_cache -> insert(#client_browser = #return);

/if;



return: #return;

30 Jan 2008, Johan Solve

Small adjustments

I moved the browser profilee config vars into the ctag (and changed them to locals) to make it more self-contained (also seems slightly faster actually), and I also added caching in a global (limited to 10000 entries) so client_browsers we have seen before will have the info returned immediately without further processing. Cached client types are returned in 2-3ms instead of 75-80ms on my MacBook.

Code additions for the cache (it would also need thread locking to be completely safe) --
near the beginning:
if: (global: '_lp_client_browser_cache') >> #client_browser;
return: $_lp_client_browser_cache -> find(#client_browser);
/if;

and near the end:

!(global: '_lp_client_browser_cache') -> isa('map') ? global: '_lp_client_browser_cache' = map;
if: $_lp_client_browser_cache -> size < 10000 && $_lp_client_browser_cache !>> #client_browser;
$_lp_client_browser_cache -> insert(#client_browser = #return);
/if;

return: #return;

Please log in to comment

Subscribe to the LassoTalk mail list

LassoSoft Inc. > Home

 

 

©LassoSoft Inc 2015 | Web Development by Treefrog Inc | PrivacyLegal terms and Shipping | Contact LassoSoft