IHttpCoNtext::CloneCoNtext 方法
建立目前要求內容的複製品。
語法
virtual HRESULT CloneContext(
IN DWORD dwCloneFlags,
OUT IHttpContext** ppHttpContext
) = 0;
參數
dwCloneFlags
[IN] DWORD
,包含複製旗標。
ppHttpContext
[OUT] IHttpCoNtext的取值指標。
傳回值
HRESULT
。 可能的值包括 (但不限於) 下表中的這些值。
值 | 描述 |
---|---|
S_OK | 表示作業成功。 |
ERROR_INVALID_PARAMETER | 表示指定的參數無效。 |
ERROR_NOT_ENOUGH_MEMORY | 表示記憶體不足,無法執行作業。 |
備註
方法 CloneContext
會建立目前要求內容的複製品。 您可以在 參數中 dwCloneFlags
指定適當的旗標,以控制複製行為。 下表列出這些旗標的可能值。
值 | 描述 |
---|---|
CLONE_FLAG_BASICS | 複製 URL、查詢字串和 HTTP 方法。 |
CLONE_FLAG_HEADERS | 複製要求標頭。 |
CLONE_FLAG_ENTITY | 複製實體主體。 |
CLONE_FLAG_NO_PRECONDITION | 請勿包含要求的任何「範圍」和「if-」標頭。 |
CLONE_FLAG_NO_DAV | 請勿包含要求的任何 WebDAV 標頭。 |
建立複製的內容之後,您可以使用複製品,就像使用父內容一樣。 例如,若要針對與父 URL 不同的 URL 執行子要求,您會針對複製的內容使用 IHttpRequest::SetUrl 方法來變更複製內容的 URL,再呼叫父內容的 IHttpCoNtext::ExecuteRequest 方法。
範例
下列程式碼範例示範如何建立執行下列工作的 HTTP 模組:
模組會註冊 RQ_MAP_PATH 通知。
此模組會建立 CHttpModule 類別,其中包含 OnMapPath 和 OnAsyncCompletion 方法。
當 Web 用戶端要求 URL 時,IIS 會呼叫模組
OnMapPath
的 方法。 這個方法會執行下列工作:測試目前要求的 URL 是否有尾端斜線或結尾為 /default.aspx。 如果 URL 以任一元素結尾,模組會
CloneContext
使用 方法來建立目前要求的複製品。呼叫複製品
IHttpRequest::SetUrl
的 方法,將複製的 URL 設定為 /example/default.aspx。IHttpContext::ExecuteRequest
呼叫 方法來執行子要求。測試非同步完成。 如果非同步完成擱置中,模組會將處理傳回至整合式要求處理管線。 如果沒有,模組會釋放複製的內容。
如果需要非同步完成,IIS 會呼叫模組
OnAsyncCompletion
的 方法。 這個方法會釋放複製的內容。模組會
CHttpModule
從記憶體中移除 類別,然後結束。
#define _WINSOCKAPI_
#include <windows.h>
#include <sal.h>
#include <httpserv.h>
// Create the module class.
class MyHttpModule : public CHttpModule
{
private:
// Create a pointer for a child request.
IHttpContext * m_pChildRequestContext;
public:
MyHttpModule(void)
{
m_pChildRequestContext = NULL;
}
REQUEST_NOTIFICATION_STATUS
OnMapPath(
IN IHttpContext * pHttpContext,
IN IMapPathProvider * pProvider
)
{
UNREFERENCED_PARAMETER( pProvider );
HRESULT hr;
BOOL fCompletionExpected;
// Retrieve a pointer to the URL.
PCWSTR pwszUrl = pProvider->GetUrl();
// Only process requests for the root.
if (0 == wcscmp(pwszUrl,L"/") || 0 == wcscmp(pwszUrl,L"/default.aspx"))
{
// Clone the current context.
hr = pHttpContext->CloneContext(
CLONE_FLAG_BASICS, &m_pChildRequestContext );
// Test for a failure.
if (FAILED(hr))
{
goto Failure;
}
// Test for an error.
if ( NULL != m_pChildRequestContext )
{
// Set the URL for the child request.
hr = m_pChildRequestContext->GetRequest()->SetUrl(
"/example/default.aspx",
(DWORD)strlen("/example/default.aspx"),false);
// Test for a failure.
if (FAILED(hr))
{
goto Failure;
}
// Execute the child request.
hr = pHttpContext->ExecuteRequest(
TRUE, m_pChildRequestContext,
0, NULL, &fCompletionExpected );
// Test for a failure.
if (FAILED(hr))
{
goto Failure;
}
// Test for pending asynchronous operations.
if (fCompletionExpected)
{
return RQ_NOTIFICATION_PENDING;
}
}
Failure:
// Test for a child request.
if (NULL != m_pChildRequestContext)
{
// Release the child request.
m_pChildRequestContext->ReleaseClonedContext();
m_pChildRequestContext = NULL;
}
}
// Return processing to the pipeline.
return RQ_NOTIFICATION_CONTINUE;
}
REQUEST_NOTIFICATION_STATUS
OnAsyncCompletion(
IN IHttpContext * pHttpContext,
IN DWORD dwNotification,
IN BOOL fPostNotification,
IN IHttpEventProvider * pProvider,
IN IHttpCompletionInfo * pCompletionInfo
)
{
// Test for a child request.
if (NULL != m_pChildRequestContext)
{
// Release the child request.
m_pChildRequestContext->ReleaseClonedContext();
m_pChildRequestContext = NULL;
}
// 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 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_MAP_PATH,
0
);
}
您的模組必須匯出 RegisterModule 函式 。 您可以為專案建立模組定義 (.def) 檔案,或使用 參數編譯模組 /EXPORT:RegisterModule
來匯出此函式。 如需詳細資訊,請參閱逐步解說 :使用機器碼建立Request-Level HTTP 模組。
您可以選擇性地使用呼叫慣例編譯器代碼, __stdcall (/Gz)
而不是明確宣告每個函式的呼叫慣例。
規格需求
類型 | 描述 |
---|---|
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 |
標頭 | Httpserv.h |
另請參閱
IHttpCoNtext 介面
IHttpCoNtext::ExecuteRequest 方法
IHttpCoNtext::ReleaseClonedCoNtext 方法