Расширения 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).