Help us shape the future of Go! Take the 2026 Go Developer Survey

tunnel

package
v0.2.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 15, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package tunnel publishes a locally-bound rysh web server at a public HTTPS URL through ngrok.

The web server binds a port on this machine; a phone or a laptop somewhere else cannot reach it. An ngrok tunnel is the door, and it is a door the session should be able to open for itself on every restart — the alternative is a hand-run `ngrok http` (or a LaunchAgent) that nobody remembers to restart, whose URL nothing in the session knows.

There are three ways in, tried in this order:

adopt   an agent is already running and already forwards our port —
        use its URL and touch nothing
create  an agent is running but not for our port — ask it, over its local
        API, to add one
spawn   no agent is running — start `ngrok http <port>` ourselves

The order is not a preference, it is the free plan: ONE agent session per account. A second `ngrok http` exits immediately with ERR_NGROK_108 and, if something respins it, rate-limits the account. So an agent that is already up is always used rather than competed with — and Stop() only ever tears down what this process actually opened.

Index

Constants

View Source
const DefaultAPIBase = "http://127.0.0.1:4040"

DefaultAPIBase is the ngrok agent's local API — the same one that serves the inspector at http://127.0.0.1:4040.

View Source
const DefaultBinary = "ngrok"

DefaultBinary is the ngrok executable, resolved through PATH when it is not an absolute path.

Variables

View Source
var ErrNoTunnel = errors.New("no tunnel")

ErrNoTunnel reports that nothing is published for a port.

Functions

func Lookup

func Lookup(ctx context.Context, apiBase string, port int) (string, error)

Lookup reports the public URL a running agent already serves for port, without establishing anything. Used by status output, where starting a tunnel as a side effect of asking about one would be a surprise.

Types

type Options

type Options struct {
	// Port is the local TCP port to publish. Required.
	Port int
	// Domain is a reserved ngrok domain (e.g. "rysh-web.ngrok.app"). Empty
	// takes whatever ephemeral URL ngrok hands out — which changes on every
	// restart, so a session meant to be reachable at a stable address wants one.
	Domain string
	// Binary is the ngrok executable; empty means DefaultBinary.
	Binary string
	// ConfigFile is an ngrok config to pass through (--config).
	ConfigFile string
	// Authtoken authenticates a spawned agent (NGROK_AUTHTOKEN). Empty leaves
	// the agent to find its own in ~/.../ngrok.yml, which is the usual setup.
	Authtoken string
	// APIBase overrides the agent API base URL; empty means DefaultAPIBase.
	APIBase string
	// Name is the tunnel name used with the agent API. Empty derives one from
	// the port ("rysh-web-<port>").
	Name string
	// LogPath is where a spawned agent's log is written. Empty discards it —
	// but a log is what turns "the tunnel did not come up" into a reason, so
	// callers should set one.
	LogPath string
	// Timeout bounds Start. Zero means defaultStartTimeout.
	Timeout time.Duration
	// HTTPClient overrides the client used for the agent API (tests).
	HTTPClient *http.Client
}

Options configures one tunnel.

type Origin

type Origin string

Origin records how a tunnel came to exist, which is exactly what decides whether Stop may take it down.

const (
	// OriginAdopted: an agent was already forwarding this port. Not ours to stop.
	OriginAdopted Origin = "adopted"
	// OriginCreated: a running agent created it at our request, over its API.
	OriginCreated Origin = "created"
	// OriginSpawned: we started the agent process ourselves.
	OriginSpawned Origin = "spawned"
)

type Tunnel

type Tunnel struct {
	// URL is the public HTTPS address.
	URL string
	// Origin says how it was established, and so what Stop is allowed to do.
	Origin Origin
	// Name is the agent-API tunnel name.
	Name string
	// Port is the local port being published.
	Port int
	// contains filtered or unexported fields
}

Tunnel is a live public endpoint for a local port.

func Start

func Start(ctx context.Context, opts Options) (*Tunnel, error)

Start establishes a tunnel for opts.Port, adopting or reusing a running agent before starting one of its own (see the package comment).

func (*Tunnel) Adopted

func (t *Tunnel) Adopted() bool

Adopted reports whether the tunnel was already up when this process asked for it — the case where Stop deliberately does nothing.

func (*Tunnel) Stop

func (t *Tunnel) Stop() error

Stop takes down the tunnel — but only what this process opened. An adopted tunnel belongs to whoever started it (a LaunchAgent, another session, the user's own terminal) and is left alone; stopping it would cut a door this process never opened.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL