Documentation
¶
Overview ¶
Package libtunnel exposes a local origin to the public internet through a tunnel backend (Cloudflare quick tunnels first), behind a thin, stable façade over stable/alpha versioned packages.
The package is split into these pieces:
- libtunnel (this package) — thin façade exposing New and the backend constructors. Stable surface for application code.
- github.com/cnuss/libtunnel/v1 — the stable Tunnel/Provider/Backend interfaces and spec types. Application code that wants to declare types against the contract imports this.
- github.com/cnuss/libtunnel/v1alpha1 — the current implementation: the lazy tunnel core plus generic providers, with backend engines in subpackages (v1alpha1/cloudflare). Internals may change between alpha revisions.
Everything is lazy: New returns immediately, and the edge connection starts on first demand — WithListener provides the origin listener explicitly, WithLocalURL points at an already-running local origin instead (the cloudflared `tunnel --url` shape), and Listener, URL, and TunnelReady mint a loopback listener if no origin was provided.
l, _ := net.Listen("tcp", "127.0.0.1:0")
conn := libtunnel.New(libtunnel.Cloudflare()).WithListener(l)
go server.Serve(conn.Listener())
select {
case <-conn.TunnelReady():
fmt.Println(conn.URL()) // public https://<hostname>/
case <-conn.Done():
log.Fatal(conn.Err()) // TunnelReady never closes on failure
}
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CacheDir ¶ added in v0.0.18
func CacheDir() string
CacheDir is where minted specs are cached and where From and Hosts look: LIBTUNNEL_CACHE_DIR if set, else a per-user location under os.UserCacheDir(). Empty if no per-user cache directory can be determined.
func Cloudflare ¶
func Cloudflare() *cloudflare.Backend
Cloudflare returns the Cloudflare backend: an in-process cloudflared quick-tunnel engine (no cloudflared binary required). Its credential chain resolves env first: adopt a spec from the LIBTUNNEL_SPEC environment variable when a parent process handed one off, replay the spec LIBTUNNEL_FROM references (hostname, file path, or literal JSON — From's resolution), and mint an anonymous *.trycloudflare.com quick tunnel otherwise. A resolved spec is exported back into the environment so spawned children inherit the same tunnel identity; a spec this process exported itself is never re-adopted — a second in-process tunnel mints its own identity.
Individual spec fields can be overridden with the backend's setters — WithID, WithName, WithHostname, WithAccountTag, WithSecret — or their LIBTUNNEL__CLOUDFLARE_* environment mirrors (env beats code, field by field); a complete credential set skips resolution entirely. WithProvider (LIBTUNNEL__CLOUDFLARE_PROVIDER) points the mint at a different quick-tunnel provider host. Chain the backend-specific setters before WithTLS / WithHTTP2, which return the CloudflareV1 interface.
func Hosts ¶ added in v0.0.18
func Hosts() []string
Hosts lists the public URLs of the specs cached on disk — "https://<hostname>:443/" each, sorted — from LIBTUNNEL_CACHE_DIR if set, else a per-user location under os.UserCacheDir(). A mint caches its spec there, so this enumerates the tunnels From can replay. Best effort: an unreadable cache yields a shorter or empty list, never an error.
func Version ¶ added in v0.0.30
func Version() string
Version reports the libtunnel release this build links against — e.g. "v0.0.29". It matches the git tag and the published container image tag, so a consumer can pin the image to the exact library version it compiles against:
image := "ghcr.io/cnuss/libtunnel:" + libtunnel.Version()
Resolution, in order: the release stamp (set only in libtunnel's own release binaries); the module version recorded in the importer's build info (the common consumer case — the version required in their go.mod); the main-module version; and finally the short VCS revision of a local build (with a -dirty suffix for an uncommitted tree). A build carrying no version information at all returns "unknown".
Image tag convention: each release publishes ghcr.io/cnuss/libtunnel tagged with both the v-prefixed release tag (matching Version exactly) and the bare semver ("0.0.29", "0.0"), plus "latest" — so concatenating Version onto the image name resolves to the matching image with no trimming.
Types ¶
type CloudflareV1 ¶ added in v0.0.7
type CloudflareV1 = v1.Backend[*cloudflare.Spec]
CloudflareV1 is the Cloudflare backend's contract type: an alias for v1.Backend[*cloudflare.Spec], re-exported so callers can declare fields and parameters without importing v1 or the cloudflare package. Cloudflare() returns the concrete *cloudflare.Backend (which satisfies this), so the backend-specific setters (WithID and friends) stay reachable.
type InterceptCtx ¶ added in v0.0.36
type InterceptCtx = v1.InterceptCtx // per-request handle: request, levers, handler
The interceptor types (see TunnelV1.WithInterceptor) are re-exported from v1 so callers can name them without importing v1.
type InterceptFn ¶ added in v0.0.35
type InterceptFn = v1.InterceptFn // shapes how a matched request is served
The interceptor types (see TunnelV1.WithInterceptor) are re-exported from v1 so callers can name them without importing v1.
type Interceptor ¶ added in v0.0.35
type Interceptor = v1.Interceptor // a {Match, Handler} pair
The interceptor types (see TunnelV1.WithInterceptor) are re-exported from v1 so callers can name them without importing v1.
type Interceptors ¶ added in v0.0.35
type Interceptors = v1.Interceptors // ordered registry; first match wins
The interceptor types (see TunnelV1.WithInterceptor) are re-exported from v1 so callers can name them without importing v1.
type MatchFn ¶ added in v0.0.35
The interceptor types (see TunnelV1.WithInterceptor) are re-exported from v1 so callers can name them without importing v1.
type TunnelV1 ¶ added in v0.0.7
TunnelV1 is the tunnel handle returned by New: a non-generic alias for v1.Tunnel, re-exported so callers can name the type without importing v1. Storable as a plain field — the backend spec type does not appear in it.
func From ¶ added in v0.0.17
From returns an unstarted tunnel that replays a previously serialized spec instead of minting or adopting one — the credentials are pinned, so it connects under the same hostname. spec is resolved in order: an existing file at that path; a file of that name in the cache dir; a cached spec for that hostname (so From("foo.trycloudflare.com") replays the cached mint); finally the serialized JSON itself. The cache dir is LIBTUNNEL_CACHE_DIR when set, else a per-user location under os.UserCacheDir() — where a mint writes its spec.
Like New, it returns immediately and WithListener (or Listener) starts the connection. A spec that can't be parsed, or whose backend tag is unknown, yields a tunnel already canceled with that cause — surfaced through Err()/Done(), per the façade's no-error contract.
The LIBTUNNEL_FROM environment variable is From's operator-side mirror: it takes the same spec reference and replays it through any backend's credential chain — including over a code-pinned From spec, after LIBTUNNEL_SPEC (env beats code; SPEC beats FROM).
func New ¶
New returns an unstarted tunnel on the given backend, which also supplies the credential chain. T is the backend's spec type, inferred from the backend and used only to wire the credential chain — it does not appear in the returned type, so the tunnel reference is non-generic and storable without threading the spec type through caller code:
libtunnel.New(libtunnel.Cloudflare())
Configure the result with With* methods; WithListener starts the connection.
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
libtunnel
command
Command libtunnel is the env-only tunnel launcher: a standalone binary with no flags and no config files — every knob comes from the environment, the same variables the library reads (see package v1).
|
Command libtunnel is the env-only tunnel launcher: a standalone binary with no flags and no config files — every knob comes from the environment, the same variables the library reads (see package v1). |
|
Package e2e is the live tier: real quick tunnels through the real Cloudflare edge, gated behind LIBTUNNEL_E2E_LIVE=1.
|
Package e2e is the live tier: real quick tunnels through the real Cloudflare edge, gated behind LIBTUNNEL_E2E_LIVE=1. |
|
examples
|
|
|
serve
command
Command serve exposes a local HTTP server to the public internet through a Cloudflare quick tunnel, waits until the tunnel is reachable end to end, then requests its own public URL to prove the round trip.
|
Command serve exposes a local HTTP server to the public internet through a Cloudflare quick tunnel, waits until the tunnel is reachable end to end, then requests its own public URL to prove the round trip. |
|
serve-tls
command
Command serve-tls is serve's TLS twin: it hands WithListener a TLS listener (tls.Listen over a self-signed, in-process cert) instead of a plain one, so the tunnel dials the origin over https.
|
Command serve-tls is serve's TLS twin: it hands WithListener a TLS listener (tls.Listen over a self-signed, in-process cert) instead of a plain one, so the tunnel dials the origin over https. |
|
subprocess
command
Command subprocess is the canonical parent→child spec handoff: the parent process mints a tunnel spec and passes it to a spawned child through the LIBTUNNEL_SPEC environment variable; the child provides the listener, connects the tunnel, and serves; the parent then requests the child's public URL.
|
Command subprocess is the canonical parent→child spec handoff: the parent process mints a tunnel spec and passes it to a spawned child through the LIBTUNNEL_SPEC environment variable; the child provides the listener, connects the tunnel, and serves; the parent then requests the child's public URL. |
|
Package v1 is the stable public surface for libtunnel.
|
Package v1 is the stable public surface for libtunnel. |
|
Package v1alpha1 is the current implementation behind the v1 tunnel interfaces: the backend-agnostic lazy core plus generic providers.
|
Package v1alpha1 is the current implementation behind the v1 tunnel interfaces: the backend-agnostic lazy core plus generic providers. |
|
cloudflare
Package cloudflare is the Cloudflare backend for libtunnel: a cloudflared quick-tunnel engine driven entirely in-process (no cloudflared binary).
|
Package cloudflare is the Cloudflare backend for libtunnel: a cloudflared quick-tunnel engine driven entirely in-process (no cloudflared binary). |
|
resolver
Package resolver does direct DNS lookups against a specific server — the dig(1) equivalent: build the query with golang.org/x/net/dns/dnsmessage, send it over UDP (retrying over TCP when the answer is truncated), and parse the reply.
|
Package resolver does direct DNS lookups against a specific server — the dig(1) equivalent: build the query with golang.org/x/net/dns/dnsmessage, send it over UDP (retrying over TCP when the answer is truncated), and parse the reply. |