💾 Archived View for gemini.circumlunar.space › users › parker › gemlog › plumber.gmi captured on 2023-11-04 at 12:06:23. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2020-09-24)

-=-=-=-=-=-=-

Plumber Madness

Today I did a hack that I am quite proud of and I want to show it to the rest of you, and it all has to do with a program called the plumber.

I won't go in-depth into the inner workings of the plumber -- you can check the paper Rob Pike wrote on it below¹ -- but the jist of it is the plumber is a program that will read text and, using a set of user-defined rules, can traffic it to other programs. It's the ultimate middle-man.

Let me show you the rule that my client typically uses:

type is text
data matches 'gemini://([a-zA-Z0-9_\-.]+)(/?[a-zA-Z0-9/_\-.~?&\(\)+%:同體大悲ü]*)'
plumb to web
plumb start torsocks gacme $0 $1 $2

There's no need to look at the first and third rule, it's the second and forth lines that are the interesting ones for now. The second line is the part of the rule that catches the gemini link.² Notice the parenthesies surrounding parts of the regular expression? That groups part of the data into its own string. I use that on the forth line as arguments for gacme. If I were to send "gemini://80h.dev/agena/" through the plumber, then $1 would match to "80h.dev" and $2 would match to "/agena/". $0 just matches to the whole line.

Hopefully by now you at least have a basic understanding as to what's going on. But showing off that simple rule isn't why I wrote this article. This rule is:

type is text
data matches 'gopher://([a-z0-9.\-]+.*)'
plumb to web
plumb start plumb 'gemini://80h.dev/agena/'$1

This rule is all I needed to turn my gemini client into a gopher client. As I'm sure you all know, "agena" is 80h's Gemini→Gopher proxy, which means all I have to do is route my gopher request to that proxy. $1 just maps to everything after "gopher://", and then we get to the command that launches it all. "plumb" is a command that just puts a message through the plumber. That $1 up there is butted up against the gemini link to agena which concatenates the two strings together. So if I wanted to go to "gopher://bitreich.org/", this rule sends "gemini://80h.dev/agena/bitreich.org/" back through the plumber, and the next pass will match it with the first rule I showed you, and everything else is taken care of!

What I wanted to show is that there was no complicated script to write, and no major modifications to my client were needed. Hell, it didn't even get touched.

=> http://doc.cat-v.org/plan_9/4th_edition/papers/plumb ¹Non-required but helpful reading for understanding

²There's some funky Chinese characters and the ü umlaut in there because some links I've run across have them in there. Before I didn't have them in, so the gemini link wouldn't get caught by the plumber. There's no good way to match *all* printable characters in a regular expression, so I just put them in the rules as I need to. I could write rules that just match ".*", and while that would work in theory I've had some trouble in the past. I'll probably work something out so my rules don't look ugly, but for now this works.