Export (0) Print
Expand All

IHttpResponse::WriteEntityChunks Method

IIS 7.0

Appends one or more HTTP_DATA_CHUNK structures to the response body.

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;

pDataChunks

[IN] A pointer to one or more HTTP_DATA_CHUNK structures.

nChunks

[IN] A DWORD that contains the number of chunks pointed to by pDataChunks.

fAsync

[IN] true if the method should complete asynchronously; otherwise, false.

fMoreData

[IN] true if more data is to be sent in the response; false if this is the last data.

pcbSent

[OUT] The number of bytes that were sent to the client if the call completes synchronously.

pfCompletionExpected

[OUT] true if an asynchronous completion is pending for this call; otherwise, false.

An HRESULT. Possible values include, but are not limited to, those in the following table.

Value

Description

S_OK

Indicates that the operation was successful.

ERROR_INVALID_PARAMETER

Indicates that the parameter is not valid (for example, the pDataChunks pointer is set to NULL).

ERROR_NOT_ENOUGH_MEMORY

Indicates that there is insufficient memory to perform the operation.

ERROR_ARITHMETIC_OVERFLOW

More than 65535 chunks have been added to the response.

Developers can use the WriteEntityChunks method to insert a single HTTP_DATA_CHUNK structure or an array of HTTP_DATA_CHUNK structures into the response body. If the operation has completed synchronously, the pcbSent parameter will receive the number of bytes that were inserted into the response.

If buffering is turned on, the WriteEntityChunks method will create a copy of any HTTP_DATA_CHUNK structures, thereby duplicating the underlying data so that it does not need to be preserved. If buffering is turned off, or the response buffer limit is reached, the WriteEntityChunks method will also flush the response. If buffering is off and the fAsync parameter is true, the memory must be preserved until the request completes.

You can configure a WriteEntityChunks operation to complete asynchronously by setting the fAsync parameter to true. In this situation, the WriteEntityChunks method will return immediately to the caller, and the pcbSent parameter will not receive the number of bytes that were inserted into the response. If buffering is disabled and the fAsync parameter is true, the memory for the pDataChunks parameter must be persisted until the asynchronous call completes.

A maximum of 65535 chunks (64 KB minus 1) can be written to a request.

The following example demonstrates how to use the WriteEntityChunks method to create an HTTP module that inserts an array of two data chunks into the response. The example then returns the response to a Web client.

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


Your module must export the RegisterModule function. You can export this function by creating a module definition (.def) file for your project, or you can compile the module by using the /EXPORT:RegisterModule switch. For more information, see Walkthrough: Creating a Request-Level HTTP Module By Using Native Code.

You can optionally compile the code by using the __stdcall (/Gz) calling convention instead of explicitly declaring the calling convention for each function.

Type

Description

Client

  • IIS 7.0 on Windows Vista

  • IIS 7.5 on Windows 7

  • IIS Express 7.5 on Windows XP, Windows Vista, Windows 7

  • IIS 8.0 on Windows 8 Client

Server

  • IIS 7.0 on Windows Server 2008

  • IIS 7.5 on Windows Server 2008 R2

  • IIS Express 7.5 on Windows Server 2003, Windows Server 2008, Windows Server 2008 R2

  • IIS 8.0 on Windows Server 2012

Product

IIS 7.0, IIS 7.5, IIS Express 7.5, IIS 8.0

Header

Httpserv.h

Community Additions

ADD
Show:
© 2014 Microsoft