Обновил 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-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 можно уже определить следующим образом:
(: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 '#: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