browscap.ini Zugriff über Pascal

Identifizieren des Browsers mit Samt seiner Eigenschaften ist eine tolle Sache, eine lange Zeit lief in Sachen "browscap.ini" nicht mehr viel, doch nun ist das Projekt unter browscap.org zu neuem Leben erwacht und ist wieder "up to date".
Um fehlende User Agents zu melden steht bei GitHub eine Seite zur Verfügung https://github.com/browscap/browscap/issues
Das Team um Thomas Müller und James Titcumb liefern da richtig gute Arbeit!

Identify the Browser an its properties is a good thing, for a long time nothing happens in terms of "browscap.ini", but now the project was awakened to new life. To report any missing user agents join GitHub https://github.com/browscap/browscap/issues .
The team led by Thomas Müller and James Titcumb are making a really good job!

Es gibt zahlreiche Beispiele im Netz um den User Agent des Client-Programms zu ermitteln, es existieren teilweise riesige Tabellen mit Bestandteilen an denen festzustellen sein soll welcher Client es wohl ist der da gerade zugreift. Da allerdings die Anzahl der Clients ständig wächst bedürfen diese Listen ein Ständigen Kontrolle. Einen bewährtes Vorgehen ist das Analysieren des User Agent mit Hilfe einer Methode die bereits seit sehr langer Zeit existiert, die Anwendung der browscap.ini Datei!

There are a lot of programs in all the diferent networks to detect the properties of the client program, mostly there are some huge tables with constituents that should be able to identify the client which is probably the currently accessing there. However, since the number of clients is constantly growing these lists needs a permanent control. A proven approach is to analyze the user agent string by using a method that has been used for a very long time, the browscap.ini file!

Für zahlreiche Systeme existieren bereits Möglichkeiten diese INI zu nutzen, nichts desto Trotz bedarf es aber auch manchmal einer speziellen Lösung. PHP stellt eine native Funktion get_browser() zur Verfügung, die allerdings nicht mehr genutzt werden sollte, stattdessen sollte ein ein Ersatz Browscap-PHP heruntergeladen werden. Für ASP gibt es die browscap.dll (MSWC.BrowserType component) und meines Wissens auch die eine oder andere kommerzielle Lösung, auf die ich an dieser Stelle allerdings nicht eingehen geschweige denn das ich sie empfehlen möchte!

For many systems there already exists a ways to use this INI, but sometimes a special solution is needed.
PHP provides a native function get_browser() which should no longer be used but instead a replacement Browscap-PHP can be downloaded. For ASP, there exists a Browscap.dll (MSWC.BrowserType component) and as I know some other commercial solutions, but at this point I doesn't want to go into it or recommend it!

Der Nachteil der Entwicklung einer Komponente in einer Script-Sprache ist zu meist die Geschwindigkeit und unter Umständen die Ressourcenhungrigkeit, wenn also eine häufig angewandte Methode kompiliert zur Verfügung steht und wenn möglich die Ressourcen an die Applikation und nicht an einen Prozess gebunden sind kann das zu einer gravierenden Zeitersparnis führen. Da aber genau dieses bei stark frequentierten Websites der Fall ist, habe ich diesen Vorgang in den ISAPI-Filter verlegt und kopiere die ermittelten Daten direkt in das Session-Objekt, wo sie dann für die komplette Session zur Verfügung stehen.

The disadvantage of the development of a component in a scripting language is usually the performance loss and possibly the used memory size, so if a frequently used method is available in a compiled version and further if the resources are attached to the application and not to a process, then that can be a serious time saver. Exactly this is the case why I have moved this process in an ISAPI filter and copy the data obtained directly in the Session object, where they are available for the entire session, especially for Websites with much traffic.

browscap.pas

Nun als Beispiel eine fertige Routine zum Testen der Zeit, die CriticalSection  ist zwar nicht erforderlich, aber da sie in der Servererweiterung auch erforderlich ist, habe ich sie direkt erhalten.

Now an Example of the usage of the Class to check the performance, the CriticalSection is not used for this Example but in the server extension it is used.

browscap.lpr

Und nun die Ausgabe, an ihr ist ganz einfach zu erkennen, das es nur Sinn macht die Full Version der browscap.ini zu nutzen wenn der eigentliche Index erhalten bleiben kann, das Laden der INI-Datei in das INI-Object und das Sortieren der Section-Liste schlägt mit satten 1123 ms zu Buche. Natürlich ist seit Kurzen auch das finden des passenden Eintrags schwerer geworden da gerade in letzter Zeit die Anzahl der Sektionen auf weit über 50.000 gestiegen ist. 32 ms hört sich nicht so schlimm an, aber auf stark frequentierten Servern kann das zu erheblichen Problemen führen.

In den letzten Optimierungen wurden Regular Expressions entfernt, eine Quicksort Routine eingesetzt, an Stelle der TStringList eigenen CustomSort Variante, das ist nicht so schön aber insgesamt ergab es eine enorme Zeitersparnis!

time read browscap.ini: 1123 ms
time to getValues: 32 ms
Comment=Firefox 28.0
Browser=Firefox
Browser_Type=Browser
Browser_Bits=32
Browser_Maker=Mozilla Foundation
Browser_Modus=
Version=28.0
MajorVer=28
MinorVer=0
Platform=Win7
Platform_Version=6.1
Platform_Description=Windows 7
Platform_Bits=64
Platform_Maker=Microsoft Corporation
Alpha=false
Beta=false
Win16=false
Win32=false
Win64=true
Frames=true
IFrames=true
Tables=true
Cookies=true
BackgroundSounds=false
JavaScript=true
VBScript=false
JavaApplets=true
ActiveXControls=false
isMobileDevice=false
isTablet=false
isSyndicationReader=false
Crawler=false
CssVersion=3
AolVersion=0
Device_Name=Windows Desktop
Device_Maker=Various
Device_Type=Desktop
Device_Pointing_Method=mouse
Device_Code_Name=Windows Desktop
Device_Brand_Name=unknown
RenderingEngine_Name=Gecko
RenderingEngine_Version=28.0
RenderingEngine_Description=For Firefox, Camino, K-Meleon, SeaMonkey, Netscape,
and other Gecko-based browsers.
RenderingEngine_Maker=Mozilla Foundation
Parent=Firefox 28.0
time to close browscap.ini: 141 ms

 Das nutzen dieser Routine in einem ActiveX Objekt, in einer ASP-Komponente wie der browscap.dll oder auch einem CGI macht daher nicht wirklich Sinn. Das Erstellen eines ISAPI-Filters oder eines Apache-Modules hingegen würde sich anbieten da in diesen Fällen die vorbereiteten Daten immer wieder genutzt werden können. Des weiteren sollten die ermittelten Werte dann in Session-Variablen gespeichert werden, damit sie nicht immer wieder bei erneuten zugriffen ermittelt werden müssen.

In meinem Auftritt also hier nutze ich dann auch noch eine optimierte Liste und nicht die Standard TStringList von Object-Pascal, leider wird der Geschwindigkeitsgewinn durch ausgiebige Überprüfungen und Logging aufgefressen, aber nur dadurch ist das Aufspüren von Fehlern möglich, siehe browscap.ini issues.