Расширения ISAPI
Главная точка входа расширения ISAPI
Файл HelloWorld.cpp необходимо настроить на поддержку функций, необходимых для обеспечения работы расширения ISAPI.
- В Visual Studio .NET откройте файл HelloWorld.cpp для редактирования посредством двойного щелчка на имени файла в окне Solution Explorer.
- Удалите функцию DLLMain (она не нужна в данном примере).
- В верхней части файла с кодом добавьте препроцессорную директиву включения для файла заголовка httpext.h и <string> (см. листинг 5.2).
- Добавьте функцию GetExtensionVersion (см. листинг 5.2).
- Добавьте функцию HttpExtensionProc (см. листинг 5.2).
// HelloWorld.cpp : Defines the entry point for
//the DLL application.
#include <httpext.h> //for ISAPI classes and structures
// tell the compiler to shut up about using STL
#pragma warning(disable:4786)
#include <string> //to build response to send back to user
using namespace std;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Name:GetExtensionVersion
In: pVer - Pointer to ISAPI structure HSE_VERSION_INFO.
Out: Returns true if you want IIS to use the extension, otherwise
if another value is returned, IIS will not use the extension
Purpose:
Called when the extension is loaded into IIS. The member
variables of HSE_VERSION_INFO, dwExtensionVersion and
lpszExtensionDesc should be filled with the extension
version and description.
Other initialization functionality could be called from this
function to set up the server to use this extension.
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO *pVer)
{
//ISAPI version
const DWORD VERSION_NUMBER = 0.9;
const char* VERSION_NAME = "Hello World";
pVer->dwExtensionVersion = VERSION_NUMBER;
strncpy( pVer->lpszExtensionDesc,
VERSION_NAME,
HSE_MAX_EXT_DLL_NAME_LEN);
return TRUE;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Name:HttpExtensionProc
In: pECB - pointer to the Extension control block structure
Out: DWORD - HSE status code
Purpose:
main entry point for HTTP request
the possible return codes are:
HSE_STATUS_SUCCESS - everything worked great
HSE_STATUS_SUCCESS_AND_KEEP_CONN - same as HSE_STATUS_SUCCESS
since IIS 4
HSE_STATUS_PENDING - wait until effort completed
HSE_STATUS_ERROR - sends a 500 error code
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
DWORD WINAPI HttpExtensionProc(EXTENSION_CONTROL_BLOCK *pECB)
{
//HTTP headers
const char* BASIC_HEADER = "Content-type: text/html\r\n\r\n";
//output values
const DWORD BUFFER_LENGTH = 4096;
TCHAR szTempBuffer[BUFFER_LENGTH];
DWORD dwBufferSize = BUFFER_LENGTH;
string sResponse;
//start our HTML document
sResponse = "<HTML><HEAD></HEAD><BODY><P>";
sResponse += "Hi! Hello World";
sResponse += "</P></BODY></HTML>";
// set content-type header
strcpy(szTempBuffer, BASIC_HEADER);
DWORD dwHeaderSize = strlen(szTempBuffer);
pECB->ServerSupportFunction(pECB->ConnID,
HSE_REQ_SEND_RESPONSE_HEADER,
NULL,
&dwHeaderSize,
(LPDWORD) szTempBuffer);
//write value to http response
DWORD dwLength=sResponse.length();
pECB->WriteClient( pECB->ConnID,
(PVOID)sResponse.c_str(),
&dwLength,
0);
//return a success code
return HSE_STATUS_SUCCESS;
}
Листинг
5.2.
Source Code for HelloWorld.cpp
Функция GetExtensionVersion
Функция GetExtensionVersion использует указатель на структуру HSE_VERSION_INFO в качестве параметра и возвращает значение BOOL в зависимости от того, использует ли IIS расширение ISAPI. Если функция GetExtensionVersion возвращает значение "истина", то расширение ISAPI используется. Функция GetExtensionVersion вызывается при загрузке расширения ISAPI в пространство процесса IIS. После загрузки расширения ISAPI эта функция повторно не вызывается. Она отлично подходит для включения кода, выполняющего проверку ключа лицензии, или для процедур инициализации, проверяющих использование расширения. В листинге 5.2 файла HelloWorld.cpp функция GetExtensionVersion только получает информацию о версии для расширения ISAPI.
Структура HSE_VERSION_INFO содержит две переменные dwExtensionVersion и lpszExtensionDesc. Этим переменным присваиваются значения при вызове функции GetExtensionVersion. В листинге 5.2 переменной dwExtensionVersion присваивается значение 0,9 типа DWORD, а переменной lpszExtensionDesc – значение HelloWorld. Эта функция всегда возвращает значение "истина", так как в IIS всегда загружается расширение ISAPI. Если расширение ISAPI зависит от наличия действительного файла лицензии, другой программной библиотеки или специальной конфигурации, тогда в функции можно выполнять соответствующую проверку и возвращать значение "ложь" в случае отрицательного результата.
Функция HttpExtensionProc
Функция HttpExtensionProc в качестве параметра использует одну из важнейших структур ISAPI – блок контроля расширения (Extension Control Block, ECB). Эта структура содержит следующие компоненты:
- данные о запросе HTTP;
- данные веб-экземпляра IIS, через которое поступил запрос;
- вспомогательные функции для анализа запроса HTTP;
- вспомогательные функции для управления ответом HTTP.
Изучая код листинга 5.2, следует отметить, что указатель на блок ECB используется только для отправки заголовка ответа клиенту и для отображения клиенту фразы "Hi! Hello World". Код C++ похож на C в структурах и вспомогательных функциях, поскольку ISAPI не сильно изменился со времени выхода первой версии IIS для обеспечения обратной совместимости. Заметным изменениям ISAPI стало добавление новых функциональных возможностей. Трудность работы с ISAPI состоит в том, что некоторые API требуют программирования с использованием решений языка C.
Первой функцией, вызываемой в блоке ECB расширения HelloWorld, является функция ServerSupportFunction. Она устанавливает заголовок в ответе HTTP для обозначения вида содержимого (текст или HTML) с помощью следующей строки:
Content-type: text/html\r\n\r\n
За заголовками ответов HTTP должны следовать две пары символов возврата каретки и перехода на новую строку ( /n и /r ).
Следующей функцией, вызываемой с помощью ECB, является функция WriteClient. Фраза "Hi! Hello World" записывается в браузер с помощью данной функции посредством передачи указателя char (char*) строковой переменной, содержащей код HTML и строку "Hi! Hello World". Функции WriteClient нужен пустой указатель ( void* ), поэтому указатель char приводится к форме пустого указателя с помощью макроса PVOID.
Реализация ISAPI "HelloWorld"
После успешной компиляции DLL расширение ISAPI можно отгружать на веб-сервер. Если в качестве расположения конечного файла DLL указан экземпляр веб-сервера или корень виртуального каталога, можно немедленно запросить файл из IIS. При выполнении отладки Visual Studio .NET браузер не откроется, и автоматического запроса ISAPI DLL из IIS (как при отладке веб-службы ASP.NET) не произойдет. Visual Studio считает проект библиотекой DLL, поэтому выдаст запрос на присвоение исполняемого файла, который использует данную библиотеку.
Запомните. Если разработчик осуществляет построение библиотеки DLL расширения ISAPI и затем тестирует DLL посредством ее запроса через IIS, при втором построении ISAPI DLL в Visual Studio .NET, скорее всего, не удастся создать DLL. IIS блокирует библиотеку DLL расширения ISAPI при ее запросе из IIS, поскольку DLL загружается в пространство процесса IIS. Для разблокирования ISAPI DLL необходимо выгрузить экземпляр веб-сайта или виртуального каталога либо заново запустить приложение. После разблокирования ISAPI DLL поверх нее в процессе построения осуществляется запись.
При первом запросе ISAPI DLL из IIS 6 в операционной системе Windows Server 2003, скорее всего, возвратится ошибка 404. В WS03 и IIS6 существует новая возможность, ограничивающая по умолчанию всякую программную поддержку серверной части, если она не включена вручную. В предыдущих версиях Windows Server компонент IIS поставлялся с включенной программной поддержкой серверной части (ASP). Эта функция включается в окне Web Service Extensions (Расширения веб-служб) консоли MMC Computer Management (Управление компьютером) (см. рис. 5.8).
увеличить изображение
Рис. 5.8. Включение программной функциональности серверной части в окне Web Service Extensions (Расширения веб-служб)
Настроим IIS на разрешение запросов расширения ISAPI HelloWorld.
- В окне администрирования расширения веб-служб щелкните на ссылке Add A New Web Service Extension (Добавить новое расширение веб-службы). Откроется диалоговое окно New Web Service Extension (Новое расширение веб-службы).
- В текстовом поле Extension Name (Имя расширения) введите имя, которое будет отображаться в окне администрирования расширения веб-служб. В нашем примере это имя HelloWorld (см. рис. 5.9).
- Нажмите на кнопку Add (Добавить), чтобы указать путь к файлу расширения ISAPI. Откроется диалоговое окно Add File (Добавление файла), в котором вручную вводится путь к файлу, либо укажите его расположение в окне Open File (Открыть файл) после нажатия на кнопку Browse (Обзор).
- Установите путь к файлу расширения ISAPI, затем нажмите на кнопку OK в диалоговом окне Add File (Добавление файла). Файла расширения ISAPI отобразится в диалоговом окне New Web Service Extension (Новое расширение веб-службы).
- Отметьте опцию Set Extension Status To Allowed (Разрешить использование расширения), после чего нажмите на кнопку OK.
Расширение HelloWorld появится в окне администрирования расширения веб-служб консоли Copmuter Management (Управление компьютером), и в поле Status (Состояние) отобразится значение Allowed (Разрешено).
В качестве альтернативы установите Allowed (Разрешено) для расширения веб-службы All Unknown ISAPI Extensions (Все неизвестные расширения ISAPI). Данный параметр разрешает выполнение любого запроса относительно любого расширения ISAPI.
Включение данной настройки нарушает безопасность сервера, поэтому используйте этот параметр только в изолированных средах, таких как среда разработки.
Разрешения на выполнение веб-экземпляра IIS или виртуального каталога устанавливаются на разрешение выполнения библиотек ISAPI DLL. По умолчанию параметр Execute Permissions (Разрешения на выполнение) в окне свойства веб-экземпляра IIS или виртуального каталога не позволяет выполнять сценарии и исполняемые файлы.
- Откройте оснастку IIS MMC Computer Management (Управление компьютером) и щелкните правой кнопкой мыши на веб-экземпляре или виртуальном каталоге для отображения контекстного меню.
- Выберите Properties (Свойства) для открытия окна свойств веб-экземпляра или виртуального каталога.
- Во вкладке Virtual Directory (Виртуальный каталог) окна свойств виртуального каталога или во вкладке Home Directory (Домашний каталог) веб-экземпляра расположено поле со списком Execute Permissions (Разрешения на выполнение) (см. рис. 5.10). Убедитесь, что отмечена опция Scripts And Executables (Сценарии и исполняемые файлы).
Если в IIS все настроено должным образом, ISAPI Hello World будет функционировать. Запросите библиотеку ISAPI DLL в адресе URL из браузера, как если бы это был файл HTML – и DLL выполнится (см. рис. 5.11).



