IIS 7.0 Построение решений веб-сервера с использованием сквозной расширяемости

Источник: max404

Веб-платформа IIS 7.0 поддерживает большее число технологий инфраструктуры приложений для размещения многофункциональных приложений, чем любая предыдущая версия IIS, она буквально напичкана функциями, которые можно использовать для развертывания этих приложений сразу же после установки. Однако в то же время вы видите (в установке Windows®) не обязательно то, что всегда получаете.
Архитектура IIS 7.0 выполнена таким образом, что позволяет ей быть расширяемой сверху донизу, это дает возможность заменять любую часть встроенного набора функций на собственные разработки, которые наилучшим образом соответствуют вашим требованиям. В результате этого вместо латания лоскутного одеяла из подключаемых модулей IIS 7.0 дает совершенно уникальные возможности по расширяемости путем реализации всех собственных функций поверх общедоступной модели расширяемости. Эта конструкция прослеживается по всей платформе, начиная от самого модульного механизма веб-сервера и до системы настройки консоли диспетчера IIS.
В этой статье я постараюсь погрузиться в тонкости модели расширения IIS 7.0, рассмотрев для этого исходный код общего пользования проекта модуля изменения ответа, который позволяет получать отклики приложений IIS и изменять их "на лету", используя для этого настраиваемые правила изменения откликов. Вначале я построю модуль веб-сервера, воспользовавшись встроенной в сервервозможностью расширения ASP.NET. Затем я создам функции развертывания и управления для модуля, разработав раздел пользовательской настройки и создав специальную страницу управления для диспетчера IIS.

Расширение веб-сервера

Модульная архитектура IIS 7.0 предоставляет возможность полностью перестроить веб-сервер под требуемую рабочую нагрузку. Зачастую это может быть выполнено просто путем установки только тех функций, которые необходимы для вашего приложения, в результате чего появляется веб-сервер с урезанной функциональностью, позволяющей делать только то, что необходимо, и ничего более.
Однако это только первый шаг. Зачастую нужная рабочая нагрузка требует наличия дополнительных функций, которые могут не входить во встроенный набор функций IIS. Или же в некоторых случаях приложениям может потребоваться специальный набор функций, для выполнения которых встроенные функции недостаточно приспособлены. Поскольку все функции IIS 7.0 построены на общедоступных интерфейсах расширяемости API, вы можете заменить любой из них собственной разработкой, которая наилучшим образом соответствует вашим требованиям.
IIS 7.0 предоставляет два способа разработки модулей веб-сервера. Во-первых, можно использовать новый интерфейс API для модулей на C++, на котором основана большая часть встроенных функций. Интерфейс API модулей заменяет расширение ISAPI и интерфейс API фильтра, применявшиеся в предыдущих версиях IIS. Этот интерфейс API является существенным усовершенствованием по сравнению с ISAPI, поскольку он способен поддерживать все функции IIS 7.0 и гораздо проще для использования в программировании. Узнать подробней об усовершенствованиях в этом интерефейсе API можно по адресу: mvolo.com/blogs/serverside/archive/2006/10/07/10-reasons-why-server-development-is-better-with-IIS7.aspx.
Во-вторых, в IIS 7.0 введена интеграция с ASP.NET, которая позволяет разрабатывать модули IIS 7.0 с использованием хорошо знакомых интерфейсов API модулей в ASP.NET. В объединенном режиме ASP.NET эти модули становятся полноправными участниками конвейерной обработки запросов IIS, как видно из рис. 1. Это позволяет модулям ASP.NET получать доступ ко встроенным объектам IIS, таким как запросы и ответы, на всех стадиях обработки и обрабатывать запросы для всех типов ресурсов - не только для тех, которые обрабатываются платформой ASP.NET.


Рис. 1 Модули ASP.NET в обработке запросов IIS 7.0

Это позволяет использовать одинаково по всему веб-узлу такие многосторонние функции ASP.NET, как проверка подлинности на основе форм, элементы управления входом в систему и служба членства. Для более подробного изучения того, как объединенный режим ASP.NET может быть использован с целью повышения функциональных возможностей приложений, написанных не для платформы ASP.NET, прочтите мою статью в январском номере журнала MSDN® Magazine за 2008 год, расположенную по адресу: msdn.microsoft.com/msdnmag/issues/08/01/PHPandIIS7.
Для разработчиков истинная ценность объединенного режима ASP.NET заключается в возможности наращивать функциональность веб-сервера IIS с использованием платформы Microsoft® .NET Framework. Это дает существенные преимущества при быстрой разработке приложений путем обеспечения возможности строить эти приложения на основе широкой поддержки платформ .NET Framework, ASP.NET, а также других платформ, таких как Windows Workflow Foundation.

Модуль изменения ответа

Объединенный конвейер ASP.NET дает возможность модулям ASP.NET выполнять широкий спектр задач в ходе обработки каждого запроса. Этот спектр содержит все, начиная от задач проверки подлинности или авторизации и до изменения исходящих ответов перед их отправкой клиенту.
Назначением модуля изменения ответа является выполнение изменения ответа: он позволяет изменять существующие ответы "на лету" при помощи набора правил замены. Для этого можно использовать механизм фильтрации ответов ASP.NET, который, благодаря объединения со средой выполнения, обеспечивает фильтрацию исходящих ответов любого содержания, включая статические файлы, а также сценарии ASP и PHP.
Если в прошлом вы разработали модуль ASP.NET, то вас, несомненно, обрадует тот факт, что вы сможете использовать те же интерфейсы API для разработки модулей ASP.NET на платформе IIS 7.0. Фактически, имеющиеся у вас модули продолжают работать точно так же, как они работали в предыдущих версиях IIS (если только не нужно использовать преимущества объединенного режима IIS 7.0 и запускать их для обработки всех запросов). Модуль является классом, реализующим интерфейс System.Web.IHttpModule и регистрирующим обработчики событий для событий конвейерной обработки одного или нескольких запросов. Модуль изменения ответов именно такой:

class ResponseModificationModule : IHttpModule
{
  public void Init(HttpApplication app)
  {
    // Wire up the filter in PreRequestHandlerExecute
    app.PreRequestHandlerExecute += 
      new EventHandler(OnPreRequestHandlerExecute);
  }

  public void OnPreRequestHandlerExecute(
    Object source, EventArgs e)
  {
    ...
  }
}

По существу, модуль подписывается на событие PreRequestHandlerExecute, которое происходит всякий раз перед выполнением обработчика запроса. Метод OnPreRequestHandlerExecute используется для чтения сведений настройки с целью определить, имеет ли ответ какие-нибудь применимые для него правила замены (подробнее о настройке - далее в этой статье), и в случае наличия таковых регистрировать поток фильтра ответов, который затем будет использован для фильтрации исходящих ответов, как показано на рис. 2.
Figure 2 Фильтр ответов

public void OnPreRequestHandlerExecute(Object source, EventArgs e)
{
  HttpApplication app = (HttpApplication)source;
  HttpContext context = app.Context;

  // Read configuration 
  ResponseModificationConfigurationSection config;
  
  ...

  // Get the list of filters
  ResponseFilterList filters = GetApplicableFilters(context, config);

  // Create the filter and wire it up
  if (null != filters && filters.Count > 0)
  {
    context.Response.Filter = 
      new ChainedBufferedStringResponseFilter(
        context, filters);
  }
}

Фильтрация ответов выполняется внутри класса ChainedBufferedStringResponseFilter, который отвечает за преобразование байтов ответов в строку при помощи набора символов ответов, а также за вызов одного или несколько фильтров ответов, которые применимы к данному запросу. Модуль связывает фильтр с ответом путем установки свойства HttpResponse.Filter. Это свойство принимает все объекты, порожденные от абстрактного класса System.IO.Stream, и позднее использует их для фильтрации тела экземпняра исходящего ответа.
Функция фильтрации ответов ASP.NET - всего лишь один из механизмов, которые становится возможным использовать при разработке модулей ASP.NET для объединенного режима платформы IIS 7.0. Кроме того, можно переписывать URL-адреса, выполнять проверку подлинности и авторизацию запросов, модифицировать или выпускать файлы "cookie" и заголовки ответов, журналировать запросы и многое другое. Большинство задач, которые ранее требовали разработки в среде ISAPI в машинном коде, теперь могут быть реализованы путем простого написания модулей ASP.NET. Поэтапные указания по сборке модулей ASP.NET для IIS 7.0, параметрам среды разработки и выполнению развертывания можно найти по адресу: mvolo.com/blogs/serverside/archive/ 2007/08/15/Developing-IIS7-web-server-features-with-the-.NET-framework.aspx.
При разработке модуля IIS 7.0 можно использовать возможности ряда функций IIS, используемых для целей управления и развертывания. Одна из таких функций - возможность указывать пользовательскую настройку модуля в файлах настройки IIS 7.0 и либо принудительно развертывать эту настройку автоматически самим приложением, либо управлять ею с помощью ряда средств администрирования IIS 7.0 и интерфейсов API. Выполнение такой процедуры является залогом того, что все функции, выполняемые модулем, будут правильно настроены и управляемы конечными пользователями.

Расширение настройки

Новая система настройки является основой для большого числа основных вариантов развертывания и управления, возможных для платформы IIS 7.0. Вместо того, чтобы быть машинно-ориентированным зранилищем настройки закрытого формата, система настройки IIS 7.0 основана на структурированных файлах настройки формата XML, располагающихся в тех же файлах настройки, используемых системой настройки ASP.NET. Более того, синтаксис данных настройки IIS идентичен синатксису данных настройки ASP.NET; эти данные могут быть совместно записаны в распространяемые файлы web.config, с которыми разработчики ASP.NET очень хорошо знакомы.
Такая схема открывает многие двери. Во-первых, она позволяет приложениям указывать данные настройки IIS вместе со своим прикладным содержимым, что упрощает процесс их развертывания до простой публикации содержимого на сервере. Это гарантирует, что приложения будут работать правильно без необходимости изменять данные машинной настройки, хранящиеся на каждом сервере, на котором эти приложения развертываются, а также без необходимости иметь полномочия администратора на каждом сервере. Структурированный файл настроки формата XML совместно с возможностью размещать настройку ASP.NET вместе с настройкой IIS в одном файле значительно упрощает задачу разработчиков создавать данные настройки, относящиеся к IIS, и управлять ими. Эта задача может выполняться с помощью редактора файлов XML, например Notepad и Visual Studio®, или может быть автоматизирована с помощью интерфейсов API настройки, предоставляемых стеком администрирования IIS 7.0.
Но самым замечательным здесь является тот факт, что система настройки IIS 7.0 является полностью расширяемой. Возможность предоставлять специальному веб-серверу право публикации настроек, которые могут устанавливаться и управляться вместе с настройкой IIS 7.0, играет ключевую роль в построении полных решений для IIS 7.0.
В отличие от системы настройки .NET, добавление нового раздела настройки IIS 7.0 не требует использования программного кода, поскольку сами разделы IIS 7.0 определяются с использованием схемы, основанной на XML. Фактически, все встроенные разделы настройки IIS 7.0 определяются с использованием этого механизма. Найти определения всех разделов настройки IIS можно найти в каталоге %windir%\system32\inetsrv\config\schema в файле IIS_Schema.xml. Например, раздел настройки <defaultDocument>, который включает и настраивает документы по умолчанию для вашего приложения, определяется следующим образом:

<sectionSchema name="system.webServer/defaultDocument">
  <attribute name="enabled" type="bool" defaultValue="true" />
  <element name="files">
    <collection addElement="add" clearElement="clear" 
      removeElement="remove" mergeAppend="false">
      <attribute name="value" type="string" isUniqueKey="true"/>
    </collection>
  </element>
</sectionSchema>

Такая схема определяет все элементы и атрибуты, которые составляют раздел настройки, их типы и дополнительные сведения, такие как определения коллекций и характер проверки атрибутов. Для получения дополнительных сведений о синтаксисе и определениях схем см. комментарии в заголовке файла настройки IIS_Schema.xml.

Настройка модуля изменения ответа

Модуль изменения ответа требует наличия собственного раздела настройки для настройки ряда специальных параметров, в том числе сведений о том, какие правила фильтрации применимы для данного приложения. Чтобы предоставить возможность использовать этот раздел в файлах настройки IIS, в первую очередь необходимо создать файл схемы, который описывал бы структуру раздела (см. рис. 3). Этот файл определяет раздел responseModification и его структуру, включая необходимые атрибуты и коллекцию правил фильтрации, которые могут настраиваться для вызова различных фильтров с дополнительной информацией о том, что и чем должно заменяться.
Figure 3 Схема настройки модуля изменения ответа

<configSchema>
  <sectionSchema name="responseModification">
    <attribute name="enabled" type="bool" defaultValue="false" />
    <collection addElement="add" clearElement="clear" 
      removeElement="remove">
      <attribute name="name" type="string" required="true" 
        isUniqueKey="true" validationType="nonEmptyString" />
      <attribute name="conditionType" type="string" required="false" />
      <attribute name="condition" type="string" required="false" />
      <attribute name="replaceType" type="string" required="true" 
        validationType="nonEmptyString" />
      <attribute name="replace" type="string" required="false" />
      <attribute name="replaceWith" type="string" required="false" />
      <attribute name="options" type="string" required="false" />
    </collection>
  </sectionSchema>
</configSchema>

Для установки этого раздела настройки необходимо сделать две вещи. Во-первых, скопируйте файл responsemod_schema.xml, содержащий сведения о схеме раздела, в папку %windir%\system32\inetsrv\config\schema. Затем объявите раздел настройки в основном файле настройки сервера, applicationHost.config. Последняя задача потребует написания некоторого кода, если вы пожелаете выполнить эту установку с помощью программы.
Чтобы упростить процесс установки раздела настройки IIS 7.0, я написал служебную программу iisschema.exe, которая выполняет обе эти задачи автоматически. Эту программу можно получить по адресу: mvolo.com/blogs/serverside/archive/2007/08/04/IISSCHEMA.EXE-_2D00_-A-tool-to-register-IIS7-configuration-sections.aspx. С использованием этой программы процедура установки раздела схемы настройки становится одношаговой:

IisSchema.exe /install responsemod_schema.xml

После того как схема раздела настройки установлена, а сам раздел объявлен в файле applicationHost.config, можно начать использовать его для определения данных настройки модуля.
Для управления настройкой раздела можно использовать любое из средств настройки IIS или интерфейсов API, точно так же, как это делалось бы с любым встроенным разделом настройки IIS 7.0. Например, я хочу включить функцию изменения ответов для моего приложения с помощью AppCmd, средства командной строки IIS 7.0:

%windir%\system32\inetsrv\AppCmd Set Config "Default Web Site/" 
/section:responseModification  /enabled:true 

Кроме того, я могу добавить в раздел настройки responseModification коллекцию правил:

%windir%\system32\inetsrv\AppCmd Set Config "Default Web Site/" 
"/+[name='StripWhitespace',replaceType=
'Mvolo.ResponseModification.Filters.HtmlDeflate']"

Если теперь вы откроете файл web.config в корневой папке веб-узла по умолчанию (обычно это %windir%\inetpub\wwwroot), вы обнаружите следующий код:

<configuration>
  <responseModification enabled="true">
    <add name="StripWhitespace" 
      replaceType="Mvolo.ResponseModification.Filters.HtmlDeflate" />
  </responseModification>
</configuration>

Если вы исправили файл приложения web.config с целью изменения данных настройки модуля, а затем загрузили его на сервер, приложение будет настроено таким образом, чтобы использовать эти новые параметры. Точно так же, если вы загрузили приложение на другой сервер, на котором установлен раздел настройки, вы можете быть уверены, что данное приложение будет использовать нужные параметры без необходимости перенастройки его на этом сервере.
В дополнение к AppCmd, теперь можно использовать для управления данными настройки данного раздела любой интерфейс API настройки IIS 7.0, включая управляемый интерфейс Microsoft.Web.Administration, поставщик WMI из IIS 7.0, объекты COM настройки IIS 7.0 , а также Windows PowerShell®. Кроме установки и чтения данных настройки, можно выполнять любые задачи управления, поддерживаемые системой настройки IIS 7.0, включая управление процессом делегирования данного раздела приложениям, защиту их содержимого путем шифрования настройки и т.д. Те мне менее, чтобы эти данные настройки были полезными, вам потребуется возможность читать их из модуля изменения ответа.
Интерфейс API Microsoft.Web.Administration является новым интерфейсом .NET Framework, предоставляемым IIS 7.0; он позволяет программам иметь доступ к данным настройки IIS 7.0. Кроме того, что этот интерфейс предоставляет программам настройки и установки возможность управлять настройкой, он также дает возможность считывать данные настройки непосредственно из управляемого модуля.
Можно использовать этот интерфейс API для чтения раздела настройки из модуля сразу же после регистрации раздела настройки, поскольку интерфейс API предоставляет нестрого типизированную модель для чтения разделов настройки. Перед тем как делать это, вам необходимо добавить ссылку на файл Microsoft.Web.Administration.dll, который находится в папке %windir%\system32\inetsrv. Заметим, что эта библиотека DLL входит в состав только IIS 7.0 под Windows Vista® или Windows Server® 2008 и не поставляется в составе .NET Framework или комплекта SDK для Windows.
После того, как ссылка добавлена, можно читать данные настройки модуля:

ConfigurationSection section = 
  WebConfigurationManager.GetSection(
    context, 
    "responseModification");

bool enabled = (bool)section["enabled"];

Класс WebConfigurationManager в пространстве имен Microsoft.Web.Administration почти идентичен WebConfigurationManager в пространстве имен System.Web.Configuration и призван заменить последний для работы с управляемыми модулями IIS 7.0, выполняющими чтение настройки IIS 7.0. Метод GetSection выбирает объект раздела настройки по пути, указанному в текущем запросе HTTP.

Строго типизированный класс настройки

Объект ConfigurationSection предоставляет нестрого типизированный доступ к любому разделу настройки, не требуя написания дополнительного кода. Можно получить доступ ко включенному атрибуту путем простого извлечения его имени в индексаторе объекта раздела и приведения его к ожидаемому типу.
Тем не менее, можно продвинуться на один шаг вперед, создав строго типизированную оболочку для раздела настройки. Можно быстро создать класс оболочки с помощью служебной программы, написанной Канвальетом Синглой (Kanwaljeet Singla), участником команды IIS; эту программу можно загрузить по адресу: blogs.iis.net/ ksingla/archive/2006/12/04/tool-to-generate-strongly-typed-classes-for-configuration-sections.aspx. Она позволяет создавать класс оболочки для раздела, имеющего примерно такой вид, как показан на рис. 4. Этот класс просто обертывает нижележащий класс ConfigurationSection и предоставляет строго типизированные свойства для доступа к исходным данным настройки.
Figure 4 Строго типизированная обертка раздела настройки

class ResponseModificationSection : ConfigurationSection
{
  public bool Enabled
  {
    get { return (bool)this["enabled"]; }
    set { this["enabled"] = value; }
  }

  public ResponseModificationRuleCollection FilterRules
  {
    get 
    { 
      return (ResponseModificationRuleCollection)
        GetCollection(typeof(ResponseModificationRuleCollection)); 
    }
  }
}

Как видно из реализации свойства Enabled, обертывание атрибутов настройки является достаточно простым. Обертывание дочерних элементов и коллекций требует последующей реализации классов оберток, наследуемых соответственно из ConfigurationElement и ConfigurationCollection (не показаны), точно таких же, как сама обертка раздела.
После того, как класс обертки создан, его можно скомпилировать в отдельную сборку и указать ссылку на него в проекте модулей или просто добавить его в виде файла исходного кода. Это позволит модулю иметь безопасный относительно типов доступ к разделу настройки:

ResponseModificationSection section =
  (ResponseModificationSection)WebConfigurationManager.GetSection(
    context, 
    "responseModification", 
    typeof(ResponseModificationSection)
  );

bool enabled = section.Enabled;

Подобным образом можно получить безопасный относительно типов доступ к коллекции правил изменения ответов и свойствам каждого элемента правил. Это значительно упрощает программирование по сравнению с разделами настройки и сокращает количество ошибок безопасности типов, которые являются довольно частыми в случае нестрого типизированного доступа к данным. Кроме того, поскольку весь код, используемый для доступа к нижележащим данным, создается автоматически с помощью служебной программы, можете настроить программу Visual Studio для автоматического построения классов оберток из файла схемы настройки при очередной компиляции проекта. Это делает управление изменениями, вносимыми в схему раздела настройки, чрезвычайно простым.

Расширение IIS Manager

Итак, я уже показал, как создать модуль изменения ответа и позволить ему читать специальный раздел настройки, который управляет его поведением. Эта настройка может храниться в тех же файлах настройки, что содержат оставшиеся данные настройки IIS, может развертываться вместе с приложением в файлах web.config, а также может обрабатываться с помощью различных программных средств и интерфейсов API, в том числе AppCmd.exe и Microsoft.Web.Administration.
К этому моменту модуль изменения ответа может быть развернут и соответствующим образом настроен в любой среде IIS. Тем не менее, можное продвинуться еще на один шаг вперед, предоставив функции специальные возможности управления для консоли диспетчера IIS. Сделав это, вы получите ряд преимуществ. Это позволит системным администраторам без труда настраивать модуль с помощью консоли диспетчера IIS, не требуя от них править непосредственно файлы настройки или использовать другие низкоуровневые служебные программы и интерфейсы API. Это также позволяет обрабатывать данные настройки модуля с помощью средств удаленного администрирования диспетчера IIS, которые предоставляют пользователю преимущества службы веб-управления (WmSvc).
В отличие от других средств, которые тоже поддерживают функции удаленного администрирования, архитектура удаленного администрирования диспетчера IIS имеет ряд ключевых преимуществ. Во-первых, она позволяет пользователям, не обладающим правами администратора на сервере, управлять веб-узлами и приложениями, которые доступны для них. Во-вторых, механизм удаленного администрирования диспетчера IIS использует протокол HTTPS, а не DCOM, который проще проходит через корпоративные брандмауэры. В сочетании обе эти возможности делают диспетчер IIS Manager привлекательным для делегированного удаленного управления веб-узлами IIS, особенно в средах совместного веб-размещения.
В полном соответствии с основной идеей IIS 7.0, диспетчер IIS имеет расширяемую архитектуру, на которой основано большинство встроенных функций диспетчера IIS. С целью упрощения случая удаленного управления каждая функция управления состоит из двух частей: компонентов клиентской части, которая предоставляет пользовательский интерфейс внутри диспетчера IIS, и серверных компонентов, которые предоставляют собственно сами службы управления.
Служба на стороне сервера загружается внутри диспетчера IIS Manager в случаях локального управления или внутри службы веб-управления в случаях удаленного управления. Во втором случае диспетчер IIS поддерживает необходимый обмен данными между компонентами в диспетчере IIS на машине клиента и службой, запущенной внутри WmSvc на машине принимающего сервера.

Создание службы

Клиентские и серверные компоненты обычно выполнены в виде двух отдельных сборок .NET, которые не ссылаются друг на друга. Обмен данными между клиентскими и серверными компонентами осуществляется посредством абстракции ModuleServiceProxy диспетчера IIS, которая использует для обмена информацией набор нестрого типизированных свойств и основных типов .NET.
Серверная сборка обычно содержит реализацию класса Microsoft.Web.Management.Server.ModuleProvider, который выполняет требуемую регистрацию служб и клиентских модулей, а также реализацию класса Microsoft.Web.Management.Server.ModuleService, который представляет методы служб для выполнения требуемых задач управления.
Моя сборка Mvolo.ResponseModificationUI.Server.dll содержит класс ResponseModificationModuleProvider, который отвечает за регистрацию класса служб ResponseModificationModuleService в дополнение к классу клиентского модуля ResponseModificationModule, как это показано на рис. 5.
Figure 5 Класс поставщика модулей

public sealed class ResponseModificationModuleProvider : 
  ConfigurationModuleProvider
{
  public override Type ServiceType
  {
    get { return typeof(ResponseModificationModuleService); }
  }

  public override ModuleDefinition 
    GetModuleDefinition(IManagementContext context)
  {
    return new ModuleDefinition(Name,
      "Mvolo.ResponseModification.UI.Client.ResponseModificationModule,"+
      "Mvolo.ResponseModificationUI.Client," +
      "Version=1.0.0.0, Culture=neutral," +
      "PublicKeyToken=309ac0e1b5482072");
  }

  protected override string ConfigurationSectionName
  {
    get { return "responseModification"; }
  }
}

Класс ResponseModificationModuleService порождается от класса ConfigurationModuleProvider, который предоставляет встроенную поддержку для управления функциями делегирования диспетчера IIS, основанными на состоянии делегирования нижележащего раздела настройки. Все, что нужно сделать, - указать имя раздела настройки, responseModification, и диспетчер IIS автоматически переключит состояние делегирования функций в зависимости от того, заблокирован или разблокирован этот раздел для отдельных путей настройки. Инфраструктура Microsoft.Web.Management предоставляет несколько других базовых классов ModuleProvider, которые поддерживают немного другие случаи делегирования для средства диспетчера IIS.
Метод GetModuleDefinition возвращает тип модуля диспетчера IIS, который будет создан на стороне клиента, чтобы зарегистрировать требуемые компоненты интерфейса пользователя диспетчера IIS, такие как страница управления.
Обратите внимание на то, что тип класса ResponseModificationModule на стороне клиента - строковый, но не объект типа Type, поскольку серверная сборка может не ссылаться на сборку клиента, которая будет загружена в диспетчер IIS на машине удаленного клиента. Это один из побочных эффектов, обусловленный тем фактом, что компоненты клиента и сервера могут быть запущены в разных процессах и не могут совместно использовать пользовательские типы.
Класс ResponseModificationModuleService отвечает за реализацию функций управления и использование методов служб, которые вызваются страницей управления в диспетчере IIS (см. рис. 6).
Figure 6 Класс службы модулей

public sealed class ResponseModificationModuleService : ModuleService
{
  [ModuleServiceMethod]
  public ArrayList GetFilterRules()
  {
    ArrayList items = new ArrayList();

    ResponseModificationSection section = 
      (ResponseModificationSection)ManagementUnit.Configuration
        .GetSection("responseModification",
          typeof(ResponseModificationSection));

    foreach (ResponseModificationRuleElement rule in section.Rules)
    {
      items.Add(GetPropertyBag(rule));
    }

  return items;
  }
  ...
}  

Метод GetFilterRules является примером использования нескольких методов службой, выполняющей задачи управления с использованием системы настройки, а также других ресурсов, локальных для сервера. Экземпляр службы всегда создается на сервере, так что он постоянно работает на локальных ресурсах, поэтому нет необходимости волноваться о раздельном доступе к ресурсам в случае удаленного администрирования. Обратите внимание на то, что я снова использую интерфейс API Microsoft.Web.Administration для доступа к разделу настройки responseModification, при этом использую строго типизированную обертку ResponseModificationConfigurationSection, созданную для обеспечения доступа модуля к настройке.
Свойство ManagementUnit является основной точкой доступа к локальному серверу, оно предоставляет ряд других объектов, которые обеспечивают доступ к системе настройки и другим объектам управления, сосредоточенным на сервере, которые были созданы с помощью платформы Microsoft.Web.Management с целью помочь в реализации задач управления сервером. Практический опыт показывает, что реализации служб должны всегда использовать блок управления для задач управления локальной настройкой, а не создавать собственные системы настройки.
Методы наподобие GetFilterRules могут возвращать клиенту данные, используя основные типы, например, ArrayList, для пересылки данных клиентским компонентам. Снова обратите внимание на то, что нельзя осуществлять обмен данными ипри помощи строго типизированных классов, определенных на серверной или клиентской сборках, потому что они предназначены для раздельного использования и не должны ссылаться друг на друга. Служба ResponseModificationModuleService также определяет дополнительные методы служб, аналогичные GetFilterRules, в том числе EditFilterRule, AddFilterRule и DeleteFilterRule, предназначенные для выполнения операций управления, которые могут быть затребованы страницей модуля изменения ответа.

Создание страницы модуля
Клиентские компоненты определяют функции графического интерфейса пользователя (GUI), предоставляемые пользователю с помощью диспетчера IIS. Клиентская сборка обычно содержит реализацию следующих классов:
Класс Microsoft.Web.Management.Client.Module, ответственный за регистрацию всех требуемых страниц диспетчера IIS и других расширений пользовательского интерфейса.
Класс Microsoft.Web.Management.Client.ModulePage, который содержит описание текущей страницы управления, отображаемой диспетчером IIS.
Класс Microsoft.Web.Management.Client.ModuleServiceProxy, коорый предоставляет клиентские компоненты совместно с классом локального прокси для вызова методов служб, используемых ModuleService.
Сборка Mvolo.ResponseModificationUI.Server.dll содержит класс ResponseModificationModule, показанный на рис. 7 (не путать собственно с классом IhttpModule, предоставляющим службы модуля при конвейерной обработке запросов IIS), который предоставляет главную точку входа для регистрации всех требуемых компонентов пользовательского интерфейса в диспетчере IIS. Этот класс регистрирует класс ResponseModificationModulePage, который содержит описание текущей управляющей страницы.
Figure 7 Класс модулей

public sealed class ResponseModificationModule : Module
{
  protected override void Initialize(IServiceProvider serviceProvider, 
    ModuleInfo moduleInfo)
  {
    base.Initialize(serviceProvider, moduleInfo);

    IControlPanel controlPanel =
      (IControlPanel)GetService(typeof(IControlPanel));

    controlPanel.RegisterPage(
      new ModulePageInfo(this,
      typeof(ResponseModificationModulePage),
      Resources.PageTitle,
      Resources.PageDescription,
      null,
      null,
      Resources.PageText
      ));
  }
}

Каждая реализация модуля создается однократно за время управляющего подключения, выоплненного диспетчером IIS, она ответственна за регистрацию всех страниц управления и элементов пользовательского интерфейса, необходимых для данного подключения. ResponseModificationModule регистрирует класс ResponseModificationModulePage, который определяет содержимое управляющей страницы.
Честно говоря, я не большой поклонник программирования пользовательских интерфейсов, я предпочел бы программировать низкоуровневые серверные программы, которые не требуют разработки интерфейса. К счастью для меня, платформа Microsoft.Web.Management предоставляет целый ряд базовых классов и поддерживающих классов, предназначенных для создания обычных управляющих страниц, включая класс Microsoft.Web.Management.Client.Win32.ModuleListPage, который я использовал для ResponseModificationModulePage.
Этот класс имеет встроенное представление в виде списка для просмотра списков элементов и работы с ними, включая упорядочение списков и работу с элементами списка. С минимальными переделками я смог создать страницу управления, содержащую перечень правил изменения ответов (см. центральную панель на рис. 8).


Рис. 8 Страница изменения ответов в диспетчере IIS

Затем я создал перечень действий, показанный в правом окне, позволяющий добавлять, изменять и удалять правила изменения ответов. При создании этого перечня задач я использовал возможности класса Microsoft.Web.Management.Client.TaskList (см. правую панель на рис. 8).
Еще немного усилий, и функция изменения, показанная на рис. 8, является на свет. Можно изучить детали пользовательского интерфейса, посмотрев исходный код для платформы изменения ответа.
Операции создания новой страницы, добавления, правки и удаления, запускаемые с панели действия, выполняются с помощью методов класса ResponseModificationModuleServiceProxy, который предоставляет локальный прокси для методов модулей, вызываемых службой модулей:

public sealed class ResponseModificationModuleServiceProxy : 
  ModuleServiceProxy
{
  public ArrayList GetFilterRules()
  {
    return (ArrayList)Invoke("GetFilterRules");
  }

  public void AddFilterRule(PropertyBag bag)
  {
    Invoke("AddFilterRule", bag);
  }

  ...
} 

Диспетчер IIS автоматически передает вызовы, сделанные к классу прокси службы модулей, на связанную службу модуля по каналу обмена данными, который может представлять собой локальный канал совместно используемой памяти или канал https на удаленный сервер.

Развертывание расширения

При развертывании расширения диспетчера IIS учтите, что нужно зарегистрировать тип поставщика модуля в файле настройки диспетчера IIS на сервере (%windir%\system32\inetsrv\config\administration.config). Настройка, показанная на рис. 9, регистрирует поставщик модуля и предоставляет возможность использовать его на всех веб-узлах по умолчанию. Заметим, что и клиентская, и серверная сборки, образующие расширение, Mvolo.ResponseModificationUI.Server.dll и Mvolo.ResponseModificationUI.Client.dll, должны быть зарегистрированы в глобальном кэше сборок (GAC) и, следовательно, должны иметь строгое имя и подпись. Это требование, позволяющее выполнить установку расширений диспетчера IIS.
Figure 9 Настройка расширения диспетчера IIS

<moduleProviders>
  ...

  <!-- Mvolo ResponseModification -->
  <add name="ResponseModification" 
    type="Mvolo.ResponseModification.UI.Server
        .ResponseModificationModuleProvider, 
      Mvolo.ResponseModificationUI.Server, 
      Version=1.0.0.0, Culture=neutral, 
      PublicKeyToken=895e90205a14f2aa, 
      processorArchitecture=MSIL" />
</moduleProviders>

<!-- For all Sites -->
<location path=".">
  <modules>
    ...
    <add name="ResponseModification" />
  </modules>
</location>

Когда диспетчер IIS используется для удаленного управления сервером, он автоматически предложит пользователю загрузить клиентскую сборку вне зависимости от того, есть она уже или еще нет (это происходит при управлении IIS 7.0 на Windows Server 2008 клиентом Windows Vista SP1, Windows XP или Windows Server 2003 с использованием удаленного диспетчера IIS, который доступен по адресу: iis.net/ downloads/?tabid=34&g=6&i=1524). Прежде чем начать установку, убедитесь в том, что доверяете как серверу, к которому подключились, так и издателю расширения диспетчера IIS, поскольку в противном случае это может привести к запуску на вашем компьютере вредоносного кода с полномочиями вашей учетной записи.

Окончательная сборка

После развертывания модуля и установки схемы раздела настройки и расширения диспетчера IIS функция изменения ответа готова к использованию. Теперь можно применять эту функцию к любому приложению на вашем сервере и настраивать его с помощью любой программы настройки или интерфейсов API IIS 7.0.
Кроме того, можно использовать диспетчер IIS для быстрого управления правилами изменения ответов в приложениях как на локальном, так и на удаленном сервере. Используя поддержку делегирования диспетчера IIS, можно установить, кто из пользователей имеет право удаленно создавать и изменять правила изменения ответов для определенных веб-узлов сервера.
Для демонстрации функции изменения ответов в действии на рис. 10 показано, как настроены правила для приложения Qdig моей галереи изображений (см. msdn.microsoft.com/msdnmag/issues/08/01/PHPandIIS7). На рис. 11 показано, как использован фильтр Mvolo.ResponseModification.Filters.RegExReplace, поставляемый в составе платформы изменения ответа, для вставки текста колонтитулов на всех страницах веб-узла без изменения исходного кода приложения.
Figure 10 Включение колонтитулов

<responseModification enabled="true">
  <add name="Header" 
    conditionType=
      "Mvolo.ResponseModification.Conditions.ContentTypeCondition"
    condition="text/html" 
    replaceType="Mvolo.ResponseModification.Filters.RegExReplace" 
    replace="<body([^>]*)>" 
    replaceWith="<body$1><h1 align="center">
      Welcome to my gallery!</h1>" 
    options="IgnoreCase" />
  
  <add name="Footer" 
    conditionType=
      "Mvolo.ResponseModification.Conditions.ContentTypeCondition"
    condition="text/html" 
    replaceType="Mvolo.ResponseModification.Filters.RegExReplace" 
    replace="</body>" 
    replaceWith="<h3 align="center">
      Copyright mvolo 2007</h3></body>" 
    options="IgnoreCase"  />
 </responseModification>


Рис. 11. Использование модуля изменения ответов для изменения ответов

Модуль изменения ответов может быть также использован для выполнения любого количества пользовательских вставок, подстановок гиперссылок и других схем изменения ответов с помощью фильтров замен. Эти фильтры могут быть развернуты глобально или вместе с приложением и настроены с помощью правил настройки в разделе настройки responseModification.

Создавайте сами

Имеется не так много полезных способов использования функции изменения ответа, а именно всякий раз, когда невозможно добиться такого же результата путем изменения исходного кода приложения (что всегда более эффективно, чем изменение ответа "на лету"). Например, я всегда использую ее для внедрения небольшого сценария в ответы формата HTML, изменяющего теги изображений для использования вариантов изображений с высокой степенью сжатия и затем "на лету" заменяющего их вариснатми более высокого качества, в результате обеспечивается более быстрый обзор при использовании медленных клиентов. При этом также используется обработчик изображений, который позволяет получить изображения формата JPEG с любой требуемой степенью сжатия для статических изображений с помощью интерфейсов API компонента работы с изображениями Microsoft Windows. На рис. 11 показан результат работы, включая верхний и нижний колонтитулы и предварительно загруженные изображения с низким разрешением (перед тем, как они автоматически будут замещены качественными изображениями).
Изменение ответов "на лету" может быть достаточно дорогостоящим механизмом как с точки зрения загрузки ЦП, так и потребностей в памяти, поскольку для хранения изменяемых ответов должно быть выделено множество буферов большого размера. Такая дополнительная нагрузка может оказаться неприемлемой для рабочих веб-узлов в зависимости от типа используемых фильтров изменения ответов, их числа и требований к производительности приложения.
Чтобы получить дополнительные сведения об использовании модуля изменения ответов, следует загрузить сам модуль и его исходный текст с веб-узла разработчиков модуля изменения ответов: (www.mvolo.com/responsemod). Когда вы ознакомитесь с работой фильтров ответов и сможете спланировать их применения при наличии ограничений производительности для их использования, изучите примеры, приведенные на веб-узле разработчиков модуля изменения ответов. Для получения дополнительных сведений о расширении IIS 7.0 настоятельно рекомендуем посетить веб-узел по адресу: iis.net и мой блог mvolo.com, который посвящен разработке и использованию IIS 7.0.

Майк Володарский (Mike Volodarsky) является техническим руководителем программы в группе "Web Platform and Tools" корпорации Майкрософт. На протяжении последних четырех лет он руководил разработкой и созданием основной функциональности для ASP.NET 2.0 и IIS 7.0. В настоящее время его усилия сосредоточены на том, чтобы помочь пользователям использовать возможности этих технологий в среде Windows Server 2008.


Страница сайта http://test.interface.ru
Оригинал находится по адресу http://test.interface.ru/home.asp?artId=22979