Опубликован: 24.11.2006 | Доступ: свободный | Студентов: 716 / 33 | Оценка: 4.46 / 4.54 | Длительность: 17:18:00
Лекция 5:

Расширения ISAPI

Главная точка входа расширения ISAPI

Файл HelloWorld.cpp необходимо настроить на поддержку функций, необходимых для обеспечения работы расширения ISAPI.

  1. В Visual Studio .NET откройте файл HelloWorld.cpp для редактирования посредством двойного щелчка на имени файла в окне Solution Explorer.
  2. Удалите функцию DLLMain (она не нужна в данном примере).
  3. В верхней части файла с кодом добавьте препроцессорную директиву включения для файла заголовка httpext.h и <string> (см. листинг 5.2).
  4. Добавьте функцию GetExtensionVersion (см. листинг 5.2).
  5. Добавьте функцию 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).

Включение программной функциональности серверной части в окне Web Service Extensions (Расширения веб-служб)

увеличить изображение
Рис. 5.8. Включение программной функциональности серверной части в окне Web Service Extensions (Расширения веб-служб)

Настроим IIS на разрешение запросов расширения ISAPI HelloWorld.

  1. В окне администрирования расширения веб-служб щелкните на ссылке Add A New Web Service Extension (Добавить новое расширение веб-службы). Откроется диалоговое окно New Web Service Extension (Новое расширение веб-службы).
  2. В текстовом поле Extension Name (Имя расширения) введите имя, которое будет отображаться в окне администрирования расширения веб-служб. В нашем примере это имя HelloWorld (см. рис. 5.9).
    Диалоговое окно New Web Service Extension (Новое расширение веб-службы)

    Рис. 5.9. Диалоговое окно New Web Service Extension (Новое расширение веб-службы)
  3. Нажмите на кнопку Add (Добавить), чтобы указать путь к файлу расширения ISAPI. Откроется диалоговое окно Add File (Добавление файла), в котором вручную вводится путь к файлу, либо укажите его расположение в окне Open File (Открыть файл) после нажатия на кнопку Browse (Обзор).
  4. Установите путь к файлу расширения ISAPI, затем нажмите на кнопку OK в диалоговом окне Add File (Добавление файла). Файла расширения ISAPI отобразится в диалоговом окне New Web Service Extension (Новое расширение веб-службы).
  5. Отметьте опцию Set Extension Status To Allowed (Разрешить использование расширения), после чего нажмите на кнопку OK.

Расширение HelloWorld появится в окне администрирования расширения веб-служб консоли Copmuter Management (Управление компьютером), и в поле Status (Состояние) отобразится значение Allowed (Разрешено).

В качестве альтернативы установите Allowed (Разрешено) для расширения веб-службы All Unknown ISAPI Extensions (Все неизвестные расширения ISAPI). Данный параметр разрешает выполнение любого запроса относительно любого расширения ISAPI.

Включение данной настройки нарушает безопасность сервера, поэтому используйте этот параметр только в изолированных средах, таких как среда разработки.

Разрешения на выполнение веб-экземпляра IIS или виртуального каталога устанавливаются на разрешение выполнения библиотек ISAPI DLL. По умолчанию параметр Execute Permissions (Разрешения на выполнение) в окне свойства веб-экземпляра IIS или виртуального каталога не позволяет выполнять сценарии и исполняемые файлы.

  1. Откройте оснастку IIS MMC Computer Management (Управление компьютером) и щелкните правой кнопкой мыши на веб-экземпляре или виртуальном каталоге для отображения контекстного меню.
  2. Выберите Properties (Свойства) для открытия окна свойств веб-экземпляра или виртуального каталога.
  3. Во вкладке Virtual Directory (Виртуальный каталог) окна свойств виртуального каталога или во вкладке Home Directory (Домашний каталог) веб-экземпляра расположено поле со списком Execute Permissions (Разрешения на выполнение) (см. рис. 5.10). Убедитесь, что отмечена опция Scripts And Executables (Сценарии и исполняемые файлы).
Установка разрешений для виртуального каталога

Рис. 5.10. Установка разрешений для виртуального каталога

Если в IIS все настроено должным образом, ISAPI Hello World будет функционировать. Запросите библиотеку ISAPI DLL в адресе URL из браузера, как если бы это был файл HTML – и DLL выполнится (см. рис. 5.11).

Выполнение расширения ISAPI HelloWorld

Рис. 5.11. Выполнение расширения ISAPI HelloWorld