Module gemlib

gemini protocol support functions

gemlib contains function to read files from gemini servers and from the local filesystem.

gemini:// and file:// are the only valid protocols.

file:// is optional for local files. Either file:///home/rsimpson/doh.gmi or just /home/rsimpson/doh.gmi are equivalent. A filename of a single dash can be used to process the standard input stream.

A port number is optional on gemini:// URLs, the default is 1965.

The code attempts to catch all errors and return nil or false and an error string. If any code throws an error, it's a bug, please file an issue in the repo.

Temporary and permanent redirections are handled internally. Your code can use the max_redirects parameter to limit the number of redirections followed. The default value is 5.

Input expected (10-19), and client certificate expected (60-69) responses are not handled internally and return errors. Your code can handle input expected by repeating the call adding the user input to the URL as a query string. It can handle client certificate errors by repeating the call and passing in an SSLContext parameter which contains the appropriate certificates.

This may change in the future, if your use-case needs better control handling input or client certificates, please let me know in the appropriate codeberg issues. See

  • https://codeberg.org/bcasiello/gemlib/issues/2
  • https://codeberg.org/bcasiello/gemlib/issues/3

gemlib is hosted on Codeberg.

Info:

Functions

get (link[, max_redirects=5[, context=DEFAULT_CONTEXT]]) retrieves the contents of a gemini URL or local file.
join_urls (base, link) create a URL out of a base and a relative URL
lines (link[, max_redirects=5[, context=DEFAULT_CONTEXT]]) retrieve lines from a gemini URL or local file.
parse_url (link) parse an absolute or relative URL
readable (link[, max_redirects=5[, context=DEFAULT_CONTEXT]]) checks if a URL is readable without reading full contents This function handles both text and binary files.

Tables

DEFAULT_CONTEXT


Functions

get (link[, max_redirects=5[, context=DEFAULT_CONTEXT]])
retrieves the contents of a gemini URL or local file. This function handles both text and binary files.

Parameters:

  • link string the URL or filename
  • max_redirects integer maximum number of redirects to follow before giving up (default 5)
  • context SSLContext luasec ssl context for connection (default DEFAULT_CONTEXT)

Returns:

  1. string the contents of the URL or filename
  2. string error message if first return value is nil

See also:

Usage:

    print(gemlib.get("gemini://gem.example.com", 3))
join_urls (base, link)
create a URL out of a base and a relative URL

Parameters:

  • base string the base URL
  • link string (possibly relative) URL

Returns:

    string the URL constructed from base and link

    This is useful to produce absolute URLs from relative links on a page, for instance, a gemlog index is likely a collection of relative links to the individual articles. Combining it with the absolute URL of the page itself gives the absolute URL of the article.

    This uses the luasocket function url.absolute as documented at https://lunarmodules.github.io/luasocket/url.html#absolute

Usage:

    local result = gemlib.join_urls("gemini://gem.example.com/index.gmi", "aboutme.gmi")
    assert("gemini://gem.example.com/aboutme.gmi" == result)
lines (link[, max_redirects=5[, context=DEFAULT_CONTEXT]])
retrieve lines from a gemini URL or local file.

This function returns an iterator which in turn returns text lines from the file. The iterator is suitable for generalised for loops.

Note: newlines are stripped from the returned lines.

This function should only be used on text files - binary files can't be reliably chopped into lines.

Parameters:

  • link string the URL or filename
  • max_redirects integer maximum number of redirects to follow before giving up (default 5)
  • context SSLContext luasec ssl context for connection (default DEFAULT_CONTEXT)

Returns:

    iterator that returns lines from the URL or file

Raises:

network errors

See also:

Usage:

    for line in gemlib.lines("gemini://gem.example.com", 3) do
       print(line)
    end
parse_url (link)
parse an absolute or relative URL

Parameters:

  • link string the URL to parse

Returns:

    ParsedUrl the parsed URL

    See the luasocket function url.parse https://lunarmodules.github.io/luasocket/url.html#parse

Usage:

    assert("gemini" == parse_url("gemini://gem.example.com/").scheme)
readable (link[, max_redirects=5[, context=DEFAULT_CONTEXT]])
checks if a URL is readable without reading full contents This function handles both text and binary files.

Parameters:

  • link string the URL or filename
  • max_redirects integer maximum number of redirects to follow before giving up (default 5)
  • context SSLContext luasec ssl context for connection (default DEFAULT_CONTEXT)

Returns:

  1. boolean true if the URL was successfully opened, false if unsuccessful
  2. string error message if first return value is false

See also:

Usage:

    local ok = gemlib.readable("gemini://gem.example.com", 3)

Tables

DEFAULT_CONTEXT

Fields:

  • mode (string) default is "client"
  • protocol (string) default is "tlsv1_2"
  • options (table) default is {"all", "no_sslv3"}

    a table used by default for TLS connections if you do not pass a context table in calls get(), lines(), or readable()

    You can use any field recognized by luasec (https://github.com/lunarmodules/luasec) See some examples at https://github.com/lunarmodules/luasec/wiki

Usage:

    -- same as default context, except use TLS version 1.3
    local context = { mode = "client", protocol = "tlsv1_3", options = { "all", "no_sslv3" }}
    local result = gemlib.readable("gemini://gem.example.com/index.gmi", 5, context)
    assert(result == true)
generated by LDoc 1.5.0 Last updated 2026-03-31 19:47:14