\documentclass[a4paper, 11pt]{article}
\renewcommand{\familydefault}{\sfdefault}
\usepackage{a4wide}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage{color}
\usepackage{graphicx}
\usepackage{setspace}
\usepackage{ulem}
\usepackage{listings}
\usepackage{float}
\usepackage[rflt]{floatflt}
\usepackage{tabularx}
\setlength{\parindent}{0pt}
\title{Browscap}
\usepackage[
pdftitle={Browscap}
pdfsubject={Ermittlung der Browser Eigenschaften anhand des User Agent Strings mit Hilfe von browscap.ini programmiert in Free Pascal}
pdfauthor={Udo Schmal}
pdfkeywords={browscap, browscap.ini, browscap.pas, Free Pascal, Delphi, Browsererkennung}
]{hyperref}
\definecolor{darkblue}{rgb}{0,0,.5}
\hypersetup{pdftex=true, colorlinks=true, breaklinks=true, linkcolor=darkblue, menucolor=darkblue, pagecolor=darkblue, urlcolor=darkblue}
\begin{document}Browscap
\singlespacing
{\LARGE \textbf{\label{sec:title}browscap.ini Zugriff über Pascal}}

Identifizieren des Browsers mit Samt seiner Eigenschaften ist eine tolle Sache, eine lange Zeit lief in Sachen \&quot;browscap.ini\&quot; nicht mehr viel, doch nun ist das Projekt unter \href{https://browscap.org}{browscap.org} zu neuem Leben erwacht und ist wieder \&quot;up to date\&quot;. \newline
Um fehlende User Agents zu melden steht bei GitHub eine Seite zur Verfügung \href{https://github.com/browscap/browscap/issues}{https://github.com/browscap/browscap/issues}\newline
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 \&quot;browscap.ini\&quot;, but now the project was awakened to new life. To report any missing user agents join GitHub \href{https://github.com/browscap/browscap/issues}{https://github.com/browscap/browscap/issues} .\newline
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! \newline


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 \href{https://github.com/browscap/browscap-php}{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.\newline
PHP provides a native function get\_browser() which should no longer be used but instead a replacement \href{https://github.com/browscap/browscap-php}{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. \newline


\href{https://www.gocher.me/code/browscap.pas}{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.\newline


\href{https://www.gocher.me/code/browscap.lpr}{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!\newline

\begin{lstlisting}[breaklines]time read browscap.ini: 1123 ms\newline
time to getValues: 32 ms\newline
Comment=Firefox 28.0\newline
Browser=Firefox\newline
Browser\_Type=Browser\newline
Browser\_Bits=32\newline
Browser\_Maker=Mozilla Foundation\newline
Browser\_Modus=\newline
Version=28.0\newline
MajorVer=28\newline
MinorVer=0\newline
Platform=Win7\newline
Platform\_Version=6.1\newline
Platform\_Description=Windows 7\newline
Platform\_Bits=64\newline
Platform\_Maker=Microsoft Corporation\newline
Alpha=false\newline
Beta=false\newline
Win16=false\newline
Win32=false\newline
Win64=true\newline
Frames=true\newline
IFrames=true\newline
Tables=true\newline
Cookies=true\newline
BackgroundSounds=false\newline
JavaScript=true\newline
VBScript=false\newline
JavaApplets=true\newline
ActiveXControls=false\newline
isMobileDevice=false\newline
isTablet=false\newline
isSyndicationReader=false\newline
Crawler=false\newline
CssVersion=3\newline
AolVersion=0\newline
Device\_Name=Windows Desktop\newline
Device\_Maker=Various\newline
Device\_Type=Desktop\newline
Device\_Pointing\_Method=mouse\newline
Device\_Code\_Name=Windows Desktop\newline
Device\_Brand\_Name=unknown\newline
RenderingEngine\_Name=Gecko\newline
RenderingEngine\_Version=28.0\newline
RenderingEngine\_Description=For Firefox, Camino, K-Meleon, SeaMonkey, Netscape,\newline
and other Gecko-based browsers.\newline
RenderingEngine\_Maker=Mozilla Foundation\newline
Parent=Firefox 28.0\newline
time to close browscap.ini: 141 ms\newline
\end{lstlisting}

 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 \href{https://www.gocher.me/browscap-ini-issues}{browscap.ini issues}.\newline

\end{document}