I. Introduction

L'environnement de développement Delphi permet un débogage aisé des applications Desktop, en revanche la tâche est plus ardue lorsqu'il s'agit d'applications web. Je vais expliquer et mettre en pratique une méthode de débogage d'applications ISAPI sous W2000/XP.

Petit rappels sur la définition d'une ISAPI : Internet Server Application Programming Interface. Cette interface a été conçue par Microsoft pour que son serveur web IIS (Internet Information Server) puisse déléguer la prise en charge d'une requête http à une application extérieure. On parle alors de génération de pages web dynamiques.

Quels sont les comportements possibles d'un serveur web lorsqu'il reçoit une requête à traiter ? Soit l'url est une ressource fixe localisable par le serveur web (généralement une page web html), auquel cas ce dernier la transmet en réponse (page statique). Si cette url ne contient pas de ressource spécifique à récupérer, c'est qu'elle comporte probablement des informations indiquant qu'une application tierce doit se charger de générer la page web : le serveur délègue alors le traitement de la requête http à cette application.

Exemple d'une url désignant une ressource spécifique localisable :

  • http://www.developpez.com/delphi/article_sylvain.html

Exemple d'une url qui va être prise en charge par une application tierce respectant l'api isapi :

  • http://msdn.microsoft.com/search.dll?keywords=toto

L'application ISAPI est une dll qui exporte des méthodes imposées (GetExtensionVersion, HttpExtensionProc et TerminateExtension). HttpExtensionProc est la méthode qui doit retourner la réponse http. A charge du développeur de la dll. Pour cela il dispose en paramètre d'un bloc de données relatives à la requête.

C'est tout le code interne à cette dll que nous souhaitons pouvoir déboguer. De la prise en charge de la requête jusqu'à la fourniture de la réponse.

II. Différents Types d'applications ISAPI

Développer une dll isapi en implémentant une méthode HttpExtensionProc revient à travailler à plutôt bas niveau, c'est à dire proche du système d'exploitation. C'est pour cela que Borland avait créé WebBroker puis Websnap qui sont deux frameworks isapi fournissant des services au développeur (création d'objets d'application, gestion login, génération simplifiée de pages web etc.), le deuxième étant plus évolué - et plus complexe - que le premier.

Le framework de développement web autour d'une ISAPI le plus avancé que je connaisse est XMLCLX issus de l'environnement de développement XMLRAD (http://xmlrad.com). Les frameworks dont je viens de parler ont été développés avec Delphi, on peut donc les déboguer avec la technique que nous allons voir.

Autre exemple : vous connaissez probablement PHP. Il est possible d'installer une distribution de PHP de type ISAPI. L'interpréteur PHP est compilé dans une DLL ISAPI; cette DLL récupère la requête http, exécute l'interprétation php puis retransmet le flux résultat au serveur web. Par contre, je n'ai pas vérifié mais il est probable que cette ISAPI soit écrite en C++ et qu'elle ait été compilée avec gcc. Si la compil peut-être effectuée avec CBuilder alors notre technique de débogage marchera tout aussi bien. Il serait alors possible de rentrer dans les arcanes de l'interpréteur PHP...

III. Projet exemple

Créez une application serveur web ISAPI. Si vous n'avez jamais touché à ce domaine de développement, le tutorial suivant devrait vous lancer sur la voie : (http://jplamon.developpez.com/isapi/ ) (allez aussi faire un tour sur www.delphicenter.net qui propose des infos et héberge des isapi).

Copiez la dll générée dans un répertoire IIS qui en Autorisation d'exécution indique : scripts et exécutables. En général, le répertoire \inetpub\scripts est configuré ainsi :

Image non disponible

Assurez vous de spécifier la Protection d'application à : Elevée (Isolé). Même si vous ne voulez pas que votre site en production repose sur ce modèle de protection, il est possible de le changer à tout moment. Que se passe-t-il quand on choisit une protection élevée ? Windows crée un composant COM+, qui exécutera l'application (la dll isapi) dans un espace mémoire protégé, indépendant de l'espace mémoire de IIS. En plus, cette application pourra profiter des services offerts par COM+.

IV. Paramétrage COM+

Il n'y a pas grand chose à vérifier dans les propriétés du composant COM+. Il faut récupérer le ProcessID (identifiant de composant COM+) pour l'indiquer à Delphi. Ouvrez le Panneau de configuration, puis Outils d'administration et enfin choisissez Services de Composants. Vous allez obtenir l'écran suivant :

Image non disponible

Ne vous inquiétez pas si la liste d'applications COM+ n'est pas la même sur votre écran que celle présentée dans ce tutorial. Peut importe, il faut juste localiser l'application Scripts :

Image non disponible

Dans l'écran de propriétés, nous allons vérifier que l'utilisateur pouvant exécuter l'application COM+ est bien l'utilisateur interactif (onglet Identité). Cela nous évitera d'être confronté à des problèmes d'autentification. Ensuite nous allons copier dans le presse papier le ProcessID de l'application (onglet Général) :

Image non disponible
Image non disponible

V. Côté Delphi...

L'étape suivante va nous amener à configurer Delphi pour le débogage de cette application. Très simple, ouvrez le menu Exécuter / Paramètres :

Image non disponible

Le champ Application hôte doit indiquer l'emplacement de l'exécutable dllhost.exe

Cet exécutable est fourni par Windows et se trouve normalement dans \WinNT\System32, mais si vous tournez avec Windows XP (cas particulier par rapport à W2000), alors effectuez une copie de dllhost.exe vers le dossier dans lequel est placée votre dll isapi.

Le champ Paramètres doit indiquer le ProcessID de l'application. Respectez la syntaxe visible sur le screenshot, et rappelez vous que vous venez de stocker l'ID dans le presse papier. CTRL V fera votre affaire :-)

Voilà, votre dll isapi est prête au débogage. D'autres méthodes existent, notamment désigner inetinfo comme application hôte (méthode préconisée lorsque vous êtes en protection d'application basse). A vous d'essayer et de conserver ce qui vous semble le plus simple et efficace.

VI. Enfin Déboguer !

Pour déboguer l'application, posez des points d'arrêts dans le code source. Et ensuite, exécutez l'application (F9). Attention il est important que ce soit Delphi qui soit à l'origine du chargement de la dll, ensuite seulement vous pouvez ouvrir le navigateur internet de votre choix (mozilla c'est bien ;-) et invoquer les url de votre application. Normalement, l'application s'arrêtera sur vos points d'arrêts.

VII. Check-up en cas de problèmes éventuels

Il peut arriver que Delphi ne s'arrête pas sur les points d'arrêts comme prévu. J'ai pu identifier plusieurs causes possibles qui auront toutes la même solution :

  1. La dll était déjà montée en mémoire, car une url avait été invoquée par mon navigateur web avant que je n'exécute l'application à partir de Delphi.
  2. Le pas à pas fonctionne mais une exception est déclenchée. Parfois, à la requête suivante, le débogage ne fonctionne plus.
  3. Dans le même esprit, au bout d'un temps déterminé (cf Délai d'expiration du composant COM+), le débogage ne fonctionne plus. Pour les points 2. et 3., je pense que cela est du à la fonctionnalité COM+ de recyclage de processus, qui consiste à relancer une nouvelle instance de dllhost quand certains critères sont rencontrés. Pour le point 3. il est aisé d'augmenter le délai d'expiration.
  4. Le ProcessID n'est pas le bon car au fur et à mesure du temps, on peut avoir créé plusieurs instances de composant COM+ sur la même application (sur le même répertoire virtuel IIS). Il faut alors les supprimer de manière à ce qu'un seul ne reste et travailler avec son ProcessID respectif. Attention, le menu de suppression d'un composant COM+ n'est pas accessible par défault, il faut au préalable le permettre dans les propriétés de ce même composant (onglet Avancé, cadre Protection, décocher "Désactiver les suppressions").

Solution:

Dans tous les cas cités, il suffit de redémarrer les services internet server (menu Démarrer / Exécuter / iisreset), et ensuite de relancer l'application avec Delphi, et tout fonctionne parfaitement.

Nous voilà arrivés au terme de ce tutorial, j'espère que c'était compréhensible et que vos points d'arrêts seront vénérés :-)) N'hésitez à m'adresser vos remarques, compléments et suggestions d'amélioration de cet articles. A bientôt !