The problem with the Gopher protocol as defined in RFC 1436 is that it doesn’t allow you to send anything to the server except for a query string. That’s not good enough for wiki editing. At the same time, we don’t want to make the interaction between Gopher server and Gopher client harder than it needs to be. This page offers a proposal:
=> RFC 1436
First, the server needs to know about a new item type which says: item is a file you can write to. Below is a Gopher menu for a wiki page. The selector for this menu is Alex/menu
. The selector for writing a new page is Alex/write/text
.
$ **echo Alex/menu | nc localhost 7070** iThe text of this page: localhost 7070 0Alex Alex localhost 7070 hAlex Alex/html localhost 7070 wReplace Alex Alex/write/text localhost 7070 1Page History Alex/history localhost 7070 i localhost 7070 iThere are no links leaving this page. localhost 7070 .
Let’s replace the text with something! We need to end our text with a period to let the server know that we don’t intend to send any more.
$ **nc localhost 7070 << 'EOF' Alex/write/text test . EOF** iPage was saved. localhost 7070 1Alex Alex/menu localhost 7070 .
Or post a text file. You need to add the selector at the top and the period at the end:
$ **( echo Alex/write/text; cat haiku.txt; echo . ) | nc localhost 7070** iPage was saved. localhost 7070 1Alex Alex/menu localhost 7070 .
Verify the page content:
$ **echo Alex | nc localhost 7070** Quiet disk rattling Keyboard clicking, then it stops. Rain falls and I think. .
The wiki also allows a different kind of upload: binary files. When uploading a file, the server has two problems:
telnet
or nc
. That’s why we need to tell the server how long the file is going to be.So anyway, how would it work? It did not make an appearance in the menu above, but the selector would be Alex/write/file
. The content-length is appended to this selector, separated by a tab character. wc -c
counts the number of bytes and when it does that for standard input, no filename is printed.
$ **echo -e "Alex/write/file\t"`wc -c < test.png` \ | cat - test.png \ | nc localhost 7070** 3Page was not saved: Files of type application/octet-stream are not allowed. localhost 7070 .
When writing a file using this selector, a content-type of application/octet
is assumed.
The wiki will extract the MIME type from the selector, if possible: Alex/image/png/write/file
, for example.
$ **echo -e "Alex/image/png/write/file\t"`wc -c < test.png` \ | cat - test.png \ | nc localhost 7070** iPage was saved. localhost 7070 1Alex Alex/menu localhost 7070 .
Test it:
$ **echo Alex | nc localhost 7070 > test2.png** $ **diff test.png test2.png**
Note that for my particular wiki, Alex/text/plain/write/file
is not quite the same as Alex/write/text
. The first will store a binary blob with MIME type text/plain
which will be served like any other binary file: no parsing for links and all that. The second will edit a wiki page, which can be read using a Gopher client.
I understand that allowing file uploads can be tricky. It’s up to the Gopher server to handle this with care: store files in write-only upload directories, or provide all the peer review facilities like a wiki does, it’s up to you to write a good Gopher server. To paraphrase the description of item type 9: “Item is a binary file! Server will read until the TCP connection closes. Beware.”
Let’s get back to uploading text files and the problem of peer review facilities: Ideally, authors would provide some metadata as they upload their document. A summary of changes made, a name. My wiki will interpret a fenced off block at the very beginning of the document as metadata.
The following example sends the selector for writing a text file called Alex, a metadata block, and finally the new text.
$ **nc localhost 7070 <<'EOF' Alex/write/text
username: Alex
summary: a different Haiku
Cold and dark outside Remember all the sick beds Good riddance old year . EOF** iPage was saved. localhost 7070 1Alex Alex/menu localhost 7070 .
Check it out:
$ **echo Alex | nc localhost 7070** Cold and dark outside Remember all the sick beds Good riddance old year .
Let’s check Recent Changes, too:
$ **echo do/rc | nc localhost 7070** iRecent Changes localhost 7070 1Show minor edits do/rc/showedits localhost 7070 i localhost 7070 i2018-01-06 localhost 7070 i localhost 7070 1Alex Alex/menu localhost 7070 i20:55 UTC by Alex from 127.0.0.1: a different Haiku localhost 7070 i localhost 7070 i2018-01-05 localhost 7070 i localhost 7070 1test test/menu localhost 7070 i21:53 UTC by 127.0.0.1 localhost 7070 .
Yay! 👍
Sources:
=> gopher-server.pl | gopher-server.t | gopher.el
Try browsing the wiki:
Note that you will not be able to edit pages because spam protection requires you to answer a question before you are allowed to save. The question is simply that you need to say hello. Luckily, we can use the metadata for text files to do this:
$ **nc alexschroeder.ch 70 << 'EOF' SandBox/write/text
username: Alex
answer: hello
This is a test. . EOF** iPage was saved. alexschroeder.ch 70 1SandBox SandBox/menu alexschroeder.ch 70 .
Anyway, here’s a quick setup for local experiments. You need to get Oddmuse, of course. And then:
=> get Oddmuse
Run perl stuff/server.pl
starts an Oddmuse Wiki on port 8080. You can edit pages on http://localhost:8080/
. Data is stored in /tmp/oddmuse
.
Run perl stuff/gopher-server.pl --port=localhost:7070 --wiki=./wiki.pl --wiki_dir=/tmp/oddmuse
to start the Gopher server on port 7070.
Run lynx gopher://localhost:7070
to browse the same wiki.
#Gopher #Wikis
(Please contact me if you want to remove your comment.)
⁂
“Phlogs” are Gopher Blogs. I think the SDF has the biggest collection of them (link goes via a proxy, the real deal is gopher://phlogosphere.org).
=> SDF | collection | gopher://phlogosphere.org
People don't like comments.
– Alex 2018-01-07 12:49 UTC
There are still problems with the code, though. I finally decided to document it as issue 15 on GitHub. For now, the interface will stay as it is. I just have issues getting this Mojo::IOLoop
code to work. [This was later fixed by switching back to Net::Server
.]
=> issue 15
– Alex Schroeder 2018-01-08 14:24 UTC
Stuff I need to check:
[[image:foo]]
links ✓
– Alex 2018-01-13 17:20 UTC
text/gemini
This content has been proxied by September (3851b).