goh
v4.3.0
Published
Gopher over HTTP (GoH)
Downloads
43
Readme
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.
Video
Presented by Sebastiaan Deckers at WFHConf on 2020-03-26.
Demo
The Commons Host CDN offers a public GoH endpoint. It requires the accept: application/gopher
HTTP request header.
https://commons.host?url=
GoH Clients
GoH Proxy
CLI
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' \
'http://localhost:7080?url=gopher://gopher.floodgap.com'
iWelcome to Floodgap Systems' official gopher server. error.host 1
iFloodgap has served the gopher community since 1999 error.host 1
...
Options
--log-level
- Log output volume. Choices:silent
,info
. Default:info
--gopher-allow-non-standard-port
- Connect to Gopher hosts on ports other than70
. 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.
API
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.
app.use(middleware)
const server = createSecureServer({ cert, key }, app)
server.listen(80)
Options
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
.
https://goh.example.com/gopher-proxy{?url}
When performing a GoH request, the GoH client expands the variable using a Gopher URL.
Given:
gopher://gopher.example.com
Result:
https://goh.example.com/gopher-proxy?url=gopher%3A%2F%2Fgopher.example.com
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
- Gopher over TLS (GoT) protocol & server
- TLS Router: Accept plaintext and encrypted clients on the same port. Forward traffic to one or more plaintext Gopher backend servers. With ALPN and SNI support for virtual hosting.