Оригинал: https://drewdevault.com/2020/11/01/What-is-Gemini-anyway.html
Я в своём блоге писал о некоторых специфичных вещах, связанных с Gemini, если взглянуть на последние два месяца или около того. Но так до сих пор и не написал более широкое введение в этот протокол: о том, что я делаю с помощью него и почему вы должны быть восхищены им так же, как и я. Давайте сделаем это сегодня!
Gemini - сетевой протокол для обмена гипертекстовыми документами. «Гипертекстовый» - в общем смысле этого слова, а не в отношении HTML («HyperText Markup Language»), который понимают веб-браузеры. Это простой сетевой протокол, который позволяет клиентам запрашивать гипертекстовые документы (в собственном формате, который называется gemtext). В некотором смысле, это эволюция протокола Gopher, но более модернизированная и упрощённая.
Gemini очень прост. Протокол использует TLS для установления шифрованного соединения (чаще используя самоподписанные сертификаты и Trust on first use (TOFU), чем центры сертификации). И он использует очень простой обмен: клиент отсылает URL того, что он хочет получить, завершая запрос символом новой строки. Сервер отвечает информационной строкой, которая содержит числовой код статуса и некоторую дополнительную информацию (такую как MIME-тип документа), затем пишет документ и завершает соединение. Аутентификация при желании выполняется с помощью клиентских сертификатов. Пользовательский ввод при желании выполняется с помощью кода ответа, который передаёт строку приглашения для ввода после чего выполняется второй запрос с ответом пользователя, который закодирован в query string URL-строки. Да и вот, собственно, и всё!
$ openssl s_client -quiet -crlf \
-servername drewdevault.com \
-connect drewdevault.com:1965 \
| awk '{ print "response: " $0 }'
gemini://drewdevault.com
response: 20 text/gemini
response: ```ASCII art of a rocket next to "Drew DeVault" in a stylized font
response: /\
response: || ________ ________ ____ ____ .__ __
response: || \______ \_______ ______ _ __ \______ \ ___\ \ / /____ __ __| |_/ |_
response: /||\ | | \_ __ \_/ __ \ \/ \/ / | | \_/ __ \ Y /\__ \ | | \ |\ __\
response: /:||:\ | ` \ | \/\ ___/\ / | ` \ ___/\ / / __ \| | / |_| |
response: |:||:| /_______ /__| \___ >\/\_/ /_______ /\___ >\___/ (____ /____/|____/__|
response: |/||\| \/ \/ \/ \/ \/
response: **
response: **
response: ```
[...]
Так почему я восхищён этим протоколом?
Моё презрение к веб-браузерам хорошо документировано (раз, два, три). Веб-браузеры чрезвычайно переусложнены и любые попытки создать новый будут являться сизифовым трудом. Удачное выполнение этой работы, если и возможно, будет неизбежно порождать лавкрафтовский беспорядок, который невозможно мэйнтейнить, полный уязвимостей, отжирающий гигабайты оперативной памяти при использовании и часы при компиляции. И учитывая, что все современные веб-браузеры, что реализуют полезную часть веб-стандартов, очень плохи и становятся только хуже, то что мы можем сделать?
Проблема неразрешимая. Мы не можем иметь «веб» без всех этих проблем. Но вот что мы можем, так это иметь нечто немного другое, что-то типа Gemini. Gemini не решает все проблемы веба, но то подмножество юзкейсов, на которое он нацелен, он решает лучше веба и это меня восхищает в нём. Я хочу отказаться от той части веба, которую Gemini выполняет лучше и найти решения для оставшихся частей веба, которые имеет смысл сохранить (подсказка: самую малую часть).
Вот некоторые аспекты этого протокола, которые я очень одобряю:
- Он очень простой. Реализация сервера или клиента может быть написана одним человеком с нуля в промежутке одного-двух дней. Новый веб-браузер может занимать миллион часов при сотнях разработчиков для полной реализации.
- Он не расширяемый. Gemini спроектирован так, чтобы его было трудно расширять без потери обратной совместимости и почти все запросы на расширение в рассылке в конечном итоге сносятся. Это хорошо. Ибо расширяемость как правило плохая идея. Расширения в конечном итоге ведут к большему усложнению и Gemini может страдать от той же участи, что и веб, если он не будет противиться расширениям.
- Он однозначен в вопросах форматирования документов. В нём нет inline-ссылок (каждая ссылка идёт на новую линию), никакого форматирования и никаких inline-изображений (inline images). Gemini строго разделяет роли доставки контента и его отображения. Доставка контента - роль исключительно сервера, а его отображение - исключительно клиента. Здесь нет «стилей сайта» и роль автора очень мала в вопросах того как должен отображаться контент. Авторы всё ещё имеют возможность проявлять себя в этих рамках, ровно как и в любых других. Да и они позволяют быть клиентам проще и действовать как пользовательский инструмент, нежели вендорский.
Некоторые люди утверждают, что нам стоит сделать «веб, но в чуть урезанном виде», т.е. взяв только «нормальное» подмножество веб-стандартов. Я не согласен с этим (например, я не считаю, что существует «нормальное» их подмножество), но я оставлю это для своего другого поста. Gemini - это новая среда, и она отлична от веба. Любой, кто входит в неё должен быть готов к этому и открыт её рамкам. Ограничения порождают креативность!
Что насчёт меня. Я работал над некоторыми проектами, связанными с Gemini. Например, этот блог теперь доступен и через Gemini и я начал писать эксклюзивный контент, доступный только через этот протокол. Я также написал некоторый софт, которым вы можете воспользоваться:
- libgmni, gmni и gmnlm - мой инструментарий для клиентского софта. Всё написанно на C11 и только лишь требует POSIX-like систему с OpenSSL. libgmni - клиенсткая библиотека общего назначения для Gemini с простым интерфейсом. gmni - CLI-утилита для выполнения Gemini-запросов, выполненная в стиле cURL. Ну и, наконец, gmnlm - line-mode браузер с богатым набором фич. Вместе эти утилиты достигают около 4000 строк кода из которых 1600 - URL-парсер, взятый из cURL.
- gmnisrv - высокопроизводительный Gemini-сервер, написанный на C11 для POSIX-систем с OpenSSL. Он поддерживает TLS без конфигурирования (zero-configuration TLS), CGI-скриптование, auto-indexing, regex routing, URL-перезапись и планирую ещё несколько вещей для версии 1.0. И весь код достигает около 6700 строк кода из которых 1600 - тот же код, взятый из cURL и ещё дополнительно 2800, взятые из quickjs Фабриса Белларда для реализации регэкспов.
- kineto - это сетевой шлюз для соединения HTTP-клиента и Gemini-сервера. Реализован в одном Go-файле при поддержке go-gemini библиотеки от ~adnano. Мой Gemini-блог доступен через этот портал, если вы хотите посмотреть его.
Так что погружайтесь и изучайте! Устанавливайте gmnisrv на свой сервер и настраивайте своё Gemini-окружение. Читайте фиды из CAPCOM. Пишите собственный софт!