← Blog of oldlisper

Обновил restas-directory-publisher

· 04.01.2013 00:00
· original author: archimag

Обновил restas-directory-publisher

Добавил в макрос restas:define-module поддержку декларации :render-method, которая позволяет задать способ по-умолчанию для генерации итогового ответа. На маршруты, у которых задан :render-method в restas:define-route, указание :render-method при определении модуля никакого влияния не оказывает.

Переработал restas-directory-publisher: привёл код в соответствие с последними изменениями RESTAS и cl-closure-template, удалил зависимость от iolib (ибо нефиг), а также удалил встроенную поддержку CGI - редко нужна, тянет за собой hunchentoot-cgi и может быть легко реализована в пользовательском коде.

Собственно, я как раз хотел показать возможность использования декларации :render-method в restas:define-module и restas:mount-module именно на примере поддержки CGI.

Сейчас файл restas-directory-publisher.asd выглядит так:

(defsystem #:restas-directory-publisher
  :defsystem-depends-on (#:closure-template)
  :depends-on (#:restas #:local-time)
  :pathname "src"
  :serial t
  :components ((:closure-template "autoindex")
               (:file "directory-publisher")
)
)

Т.е. первым делом компилируется файл с шаблонами src/autoindex.tmpl, после чего модуль #:restas.directory-publisher можно уже определить следующим образом:

(restas:define-module #:restas.directory-publisher
  (:use #:cl #:iter)
  (:export #:*directory*
           #:*directory-index-files*
           #:*autoindex*
           #:*ignore-pathname-p*
           #:pathname-info
           #:hidden-pathname-p
)

  (:render-method #'restas.directory-publisher.view:autoindex)
)

restas.directory-publisher.view:autoindex - это просто функция, создаваемая при компиляции файла шаблонов.

Модуль #:restas.directory-publisher содержит один единственный маршрут, который в основном возвращает файлы для обработки которых restas.directory-publisher.view:autoindex вызываться не будет (а будет вызываться только при генерации страницы autoindex если установлена опция restas.directory-publisher:*autoindex*).

И вот теперь я могу захотеть публиковать через restas-directory-publisher не только файлы, но и дать возможность исполнять CGI-скрипты (необходимый функционал есть в hunchentoot-cgi), например, для публикации веб-интерфейса к git с помощью gitweb.cgi. Вот полный код:

(asdf:operate 'asdf:load-op '#:restas-directory-publisher)
(asdf:operate 'asdf:load-op '#:hunchentoot-cgi)

(restas:define-module #:homesite
  (:use #:cl)
)


(in-package #:homesite)

(defclass cgi-handler () ())

(defmethod restas:render-object ((renderer cgi-handler) (file pathname))
  (cond
    ((and (string= (pathname-type file) "cgi"))
     (hunchentoot-cgi::handle-cgi-script file)
)

    (t
     (call-next-method)
)
)
)


(restas:mount-module -gitweb- (#:restas.directory-publisher)
  (:url "/gitweb/")
  (:render-method (make-instance 'cgi-handler))
  (restas.directory-publisher:*directory* #P"/usr/share/gitweb/")
  (restas.directory-publisher:*directory-index-files* '("gitweb.cgi"))
)


(restas:start '#:homesite :port 8080)

Теперь по адресу http://localhost:8080/gitweb/ можно будет наблюдать стандартный gitweb-интерфейс к своим проектам (ну, необходимую настройку gitweb я опускаю).

Правда, у пакета hunchentoot-cgi есть какие-то проблемы: gitweb.cgi завёлся без проблем, а вот php-cgi работать не хочет, плюс немного гибкости не хватает. Надо будет как-нибудь что-нибудь там пропатчить.

Чуть более развёрнутый пример использования restas-directory-publisher можно посмотреть здесь: https://github.com/archimag/restas-directory-publisher/blob/master/example/homesite.lisp