I'm going to implement a Gopher client in rust because it seems like a good project to try out. I'm going straight to the source for this which means that I'm going to implement the client based on my reading of the RFC. Which will be a first and I think quite fun. It's short RFC and the gopher protocol is very simple. I'm also going to use bare rust so I'll try to keep the number of dependencies down to 0.
Let's get started!
The RFC to read:
- Protocol goes over TCP on port 70
- Clients send strings called 'selector' to the server
- The Server responds with text and terminating chracter is a period on a line by itself.
Connection is automatically closed.
Gopher is designed to appear like a filesystem
Each line in a gopher listing 5 parts
- User visible name
- Domain name
User should only see the User Visible Name
Only time the Client sends back more than one string is on a search, selector is sent along with a space delimited string of words to search for
Server will respond with a regular listing but this may span multiple subnets and even the internet
Example of a Gopher listing:
0About internet GopherFStuff:About usFrawBits.micro.umn.eduF70
F is tab, so a gopher listing is a tab delimited string, with each string being on a new line.
TypeUser Visible NameFPathFDomain nameFPort
- Note Type doesn't have a tab delimiter.
Path is the selector string the client will send to the Domain Name on Port.
User should only see the User Visible Name.
If there is more tabs than this, ignore the rest.
Displaying the types is up to the client and the author's taste.
There can be root level Gopher servers that hold listings pointing to other Gopher servers, this should be load balanced.
Recommended to have an About document with contact information as well as what the server holds on each Gopher server in the top level.
The base types are 0 for files, 1 for directories and 7 for search.
Client can save the paths the User navigates to to form a stack
Client can cache stuff to skip network calls
Types that are not known can be marked as unknown or ignored, up to the client
New features to Gopher are only done via the types field, any further changes to Gopher will be server changes.
This is the distilled down notes of the RFC and should be enough to get started. The design I'll go for is that of the Linux shell and I'll treat Gopher as a filesystem as the RFC mentioned.
Something I've learned as I built the client and browsed around is the i type, it is sort of an unofficial addon to the gopher protocol such that you can attach links and text all in one document.
A very hacky but smart solution to a problem and I'm curious who came up with it :)