4.3.0 • Public • Published

Gopher over HTTP

Gopher over HTTP (GoH) proxy for command line use, and a middleware for Node.js web servers and frameworks.

Supports the plaintext Gopher protocol as well as the encrypted and vhost-capable Gopher over TLS (GoT) with SNI and ALPN.


Presented by Sebastiaan Deckers at WFHConf on 2020-03-26.

Talk about Gopher at WFHConf 2020


The Commons Host CDN offers a public GoH endpoint. It requires the accept: application/gopher HTTP request header.


GoH Clients

GoH Proxy


Runs a local GoH proxy for use by HTTP clients.

$ npx goh
Listening on http://localhost:7080
GET /url=gopher://gopher.floodgap.com
$ curl -H 'Accept: application/gopher' \
iWelcome to Floodgap Systems' official gopher server. error.host 1
iFloodgap has served the gopher community since 1999 error.host 1


  • --log-level - Log output volume. Choices: silent, info. Default: info
  • --gopher-allow-non-standard-port - Connect to Gopher hosts on ports other than 70. Default: false
  • --gopher-allow-private-address - Connect to Gopher hosts on a private IP address. Default: false
  • --gopher-connection-timeout - Maximum idle time on the Gopher connection. Default: 10000
  • --gopher-handshake-timeout - Maximum duration of the TLS connection establishment. Default: 10000
  • --http - Accept plaintext HTTP connections. Default: true
  • --http-port - Port for HTTP connections. Default: 7080
  • --https - Accept encrypted HTTPS connections. Default: false
  • --https-port - Port for HTTPS connections. Default: 7443
  • --https-public-certificate - File path of the TLS public certficate. Default: ""
  • --https-private-key - File path of the TLS private key. Default: ""
  • --https-certificate-authority - File paths of the CA certificate chain. Default: ""
  • --tls-origin-cache-max-ttl - Origin TLS probe cache expiry. Default: 86400000 (24 hours in milliseconds)
  • --config - Path to JSON config file
  • --version - Show version number
  • --help - Show help

CLI options can also be specified as environment variables prefixed by GOH_ and uppercased with underscores.


Middleware for Node.js HTTP servers and frameworks.

const { goh } = require('goh')
// Defaults
const options = {
  // Respond to HTTP/1 connections
  allowHTTP1: false,
  // Allow connections to ports other than 70
  unsafeAllowNonStandardPort: false,
  // Allow connections to private IP addresses (i.e. LAN)
  unsafeAllowPrivateAddress: false,
  // Maximum connection idle time
  timeout: 10000, // 10 seconds
  // Maximum TLS & TCP connection establishment duration
  handshakeTimeout: 10000, // 10 seconds
  // Gopher over TLS probe cache expiration
  originCacheMaxAge: 24 * 60 * 60 * 1000 // 24 hours
const middleware = goh(options)

Use the middleware with popular Node.js web application frameworks like Connect or Fastify.

const { createSecureServer } = require('http2')
const app = require('connect')() // or fastify, etc.
const server = createSecureServer({ cert, key }, app)


allowHTTP1 is a boolean. By default, false, only HTTP/2 (or later) clients are accepted. Set to true to also accept requests from HTTP/1 clients.

unsafeAllowNonStandardPort is a boolean. The default is false which restricts use to the standard Gopher port 70. If true the middleware accepts URLs with any port number. Allowing any port is potentially unsafe and not recommended. The middleware does not validate the response, effectively becoming an open TCP/IP proxy.

unsafeAllowPrivateAddress is a boolean. The default is false which blocks connection attempts to any private IPv4 or IPv6 address. This is important for security when operating a public GoH service to avoid exposing LAN hosts to malicious external users. Set to true to allow connections to remote hosts with private IP addresses.

timeout is the number of milliseconds to keep idle Gopher sessions active. Defaults to 10000 (10 seconds). The HTTP connection (aka session) is not closed, only the TCP/IP socket to the Gopher server and its corresponding HTTP/2 streams with the HTTP user agent.

handshakeTimeout is the number of milliseconds to wait for TCP/IP and TLS connection establishment. The default is 10000 (10 seconds).

originCacheMaxAge is the number of milliseconds to cache Gopher over TLS probe results. The default is 86400000 (24 hours).

Any other options are passed to the net.Socket and tls.TLSSocket constructors. This can be used, for example, to disable rejectUnauthorized in a unit test.

Gopher over HTTP (GoH) protocol

GoH maps the Gopher protocol onto an HTTP exchange. Both Gopher and HTTP use concepts of client-server and request-response. The GoH mapping is therefore appropriately simple and straightforward.

A GoH client is configured with a URI Template of a GoH server. The URI Template must contain a variable named url.


When performing a GoH request, the GoH client expands the variable using a Gopher URL.





A GoH request uses the GET HTTP method.

A GoH client should include an HTTP Accept request header field to indicate support for GoH.

Accept: application/gopher

A GoH server must include an HTTP Content-Type response header field indicating the body contains a Gopher response.

Content-Type: application/gopher

A GoH server response has the Gopher response as its body.

A GoH server response should include an HTTP Via response header field as per Section 5.7.1 of [RFC7230]. The protocol-name value must be Gopher. Since there is no registered version of the Gopher protocol, the protocol-version must be set to RFC1436. If Gopher over TLS is used, the comment field may be set to the TLS version.

Via: Gopher/RFC1436 gopher.example.com TLSv1.3

See Also

Package Sidebar


npm i goh

Weekly Downloads






Unpacked Size

18.9 kB

Total Files


Last publish


  • seb