This patch constitutes an entirely new iteration of gmi, rewritten
almost from scratch. The implementation is different, but the
It fixes a number of issues, not least of which was a bug where
downloads of binary files, such as images and audio files, became
corrupt on disk. I believe this was due to a combination of two
things: (1) that shell command substitution was deleting null bytes
and (2) that a sed(1) command was deleting important line feed
characters ("\r") in the binary data. I’m by no means an expert on
binary formats so my understanding is limited here. Anyway, with the
offending sed command removed and the binary data encoded in base64
using uuencode(1), this issue seems to have gone away. uuencode(1)
and uudecode(1) are two programs specified by POSIX.
User-facing changes include:
* Gemini URLs specified on the command-line now require the
‘gemini://’ scheme in front. Otherwise it will be interpretted
as a relative file.
* When visiting files on disk, relative references are now followed
* Fixed a bug where reloading a page failed in certain situations.
* gmi now resolves dot (.) and dot-dot (..) segments, as any good
Gemini client should, fixing browsing issues with certain server
* Downloaded files are now opened automatically after being written
to disk, using xdg-open(1).
* gmi now honours the format MIME parameter specified in RFC
3676. With format=flowed, gmi calls less(1) with the -S option
(--chop-long-lines), preventing text wrap in the pager.
Changes to the implementation are too numerous to document fully, but
here are some of them:
* Requests to Gemini servers now happens in a new function named
‘ssl’. Reading of files on disk happens in the ‘request’ function.
* Responses are now encoded as base64 using uuencode(1) and
uudecode(1). Without this, null bytes in binary data are deleted
when stored in a shell variable using command substitution, causing
files to become corrupted after download and before writing to disk.
* Renamed ‘read_filetype’ to ‘read_mimetype’
* Fixed a bug affecting how mimetype meta strings were parsed in
* The displaying of code 20 responses is now handled by a new function
named ‘success’. The definition of the success function is wrapped
in parentheses rather than curly braces so that it runs in a
subshell, which prevents variables assigned by ‘read_mimetype’
persisting into other responses.
* Resolution of dot (.) and dot-dot (.) path segments is achieved
using a new function named ‘canonicalise’.
* Added a ‘die’ function.
New and remaining known issues are documented in the readme.
Remove feature to read from standard input
This was broken, probably because the stdin we expect to receive is
actually displaced by the main read-while loop. So when
is finally executed to read the document body, it instead reads
whatever happens to be coming into that read-while loop. I think.
It would be nice to get this fixed and re-added as it is an
interesting feature. In fact, I don’t know of any other Gemini
client that can do this -- please let me know if there is one!