IHttpCompletionInfo::GetCompletionBytes メソッド
非同期操作で完了したバイト数を返します。
構文
virtual DWORD GetCompletionBytes(
VOID
) const = 0;
パラメーター
このメソッドは、パラメーターを受け取りません。
戻り値
DWORD
バイト数を格納する 。
解説
GetCompletionBytes
メソッドを使用すると、非同期操作中に完了したバイト数を取得できます。 操作が非同期に完了すると、IIS は IHttpCompletionInfo インターフェイスを作成し、そのインターフェイスをモジュールの CHttpModule::OnAsyncCompletion メソッドに渡して非同期操作の結果を処理します。 その後、 を使用 GetCompletionBytes
して、非同期操作の完了したバイトを取得できます。
たとえば、モジュールが IHttpRequest::ReadEntityBody メソッドに非同期的に完了するように要求した場合、 GetCompletionBytes
読み取られたバイト数が返されます。 同様に、 モジュールが IIHttpResponse::Flush メソッドの非同期完了を要求した場合、 GetCompletionBytes
クライアントにフラッシュされたバイト数が返されます。 さらに、 は、 GetCompletionBytes
IHttpContext::P ostCompletion メソッドを呼び出すときに指定したバイト数を返します。
例
次のコード例は、次のタスクを実行する HTTP モジュールを作成する方法を示しています。
モジュールは、 RQ_BEGIN_REQUEST と RQ_MAP_REQUEST_HANDLER 通知に登録します。
モジュールは、OnBeginRequest、OnMapRequestHandler、および
OnAsyncCompletion
メソッドを含む CHttpModule クラスを作成します。Web クライアントが URL を要求すると、IIS はモジュールの
OnBeginRequest
メソッドを呼び出します。 このメソッドは、次のタスクを実行します。既存の応答バッファーをクリアし、応答の MIME の種類を設定します。
文字列の例を作成し、その文字列を Web クライアントに非同期的に返します。
エラーまたは非同期完了をテストします。 非同期完了が保留中の場合、モジュールは保留中の通知状態を統合された要求処理パイプラインに返します。
その後、IIS はモジュールの
OnMapRequestHandler
メソッドを呼び出します。 このメソッドは、次のタスクを実行します。現在の応答バッファーを Web クライアントにフラッシュします。
エラーまたは非同期完了をテストします。 非同期完了が保留中の場合、モジュールは保留中の通知状態をパイプラインに返します。
非同期入力候補が必要な場合、IIS はモジュールの
OnAsyncCompletion
メソッドを呼び出します。 このメソッドは、次のタスクを実行します。有効な
IHttpCompletionInfo
インターフェイスをテストします。 有効なIHttpCompletionInfo
インターフェイスが渡された場合、メソッドは、 メソッドと GetCompletionStatus メソッドをそれぞれ呼び出GetCompletionBytes
して、完了したバイトを取得し、非同期操作の状態を返します。完了情報を含む文字列を作成し、その情報をイベントとしてイベント ビューアーのアプリケーション ログに書き込みます。
モジュールは、 クラスを
CHttpModule
メモリから削除してから終了します。
#define _WINSOCKAPI_
#include <windows.h>
#include <sal.h>
#include <httpserv.h>
#include <wchar.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;
// Buffer to store the byte count.
DWORD cbSent = 0;
// Buffer to store if asyncronous completion is pending.
BOOL fCompletionExpected = false;
// Create an example string to return to the Web client.
char szBuffer[] = "Hello World!";
// 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);
// Create a data chunk.
HTTP_DATA_CHUNK dataChunk;
// Set the chunk to a chunk in memory.
dataChunk.DataChunkType = HttpDataChunkFromMemory;
// Set the chunk to the buffer.
dataChunk.FromMemory.pBuffer =
(PVOID) szBuffer;
// Set the chunk size to the buffer size.
dataChunk.FromMemory.BufferLength =
(USHORT) strlen(szBuffer);
// Insert the data chunk into the response.
hr = pHttpContext->GetResponse()->WriteEntityChunks(
&dataChunk,1,TRUE,TRUE,&cbSent,&fCompletionExpected);
// Test for a failure.
if (FAILED(hr))
{
// Set the HTTP status.
pHttpContext->GetResponse()->SetStatus(
500,"Server Error",0,hr);
// End additional processing.
return RQ_NOTIFICATION_FINISH_REQUEST;
}
// Test for pending asynchronous operations.
if (fCompletionExpected)
{
return RQ_NOTIFICATION_PENDING;
}
// Return processing to the pipeline.
return RQ_NOTIFICATION_CONTINUE;
}
REQUEST_NOTIFICATION_STATUS
OnMapRequestHandler(
IN IHttpContext * pHttpContext,
IN IMapHandlerProvider * pProvider
)
{
// Create an HRESULT to receive return values from methods.
HRESULT hr;
// Buffer to store the byte count.
DWORD cbSent = 0;
// Buffer to store if asyncronous completion is pending.
BOOL fCompletionExpected = false;
// Flush the response to the client.
hr = pHttpContext->GetResponse()->Flush(
TRUE,FALSE,&cbSent,&fCompletionExpected);
// Test for a failure.
if (FAILED(hr))
{
// Set the HTTP status.
pHttpContext->GetResponse()->SetStatus(
500,"Server Error",0,hr);
}
// Test for pending asynchronous operations.
if (fCompletionExpected)
{
return RQ_NOTIFICATION_PENDING;
}
// End additional processing.
return RQ_NOTIFICATION_CONTINUE;
}
REQUEST_NOTIFICATION_STATUS
OnAsyncCompletion(
IN IHttpContext * pHttpContext,
IN DWORD dwNotification,
IN BOOL fPostNotification,
IN IHttpEventProvider * pProvider,
IN IHttpCompletionInfo * pCompletionInfo
)
{
if ( NULL != pCompletionInfo )
{
// Create strings for completion information.
char szNotification[256] = "";
char szBytes[256] = "";
char szStatus[256] = "";
// Retrieve and format the completion information.
sprintf_s(szNotification,255,"Notification: %u",
dwNotification);
sprintf_s(szBytes,255,"Completion Bytes: %u",
pCompletionInfo->GetCompletionBytes());
sprintf_s(szStatus,255,"Completion Status: 0x%08x",
pCompletionInfo->GetCompletionStatus());
// Create an array of strings.
LPCSTR szBuffer[3] = {szNotification,szBytes,szStatus};
// Write the strings to the Event Viewer.
WriteEventViewerLog(szBuffer,3);
}
// Return processing to the pipeline.
return RQ_NOTIFICATION_CONTINUE;
}
MyHttpModule(void)
{
// Open a handle to the Event Viewer.
m_hEventLog = RegisterEventSource( NULL,"IISADMIN" );
}
~MyHttpModule(void)
{
// Test if the handle for the Event Viewer is open.
if (NULL != m_hEventLog)
{
// Close the handle to the Event Viewer.
DeregisterEventSource( m_hEventLog );
m_hEventLog = NULL;
}
}
private:
// Handle for the Event Viewer.
HANDLE m_hEventLog;
// Define a method that writes to the Event Viewer.
BOOL WriteEventViewerLog(LPCSTR * lpStrings, WORD wNumStrings)
{
// Test whether the handle for the Event Viewer is open.
if (NULL != m_hEventLog)
{
// Write any strings to the Event Viewer and return.
return ReportEvent(
m_hEventLog, EVENTLOG_INFORMATION_TYPE,
0, 0, NULL, wNumStrings, 0, lpStrings, NULL );
}
return FALSE;
}
};
// 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 we 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 );
return pModuleInfo->SetRequestNotifications(
new MyHttpModuleFactory,
RQ_BEGIN_REQUEST | RQ_MAP_REQUEST_HANDLER,
0
);
}
モジュールは RegisterModule 関数をエクスポートする必要があります。 この関数をエクスポートするには、プロジェクトのモジュール定義 (.def) ファイルを作成するか、スイッチを使用してモジュールを /EXPORT:RegisterModule
コンパイルします。 詳細については、「 チュートリアル: ネイティブ コードを使用したRequest-Level HTTP モジュールの作成」を参照してください。
必要に応じて、各関数の呼び出し規約を __stdcall (/Gz)
明示的に宣言するのではなく、呼び出し規約を使用してコードをコンパイルできます。
要件
Type | 説明 |
---|---|
Client | - 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 |
参照
IHttpCompletionInfo インターフェイス
IHttpCompletionInfo::GetCompletionStatus メソッド