relay

package
v0.58.0 Latest Latest
Warning

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

Go to latest
Published: May 18, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package relay implements an in-memory ticket-based HTTPS byte relay for codex-exec-gateway. env-mcp's copy_path tool mints a ticket and then dispatches `curl PUT` on the source executor and `curl GET` on the destination — bytes flow directly between executor and gateway without going through env-mcp's WS protocol path.

Per spec: docs/superpowers/specs/2026-05-18-copy-path-http-relay.md

Index

Constants

View Source
const (
	DefaultRelayTTL             = 5 * time.Minute
	DefaultRelayMaxPerWorkspace = 16
)

Defaults; can be overridden via NewRegistryOptions.

Variables

View Source
var (
	ErrTicketNotFound      = errors.New("relay: ticket not found or expired")
	ErrTicketAlreadyClaim  = errors.New("relay: that side of the ticket is already claimed")
	ErrWorkspaceCapReached = errors.New("relay: workspace concurrent relay cap reached")
	ErrTimeout             = errors.New("relay: timed out waiting for the other side")
)

Errors surfaced by Registry / Relay.

Functions

func ExtractBearerTicket

func ExtractBearerTicket(authz string) (string, bool)

ExtractBearerTicket pulls the ticket out of "Authorization: Bearer <ticket>". Returns ("", false) if absent or malformed.

Types

type CreateOptions

type CreateOptions struct {
	WorkspaceID string
	SourceExeID string
	DestExeID   string
	TTL         time.Duration // 0 = registry default
	MaxBytes    int64         // 0 = unlimited
}

CreateOptions controls the per-Relay knobs at mint time.

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry is the in-memory map of all live relay tickets, plus a per-workspace concurrent-count tracker for the cap.

func NewRegistry

func NewRegistry(maxPerWorkspace int, defaultTTL time.Duration, logger *slog.Logger) *Registry

NewRegistry constructs a Registry. maxPerWorkspace and defaultTTL default to package constants when 0.

func (*Registry) ActiveCount

func (r *Registry) ActiveCount() int

ActiveCount reports how many relays are in-flight (any state). Mostly for metrics / smoke tests.

func (*Registry) Create

func (r *Registry) Create(opt CreateOptions) (*Relay, error)

Create mints a ticket and starts the pairing goroutine.

func (*Registry) Lookup

func (r *Registry) Lookup(ticket string) (*Relay, bool)

Lookup returns the relay for the ticket, or false if expired/unknown. Returns false but doesn't garbage-collect — the pairing goroutine owns deletion via the onDone callback.

type Relay

type Relay struct {
	Ticket      string
	WorkspaceID string
	SourceExeID string
	DestExeID   string
	MaxBytes    int64
	ExpiresAt   time.Time
	// contains filtered or unexported fields
}

Relay is one in-flight or pending byte-pump session, keyed by ticket.

func (*Relay) AcceptGet

func (r *Relay) AcceptGet(w http.ResponseWriter) (status int, body []byte)

AcceptGet is the GET-side equivalent. The GET handler should NOT write to w after this returns — bytes are streamed via w during the call.

func (*Relay) AcceptPut

func (r *Relay) AcceptPut(reader io.Reader) (status int, body []byte)

AcceptPut blocks until the pairing goroutine is ready to pull bytes from this PUT side, the GET side fails to show up, or ttl elapses. On return, the PUT handler should write `status` + `body` to the HTTP response.

423 Locked is returned if a PUT has already claimed this ticket.

func (*Relay) Bytes

func (r *Relay) Bytes() int64

Bytes reports the number transferred (only valid after Done fires).

func (*Relay) Done

func (r *Relay) Done() <-chan struct{}

Done is closed once the relay finishes (success or error).

func (*Relay) Err

func (r *Relay) Err() error

Err reports the io.Copy error, if any (valid after Done).

Jump to

Keyboard shortcuts

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