Как подменить объект запроса

Опубликовано Fal'K°: 03.06.2008 в 15:58

Появилась у меня задача внести изменение в логику работы стандартного объекта запроса. В предыдущей статье я рассказывал откуда берется запрос и как он попадает в публикатор.

Далее подразумевается работа с HTTP запросом, но, думаю, понимая общие принципы можно добиться нужного результата и с другими типами запросов.

С чего начать?

Для начала нам необходимо создать собственный объект, пусть это будет CustomRequest, и унаследовать его от BrowserRequest, который можно найти в файле /path/to/zope/publisher/browser.py. Далее реализуете собственную расширенную функциональность в соответствии с вашей задачей.

Регистрация компонента

Теперь у нас есть собственный объект запроса, осталось только сказать публикатору Zope чтобы он использовал его вместо запроса по умолчанию. Зарегистрируем новый объект запроса как утилиту в файле конфигурации нашего компонента, например как показано ниже:

<configure
xmlns="http://namespaces.zope.org/zope">

<utility
component=”.publication.CustomRequest”
provides=”zope.app.publication.interfaces.IBrowserRequestFactory”
/>

<class class=”.publication.CustomRequest”>
<require like_class=”zope.publisher.browser.BrowserRequest” />
</class>

<class class=”.publication.CustomRequest”>
<require like_class=”zope.publisher.browser.BrowserResponse” />
</class>

</configure>

Как это работает?

При публикации сервер обращается к фабрике HTTPPublicationRequestFactory (см. /path/to/zope/app/publication/httpfactory.py) где в методе __call__ по заданным параметрам производится поиск в реестре фабрик (публикаторов) с интерфейсом IRequestPublicationFactory. Стандартный их список можно найти в файле /path/to/zope/app/publication/configure.zcml. Найденная фабрика возвращает класс запроса и публикатора. В нашем случае этой фабрикой будет BrowserFactory (см. /path/to/zope/app/publication/requestpublicationfactories.py):

/path/to/zope/app/publication/requestpublicationfactories.py
  1.  
  2. class BrowserFactory(object):
  3.  
  4.     implements(IRequestPublicationFactory)
  5.  
  6.     def canHandle(self, environment):
  7.         return True
  8.  
  9.     def __call__(self):
  10.         request_class = component.queryUtility(
  11.                 interfaces.IBrowserRequestFactory, default=BrowserRequest)
  12.         return request_class, BrowserPublication

Как видно из кода, фабрика ищет утилиту, зарегистрированную под интерфейсом IBrowserRequestFactory. Так что найдет она наш класс запроса, который мы зарегистрировали выше.

Если же не зарегистрированно ни одной утилиты с этим интерфейсом, будет использован стандартный класс BrowserRequest.

Комментарии (1)

  1. Дмитрий
    30 Август 2008

    Грасиас за статью. Как раз на днях заинтересовался исследованием этой темы - и вот - ваш пост! Очень кстати!

Оставить комментарий

Вход по OpenID

Стандартный вход

Опции:

Размер

Цвета