Procédure pas à pas : création d’un module HTTP Request-Level à l’aide de code natif

Cette procédure pas à pas montre comment utiliser C++ pour créer un exemple de module HTTP au niveau de la demande qui implémente la nouvelle architecture de traitement des demandes dans IIS 7. Cette nouvelle architecture étend les fonctionnalités de programmation de code natif lorsque vous écrivez des applications IIS sur des versions antérieures de ASP.NET modules HTTP et des filtres ou extensions ISAPI. Pour plus d’informations sur la conception de modules HTTP à l’aide de la nouvelle architecture de traitement des requêtes, consultez Conception Native-Code modules HTTP.

Dans cette procédure pas à pas, vous allez créer un projet C++ pour votre module HTTP, ajouter le code requis pour un projet « Hello World », puis compiler et tester le module.

Prérequis

Le logiciel suivant est requis pour effectuer les étapes de l’exemple :

  • IIS 7.

  • Visual Studio 2005 :

  • Kit de développement logiciel (SDK) Windows.

    Note Vous pouvez utiliser Visual Studio .NET 2003 ou une version antérieure, bien que les étapes pas à pas ne soient pas identiques.

Création du module

Dans cette partie de la procédure pas à pas, vous allez créer un projet DLL C++ vide pour votre module HTTP.

Pour créer un projet DLL C++

  1. Ouvrez Visual Studio 2005.

  2. Vérifiez que les options globales ont tous les chemins d’accès appropriés aux fichiers include du SDK :

    1. Dans le menu Outils , cliquez sur Options.

    2. Développez le nœud Projets et solutions dans l’arborescence, puis cliquez sur Répertoires VC++.

    3. Dans la zone de liste déroulante Afficher les répertoires pour , sélectionnez Inclure des fichiers.

    4. Vérifiez que le chemin d’accès où vous avez installé les fichiers include du SDK Windows est répertorié. Si le chemin d’accès n’est pas répertorié, cliquez sur l’icône Nouvelle ligne , puis ajoutez le chemin d’accès où vous avez installé les fichiers include du SDK. Le répertoire d’installation par défaut est $(VCInstallDir)PlatformSDK\bin.

    5. Cliquez sur OK.

  3. Créez un projet C++ :

    1. Dans le menu Fichier , pointez sur Nouveau, puis cliquez sur Projet.

      La boîte de dialogue Nouveau projet s’affiche.

    2. Dans le volet Types de projets, développez le nœud Visual C++ , puis cliquez sur Win32.

    3. Dans le volet Modèles , sélectionnez Projet Win32.

    4. Dans la zone Nom , tapez HelloWorld.

    5. Dans la zone Emplacement , tapez le chemin d’accès de l’exemple.

    6. Cliquez sur OK.

      L’Assistant Application Win32 s’ouvre.

    7. Cliquez sur Paramètres de l’application.

    8. Sous Type d’application, cliquez sur DLL.

    9. Sous Options supplémentaires, cliquez sur Projet vide.

    10. Cliquez sur Terminer.

Ajout du code et des fichiers sources

L’étape suivante consiste à ajouter les fichiers C++ et de définition de module requis au projet.

Pour ajouter les fichiers sources au projet

  1. Créez le fichier de définition de module pour exporter la fonction RegisterModule :

    1. Dans Explorateur de solutions, cliquez avec le bouton droit sur Fichiers sources, pointez sur Ajouter, puis cliquez sur Nouvel élément.

      La boîte de dialogue Ajouter un nouvel élément s’ouvre.

    2. Développez le nœud Visual C++ dans le volet Catégories , puis cliquez sur Code.

    3. Dans le volet Modèles , sélectionnez le modèle Fichier de définition de module .

    4. Dans la zone Nom , tapez HelloWorld et laissez le chemin d’accès par défaut du fichier dans la zone Emplacement .

    5. Cliquez sur Add.

    6. Ajoutez une ligne avec EXPORTS et RegisterModule. Votre fichier doit ressembler au code ci-dessous :

      LIBRARY"HelloWorld"  
      EXPORTS  
          RegisterModule  
      

      Notes

      Au lieu de créer un fichier de définition de module, vous pouvez exporter la fonction RegisterModule à l’aide du commutateur /EXPORT:RegisterModule .

  2. Créez le fichier C++ :

    1. Dans Explorateur de solutions, cliquez avec le bouton droit sur Fichiers sources, pointez sur Ajouter, puis cliquez sur Nouvel élément.

      La boîte de dialogue Ajouter un nouvel élément s’ouvre.

    2. Développez le nœud Visual C++ dans le volet Catégories , puis cliquez sur Code.

    3. Dans le volet Modèles , sélectionnez le modèle Fichier C++ .

    4. Dans la zone Nom , tapez HelloWorld et laissez le chemin d’accès par défaut du fichier dans la zone Emplacement .

    5. Cliquez sur Add.

    6. Ajoutez le code suivant :

      #define _WINSOCKAPI_
      #include <windows.h>
      #include <sal.h>
      #include <httpserv.h>
      
      // Create the module class.
      class CHelloWorld : public CHttpModule
      {
      public:
          REQUEST_NOTIFICATION_STATUS
          OnBeginRequest(
              IN IHttpContext * pHttpContext,
              IN IHttpEventProvider * pProvider
          )
          {
              UNREFERENCED_PARAMETER( pProvider );
      
              // Create an HRESULT to receive return values from methods.
              HRESULT hr;
              
              // Retrieve a pointer to the response.
              IHttpResponse * pHttpResponse = pHttpContext->GetResponse();
      
              // Test for an error.
              if (pHttpResponse != NULL)
              {
                  // Clear the existing response.
                  pHttpResponse->Clear();
                  // Set the MIME type to plain text.
                  pHttpResponse->SetHeader(
                      HttpHeaderContentType,"text/plain",
                      (USHORT)strlen("text/plain"),TRUE);
      
                  // Create a string with the response.
                  PCSTR pszBuffer = "Hello World!";
                  // Create a data chunk.
                  HTTP_DATA_CHUNK dataChunk;
                  // Set the chunk to a chunk in memory.
                  dataChunk.DataChunkType = HttpDataChunkFromMemory;
                  // Buffer for bytes written of data chunk.
                  DWORD cbSent;
                  
                  // Set the chunk to the buffer.
                  dataChunk.FromMemory.pBuffer =
                      (PVOID) pszBuffer;
                  // Set the chunk size to the buffer size.
                  dataChunk.FromMemory.BufferLength =
                      (USHORT) strlen(pszBuffer);
                  // Insert the data chunk into the response.
                  hr = pHttpResponse->WriteEntityChunks(
                      &dataChunk,1,FALSE,TRUE,&cbSent);
      
                  // Test for an error.
                  if (FAILED(hr))
                  {
                      // Set the HTTP status.
                      pHttpResponse->SetStatus(500,"Server Error",0,hr);
                  }
      
                  // End additional processing.
                  return RQ_NOTIFICATION_FINISH_REQUEST;
              }
      
              // Return processing to the pipeline.
              return RQ_NOTIFICATION_CONTINUE;
          }
      };
      
      // Create the module's class factory.
      class CHelloWorldFactory : public IHttpModuleFactory
      {
      public:
          HRESULT
          GetHttpModule(
              OUT CHttpModule ** ppModule, 
              IN IModuleAllocator * pAllocator
          )
          {
              UNREFERENCED_PARAMETER( pAllocator );
      
              // Create a new instance.
              CHelloWorld * pModule = new CHelloWorld;
      
              // Test for an error.
              if (!pModule)
              {
                  // Return an error if the factory cannot create the instance.
                  return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
              }
              else
              {
                  // Return a pointer to the module.
                  *ppModule = pModule;
                  pModule = NULL;
                  // Return a success status.
                  return S_OK;
              }            
          }
      
          void
          Terminate()
          {
              // Remove the class from memory.
              delete this;
          }
      };
      
      // Create the module's exported registration function.
      HRESULT
      __stdcall
      RegisterModule(
          DWORD dwServerVersion,
          IHttpModuleRegistrationInfo * pModuleInfo,
          IHttpServer * pGlobalInfo
      )
      {
          UNREFERENCED_PARAMETER( dwServerVersion );
          UNREFERENCED_PARAMETER( pGlobalInfo );
      
          // Set the request notifications and exit.
          return pModuleInfo->SetRequestNotifications(
              new CHelloWorldFactory,
              RQ_BEGIN_REQUEST,
              0
          );
      }
      

Compilation et test du module

Pour compiler et tester le projet

  1. Compilez le module HTTP :

    1. Dans le menu Générer, cliquez sur Générer la solution.

    2. Vérifiez que Visual Studio n’a pas retourné d’erreurs ou d’avertissements.

    3. Ajoutez le module HelloWorld.dll (avec le chemin d’accès complet) à la globalModules section du fichier %windir%\system32\inetsrv\config\applicationHost.config.

  2. Utilisez Internet Explorer pour accéder à votre site Web ; vous devez voir « Exemple de demande de début » avec le nombre de demandes affiché.

Notes

Vous devez arrêter IIS avant de lier votre projet sur les builds suivantes.

Résolution des problèmes liés à vos paramètres

Si votre module ne se compile pas ou ne fonctionne pas comme prévu, voici plusieurs domaines que vous pouvez case activée :

  • Vérifiez que vous avez spécifié __stdcall pour vos fonctions exportées ou que vous avez configuré la compilation à l’aide de la convention d’appel __stdcall (/Gz) .

  • Vérifiez qu’IIS a chargé HelloWorld.dll :

    1. Dans le Gestionnaire des services Internet, cliquez sur Site web par défaut dans le volet Connexions .

    2. Dans l’espace de travail (volet central), sélectionnez Affichage des fonctionnalités.

    3. Dans la zone Regrouper par , sélectionnez Catégorie.

    4. Dans la catégorie Composants serveur , double-cliquez sur Modules.

    5. Vérifiez que le module HelloWorld est répertorié.

  • Vérifiez que vous avez ajouté l’exportation correcte RegisterModule à votre fichier de définition.

  • Vérifiez que vous avez ajouté le fichier de définition aux paramètres du projet. Pour ajouter le fichier aux paramètres du projet, procédez comme suit :

    1. Dans le menu Projet , cliquez sur Propriétés.

    2. Développez le nœud Propriétés de configuration dans l’arborescence, développez le nœud Éditeur de liens, puis cliquez sur Entrée.

    3. Pour les paramètres du fichier de définition de module , vérifiez que votre fichier de définition est répertorié.

Voir aussi

Création de modules HTTP Native-Code
Conception de modules HTTP Native-Code