Dʒɛmɪni wrappers (aka middleware)
Dʒɛmɪni now supports wrappers which means you can run code before and after a request, manipulating both the request parameters and the response status, meta and/or body. Why? Superpowers! Let's start with a couple of examples.
Here's how dʒɛmɪni (roughly) implements request logging now:
(define (wrap handler)
(lambda (req)
(log-info "server=~s url=~s"
(assq 'server-name req)
(assq 'url req))
(handler req)))
Given a "handler" function "wrap" composes a new handler which first logs the server name and the url and than handles the request like it normally would. The above only deals with the "before" situation. Here's an example of manipulating the response:
(define (wrap handler)
(lambda (req)
(call-with-values
(lambda () (handler req))
(case-lambda
[(status meta body)
(if (string-prefix? meta "text/")
(values status meta
(string-replace (if (string? body)
body
(read-string 65536 body)) ; nobody needs more than 64k, right?
"http"
"that-other-protocol"))
(values status meta body))]
[res
(apply values res)]))))
Above is a wrapper which changes all occurrences of "http" in a returned text response with "that-other-protocol". Note the use of (call-with-values .. (case-lambda ..)) because a handler will return either 3 or 2 values; 3 (status, meta and body) for "20"-responses and 2 (status and meta) for all other responses.
A wrapper is configured on the commandline like:
racket dezhemini.rkt -W my-fancy-wrapper.rkt example.com:root
Other possible applications of this:
- automatically putting headers and footers on you gemini responses
- including snippets from other files
- include the file modification timestamp in footer
- replace placeholders with "live" data
- apply some kind of templating engine
- transform to other formats automatically
- insert some kind of comment section at the bottom
- ..
The "examples/wrappers" directory also includes an example to automatically set "lang" according to the directory name the requests is served from.
Enjoy! And please, don't be shy and share your wrappers (and handlers) on the dezhemini mailing list.
Cheers,
R.
--
📅 2021-08-29
🏷 dʒɛmɪni, announcement
📧 hello@rwv.io
CC BY-NC-SA 4.0