howto-db/data/pages/gemini_protocol.txt
2024-02-21 01:00:03 +00:00

217 lines
15 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

====== Gemini (протокол) ======
Gemini - сетевой протокол прикладного уровня, являющийся наследником протокола Gopher.
Ориентирован на минимализм и приватность, поскольку исключает использование таких технологий как сжатие, Cookies и JavaScript;
формат передаваемых данных ограничен текстом или бинарными данными, обязательной является подпись TLS.
Тем не менее, протокол вполне многофункционален и позволяет работать с различными типами ресурсов: как хостинг статических файлов так и системы с авторизацией и обработкой пользовательских запросов - форумы, поисковые системы, организация радио и видео вещания, обмен изображениями и другими мультимедийными данными.
В виду своих характеристик, Gemini будет интересен тем, кого не устраивает "раздутость" современного протокола HTTP, а также подойдёт для пользователей командной строки, E-ink планшетов.
===== Терминология =====
Как и во многих других экосистемах, для Gemini характерна своя терминология, знание которой поможет лучше понимать контекст и формировать поисковые запросы.
* **Gemini space** - экосистема Gemini, подобно термину "Fediverse" для федеративной тематики
* **Capsule** - капсула, веб-сайт - название протокола отсылается к тематике космической программы, поэтому в сети многие ресурсы наследуют концепцию в своих названиях
* **Gemlog** - блог, персональная страница, фид профиля
===== Разметка =====
==== Gemtext ====
Текстовые ресурсы gemtext - это обычный текст (MIME text/gemini) опционально содержащий мета-теги в начале каждой строки:
<code>
# h1
## h2
### h3
=> ссылка
> цитата
* элемент списка
```
исходный код
```
</code>
Некоторые браузеры поддерживают разметку inline:
<code>
``` заголовок неформатируемого блока
*bold*
_underline_
</code>
В разметке gemini не используются декоративные технологии вроде CSS, при этом задача отрисовки ресурса выполняется на стороне браузера и полностью делегирована клиенту.
==== Gemfeed ====
Поскольку текстовый регламент протокола не подразумевает использование тегов, такие стандарты оповещений как Atom и RSS, без [[https://tildegit.org/solderpunk/gemfeed|внешних средств интеграции]], в Gemini неприменимы.
Несмотря на это, нативные подписки возможны - средствами [[https://geminiprotocol.net/docs/companion/subscription.gmi|стандарта]] для программной интерпретации изменений документа gemtext.
Говоря проще, протокол сохраняет человеко-понятную структуру документа, при этом позволяет клиентским приложениям отслеживать его обновления.
<WRAP round info 60%>
В браузере Lagrange, подписаться на обновления страницы можно с помощью меню ''Bookmarks'' - ''Subscribe to page...'' и выбрать соответствующий странице способ (меню подписок: ''View'' - ''Show Feeds'')
</WRAP>
=== Отслеживание по дате ===
В данном подходе, осуществляется отслеживание по впереди идущей за ссылкой дате, в формате ISO 8601 (Y-m-d), например:
<file - /index.gmi>
# Заголовок страницы, выполняет роль заголовка фида
Содержимое параграфа, игнорируется
=> /index.gmi любая ссылка, игнорируется
## Подраздел страницы, игнорируется
Произвольное содержимое подраздела, игнорируется
## Публикации
=> /pub1.gmi 2024-01-28 Ссылка на первую публикацию, отслеживается
=> /pub2.gmi 2024-01-29 Ссылка на вторую публикацию, отслеживается
=> /pub3.gmi Ссылка публикацию, не отслеживается (так как не содержит даты)
=> /pub4.gmi Ссылка публикацию, не отслеживается (так как дата является частью заголовка) 2024-01-30
</file>
Таким образом, документ не теряет читаемость для человека и при этом содержит мета-информацию для интерпретатора обновлений.
Единственный недостаток такого подхода заключается в том, что обновления нельзя получать чаще, чем раз в сутки.
Как заявлено в документации, связано это с временной зоной.
=== Отслеживание по заголовкам ===
Альтернативный подход, отслеживающий изменения в заголовках документа
<file - blog.gmi>
# Мой блог, заголовок фида
Параграф описания
## Первая публикация, отслеживается
Описание первой публикации
=> /pub1.gmi Читать
## Вторая публикация, отслеживается
Описание второй публикации
=> /pub2.gmi Читать
...
</file>
===== Коды статусов =====
* **10-19** - //input expected// - ожидается ввод - используется например для отправки и получения данных форм
* **20-29** - //success// - код 20 аналогичен коду 200 в HTTP
* **30-39** - //redirection// - диапазон переадресации, в отправляемом пакете, код обычно сопровождается мета-ссылкой: ''code + link + \n\r + text''
* **40-49** - //temporary failure//
* **50-59** - //permanent failure//
* **60-69** - //client certificates// - в Gemini сертификаты используются для идентификации и авторизации пользователей
Клиент обязан отклонять любой код меньше 10 или больше 69, при этом уведомить пользователя.
В неопределённых случаях, приоритет будет отдан коду с начальным значением диапазона, например, 10 для 11 или 20 для 27.
===== Обработка запросов =====
Протокол предусматривает обмен пакетами с заголовками длиной максимум 1024 байт.
В эту длину необходимо уместить мета информацию пакета - например строку URI и/или данные пользовательского ввода.
Текстовые данные должны быть закодированы в стандарт RFC 3986 (известный такими функциями, как urlencode).
В какой то степени, это сокращает полезный объём заголовка при использовании например кириллицы.
Тело пакета состоит из "сырых" текстовых или бинарных данных без сжатия; сервер закрывает соединение после отправки последнего байта.
С помощью отправляемых клиенту статусов группы "10", сервер способен запрашивать пользовательский ввод (вместо привычных форм, обычно в браузерах Gemini - это всплывающее текстовое окно)
После получения и обработки данных, сервер обычно возвращает статус "20", статус "51" (не найдено) или редирект на целевую страницу с кодом "30".
Пример типичного пакета с фразой "Hello world!":
<code>
20 text/gemini; charset=utf-8; lang=en\r\nHello%20world%21
</code>
===== Клиент =====
Чтобы открыть ресурс с адресом %%gemini://%% необходим специальный браузер, стандартно работающий с портом 1965.
Пользователи GUI, могут начать с популярных [[https://gmi.skyjake.fi/lagrange/|Lagrange]] или [[https://kristall.random-projects.net/|Kristall]].
**Специфика**
* так как большинство клиентов возвращают одно-текстовое строчное поле запроса, добавить новую строку можно комбинацией клавиш Shift+Enter
* в протоколе Gemini нет webstorage и cookies, поэтому некоторые интерактивные сайты запрашивают для авторизации сертификат, который также используется для быстрой смены аккаунта
* вместо фидов RSS есть встроенные в браузер инструменты отслеживания контента (см. [[gemini_protocol#gemfeed]])
===== Сервер =====
Понятие "сервер" в среде Gemini может быть непривычным для пользователей веб, поскольку вместо прокси Nginx или Apache, этот термин зачастую предусматривает полноценный сервис для конкретной задачи, резервирующий за собой отдельный хост и порт.
В каталоге [[https://github.com/kr1sp1n/awesome-gemini#servers|awesome-gemini]] представлено большое количество таких решений.
Например, для запуска простой статики, подойдёт сервер [[https://github.com/mbrubeck/agate|Agate]] (Rust).
При этом, название привычного %%index.html%% будет зависеть от выбранного сервера, для Agate - это %%index.gmi%%
Запуск динамических ресурсов часто предусматривает разработку собственного сокет-сервера для реализации специфики отдельно взятого приложения.
Веб-разработчикам проще понять принцип работы "server-side" на примере нескольких файлов [[https://github.com/eapl-gemugami/gemini-php|gemini-php]].
В разработке новых проектов - лучше использовать более актуальне решения, например, из простых - форк библиотеки [[https://github.com/YGGverse/titan-II|titan-II]], примеры реализации на базе которой, можно посмотреть в исходном коде [[https://github.com/kevachat/geminiapp|geminiapp]] для [[social_media:kevachat|KevaChat]] или [[https://github.com/YGGverse/betahowto|проекте зеркала]] данного сайта.
==== Виртуальные хосты ====
Чтобы запускать различные сервисы на одном IP (не меняя стандартный порт) следует установить общий прокси-сервер, который будет осуществлять маршрутизацию запросов на соответствующий адрес/интерфейс.
Если для HTTP - это Apache или Nginx, то для протокола Gemini используются следующие решения:
* [[gemini_protocol:gmid]] (C)
* [[gemini_protocol:twins]] (Go)
===== Ресурсы =====
* %%gemini://geminiprotocol.net%% - домашняя страница проекта
* %%gemini://geminiprotocol.net/docs/ru/%% - документация на русском
* %%gemini://geminispace.info%% - внутрисетевой поиск
* %%gemini://station.martinrue.com%% - социальная сеть по типу twitter
* %%gemini://astrobotany.mozz.us%% - ASCII ботаника
===== Yggdrasil =====
В зависимости от поддержки IPv6 отдельно взятым сервером, в большинстве случаев, Gemini штатно и без проблем работает с Yggdrasil.
Единственным моментом является TLS поверх уже имеющегося слоя.
==== Внутрисетевые ресурсы ====
* %%gemini://[301:23b4:991a:634d::b]%% - зеркало сайта, в рамках проекта [[https://github.com/YGGverse/bdoku|β-Doku]]
* %%gemini://betahowto.ygg%% - алиас
* %%gemini://betahowto.duckdns.org%% - алиас в Интернет
* %%gemini://[301:23b4:991a:634d::1965]%% - инстанс [[social_media:kevachat|KevaChat]]
* %%gemini://kevachat.ygg%% - алиас
* %%gemini://[301:23b4:991a:634d::db]%% - эксплорер блокчейна KevaCoin [[https://github.com/kvazar-network/geminiapp|KVAZAR]]
* %%gemini://kvazar.ygg%% - алиас
* %%gemini://kvazar.duckdns.org%% - алиас в Интернет
===== Статьи внутри раздела =====
{{indexmenu>:gemini_protocol}}
===== Ссылки =====
* [[https://geminiprotocol.net|Официальный сайт]]
* [[https://ru.wikipedia.org/wiki/Gemini_(протокол)|Страница на википедии]]
* [[https://github.com/kr1sp1n/awesome-gemini|Каталог программного обеспечения на GitHub]]
* [[https://www.dokuwiki.org/plugin:gemini|Плагин для DokuWiki]] | [[https://github.com/YGGverse/bdoku|Проект β-Doku]]