Compartilhar via


Método IHttpRequest::ReadEntityBody

Retorna o corpo da entidade de solicitação HTTP.

Sintaxe

virtual HRESULT ReadEntityBody(  
   OUT VOID* pvBuffer,  
   IN DWORD cbBuffer,  
   IN BOOL fAsync,  
   OUT DWORD* pcbBytesReceived,  
   OUT BOOL* pfCompletionPending = NULL  
) = 0;  

Parâmetros

pvBuffer
[OUT] Um ponteiro para um buffer que recebe o corpo da solicitação.

cbBuffer
[IN] O tamanho, em bytes, do buffer apontado por pvBuffer.

fAsync
[IN] true para concluir a operação de forma assíncrona; caso contrário, false.

pcbBytesReceived
[OUT] Um ponteiro para um DWORD buffer que recebe o número de bytes realmente lidos se a chamada de método for concluída de forma síncrona.

pfCompletionPending
[OUT] Um ponteiro para um buffer booliano que recebe um valor que especifica se uma conclusão assíncrona está pendente.

Valor Retornado

Um HRESULT. Os possíveis valores incluem, mas sem limitação, aqueles na tabela a seguir.

Valor Descrição
S_OK Indica que a operação foi bem-sucedida.
ERROR_CONNECTION_INVALID Indica que a contagem de bytes da solicitação atual está incorreta.
ERROR_HANDLE_EOF Indica que não há dados restantes a serem lidos.
ERROR_INVALID_PARAMETER Indica que um valor inválido foi passado em um dos parâmetros.
ERROR_NOT_ENOUGH_MEMORY Indica que não há memória suficiente para executar a operação.

Comentários

O ReadEntityBody método dá suporte a chamadas síncronas e assíncronas.

Observação

Se você estiver chamando o ReadEntityBody método de forma assíncrona, seu módulo precisará retornar imediatamente após a chamada.

Depois que o ReadEntityBody método for chamado, o pvBuffer buffer conterá o corpo da solicitação e o pcbBytesReceived buffer conterá o tamanho, em bytes, do corpo da solicitação que foi retornado no pvBuffer buffer se a chamada do método for concluída de forma síncrona.

Além disso, o pfCompletionPending buffer conterá um valor booliano que especifica se uma conclusão assíncrona está pendente.

Exemplo

O exemplo de código a seguir demonstra como usar o ReadEntityBody método para criar um módulo HTTP que recupera uma seção de buffer de 1 KB da solicitação atual.

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

// NOTE - Data needs to be passed to this module, e.g. a POST request, or it will not appear to return anything.

// 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 a data chunk.
        HTTP_DATA_CHUNK dataChunk;
        // Set the chunk to a chunk in memory.
        dataChunk.DataChunkType = HttpDataChunkFromMemory;

        // Clear the existing response.
        pHttpContext->GetResponse()->Clear();
        // Set the MIME type to plain text.
        pHttpContext->GetResponse()->SetHeader(
            HttpHeaderContentType,"text/plain",
            (USHORT)strlen("text/plain"),TRUE);

        // Allocate a 1K buffer.
        DWORD cbBytesReceived = 1024;
        void * pvRequestBody = pHttpContext->AllocateRequestMemory(cbBytesReceived);
        
        // Test for an error.
        if (NULL == pvRequestBody)
        {
            // Set the error status.
            hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
            pProvider->SetErrorStatus( hr );
            // End additional processing.
            return RQ_NOTIFICATION_FINISH_REQUEST;
        }

        if (pHttpContext->GetRequest()->GetRemainingEntityBytes() > 0)
        {
            // Loop through the request entity.
            while (pHttpContext->GetRequest()->GetRemainingEntityBytes() != 0)
            {

                // Retrieve the request body.
                hr = pHttpContext->GetRequest()->ReadEntityBody(
                    pvRequestBody,cbBytesReceived,false,&cbBytesReceived,NULL);
                // Test for an error.
                if (FAILED(hr))
                {
                    // End of data is okay.
                    if (ERROR_HANDLE_EOF != (hr  & 0x0000FFFF))
                    {
                        // Set the error status.
                        pProvider->SetErrorStatus( hr );
                        // End additional processing.
                        return RQ_NOTIFICATION_FINISH_REQUEST;
                    }
                }
                dataChunk.FromMemory.pBuffer = pvRequestBody;
                dataChunk.FromMemory.BufferLength = cbBytesReceived;
                
                hr = pHttpContext->GetResponse()->WriteEntityChunks(
                    &dataChunk,1,FALSE,TRUE,NULL);
                if (FAILED(hr))
                {
                    // Set the error status.
                    pProvider->SetErrorStatus( hr );
                    // End additional processing.
                    return RQ_NOTIFICATION_FINISH_REQUEST;
                }
            }
            // 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
    );
}

Seu módulo deve exportar a função RegisterModule . Você pode exportar essa função criando um arquivo de definição de módulo (.def) para seu projeto ou pode compilar o módulo usando a opção /EXPORT:RegisterModule . Para obter mais informações, consulte Passo a passo: criando um módulo HTTP Request-Level usando código nativo.

Opcionalmente, você pode compilar o código usando a __stdcall (/Gz) convenção de chamada em vez de declarar explicitamente a convenção de chamada para cada função.

Requisitos

Type Descrição
Cliente - IIS 7.0 no Windows Vista
- IIS 7.5 no Windows 7
- IIS 8.0 no Windows 8
- IIS 10.0 no Windows 10
Servidor - IIS 7.0 no Windows Server 2008
- IIS 7.5 no Windows Server 2008 R2
- IIS 8.0 no Windows Server 2012
- IIS 8.5 no Windows Server 2012 R2
- IIS 10.0 no Windows Server 2016
Produto - 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
parâmetro Httpserv.h

Consulte Também

IHttpRequest Interface
Método IHttpRequest::GetRemainingEntityBytes
Método IHttpRequest::InsertEntityBody