CHttpModule 类

定义请求级 HTTP 模块的基类。

语法

class CHttpModule  

方法

下表列出了 类 CHttpModule 公开的方法。

名称 说明
~CHttpModule 解除分配 类的 CHttpModule 实例。
CHttpModule 初始化 CHttpModule 类的新实例。
释放 释放 CHttpModule 类的当前实例所使用的所有资源。
OnAcquireRequestState 表示将处理 AcquireRequestState 事件的方法,当 IIS 检索当前请求的状态时发生该事件。
OnAsyncCompletion 表示将处理异步完成事件的方法,该事件在异步操作完成处理后发生。
OnAuthenticateRequest 表示将处理 AuthenticateRequest 事件的方法,该事件在 IIS 建立用户标识时发生。
OnAuthorizeRequest 表示将处理 AuthorizeRequest 事件的方法,该事件在 IIS 验证用户授权时发生。
OnBeginRequest 表示将处理 BeginRequest 事件的方法,该事件作为当前请求的 HTTP 集成请求处理管道中的第一个事件发生。
OnCustomRequestNotification 表示将处理自定义事件的方法,该事件在模块引发用户定义的通知时发生。
OnEndRequest 表示将处理 EndRequest 事件的方法,该事件作为当前请求的 HTTP 集成请求处理管道中的最后一个事件发生。
OnExecuteRequestHandler 表示将处理 ExecuteRequestHandler 事件的方法,当 IIS 为当前请求执行处理程序时发生该事件。
OnLogRequest 表示将处理 LogRequest 事件的方法,当 IIS 准备记录当前请求时发生该事件。
OnMapPath 表示将处理 MapPath 事件的方法,该事件在操作请求为当前请求映射的物理路径时发生。
OnMapRequestHandler 表示将处理 MapRequestHandler 事件的方法,当 IIS 将当前请求映射到事件处理程序时发生该事件。
OnPostAcquireRequestState 表示将处理 AcquireRequestState 后事件的方法,该事件在 IIS 检索当前请求的状态之后发生。
OnPostAuthenticateRequest 表示将处理 AuthenticateRequest 后事件的方法,该事件在 IIS 建立用户标识后发生。
OnPostAuthorizeRequest 表示将处理 AuthorizeRequest 后事件的方法,该事件在 IIS 已验证用户授权之后发生。
OnPostBeginRequest 表示将处理 BeginRequest 后事件的方法,该事件在 HTTP 集成请求处理管道中的第一个事件之后发生。
OnPostEndRequest 表示将处理后事件的方法,该事件发生在当前请求的 HTTP 集成请求处理管道中的最后一个 EndRequest 事件之后。
OnPostExecuteRequestHandler 表示将处理 ExecuteRequestHandler 后事件的方法,该事件在 IIS 执行当前请求的处理程序之后发生。
OnPostLogRequest 表示将处理 LogRequest 后事件的方法,该事件在 IIS 记录当前请求后发生。
OnPostMapRequestHandler 表示将处理 MapRequestHandler 后事件的方法,该方法在 IIS 将当前请求映射到相应的事件处理程序之后发生。
OnPostPreExecuteRequestHandler 表示将处理 PreExecuteRequestHandler 后事件的方法,该事件在 IIS 执行请求处理程序之前发生。
OnPostReleaseRequestState 表示将处理 ReleaseRequestState 发布当前状态后发生的后事件的方法。
OnPostResolveRequestCache 表示将处理 ResolveRequestCache 后事件的方法,该事件在 IIS 已解析来自缓存的请求之后发生。
OnPostUpdateRequestCache 表示将处理 UpdateRequestCache 后事件的方法,该事件在 IIS 将请求存储在缓存中之后发生。
OnPreExecuteRequestHandler 表示将处理 PreExecuteRequestHandler 事件的方法,该事件在 IIS 执行请求处理程序之前发生。
OnReadEntity 表示将处理 ReadEntity 事件的方法,该事件在操作从请求缓冲区读取数据时发生。
OnReleaseRequestState 表示将处理 ReleaseRequestState 事件的方法,该事件在当前状态释放时发生。
OnResolveRequestCache 表示将处理 ResolveRequestCache 事件的方法,该事件在 IIS 解析缓存中的请求时发生。
OnSendResponse 表示将处理 SendResponse 事件的方法,该事件在 IIS 发送响应缓冲区时发生。
OnUpdateRequestCache 表示将处理 UpdateRequestCache 事件的方法,当 IIS 将请求存储在缓存中时发生。

派生类

此类不包含派生类。

备注

CHttpModule 是请求级 HTTP 模块的基类。 若要创建 CHttpModule派生类,需要创建一个请求级 HTTP 模块,该模块包含继承自 CHttpModule 的类和派生自 IHttpModuleFactory 接口的类。 有关创建 HTTP 模块的详细信息,请参阅 设计Native-Code HTTP 模块

CHttpModule 提供受保护的构造函数和析构函数方法以及公共 Dispose 方法。 在请求结束时, Dispose 调用 方法以删除 派生类的 CHttpModule实例。

CHttpModule 还定义 IIS 7 在集成请求处理管道中处理请求级别事件时调用的特定于通知的方法。 HTTP 模块可以通过在模块的导出 RegisterModule 函数中定义通知列表来注册特定事件。

确定性请求事件

在集成管道内请求级别事件的正常流中,大多数请求级通知方法按时间顺序进行处理。 每个确定性请求级通知方法都有一个匹配的事件后通知,它允许 HTTP 模块在事件发生时或事件发生后立即进行处理。

下表列出了按时间顺序排列的请求级别事件和事件后通知方法,这些方法在集成管道中的出现顺序。

事件通知方法 事件后通知方法
OnBeginRequest OnPostBeginRequest
OnAuthenticateRequest OnPostAuthenticateRequest
OnAuthorizeRequest OnPostAuthorizeRequest
OnResolveRequestCache OnPostResolveRequestCache
OnMapRequestHandler OnPostMapRequestHandler
OnAcquireRequestState OnPostAcquireRequestState
OnPreExecuteRequestHandler OnPostPreExecuteRequestHandler
OnExecuteRequestHandler OnPostExecuteRequestHandler
OnReleaseRequestState OnPostReleaseRequestState
OnUpdateRequestCache OnPostUpdateRequestCache
OnLogRequest OnPostLogRequest
OnEndRequest OnPostEndRequest

例如, OnBeginRequest 发生在 之前 OnAuthenticateRequestOnMapRequestHandler 发生在 OnAcquireRequestState之前,等等。

注意

事件后通知发生在下一个按时间顺序的请求级别通知之前。 例如, OnPostAuthenticateRequest 发生在 之前 OnAuthorizeRequestOnPostUpdateRequestCache 发生在 OnLogRequest之前,等等。

不确定的请求事件

其余请求级通知方法不按任何特定顺序进行处理;相反,IIS 会在发生特定的不确定事件时处理这些事件。 下表列出了不确定的请求级别事件和任何相关的事件后通知方法。

事件通知方法 事件后通知方法
OnAsyncCompletion (无) 1
OnCustomRequestNotification (无) 2
OnMapPath (无)
OnReadEntity (无)
OnSendResponse (无)

1OnAsyncCompletion HTTP 模块中发生异步事件时,将调用 方法。 因此,无法使用模块的导出 RegisterModule 函数注册异步通知。 相反,模块将提供一个 OnAsyncCompletion 方法来处理在调用方法后发生的通知,这些方法以异步方式返回 (例如 IHttpContext::ExecuteRequestIHttpResponse::WriteEntityChunks 方法) 。 当 IIS 调用 OnAsyncCompletion时, 方法将传递指示通知类型的参数,以及通知是针对事件还是事件后通知。

2 该方法 OnCustomRequestNotification 没有相应的事件后通知方法。 HTTP 模块可以使用模块的导出 RegisterModule 函数注册自定义通知,但模块无法注册自定义通知发生后发生的通知。

示例

以下示例演示如何创建简单的“Hello World”HTTP 模块。 模块定义一个导出的 RegisterModule 函数,该函数将接口的 IHttpModuleFactory 实例传递给 IHttpModuleRegistrationInfo::SetRequestNotifications 方法,并注册 RQ_BEGIN_REQUEST 通知。 IIS 使用 IHttpModuleFactory::GetHttpModule 方法创建类的 CHttpModule 实例并返回成功状态。 IIS 还使用 IHttpModuleFactory::Terminate 方法从内存中删除工厂。

RQ_BEGIN_REQUEST发生通知时,IIS 会调用模块的 OnBeginRequest 方法来处理当前请求。 OnBeginRequest 清除响应缓冲区并修改响应的 MIME 类型。 然后, 方法创建一个包含“Hello World”字符串的数据区块,并将该字符串返回给 Web 客户端。 最后,模块返回状态指示器,通知 IIS 所有通知已完成,然后退出。

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

模块必须导出 函数 RegisterModule 。 可以通过为项目创建模块定义 (.def) 文件导出此函数,也可以使用 开关编译模块 /EXPORT:RegisterModule 。 有关详细信息,请参阅 演练:使用本机代码创建Request-Level HTTP 模块

可以选择使用调用约定编译代码, __stdcall (/Gz) 而不是为每个函数显式声明调用约定。

要求

类型 说明
客户端 - Windows Vista 上的 IIS 7.0
- Windows 7 上的 IIS 7.5
- Windows 8 上的 IIS 8.0
- Windows 10 上的 IIS 10.0
服务器 - Windows Server 2008 上的 IIS 7.0
- Windows Server 2008 R2 上的 IIS 7.5
- Windows Server 2012 上的 IIS 8.0
- Windows Server 2012 R2 上的 IIS 8.5
- Windows Server 2016 上的 IIS 10.0
产品 - IIS 7.0、IIS 7.5、IIS 8.0、IIS 8.5、IIS 10.0
- IIS Express 7.5、IIS Express 8.0、IIS Express 10.0
Header Httpserv.h

另请参阅

创建Native-Code HTTP 模块
CGlobalModule 类