marmotte is a modern gopher server.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
beastieboy c1fb7f09f8 better-docs (#3) 12 months ago
gopher Added basic functionality and types 12 months ago
.gitignore Initial commit 12 months ago
LICENSE Initial commit 12 months ago better-docs (#3) 12 months ago
go.mod Added basic functionality and types 12 months ago
go.sum Added basic functionality and types 12 months ago
gopherplus.txt better-docs (#3) 12 months ago
main.go Added basic functionality and types 12 months ago


marmotte is a modern gopher server.

What is marmotte?

marmotte is a modern way to run a modern gopher server. marmotte implements the Gopher protocol RFC1436, as well as the more recent extensions Gopher+ and the Gopher/Gopher+ URI Scheme RFC 4266. marmotte goes beyond this and also offers backwards-compatible ways to request code execution on the server. The possiblities include automatic conversion to any format, applying filters to data (images, text, audio...), offering a simple interface to batch jobs or toggling features in the server or even automatic redirection via request rewrite. marmotte is extensible and operations can be added dynamically by simply editing the configuration file.

Why bother?

Even though there is a fantastic wealth of information today on the Web, it always comes wrapped in a thick coat of advertisement, imposed aesthetics and user experience, and related and unrelated options all mixed together, from twitting to becoming a member to pinning on Pinterest to discussing on Reddit. This is not to say all these are bad in themselves, but rather that they tend to obfuscate or take precedence over actual content. An idea here is that the means of publication themselves have an influence on how the information is conveyed, and as a result, on how much information actually makes it to the user.

I believe that simpler means of publication yield simple means of use, that openness leads to creativity and that putting an emphasis on content attracts an audience with a taste and expectations for high quality content. This tends to create a virtuous circle, where the bar is constantly raised by the audience and, in turn, by the production, trying to meet and then exceed the expectations.

Also, it's fun. :)

An open design

marmotte is designed to support multiple protocols, and to be an easy to use all-in-one server. The focus today is on Gopher, but Gemini and other protocols will be implemented in the future (maybe even HTTP!).

The first protocol implemented by marmotte is Gopher. This decision is in direct connection to the technical qualities of the protocol: very straightforward, easy to implement, and amazingly open in its design, especially by today's standards. And this is also what motivates picking Gopher as a first implementation: Gopher embodies perfectly the spirit of the early Internet. Do not sell the information by diguising it, just share the information. Do not impose a specific design, let the users, via their client, decide for themselves. Do not impose, propose. Don't pretend, just stay genuine.

marmotte also will go beyond just serving local files. In the original RFC for Gopher, the protocol's mission is described as "distributed document search and retrieval". Once again, the loose, unassuming wording in the RFC opens the door to many interpretations, and one is to have Gopher work as a gateway to other protocols. This means marmotte can front remote sites running under a different protocol, like FTP, HTTP and NNTP, for example.

Getting started guide

To get started, simply clone this repository, edit main.go to set the root directory you want to serve, and run it.

$ git clone
$ cd marmotte
$ $EDITOR main.go # change the root directory
$ go run main.go # the server now listens on gopher://localhost:7070

Tour of the code

As of today, the code lives in a single package, simply called gopher. The code makes use of the following concepts and types:

  • A Context contains the configuration for the running server, including the lists of Request and Response Transformers. It is the very first thing that is initialised, and is passed to all Request/Response-handling mechanism for reading and writing, updating the current status. Note that the Context is unique per server, not per Request, and should not be used to pass data from one Transformer down to another. Instances of Request and Response should be used for this purpose.
  • A new Request is instantiated for each incoming connection that successfully sends a well-formatted Gopher request to the server. A Request contains information on its kind (today, Gophermap or simple path, tommorrow, functions and others). A Request is send down the series of all configured RequestTransformer instances (not implemented today, see below Limitations).
  • A new Response instance is instantiated once a Request has been created. It contains information about the data requested, deduced from the MIME type of the file on the disk. This Response goes through the series of all configured ResponseTransformer instances before its content is sent back to the client that originated the request. The ResponseTransformer instances are responsible for preparing the data and applying all the modifications and adaptations necessary before the data is written back on the socket.
  • A RequestTransformer is made of a TransformerPredicate and a RequestTransformerFunc. The former is a function that determines whether the RequestTransformer is applicable to the given Request and Context, and the latter is the function itself. Both the Request and the Context can be updated by the RequestTransformerFunc (a good example is a redirection, where the Request is updated to contain the new destination).
  • A ResponseTransformer is made of a TransformerPredicate and a ResponseTransformerFunc. The tandem work the same way as for responses, where the former determines whether the latter is applicable to the given Context, Request and Response. Here, the Request has become read-only and only the Context and the Response instances can be modified. The various content sections of the Response instance are typically updated by the ResponseTransformerFunc.
  • The file files.go is where file types are determined, based on the MIME type deduction.
  • The file server.go contains the main loop, where network connections are accepted, parsed, transformations are applied and data is written back on the socket.


marmotte is under active development, and currently does not implement all the features listed in the first section, What is marmotte?.

Currently implemented features

Below is a list of the features currently implemented. This is by no means a complete roadmap, but gives an overview of the usability of marmotte for a given purpose.

  • Gopher Protocol RFC 1436
  • Gopher+
  • Response Transformers infrastructure
  • Gopher protocol implemented via Transformers
  • Gophermap Header Transformer
  • Backwards-compatible selector/URI to offer and select Transformers
  • Request Transformers infrastructure
  • Simple redirect based on Request Transformers
  • Image filtering via Transformers


marmotte is published under the 2-Clause BSD License. A copy of the license is included in the source repository.