Documentation
¶
Overview ¶
Package xpos provides a Go SDK for XPOS — instant public URLs via SSH tunnels.
XPOS exposes local services to the internet through SSH tunnels. This SDK wraps the SSH CLI into a clean, idiomatic Go library and CLI tool. Zero external dependencies — uses only the Go standard library.
Quick Start ¶
Create and start a tunnel with a single call:
tunnel, err := xpos.Connect(ctx, xpos.WithPort(3000))
if err != nil {
log.Fatal(err)
}
fmt.Println(tunnel.URL) // https://abc.xpos.to
defer tunnel.Close()
<-tunnel.Done()
Authentication ¶
Pass a token to unlock features like reserved subdomains and longer expiry:
tunnel, err := xpos.Connect(ctx,
xpos.WithPort(3000),
xpos.WithToken("tk_xxx"),
xpos.WithSubdomain("myapp"),
)
Alternatively, set the XPOS_TOKEN environment variable and omit WithToken.
TCP Tunnels ¶
Expose TCP services (databases, etc.) by setting the mode to "tcp":
tunnel, err := xpos.Connect(ctx,
xpos.WithPort(5432),
xpos.WithToken("tk_xxx"),
xpos.WithMode("tcp"),
)
fmt.Println(tunnel.URL) // 1.2.3.4:54321
Requirements ¶
An SSH client must be installed and available in your PATH. SSH is pre-installed on macOS, Linux, and Windows 10+.
See https://xpos.dev for more information.
Index ¶
- Constants
- func BuildRemoteForward(port int, host, subdomain, domain string) string
- func BuildSSHUser(token, mode string) string
- func FormatExpiry(rfc3339 string) string
- func ResolveToken(token string) string
- func ShouldFilterLine(line string) bool
- type Option
- func WithConnectTimeout(d time.Duration) Option
- func WithDomain(domain string) Option
- func WithHost(host string) Option
- func WithMode(mode string) Option
- func WithOnClose(fn func(exitCode int)) Option
- func WithOnConnect(fn func(url, expiresAt string)) Option
- func WithOnOutput(fn func(text string)) Option
- func WithPort(port int) Option
- func WithSSHPort(port int) Option
- func WithServer(server string) Option
- func WithSubdomain(name string) Option
- func WithToken(token string) Option
- type Tunnel
Constants ¶
const ( ModeHTTP = "http" ModeTCP = "tcp" )
Mode constants for tunnel type.
const ( DefaultHost = "127.0.0.1" DefaultServer = "go.xpos.dev" DefaultSSHPort = 443 DefaultMode = ModeHTTP )
Default configuration values matching all XPOS SDKs.
const ( DefaultConnectTimeout = 15 * time.Second DefaultKillTimeout = 3 * time.Second )
Default timeouts.
Variables ¶
This section is empty.
Functions ¶
func BuildRemoteForward ¶
BuildRemoteForward constructs the -R argument for SSH. For custom domains: "domain:80:host:port" For subdomains: "subdomain:80:host:port" For random: "0:host:port"
func BuildSSHUser ¶
BuildSSHUser constructs the SSH username from a resolved token and mode. Anonymous connections use "x". TCP mode appends "+tcp" to the token.
func FormatExpiry ¶
FormatExpiry converts an RFC3339 expiry timestamp into a human-readable countdown string like "Expires in 3h 0m (12:00 UTC)".
func ResolveToken ¶
ResolveToken resolves an auth token from the given value or the XPOS_TOKEN environment variable. Auto-prepends "tk_" if missing. Returns empty string if no token is available.
func ShouldFilterLine ¶
ShouldFilterLine reports whether a line should be suppressed from CLI pass-through display. These lines are parsed and displayed by the CLI itself in a formatted manner.
Types ¶
type Option ¶
type Option func(*options)
Option configures a Tunnel. Use the With* functions to create Options.
func WithConnectTimeout ¶
WithConnectTimeout sets the maximum time to wait for tunnel establishment. Default: 15 seconds.
func WithDomain ¶
WithDomain sets a custom domain (Business plans). Mutually exclusive with WithSubdomain. Requires a token.
func WithOnClose ¶
WithOnClose sets a callback invoked when the tunnel closes. Receives the SSH process exit code.
func WithOnConnect ¶
WithOnConnect sets a callback invoked when the tunnel connects successfully. Receives the public URL and optional expiry timestamp.
func WithOnOutput ¶
WithOnOutput sets a callback invoked with raw SSH output text. Called for every chunk of data received from the SSH process.
func WithSSHPort ¶
WithSSHPort sets the SSH server port. Default: 443.
func WithServer ¶
WithServer sets the SSH server hostname. Default: "go.xpos.dev".
func WithSubdomain ¶
WithSubdomain sets a reserved subdomain (Pro+ plans). Mutually exclusive with WithDomain. Requires a token.
type Tunnel ¶
type Tunnel struct {
// URL is the public tunnel URL.
// For HTTP tunnels: "https://abc.xpos.to"
// For TCP tunnels: "1.2.3.4:54321"
// Populated after Start returns successfully.
URL string
// ExpiresAt is the RFC3339 expiry timestamp, if any.
// Empty string for paid plans with no expiry.
ExpiresAt string
// Connected indicates whether the tunnel is currently active.
Connected bool
// contains filtered or unexported fields
}
Tunnel manages an SSH subprocess that creates an XPOS tunnel. Create one with NewTunnel and call Start, or use the Connect convenience function.
func Connect ¶
Connect creates a new Tunnel with the given options and starts it. This is a convenience function combining NewTunnel and Start.
Example:
tunnel, err := xpos.Connect(ctx, xpos.WithPort(3000))
if err != nil {
log.Fatal(err)
}
fmt.Println(tunnel.URL)
defer tunnel.Close()
func NewTunnel ¶
NewTunnel creates a new Tunnel with the given options. The tunnel is not started until Start is called.
Returns an error if the options are invalid (missing port, bad mode, conflicting subdomain/domain, etc.).
func (*Tunnel) Close ¶
func (t *Tunnel) Close()
Close gracefully shuts down the tunnel. Sends an interrupt signal first, then force-kills after the kill timeout (default 3 seconds) if the process hasn't exited.
Close is safe to call multiple times and from multiple goroutines.
func (*Tunnel) Done ¶
func (t *Tunnel) Done() <-chan struct{}
Done returns a channel that is closed when the tunnel's SSH process exits. Use this to detect tunnel closure without blocking:
select {
case <-tunnel.Done():
fmt.Println("Tunnel closed")
case <-ctx.Done():
tunnel.Close()
}
func (*Tunnel) Start ¶
Start spawns the SSH process and blocks until the tunnel URL is available, an error occurs, or the context is cancelled.
The context controls cancellation but does not override the connect timeout (default 15s, configurable via WithConnectTimeout). Both the context and the timeout can terminate the connection attempt.
After Start returns successfully, the tunnel is active. Use Close to stop it, Wait or Done to block until it closes naturally.
Start may only be called once per Tunnel. To create a new tunnel, call NewTunnel again.