Метод IHttpContext::ExecuteRequest
Выполняет дочерний запрос.
Синтаксис
virtual HRESULT ExecuteRequest(
IN BOOL fAsync,
IN IHttpContext* pHttpContext,
IN DWORD dwExecuteFlags,
IN IHttpUser* pHttpUser,
OUT BOOL* pfCompletionExpected = NULL
) = 0;
Параметры
fAsync
[IN] Всегда true
(указывает асинхронное выполнение).
pHttpContext
[IN] Указатель на дочерний элемент IHttpContext для выполнения.
dwExecuteFlags
[IN] Объект , DWORD
содержащий флаги выполнения запроса.
pHttpUser
[IN] Указатель на IHttpUser для запроса. (необязательно)
pfCompletionExpected
[OUT] true
значение , если асинхронное завершение по-прежнему ожидается; в противном случае — false
. (необязательно)
Возвращаемое значение
Объект HRESULT
. Допустимые значения включают, но не ограничиваются, значения, приведенные в следующей таблице.
Значение | Описание: |
---|---|
S_OK | Указывает, что операция прошла успешно. |
ERROR_NOT_SUPPORTED | Указывает, что запрос не поддерживается (например, fAsync задано значение false или дочерний запрос не был клонирован из родительского запроса). |
ERROR_STACK_OVERFLOW | Указывает, что запрос превышает ограничение для рекурсивных дочерних запросов. |
Комментарии
Метод ExecuteRequest
выполняет дочерний запрос, указанный интерфейсом IHttpContext в параметре pHttpContext
. Этот контекст запроса необходимо создать с помощью метода IHttpContext::CloneContext .
Важно!
Попытка выполнить дочерний запрос, который не был клонирован родительским запросом, вернет ERROR_NOT_SUPPORTED.
Каждый дочерний контекст может выполняться только один раз, хотя дочерние запросы могут быть вложены рекурсивно.
Примечание
Ограничение для рекурсивных дочерних запросов составляет 10.
Метод ExecuteRequest
поддерживает только асинхронную операцию, которая предотвращает исчерпание пула потоков.
Важно!
Попытка выполнить синхронный дочерний запрос вернет ERROR_NOT_SUPPORTED.
Поведением выполнения дочернего запроса можно управлять, указав флаги выполнения в dwExecuteFlags
. В следующей таблице перечислены возможные значения для этих флагов.
Значение | Описание |
---|---|
EXECUTE_FLAG_NO_HEADERS | Подавляйте заголовки HTTP для дочернего запроса. |
EXECUTE_FLAG_IGNORE_CURRENT_INTERCEPTOR | Игнорируйте текущий обработчик сопоставления скриптов для этой цепочки запросов. |
EXECUTE_FLAG_IGNORE_APPPOOL | Выполните запрос, даже если дочерний запрос находится не в том же пуле приложений. |
EXECUTE_FLAG_DISABLE_CUSTOM_ERROR | Отключите пользовательские ошибки для дочернего запроса. |
EXECUTE_FLAG_SAME_URL | URL-адрес дочернего запроса совпадает с url-адресом родительского запроса. Примечание: Обработчики карты скриптов используют этот флаг для пересылки выполнения. |
EXECUTE_FLAG_BUFFER_RESPONSE | Не сбрасывайте дочерний ответ; возвращает ответ на родительский запрос. |
EXECUTE_FLAG_HTTP_CACHE_ELIGIBLE | Ответ ребенка по-прежнему имеет право на кэширование Http.sys. Примечание: Кэширование отключено по умолчанию при выполнении дочернего запроса. |
Если указать IHttpUser
интерфейс для pHttpUser
, проверка подлинности для дочернего запроса будет пропущена.
Пример
В следующем примере кода показано, как создать модуль HTTP, который выполняет следующие задачи:
Модуль регистрируется для уведомления RQ_MAP_PATH .
Модуль создает класс CHttpModule , содержащий методы OnMapPath и OnAsyncCompletion .
Когда веб-клиент запрашивает URL-адрес, IIS вызывает метод модуля
OnMapPath
. Этот метод выполняет следующие задачи:Проверяет, соответствует ли URL-адрес текущего запроса двум конкретным URL-адресам в корне веб-сайта. Если URL-адрес совпадает с указанным URL-адресом, модуль использует
IHttpContext::CloneContext
метод для создания клона текущего запроса.Вызывает метод клона
IHttpRequest::SetUrl
, чтобы задать ДЛЯ клона URL-адрес /example/default.aspx.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::CloneContext
Метод IHttpContext::GetParentContext
Метод IHttpContext::ReleaseClonedContext