IHttpCachePolicy::GetKernelCachePolicy メソッド
カーネルのキャッシュ ポリシーを返します。
構文
virtual HTTP_CACHE_POLICY* GetKernelCachePolicy(
VOID
) = 0;
パラメーター
このメソッドは、パラメーターを受け取りません。
戻り値
HTTP_CACHE_POLICYへのポインター。
解説
要求イベントまたは応答イベントに登録する CHttpModule 派生クラスは、対応するvirtual
メソッドのパラメーターとして IHttpContext ポインターを受け取ります。 IHttpContext::GetResponse メソッド、次に IHttpResponse::GetCachePolicy メソッドを呼び出し、最後に メソッドをGetKernelCachePolicy
呼び出してポインターをHTTP_CACHE_POLICY
取得します。
戻り値は GetKernelCachePolicy
実装によって異なります。 ガイドラインとして次の情報を使用する必要がありますが、すべてのシナリオで正しくない場合があります。
IHttpCachePolicy インターフェイスの現在の既定の実装者は、 構造体をprivate``HTTP_CACHE_POLICY
宣言します。 この実装者の構築中に、この構造体の Policy メンバーは に HttpCachePolicyNocache
設定され、この構造体の SecondsToLive メンバーは 0 に設定されます。 メソッドは GetKernelCachPolicy
、この同じ HTTP_CACHE_POLICY
構造体のアドレスを返します。
実装側の注意
IHttpCachePolicy の実装者は、このデータを使用したメモリ管理を担当します。したがって、IHttpCachePolicy
動的メモリ割り当てを使用する実装者は、不要になったときにポインターをHTTP_CACHE_POLICY
解放または呼び出すdelete
必要があります。
呼び出し元に関する注意事項
IHttpCachePolicy
実装者は、このデータを使用したメモリ管理を担当します。そのため、IHttpCachePolicy
このデータが不要になった場合、クライアントは返されたHTTP_CACHE_POLICY
ポインターを解放したり、 を呼び出delete
したりすることはできません。
例
次のコード例では、RQ_BEGIN_REQUESTイベントとRQ_SEND_RESPONSE イベントをリッスンするグローバル モジュールを作成する方法を示します。 次に、モジュールはポインターを IHttpCachePolicy
取得し、カーネルのキャッシュ ポリシー情報を応答ストリームに書き込みます。
#pragma warning( disable : 4290 )
#pragma warning( disable : 4530 )
#define _WINSOCKAPI_
#include <windows.h>
#include <sal.h>
#include <tchar.h>
#include <httptrace.h>
#include <httpserv.h>
#include <httpcach.h>
#include <string>
using namespace std;
// The CConvert class mirrors the Convert class that is
// defined in the .NET Framework. It converts primitives
// and other data types to wstring types.
class CConvert
{
public:
// The ToString method converts a long to a wstring.
// l: the long value to convert to a wstring.
// return: the long as a wstring.
static wstring ToString(long l)
{
WCHAR str[256];
str[0] = '\0';
_ltow_s(l, str, 256, 10);
return str;
}
// The ToByteString converts a double-byte
// character string to a single-byte string.
// str: the double-byte string to convert.
// return: a single-byte string copied from str.
static string ToByteString(const wstring& str)
{
// Get the length of the
// double-byte string.
size_t length = str.length();
// Create a temporary char pointer.
char* byteChar = new char[length+1];
byteChar[0] = '\0';
// Copy the double-byte character string
// into the single-byte string.
size_t charsReturned = 0;
wcstombs_s(&charsReturned, byteChar,
length+1, str.c_str(), length+1);
// Create a string to return.
string retString = byteChar;
// Delete the temporary string and
// set that string to NULL.
delete[] byteChar;
byteChar = NULL;
// Return the single-byte string.
return retString;
}
// The ToString method converts a ULONG to a wstring.
// u: the ULONG value to convert to a wstring.
// return: the value of u as a wstring.
static wstring ToString(ULONG u)
{
return (ToString((long)u));
}
};
// The CResponseWriter class writes
// text to the response stream.
class CResponseWriter
{
public:
// Creates the CResponseWriter class.
// response: the IHttpResponse
// pointer to write to.
// throws: a _com_error exception if
// the IHttpResponse pointer is NULL.
CResponseWriter(IHttpResponse* response)
throw (_com_error)
{
// If the response is NULL,
// throw an exception.
if (NULL == response)
{
ThrowOnFail(E_INVALIDARG);
}
// Set the internal response.
m_response = response;
}
// The destructor for the CResponseWriter
// class. The CResponseWriter method
// sets the IHttpResponse pointer to NULL.
virtual ~CResponseWriter()
{
m_response = NULL;
}
// The Write method writes the
// PCSTR to the response stream.
// pszValue: the PCSTR to write.
// throws: a _com_error if the
// Write method fails.
void Write
(
PCSTR pszValue
) throw (_com_error)
{
// The string must not be
// NULL, and its length must
// be greater than 0.
if ((NULL == pszValue) ||
(strlen(pszValue) < 1))
{
// Throw an invalid argument
// exception.
ThrowOnFail(E_INVALIDARG);
}
// Create a data chunk structure.
HTTP_DATA_CHUNK dataChunk;
// Set the chunk to a chunk in memory.
dataChunk.DataChunkType =
HttpDataChunkFromMemory;
// Set the chunk to
// the pszValue parameter.
dataChunk.FromMemory.pBuffer =
(PVOID)pszValue;
// Set the chunk size
// to the pszValue length.
dataChunk.FromMemory.BufferLength =
(USHORT)strlen(pszValue);
// Declare and initialize OUT
// parameters for the WriteEntityChunks
// method.
DWORD pcbSent = 0;
BOOL pfCompletionExpected = FALSE;
// Write the entity chunks to
// the response stream.
HRESULT hr =
m_response->WriteEntityChunks
(&dataChunk,
1,
FALSE,
FALSE,
&pcbSent,
&pfCompletionExpected);
// Throw an exception if the call
// to WriteEntityChunks is not a
// success.
ThrowOnFail(hr);
}
// The WriteLine method writes a string
// and newline characters to the response steam.
// pszValue: the PCSTR string to write.
// throws: a _com_error if the PCSTR
// or the newline characters are not
// written to the response stream.
void WriteLine
(
PCSTR pszValue
) throw (_com_error)
{
// Try to write the pszValue parameter.
Write(pszValue);
// Try to write the newline characters.
Write("\r\n");
}
// Convenience method that writes a name
// and value pair to the response stream.
// name: the name of the parameter.
// value: the value of the parameter.
// throws: a _com_error exception if
// the response stream is not written.
void WriteLine
(
const wstring& name,
const wstring& value
) throw (_com_error)
{
// Convert the UNICODE strings
// to mutlibyte strings.
string nameMulti =
CConvert::ToByteString(name);
string valueMulti =
CConvert::ToByteString(value);
// Create the string to write.
string writeString =
nameMulti +
string(": ") +
valueMulti;
// Write the line to
// the response stream.
WriteLine(writeString.c_str());
}
// Tests an HRESULT for success.
// hr: the HRESULT value to inspect.
// throws: a _com_error if the HRESULT
// parameter is not S_OK.
static void ThrowOnFail(HRESULT hr)
{
if (FAILED(hr))
{
_com_error ce(hr);
throw ce;
}
}
private:
// Specify the IHttpResponse
// pointer to write to.
IHttpResponse* m_response;
};
// The CCachePolicyModule is a CHttpModule
// class that handles response processing
// by updating the IHttpCachePolicy pointer
// and writing that IHttpCachePolicy data
// to the response stream.
class CCachePolicyModule : public CHttpModule
{
public:
// The CHttpResponseModule method is
// the public virtual destructor for
// the CHttpResponseModule class.
virtual ~CCachePolicyModule()
{
}
// The OnSendResponse method is the method
// supporting the RQ_SEND_RESPONSE event type.
// pHttpContext: the current IHttpContext pointer.
// pProvider: the current IHttpEventProvider pointer.
// return: RQ_NOTIFICATION_FINISH_REQUEST if the
// IHttpCachePolicy data is written. Otherwise,
// RQ_NOTIFICATION_CONTINUE.
virtual
REQUEST_NOTIFICATION_STATUS
OnSendResponse
(
IN IHttpContext* pHttpContext,
IN ISendResponseProvider* pProvider
)
{
// Return if the IHttpContext
// pointer is NULL.
if (NULL == pHttpContext)
{
return RQ_NOTIFICATION_CONTINUE;
}
// Get the IHttpResponse pointer
// from the IHttpContext pointer.
IHttpResponse* response =
pHttpContext->GetResponse();
// Return if the IHttpResponse
// pointer is NULL.
if (NULL == response)
{
return RQ_NOTIFICATION_CONTINUE;
}
// Get the IHttpCachePolicy pointer
// from the IHttpResponse pointer.
IHttpCachePolicy* policy =
response->GetCachePolicy();
// Return if the IHttpCachePolicy
// pointer is NULL.
if (NULL == policy)
{
return RQ_NOTIFICATION_CONTINUE;
}
// Wrap calls in one try-catch statement
// because a CResponseWriter might throw
// a _com_error exception.
try
{
// Create a CResponseWriter using
// the IHttpResponse pointer.
CResponseWriter writer(response);
// Clear the existing response stream.
response->Clear();
// Set the response header to plain text.
HRESULT hr =
response->SetHeader(HttpHeaderContentType,
"text/plain",
(USHORT)strlen("text/plain"),
TRUE);
// Throw an excepion if the
// SetHeader method failed.
CResponseWriter::ThrowOnFail(hr);
// Write the IHttpCachePolicy pointer
// data to the response stream.
Write(policy, writer);
}
catch(_com_error& ce)
{
// Set the error status
// using the COM exception.
response->SetStatus(500,
"OnSendResponse",
0, ce.Error());
// Continue processing.
return RQ_NOTIFICATION_CONTINUE;
}
// Finish the request because
// the response is written.
return RQ_NOTIFICATION_FINISH_REQUEST;
}
protected:
// The Write method writes HTTP_CACHE_POLICY_TYPE
// data to the response stream.
// policyType: the HTTP_CACHE_POLICY_TYPE.
// writer: the CResponseWriter to use
// for writing to the response stream.
// throws: a _com_error exception.
static void Write
(
HTTP_CACHE_POLICY_TYPE policyType,
CResponseWriter& writer
) throw (_com_error)
{
// Create an empty string to write the
// value of the HTTP_CACHE_POLICY_TYPE to.
wstring value;
// Write to the value string dependent
// upon the value of the HTTP_CACHE_POLICY_TYPE.
switch (policyType)
{
case HttpCachePolicyNocache:
{
value = L"HttpCachePolicyNocache";
break;
}
case HttpCachePolicyUserInvalidates:
{
value = L"HttpCachePolicyUserInvalidates";
break;
}
case HttpCachePolicyTimeToLive:
{
value = L"HttpCachePolicyTimeToLive";
break;
}
case HttpCachePolicyMaximum:
{
value = L"HttpCachePolicyMaximum";
break;
}
default:
{
value = L"Error";
break;
}
}
// Write the policy type as a
// string to the response stream.
writer.WriteLine(L"Policy Type", value);
}
// The Write method writes HTTP_CACHE_POLICY
// pointer data to the response stream.
// cachePolicy: the HTTP_CACHE_POLICY
// pointer to write.
// writer: the CResponseWriter to use
// for writing to the response stream.
// throws: a _com_error exception.
static void Write
(
HTTP_CACHE_POLICY* cachePolicy,
CResponseWriter& writer
) throw (_com_error)
{
// If the HTTP_CACHE_POLICY pointer
// is NULL then return.
if (NULL == cachePolicy)
{
return;
}
// Get the HTTP_CACHE_POLICY_TYPE from
// the HTTP_CACHE_POLICY pointer.
HTTP_CACHE_POLICY_TYPE policyType =
cachePolicy->Policy;
// Write the HTTP_CACHE_POLICY_TYPE
// to the response stream.
Write(policyType, writer);
// Get the seconds to live from
// the HTTP_CACHE_POLICY pointer.
ULONG secondsToLiveULONG =
cachePolicy->SecondsToLive;
// Convert the ULONG to a wstring.
wstring secondsToLive =
CConvert::ToString(secondsToLiveULONG);
// Write the Seconds-to-Live
// to the response stream.
writer.WriteLine(L"Seconds-to-Live", secondsToLive);
}
// The Write method writes IHttpCachePolicy
// pointer data to the response stream.
// httpCachePolicy: the IHttpCachePolicy
// pointer to write to the stream.
// writer: the CResponseWriter writer
// for writing to the response stream.
// throws: a _com_error exception.
static void Write
(
IHttpCachePolicy* httpCachePolicy,
CResponseWriter& writer
) throw (_com_error)
{
// If the IHttpCachePolicy
// pointer is NULL, return.
if (NULL == httpCachePolicy)
{
return;
}
// Get the HTTP_CACHE_POLICY
// pointer for the kernel from
// the IHttpCachePolicy pointer.
HTTP_CACHE_POLICY* kernelCachePolicy =
httpCachePolicy->GetKernelCachePolicy();
// Write the cache policy for the
// kernel to the response stream.
Write(kernelCachePolicy, writer);
}
};
// The CCachePolicyFactory class implements the
// IHttpModuleFactory interface and creates a new
// CCachePolicyModule pointer and registers that
// pointer for request and response events.
class CCachePolicyFactory : public IHttpModuleFactory
{
public:
// The RegisterCHttpModule method creates a new
// CCachePolicyFactory pointer and sets this new
// CCachePolicyFactory pointer as the IHttpModuleFactory
// pointer on the IHttpModuleRegistrationInfo pointer.
// dwServerVersion: the current server version.
// pModuleInfo: the current
// IHttpModuleRegistrationInfo pointer.
// pGlobalInfo: the current IHttpServer pointer.
// return: the value returned from the the call
// to the SetRequestNotifications on the
// IHttpModuleRegistrationInfo pointer.
static HRESULT RegisterCHttpModule
(
DWORD dwServerVersion,
IHttpModuleRegistrationInfo* pModuleInfo,
IHttpServer* pGlobalInfo
)
{
// Create a new CCachePolicyFactory pointer.
CCachePolicyFactory* policyFactory =
new CCachePolicyFactory;
// Test for NULL on the new
// CCachePolicyFactory pointer.
if (NULL == policyFactory)
{
// Return an out-of-memory error
// code if moduleFactory is NULL.
return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
}
// Set the request notifications for RQ_SEND_RESPONSE
// messages on the new CCachePolicyFactory pointer.
return pModuleInfo->SetRequestNotifications
(policyFactory,
RQ_SEND_RESPONSE,
0);
}
// The GetHttpModule method creates a new
// CCachePolicyModule pointer and sets the
// new CCachePolicyModule on the ppModule parameter.
// ppModule: the new CHttpResponseModule pointer to return.
// pAllocator: currently unused.
// return: ERROR_NOT_ENOUGH_MEMORY if the
// heap is exhausted; otherwise, S_OK.
virtual
HRESULT
GetHttpModule
(
OUT CHttpModule** ppModule,
IN IModuleAllocator* pAllocator
)
{
// Call the UNREFERENCED_PARAMETER macro
// with the IModuleAllocator pointer, because
// this parameter is currently unused.
UNREFERENCED_PARAMETER(pAllocator);
// Set the dereferenced ppModule
// to a new CHttpResponseModule pointer.
(*ppModule) = new CCachePolicyModule;
// If the new CHttpResponseModule is
// NULL, return an error indicating
// that heap memory is exhausted.
if (NULL == (*ppModule))
{
return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
}
// Return S_OK.
return S_OK;
}
// The Terminate method
// calls delete on this.
virtual
void
Terminate()
{
delete this;
}
protected:
// The CCachePolicyFactory method is
// the protected constructor for the
// CCachePolicyFactory class.
CCachePolicyFactory()
{
}
// The CCachePolicyFactory method is
// the protected virtual destructor for
// the CCachePolicyFactory class.
virtual ~CCachePolicyFactory()
{
}
private:
};
// The RegisterModule method is the
// main entry point for the DLL.
// dwServerVersion: the current server version.
// pModuleInfo: the current
// IHttpModuleRegistrationInfo pointer.
// pGlobalInfo: the current IHttpServer pointer.
// return: the value returned by calling the
// CCachPolicyFactory::RegisterCHttpModule method.
HRESULT
__stdcall
RegisterModule(
DWORD dwServerVersion,
IHttpModuleRegistrationInfo* pModuleInfo,
IHttpServer* pGlobalInfo
)
{
return CCachePolicyFactory::RegisterCHttpModule
(dwServerVersion,
pModuleInfo,
pGlobalInfo);
}
ネイティブ DLL モジュールを作成してデプロイする方法の詳細については、「 チュートリアル: ネイティブ コードを使用したRequest-Level HTTP モジュールの作成」を参照してください。
上記のコードは、次のようなデータを応答ストリームに書き込みます。
Policy Type: HttpCachePolicyNocache
Seconds-to-Live: 0
必要に応じて、各関数の呼び出し規則を明示的に宣言するのではなく、__stdcall (/Gz)
呼び出し規則を使用してコードをコンパイルできます。
スレッド セーフ
メソッドは GetKernelCachePolicy
スレッド セーフです。 ただし、これらのメンバーは共有構造上の HTTP_CACHE_POLICY
フィールドであるため、メンバー public
を個別に変更してもスレッド セーフではありません。
要件
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 |