*STATUS:* ¡Work in progress! ¡Todavía no enviado a FUDForum!

El protocolo Gemini según Wikipedia:

Gemini es un protocolo de comunicación en la capa de aplicación de Internet para acceder a documentos remotos, similar al Protocolo de Transferencia de Hipertexto y a Gopher. Está pensado como una tercera alternativa a esos protocolos. Viene con un formato de documento especial, comúnmente llamado "gemtext", que permite enlazar con otros documentos. Iniciado por alguien conocido como Solderpunk, el protocolo está siendo finalizado de forma colaborativa y actualmente no ha sido presentado al IETF para su estandarización. [...] El diseño es deliberadamente poco extensible, para preservar uno de los objetivos declarados del proyecto: la simplicidad.

Instalar Dezhemini

El servidor Dezhemini se puede instalar de varias maneras:

Para más información, visitar [el archivo index.gmi del repositorio de dezhemini] o usando un cliente de Gemini su cápsula oficial: .

El servidor se puede iniciar para servir los documentos en `./root/ ` con el siguiente comando:

Y con lagrange o elpher, se puede acceder a la cápsula con la dirección `gemini://127.0.0.1 ` ó `gemini://localhost ` .

el archivo index.gmi del repositorio de dezhemini

Handlers y wrappers

Dezhemini es extensible y programable, y existen dos formas de hacerlo (además de retocar el código fuente): utilizando handlers y/o wrappers. Los handlers son funciones que reciben una solicitud (/request/) Gemini como entrada y emite el código de estado junto con el texto o contenido de salida. Los wrappers son funciones que se ejecutan alrededor de un handler, de hecho, reciben al función handler y la llaman, pudiendo modificar su entrada o salida a gusto del programador.

Handlers

Los handlers pueden retornar dos cosas: una serie de valores indicando que se procesa el requerimiento, o `#f ` indicando que este handler no lo procesará y deberá pasar al próximo. Los handlers instalados por defecto son los siguientes y en este orden:

En el siguiente handler de ejemplo se detecta si el path es `/index.gmi `, y si lo es, retorna "Hello world". Este ejemplo debe almacenarse en un archivo, supongamos "hello-handler.rkt".

#lang racket
(provide handler)
(define (say-hello)
  (values 20 "text/gemini" "# Hello world!"))
(define (handler req)
  (let ([path (cdr (assq 'path-info req))])
    (if (equal? path "/index.gmi")
        (say-hello)
        #f)))

Ahora, para utilizarlo, se debe ejecutar dezhemini con los siguientes parámetros:

,----

| dezhmnsrv -P hello-handler.rkt localhost:root

`----

Si se utiliza `-P hello-handler.rkt `, el handler se agrega al principio de la lista, quedando en el siguiente orden: hello-handler, cgi-handler, directory-redirect-handler y file-handler. Con `-A hello-handler.rkt ` se agrega al final, quedando: cgi-handler, directory-redirect-handler, file-handler y hello-handler.

Para jugar, observar que si se cambia `(equal? path "/index.gmi") ` por `(string-suffix? path "/index.gmi") ` se puede responder lo mismo para cualquier path que exista o no y que se busque el archivo index.gmi.

Wrappers

Posiblemente, el funcionamiento de un wrapper se comprende mejor con un ejemplo muy simple. En el siguiente código se define un wrapper que llama al handler que corresponde sin modificar su resultado, solo musetra un mensaje en la terminal cuando se ejecuta.

#lang racket
(provide wrap)
(define (wrap handler)
  (lambda (req)
    (displayln "do stuff before handling request")
    (handler req)))

Al ejecutarse el wrapper, se retorna una nueva función anónima (lambda) con un parámetro. Esta función es la que se ejecutará al llamar al handler para procesar la salida. Por consiguiente, al acceder a una dirección de Gemini, Dezhemini intentará ejecutar esta función anónima, que a su vez, ejecutará el handler como se indicó previamente. Sorpresivamente, en este caso, la salida será solamente una vez "do stuff before handling request" y no una por cada handler.