"Простой" Gemini сервер понемногу набирает жирок. Я с большой неохотой каждый раз добавляю в него новую функцию, которая в свою очередь немного усложняет код. И вот, наконец, я добавил свой упрощенный аналог CGI: VGI. Возможно стоило сделать это немного раньше и часть функций не добавлять в сам сервер, а переложить их на плечи механизма формирования динамического содержимого.
Предыдущая запись блога разработки
Что нового в версии 0.2.0:
У меня в голове есть пара идей насчёт того, что я хотел бы перенести часть используемых инструментов в Gemini (или хотя бы иметь Gemini интерфейс к каким-то сервисам, которыми я пользуюсь). Но для этого недостаточно сервера статики. Чаще всего нужно выполнить HTTP[S]-запрос, разобрать возвращённый HTML/JSON и сформировать результаты в виде .gmi страницы. Звучит как запуск какого-то скрипта. Значит нужен аналог CGI, но для Gemini:
https://en.wikipedia.org/wiki/Common_Gateway_Interface
Немного изучив вопрос оказалось, что механизм CGI не такой уж и простой. И даже существуют некоторые рекомендации о том, какие части механизма CGI нужно реализовывать в своём Gemini сервере. Оригинальную ссылку на обсуждение в списке рассылке я нашёл в коде Gemini сервера vger. Но на момент, когда я попытался её открыть она уже была недоступна, поэтому на всякий случай прикладываю еще и ссылку на web.archive.org.
https://lists.orbitalfox.eu/archives/gemini/2020/000315.html
https://tildegit.org/solene/vger
Немного подумав я решил не ограничивать себя существующими в CGI возможностями и, следуя духу Тривиальных Технологий, реализовал только то, что нужно мне "здесь и сейчас": VGI (Vostok's Gateway Interface).
При запуске сервера vostok появились два новых аргумента командной строки:
Префикс пути обрабатывается до нормализации пути и с учётом регистра. То есть для запущенного сервера:
vostok -c cert/server.crt -k cert/server.key -f ./ -g vgi -e ./vgi.sh
Запросы `gemini://127.0.0.1/vgi`, `gemini://127.0.0.1/vgi/`, `gemini://127.0.0.1/vgix` или `gemini://127.0.0.1/vgi?a=b` будут перенаправлены команде `./vgi.sh`.
А, например, `gemini://127.0.0.1/Vgi`, `gemini://127.0.0.1/./vgi` или `gemini://127.0.0.1/sub/../vgi` не будут восприняты как VGI и будут обработаны поиском статических файлов на файловой системе.
В репозитории vostok добавлен минимальный пример VGI в виде shell скрипта:
$ cat vgi.sh #!/bin/sh # Answer header: echo "20 text/gemini\r" # Answer body: echo "# VGI demo\r" echo "\r" echo "Requested URL: \r" echo "=> $(cat -)"
Мне кажется тут наглядно видно, что взаимодействие с командой VGI осуществляется через стандартные потоки ввода и вызова.
Через стандартный поток вывода от команды VGI ожидается полный ответ по Gemini протоколу. То есть в первой строке заголовок со статусом и MIME (или текстом ошибки). За заголовком (который заканчивается переводом строки) должно сделать тело ответа.
А через стандартный поток ввода в команду VGI поступает сырой Gemini запрос (абсолютный URL c переводами строки в конце). Его-то и читает команда `cat -` в демонстрационном VGI скрипте.
В качестве немного более сложного примера был реализован Gemini фронтенд к Google переводчику:
GTransl 🔁 Gemini фронтенд к Google переводчику
Комментарии через ActivityPub (Fediverse) можно оставить здесь: