Метод 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 | Не включайте заголовки range и if-для запроса. |
CLONE_FLAG_NO_DAV | Не включайте заголовки WebDAV для запроса. |
После создания клонированного контекста можно использовать клон так же, как и родительский контекст. Например, чтобы выполнить дочерний запрос на URL-адрес, отличный от родительского, следует использовать метод IHttpRequest::SetUrl для клонированного контекста, чтобы изменить URL-адрес клонированного контекста перед вызовом метода IHttpContext::ExecuteRequest родительского контекста.
Пример
В следующем примере кода показано, как создать модуль HTTP, который выполняет следующие задачи:
Модуль регистрируется для уведомления RQ_MAP_PATH .
Модуль создает класс CHttpModule , содержащий методы OnMapPath и OnAsyncCompletion .
Когда веб-клиент запрашивает 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
параметра . Дополнительные сведения см. в разделе Пошаговое руководство. Создание модуля HTTP Request-Level с помощью машинного кода.
При необходимости можно скомпилировать код с помощью __stdcall (/Gz)
соглашения о вызовах вместо явного объявления соглашения о вызовах для каждой функции.
Требования
Тип | Описание |
---|---|
клиент | — IIS 7.0 в Windows Vista — IIS 7.5 в Windows 7 — IIS 8.0 в Windows 8 — IIS 10.0 в Windows 10 |
Сервер | — IIS 7.0 в Windows Server 2008 — IIS 7.5 в Windows Server 2008 R2 — IIS 8.0 в Windows Server 2012 — IIS 8.5 в Windows Server 2012 R2 — IIS 10.0 в Windows Server 2016 |
Продукт | — 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