IHttpResponse::WriteEntityChunks 方法

将一个或多个 HTTP_DATA_CHUNK 结构追加到响应正文。

语法

virtual HRESULT WriteEntityChunks(  
   IN HTTP_DATA_CHUNK* pDataChunks,  
   IN DWORD nChunks,  
   IN BOOL fAsync,  
   IN BOOL fMoreData,  
   OUT DWORD* pcbSent,  
   OUT BOOL* pfCompletionExpected = NULL  
) = 0;  

parameters

pDataChunks
[IN]指向一个或多个 HTTP_DATA_CHUNK 结构的指针。

nChunks
[IN]一个 , DWORD 它包含 指向 pDataChunks的区块数。

fAsync
[IN] true 如果方法应异步完成,则为 ;否则为 false

fMoreData
[IN] true 如果要在响应中发送更多数据,则为 ; false 如果这是最后一个数据,则为 。

pcbSent
[OUT]如果调用同步完成,则发送到客户端的字节数。

pfCompletionExpected
[OUT] true 如果此调用的异步完成挂起,则为 ;否则为 false

返回值

HRESULT。 可能的值包括(但并不限于)下表中的项。

说明
S_OK 指示操作成功。
ERROR_INVALID_PARAMETER 指示参数无效 (例如, pDataChunks 指针设置为 NULL) 。
ERROR_NOT_ENOUGH_MEMORY 指示内存不足,无法执行操作。
ERROR_ARITHMETIC_OVERFLOW 已向响应添加超过 65535 个区块。

备注

开发人员可以使用 WriteEntityChunks 方法将单个 HTTP_DATA_CHUNK 结构或结构数组 HTTP_DATA_CHUNK 插入响应正文中。 如果操作已同步完成,则 pcbSent 参数将接收已插入响应的字节数。

如果打开缓冲,该方法 WriteEntityChunks 将创建任何 HTTP_DATA_CHUNK 结构的副本,从而复制基础数据,以便无需保留它。 如果缓冲已关闭,或达到响应缓冲区限制,则 WriteEntityChunks 方法还将刷新响应。 如果缓冲关闭且 fAsync 参数为 true,则必须保留内存,直到请求完成。

通过将 参数true设置为 fAsync ,可以将操作配置为WriteEntityChunks异步完成。 在这种情况下, WriteEntityChunks 方法将立即返回给调用方,并且 pcbSent 参数不会接收插入到响应中的字节数。 如果禁用缓冲并且 fAsync 参数为 true,则必须保留参数的 pDataChunks 内存,直到异步调用完成。

最多可以向请求写入 65535 个区块, (64 KB 减去 1) 。

示例

以下示例演示如何使用 WriteEntityChunks 方法创建 HTTP 模块,该模块将包含两个数据区块的数组插入响应中。 然后,该示例将响应返回到 Web 客户端。

#define _WINSOCKAPI_
#include <windows.h>
#include <sal.h>
#include <httpserv.h>

// Create the module class.
class MyHttpModule : 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;
        
        // Create an array of data chunks.
        HTTP_DATA_CHUNK dataChunk[2];

        // Buffer for bytes written of data chunk.
        DWORD cbSent;
        
        // Create string buffers.
        PCSTR pszOne = "First chunk data\n";
        PCSTR pszTwo = "Second chunk data\n";

        // 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);
            
            // Set the chunk to a chunk in memory.
            dataChunk[0].DataChunkType = HttpDataChunkFromMemory;
            // Set the chunk to the first buffer.
            dataChunk[0].FromMemory.pBuffer =
                (PVOID) pszOne;
            // Set the chunk size to the first buffer size.
            dataChunk[0].FromMemory.BufferLength =
                (USHORT) strlen(pszOne);

            // Set the chunk to a chunk in memory.
            dataChunk[1].DataChunkType = HttpDataChunkFromMemory;
            // Set the chunk to the second buffer.
            dataChunk[1].FromMemory.pBuffer =
                (PVOID) pszTwo;
            // Set the chunk size to the second buffer size.
            dataChunk[1].FromMemory.BufferLength =
                (USHORT) strlen(pszTwo);

            // Insert the data chunks into the response.
            hr = pHttpResponse->WriteEntityChunks(
                dataChunk,2,FALSE,TRUE,&cbSent);

            // Test for an error.
            if (FAILED(hr))
            {
                // Set the error status.
                pProvider->SetErrorStatus( 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 MyHttpModuleFactory : public IHttpModuleFactory
{
public:
    HRESULT
    GetHttpModule(
        OUT CHttpModule ** ppModule, 
        IN IModuleAllocator * pAllocator
    )
    {
        UNREFERENCED_PARAMETER( pAllocator );

        // Create a new instance.
        MyHttpModule * pModule = new MyHttpModule;

        // 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 MyHttpModuleFactory,
        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

另请参阅

IHttpResponse 接口
IHttpResponse::WriteEntityChunkByReference 方法