đŸ Archived View for gemini.omarpolo.com âș post âș gemini-clojure.gmi captured on 2022-07-16 at 13:32:41. Gemini links have been rewritten to link to archived content
âŹ ïž Previous capture (2022-06-03)
âĄïž Next capture (2023-01-29)
-=-=-=-=-=-=-
Written while listening to âGood Advicesâ by R.E.M..
Published: 2021-10-16
Tagged with:
Iâd like to announce âcom.omarpolo/geminiâ: a new clojure library to make Gemini requests.
com.omarpolo/gemini: A Clojure library to make Gemini requests
Itâs also available on clojars, so go download it! :D
I needed something to ping antenna when I publish things on this blog. The site is assembled using some clojure scripts (not the most idiomatic clojure youâd read, but it works) and Iâm already shelling out to rsync for the upload. To ping antenna I wanted to do something natively.
Gemini is a simple protocol, isnât it? Writing something from scratch should be simple, right?
It wasnât simple, at least for me. I kinda get sleepy when I have to dig into the Java stdlib to learn how to do things. And I donât know how to do networking at all in java, so there was a lot that I needed to learn.
I ended up writing a Java class, not because itâs required but because itâs easier. It exposes a really simple and barebone APIs to make Gemini requests and then wrote a more idiomatic (I hope) clojure wrapper around.
Speaking of Java, disabling the certificate validation wasnât exactly straightforward (you need to provide your own X509ExtendedTrustManager) and quite surprisingly it doesnât do SNI by default.
The magic spell to force a SSLSocket to do SNI is to
var params = new SSLParameters(); params.setServerNames(Collections.singletonList(new SNIHostName(host))) /* ⊠*/ var socket = âŠ; socket.setSSLParameters(params);
I was able to contribute back the same trick to jgemini, a Java graphical Gemini browser.
jgemini: A Java-based graphical browser for the Gemini protocol
The main function is âfetchâ. It takes a map and return a map. So clojure-ish.
The feature list is pretty short honestly:
and thereâs a major drawback: the âcloseâ function must be called to clean things up. Thereâs a âwith-requestâ macro (similar to âwith-openâ) that should help.
Itâs easy to stream a request since Iâm exporting the BufferedReader to clojure clients, you can just read from it. In combo with my gemtext library, itâs possible to stream text/gemini!
com.omarpolo/gemtext: text/gemini for clojure/clojurescript
Gemini is simple, so there isnât very much more to do. I planning to provide a function to control the certificates, so that one can implement TOFU on top of this library, but thatâs that.
Iâm still not completely happy of the provided APIs, but they doesnât seem too bad and I donât have a clue on how to improve them. Iâm open to suggestions thought ;)
-- text: CC0 1.0; code: public domain (unless specified otherwise). No copyright here.
For comments, write at < blog at omarpolo dot com > or @op@bsd.network in the fediverse.