Expose a local HTTP server through a temporary Cloudflare Quick Tunnel URL. No account, no config file, embedded directly in your Go program.
local:8080 -> cloudflared edge -> https://random-name.trycloudflare.com
go get github.com/lib-x/cf-quicktunnelNote: This library wraps cloudflare/cloudflared internals directly. Cloudflared does not expose a stable Go API, so pin to a known-good version and test when upgrading.
t, err := quicktunnel.New(quicktunnel.Config{
LocalAddr: "http://localhost:8080",
Protocol: quicktunnel.ProtocolQUIC, // or ProtocolHTTP2 / ProtocolAuto
})
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
urlCh, errCh := t.Start(ctx)
url := <-urlCh
fmt.Println("Public URL:", url) // https://xxxxx.trycloudflare.com
// ... do work ...
t.Stop(0) // graceful shutdown (uses GracePeriod from config)
<-errCh // wait for clean exit| Field | Default | Description |
|---|---|---|
LocalAddr |
http://localhost:8080 |
Origin the tunnel proxies to |
HAConnections |
1 |
Parallel connections to Cloudflare edge |
GracePeriod |
30s |
How long to drain connections on graceful stop |
Mode |
ShutdownGraceful |
ShutdownGraceful or ShutdownImmediate |
Protocol |
"quic" |
"quic", "http2", or "auto" |
Log |
discard | *zerolog.Logger for tunnel internals |
Use the exported protocol constants instead of spelling strings in callers:
quicktunnel.ProtocolQUIC
quicktunnel.ProtocolHTTP2
quicktunnel.ProtocolAutoGraceful (default): t.Stop(timeout) signals cloudflared to drain existing
connections. If they don't finish within timeout (or GracePeriod if 0), the
context is force-cancelled.
Immediate: cancelling the context or calling t.Stop(0) tears down all
connections immediately.
You don't need a separately running server — bind to a random port and pass the address:
ln, _ := net.Listen("tcp", "127.0.0.1:0")
go http.Serve(ln, myHandler)
t, _ := quicktunnel.New(quicktunnel.Config{
LocalAddr: "http://" + ln.Addr().String(),
})See examples/basic for a fixed-port demo and
examples/proxy for the full in-process handler
pattern.
Both examples accept a protocol flag:
go run ./examples/basic -protocol quic
go run ./examples/basic -protocol http2
go run ./examples/proxy -protocol autoDefault tests avoid external network calls:
go test ./...Run the real forwarding test explicitly. It starts a local HTTP server, creates a Quick Tunnel, fetches the temporary public URL, and verifies that a request through Cloudflare reaches the local server:
QUICKTUNNEL_INTEGRATION=1 QUICKTUNNEL_PROTOCOL=quic go test -run TestQuickTunnelForwardsHTTP -v
QUICKTUNNEL_INTEGRATION=1 QUICKTUNNEL_PROTOCOL=http2 go test -run TestQuickTunnelForwardsHTTP -v- Quick Tunnel URLs are temporary and public — anyone with the URL can access your server.
- Cloudflare may rate-limit or block tunnel creation; don't use this for production traffic.
- The library embeds cloudflared as a library dependency. The cloudflared team does not officially support this usage pattern; internal APIs may change between versions.
- Tunnels are not guaranteed to stay up indefinitely; cloudflared handles reconnection automatically up to
Retriesattempts.