Documentation
¶
Overview ¶
Package proxy provides a local reverse proxy for forwarding traffic from a stable listen port to a worktree's dynamically allocated port. Supports optional TLS termination via mkcert or self-signed certificates.
Index ¶
- Constants
- func BuildRouterURL(port int, project, branch, domain string, routerPort int, ...) string
- func BuildTunnelURL(project, branch, tunnelDomain string) string
- func CACertExpiry() (time.Time, error)
- func CACertPath() string
- func CANeedsRegen(domain string) bool
- func EnsureCA(domain string) (string, error)
- func IsCAInstalled() bool
- func RouteKey(project, branch string) string
- func Run(opts Options) error
- func TrustCA(caCertFile string) error
- func UntrustCA() error
- type AliasSource
- type BackendState
- type CertManager
- type Options
- type PortProbe
- type Router
- func (r *Router) Refresh()
- func (r *Router) Routes() map[string]int
- func (r *Router) Run() error
- func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)
- func (r *Router) WithAliases(src AliasSource) *Router
- func (r *Router) WithBaseDomain(domain string) *Router
- func (r *Router) WithTLS() *Router
- func (r *Router) WithVersion(v string) *Router
- type SupervisorProbe
Constants ¶
const HealthEndpoint = "/_treeline/health"
HealthEndpoint is the path the doctor probes to confirm the running router is responsive (not just bound to a port).
Variables ¶
This section is empty.
Functions ¶
func BuildRouterURL ¶
func BuildRouterURL(port int, project, branch, domain string, routerPort int, svcRunning, pfConfigured bool) string
BuildRouterURL returns the HTTPS router URL for a given project/branch when the router is active, or falls back to a plain localhost URL. Pass svcRunning and pfConfigured from service.IsRunning() and service.IsPortForwardConfigured() to keep this function testable.
func BuildTunnelURL ¶
BuildTunnelURL returns the tunnel URL for a given project/branch when a tunnel domain is configured, or an empty string if not applicable.
func CACertExpiry ¶
CACertExpiry returns the CA certificate's NotAfter time, or an error if the cert can't be read/parsed. Used by gtl doctor for cert health.
func CACertPath ¶
func CACertPath() string
CACertPath returns the path to the CA certificate (for display to the user).
func CANeedsRegen ¶ added in v0.48.0
CANeedsRegen reports whether EnsureCA(domain) would replace the on-disk CA. Callers use this to remove the stale trusted root before EnsureCA overwrites ca.pem (the untrust helpers match by the file's current content).
func EnsureCA ¶
EnsureCA generates a local CA if one doesn't exist, is expiring within 7 days, or lacks X.509 name constraints covering domain. Returns the path to the CA certificate (for trusting). The name constraints scope the CA to localhost plus the router's configured domain and the loopback IP ranges, so a stolen ca-key.pem can only MITM those names — not arbitrary public hosts.
func IsCAInstalled ¶
func IsCAInstalled() bool
IsCAInstalled checks whether the local CA has been generated.
func RouteKey ¶
RouteKey derives a DNS-safe route key from a project name and branch. Exported so gtl setup can display the router URL.
func Run ¶
Run starts a reverse proxy on ListenPort forwarding all traffic to TargetPort. It blocks until interrupted by SIGINT/SIGTERM and then performs a graceful shutdown.
Types ¶
type AliasSource ¶
AliasSource returns static alias routes to merge into the route table. Registry routes take priority over aliases.
type BackendState ¶ added in v0.42.0
type BackendState int
BackendState classifies why a proxied request couldn't reach the upstream dev server. The router uses this to pick a status page so users can tell "still starting" apart from "actually broken".
const ( BackendUnknown BackendState = iota BackendStarting // supervisor + child both up, port not yet listening BackendNotStarted // allocation exists, supervisor not running BackendStopped // supervisor running, no live child (stopped or crashed) BackendUnreachable // supervisor responded with something unexpected )
type CertManager ¶
type CertManager struct {
// contains filtered or unexported fields
}
CertManager generates per-hostname TLS certificates on demand, signed by the local CA. This avoids wildcard certs (*.localhost) which Safari and Chromium reject for the .localhost TLD.
func NewCertManager ¶
func NewCertManager(domain string) (*CertManager, error)
NewCertManager loads the local CA and returns a manager that generates per-hostname certs via GetCertificate for SNIs within domain. Returns an error if the CA hasn't been created yet (user needs to run 'gtl serve install').
func (*CertManager) GetCertificate ¶
func (cm *CertManager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error)
GetCertificate is a tls.Config callback that returns a cert with an exact SAN for the requested hostname. Issued certs are kept in an LRU cache capped at maxCachedCerts entries: even in-domain SNI floods (each a fresh keygen + CA signature) can only occupy a bounded amount of memory, and old entries are evicted rather than the cache freezing while issuance continues unbounded.
type PortProbe ¶ added in v0.42.0
PortProbe attempts a TCP connection to localhost:port within the given timeout and returns true if the port is accepting connections.
type Router ¶
type Router struct {
// contains filtered or unexported fields
}
Router is a subdomain-based reverse proxy that routes {project}-{branch}.localhost requests to the correct worktree port by reading allocations from the git-treeline registry.
func (*Router) Refresh ¶
func (r *Router) Refresh()
Refresh forces an immediate route table rebuild. Useful after calling builder methods (WithAliases, WithBaseDomain) to populate routes before Run() starts the periodic refresh ticker.
func (*Router) Run ¶
Run starts the router HTTP/HTTPS server and blocks until SIGINT/SIGTERM. Routes are refreshed from the registry every 5 seconds.
func (*Router) WithAliases ¶
func (r *Router) WithAliases(src AliasSource) *Router
WithAliases adds an alias source that is merged on each route refresh. Call Refresh() after all builders to populate the route table immediately.
func (*Router) WithBaseDomain ¶
WithBaseDomain sets the local TLD used for subdomain extraction.
func (*Router) WithTLS ¶
WithTLS enables HTTPS using the local CA cert generated by gtl serve install.
func (*Router) WithVersion ¶ added in v0.48.0
WithVersion records the CLI version that launched the router so the health endpoint can report it. Optional; empty when unset.
type SupervisorProbe ¶ added in v0.42.0
SupervisorProbe asks the supervisor at socketPath for its status. Returns "running", "stopped", or an empty string if the supervisor can't be reached. Pulled out so tests can inject a fake.