1 Introduction
L’objectif de cet article est de présenter la création d’un HTTPHandler simple en Visual Basic .NET.
Les HTTPHandlers offrent une manière simple d’intercepter l’ensemble des Requêtes/Réponses des sessions utilisateurs en cours. Par certains côtés, les HTTPHandlers ressemblent aux filtres ISAPI.
En quoi un HTTPHandler peut-il nous aider au niveau d’un site Web ? Voici quelques exemples où un HTTPHandler serait utile :
· Redirection d’URL en cas de changement complet de l’arborescence d’un site Web,
· Tracer les accès à certaines ressources,
· Créer des ressources virtuelles n’ayant aucune existence physique,
· Mettre en place une sécurité spécifique lors de l’accès à une ressource d’un site,
· Traiter de nouvelles extensions non reconnues à la base par la runtime HTTP,
· Etc.
Bref, comme vous pouvez le constater les applications ne manquent pas. Je vous propose d’entrer dans le vif du sujet dans le prochain chapitre.
2 Un peu de théorie
Les HTTPHandler nous offrent un mécanisme simple pour intercepter l’ensemble des requêtes utilisateur faites sur un site Web afin de réaliser des opérations spécifiques à vos applications.
Lorsque IIS reçoit une requête HTTP, il transfère la demande au Worker Process ASP.NET. La Runtime HTTP se charge ensuite de créer l’instance de la bonne HTTP Application. Cette dernière permet ensuite d’exécuter les HTTP Modules par défaut (état, etc.), ainsi qu’éventuellement les vôtres. Une fois que l’ensemble des HTTP Modules ont réalisé leurs opérations, l’HTTP Application se charge de la création des HTTP Handlers. Enfin, les événements de la page demandée sont finalement exécutés (Code Behind).
Voici donc les étapes logiques pour créer un HTTPHandler :
1. Création d’une classe qui implémente l’interface IHTTPHandler,
a. Implémentation de la méthode « ProcessRequest » pour le traitement spécifique. Cette dernière recevra en paramètre l’ensemble des informations concernant la requête en elle-même, mais aussi la session utilisateur en cours,
b. Implémentation de la propriété « IsReusable » qui permet de spécifier si une même instance de notre HTTPHandler pourra servir une autre requête du même type.
Notez au passage que la classe de base « Page », dont héritent tous les formulaires Web, implémente l’interface IHTTPHandler.
2. Compilation de l’assembly (éventuellement la signer),
3. Paramétrage du nouvel HTTPHandler au niveau du site souhaité (Web.config) ou au niveau de la machine (machine.config). L’opération consiste à « mapper », le chemin à intercepter (fichier, répertoire) pour un certain type de verbes HTTP (GET, POST, ALL) et d’y associer l’assembly précédemment définie,
4. Enfin, si votre HTTPHandler intercepte de nouvelles extensions, il faudra définir au niveau IIS que l’extension devra être traitée par le filtre ASP.NET, pour les verbes définis en paramètre.
L’exemple que je me propose de développer est simple. Il s’agit de mettre en place un mécanisme de comptabilisation (dans une base SQL Server 2000) des fichiers « *.zip » et « *.doc » téléchargés sur un site web donné.
3.1 La base de données
Elle est des plus simples : une seule table, avec :
· Le nom du fichier téléchargé,
· Le nombre de téléchargements pour ce fichier,
· La date du dernier téléchargement.

Une procédure stockée pour l’ajout/modification en base :
· « sInsertDownloadTracker »
3.2 Les classes
Voici le diagramme représentant le HTTPHandler créé dans l’exemple :

Au sein de la méthode « ProcessRequest », les étapes de traitement sont les suivantes :
1. Récupération du chemin physique à partir du chemin virtuel de la ressource demandée par le client,
2. Ouverture du flux en lecture seule et chargement en mémoire,
3. Récupération du ContentType du fichier demandé par le client en fonction de son extension (interrogation de IIS://localhost/MimeMap via « System.DirectoryServices »). Mise en cache dans une variable application de la collection des « ContentType » définis au niveau IIS,
4. Changement du ContentType de la requête utilisateur en fonction de celui du fichier,
5. Ecriture du binaire du fichier demandé dans la réponse renvoyée au client,
6. Création (si besoin) et Incrémentation en base du compteur historique. Pour cela utilisation de la classe « Bewise.Data »,
7. Fermeture du flux dans le « Finally ».
3.3 Le fichier de configuration
Voici les balises ajoutées (dans la balise « system.web ») au fichier de configuration afin d’assurer le traitement des extension « *.doc » et « *.zip » :
<HTTPHandlers>
<add
verb="*" path="*.zip"
type="Bewise.HTTPHandler.DownloadTrackerHTTPHandler, Bewise.HTTPHandler" />
<add
verb="*" path="*.doc" type="Bewise.HTTPHandler.DownloadTrackerHTTPHandler, Bewise.HTTPHandler" />
</HTTPHandlers>
3.4 Enregistrement IIS
Une étape supplémentaire consiste à préciser à IIS (répertoire virtuel correspondant ou site complet), que de nouvelles extension (*.doc et *.zip) doivent être traitées par le filtre ISAPI ASP.NET. Voici un exemple pour l’extension « *.doc » :

4 Conclusion
Dans cet exemple, je vous ai fait découvrir la notion d’HTTP Handler. Je vous ai aussi montré la réelle simplicité pour en créer un.
Bien entendu, l’exemple fourni peut être amélioré, notamment sur les points suivants :
· L’exemple utilise une assembly appelée Bewise.dll, dont seul le binaire a été fourni. Toutefois, il serait relativement simple de remplacer les quelques appels à cette assembly par le Building Block Data de Microsoft pour gérer l’accès aux données,
· Signer le projet « Bewise.HTTPHandler »,
· Ajouter une gestion des erreurs cohérentes dans le projet « Bewise.HTTPHandler »,
· La méthode « GetContentType » (classe « DownloadTrackerHTTPHandler ») verrouille l’accès aux informations via l’objet Application (Lock et Unlock). Il serait intéressant de mettre en place un verrouillage avec un moniteur (Monitor.Enter, Monitor.Exit). D’ailleurs, ce verrouillage devrait être positionné avant la déclaration de la variable « ht » de type « HashTable »,
· Il est aussi possible d’externaliser le requêtage aux types Mime (définis au niveau IIS) dans une classe dédiée pour des raisons d’encapsulation et de réutilisation,
· Je me doute que le contenu de la procédure stockée « sInsertDownloadTracker » risque d’énerver plus d’un architecte, aussi je prends les devants ! Une règle métier est codée dedans : ce n’est vraiment pas bien !. De plus, il n’y a pas de transaction (ni au niveau composant, ni au niveau de la procédure stockée), mais l’objectif de l’article était de présenter un exemple simple d’HTTPHandler !