「‍」 Lingenic

GOPHER-OVER-HTTP

(⤓.txt ◇.txt); γ ≜ [2026-03-01T132228.774, 2026-03-01T132228.774] ∧ |γ| = 1

GOPHER OVER HTTP(S)

Lingenic revives gopher by changing the transport.


SUMMARY

- Accept: text/gopher triggers gopher format response
- Content-Type: text/gopher; charset=utf-8
- Standard HTTP caching headers


THE FORMAT

Gopher is a 1991 format for hierarchical text menus. Tab-separated fields. Type indicators. Selectors as paths. No markup. No styling. Just structured text.


THE PROTOCOL

The original protocol ran on port 70 over raw TCP. That protocol is blocked by firewalls, ignored by CDNs, unsupported by browsers. The infrastructure of the modern internet assumes HTTP.

The format itself has no such constraints.


THE PROBLEM

Running a traditional gopher server requires port 70 access, direct IP exposure, and separate infrastructure. The protocol's simplicity becomes operational complexity.

This is backwards. The simplicity should be in the output, not the transport.


THE SOLUTION

Serve gopher format over HTTP.

The client sends:

    GET /design/terminal/ HTTP/1.1
    Accept: text/gopher

The server responds:

    HTTP/1.1 200 OK
    Content-Type: text/gopher; charset=utf-8

    i                        TERMINAL                              	fake	0
    i                                                              	fake	0
    1[root]	/	lingenic.com	70
    i > design	fake	0
    i	fake	0
    0readme.txt	/design/terminal/readme.txt	lingenic.com	70
    1src	/design/terminal/src	lingenic.com	70
    i	fake	0
    i────────────────────────────────────────	fake	0
    i                   lingenic.com                               	fake	0
    .

Same menu format. Same item types. Same tab-separated fields. The only difference is transport: HTTP instead of raw TCP.


WHAT THIS ENABLES

The gopher response goes through your CDN. It gets cached. It's protected from DDoS. It shares infrastructure with the HTML site. No port 70 exposure. No separate server.

A gopher client that speaks HTTP gets:

- CDN edge caching
- HTTPS encryption
- Firewall traversal
- Standard tooling (curl, wget, fetch)

The protocol becomes the format. The transport becomes HTTP.


THE CLIENT

A gopher client over HTTP:

1. Request with Accept: text/gopher
2. Parse tab-separated response
3. Render menu
4. Follow links

Fifty lines of code. The port 70 field in menu items is vestigial — the client uses HTTP. The field remains for format compatibility.


CONTENT NEGOTIATION

The same URL serves different formats based on Accept header:

    Accept: text/html      →  HTML page with styling
    Accept: text/gopher    →  Gopher menu format
    Accept: text/plain     →  Raw directory listing
    Accept: text/hsv       →  Structured data format

One URL, multiple representations. The client declares what it wants. The server responds appropriately. This is how HTTP was designed to work.


THE TRADEOFF

Traditional gopher clients expect port 70 and raw TCP. That won't do today.

But it is the format that matters. The format is what we keep.


THE POINT

Gopher was never about the TCP handshake or the port number. It was about the output: a simple, parseable, text-based menu format that any client could render.

That format transfers directly to HTTP. The selectors become paths. The host field becomes informational. The port field becomes vestigial. Everything else is identical.

This is gopher. The transport changed. Nothing else did.


IMPLEMENTATION

Server side (keep-serve):

- Accept: text/gopher triggers gopher format response
- Content-Type: text/gopher; charset=utf-8
- Same path resolution as HTML
- Same header/footer structure
- Standard HTTP caching headers

Client side (separate project):

- HTTP client with Accept: text/gopher
- Menu parser (split on tabs, check item types)
- TUI renderer (ncurses or similar)
- Navigation (arrow keys, enter to follow)

The server is running. The client it to be released.

---
Lingenic LLC
2026