Compartir a través de


Tutorial: Creación de un módulo HTTP de Request-Level mediante código nativo

En este tutorial se muestra cómo usar C++ para crear un módulo HTTP de nivel de solicitud de ejemplo que implementa la nueva arquitectura de procesamiento de solicitudes en IIS 7. Esta nueva arquitectura amplía las funcionalidades de programación de código nativo cuando se escriben aplicaciones IIS en versiones anteriores de ASP.NET módulos HTTP e extensiones de ISAPI. Para obtener más información sobre cómo diseñar módulos HTTP mediante la nueva arquitectura de procesamiento de solicitudes, consulte Diseño de Native-Code módulos HTTP.

En este tutorial, creará un proyecto de C++ para el módulo HTTP, agregará el código necesario para un proyecto de "Hola mundo" y, a continuación, compilará y probará el módulo.

Prerrequisitos

El software siguiente es necesario para completar los pasos del ejemplo:

  • IIS 7.

  • Visual Studio 2005.

  • Kit de desarrollo de software (SDK) de Windows.

    Nota Puede usar Visual Studio .NET 2003 o versiones anteriores, aunque es posible que los pasos del tutorial no sean idénticos.

Creación del módulo

En esta parte del tutorial, creará un proyecto DLL de C++ vacío para el módulo HTTP.

Para crear un nuevo proyecto DLL de C++

  1. Abra Visual Studio 2005.

  2. Compruebe que las opciones globales tienen todas las rutas de acceso correctas al SDK incluyen archivos:

    1. En el menú Herramientas , haga clic en Opciones.

    2. Expanda el nodo Proyectos y soluciones en la vista de árbol y, a continuación, haga clic en Directorios de VC++.

    3. En el cuadro desplegable Mostrar directorios para , seleccione Incluir archivos.

    4. Compruebe que aparece la ruta de acceso donde instaló los archivos de inclusión del SDK de Windows. Si la ruta de acceso no aparece, haga clic en el icono Nueva línea y agregue la ruta de acceso donde instaló los archivos de inclusión del SDK. El directorio de instalación predeterminado es $(VCInstallDir)PlatformSDK\bin.

    5. Haga clic en OK.

  3. Cree un nuevo proyecto de C++:

    1. En el menú Archivo , elija Nuevoy haga clic en Proyecto.

      Aparece el cuadro de diálogo Nuevo proyecto .

    2. En el panel Tipos de proyecto , expanda el nodo Visual C++ y, a continuación, haga clic en Win32.

    3. En el panel Plantillas , seleccione Proyecto Win32.

    4. En el cuadro Nombre , escriba HelloWorld.

    5. En el cuadro Ubicación , escriba la ruta de acceso del ejemplo.

    6. Haga clic en OK.

      Se abre el Asistente para aplicaciones Win32 .

    7. Haga clic en Configuración de la aplicación.

    8. En Tipo de aplicación, haga clic en DLL.

    9. En Opciones adicionales, haga clic en Proyecto vacío.

    10. Haga clic en Finalizar

Agregar el código y los archivos de código fuente

El siguiente paso es agregar los archivos de definición de módulo y C++ necesarios al proyecto.

Para agregar los archivos de origen al proyecto

  1. Cree el archivo module-definition para exportar la función RegisterModule :

    1. En Explorador de soluciones, haga clic con el botón derecho en Archivos de origen, seleccione Agregary, a continuación, haga clic en Nuevo elemento.

      Se abrirá el cuadro de diálogo Agregar nuevo elemento.

    2. Expanda el nodo Visual C++ en el panel Categorías y, a continuación, haga clic en Código.

    3. En el panel Plantillas , seleccione la plantilla Archivo de definición de módulo .

    4. En el cuadro Nombre , escriba HelloWorld y deje la ruta de acceso predeterminada para el archivo en el cuadro Ubicación .

    5. Haga clic en Agregar.

    6. Agregue una línea con EXPORTS y RegisterModule. El archivo debe tener un aspecto similar al código siguiente:

      LIBRARY"HelloWorld"  
      EXPORTS  
          RegisterModule  
      

      Nota

      En lugar de crear un archivo de definición de módulo, puede exportar la función RegisterModule mediante el modificador /EXPORT:RegisterModule .

  2. Cree el archivo de C++:

    1. En Explorador de soluciones, haga clic con el botón derecho en Archivos de origen, seleccione Agregary, a continuación, haga clic en Nuevo elemento.

      Se abrirá el cuadro de diálogo Agregar nuevo elemento.

    2. Expanda el nodo Visual C++ en el panel Categorías y, a continuación, haga clic en Código.

    3. En el panel Plantillas , seleccione la plantilla Archivo de C++ .

    4. En el cuadro Nombre , escriba HelloWorld y deje la ruta de acceso predeterminada para el archivo en el cuadro Ubicación .

    5. Haga clic en Agregar.

    6. Agregue el siguiente código:

      #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
          );
      }
      

Compilación y prueba del módulo

Para compilar y probar el proyecto

  1. Compile el módulo HTTP:

    1. En el menú Compilar , haga clic en Compilar solución.

    2. Compruebe que Visual Studio no devolvió errores ni advertencias.

    3. Agregue el módulo HelloWorld.dll (con la ruta de acceso completa) a la globalModules sección del archivo %windir%\system32\inetsrv\config\applicationHost.config.

  2. Use Internet Explorer para ir a su sitio web; debería ver "Begin Request sample" (Iniciar solicitud de ejemplo) con el recuento de solicitudes mostrado.

Nota

Deberá detener IIS antes de vincular el proyecto en compilaciones posteriores.

Solución de problemas de la configuración

Si el módulo no compila o no funciona según lo previsto, estas son varias áreas que puede comprobar:

  • Asegúrese de que ha especificado __stdcall para las funciones exportadas o que ha configurado la compilación mediante la __stdcall (/Gz) convención de llamada.

  • Asegúrese de que IIS ha cargado HelloWorld.dll:

    1. En el Administrador de IIS, haga clic en Sitio web predeterminado en el panel Conexiones .

    2. En el área de trabajo (panel central), seleccione Vista características.

    3. En el cuadro Agrupar por , seleccione Categoría.

    4. En la categoría Componentes del servidor , haga doble clic en Módulos.

    5. Compruebe que aparece el módulo HelloWorld.

  • Asegúrese de que ha agregado la exportación correcta RegisterModule al archivo de definición.

  • Asegúrese de que ha agregado el archivo de definición a la configuración del proyecto. Para agregar el archivo a la configuración del proyecto, complete los pasos siguientes:

    1. En el menú Proyecto , haga clic en Propiedades.

    2. Expanda el nodo Propiedades de configuración en la vista de árbol, expanda el nodo Enlazador y, a continuación, haga clic en Entrada.

    3. Para la configuración del archivo de definición de módulo , asegúrese de que aparece el archivo de definición.

Consulte también

Creación de módulos HTTP de Native-Code
Diseño de módulos HTTP de Native-Code