substrate

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Mar 5, 2025 License: MIT Imports: 36 Imported by: 0

README

Substrate Caddy Module

Overview

Substrate is a custom Caddy v2 module designed to execute commands based on HTTP requests. It manages processes and proxies traffic to dynamically created backends.

What's special about it is that it allows the proxies themselves to tell Caddy which files and paths they are set up to respond.

You can think of it as a generic Franken PHP for your own backend.

Installation

To use this module, build Caddy with the Substrate module included:

xcaddy build --with github.com/fserb/substrate

Configuration

Substrate provides a global app and a handler for HTTP requests.

Global Configuration

To enable the module globally, use the substrate directive in the global options block:

{
    substrate {
        env <key> <value>
        restart_policy always|never|on_failure
        redirect_stdout stdout|stderr|null|file <filename>
        redirect_stderr stdout|stderr|null|file <filename>
    }
}
  • env: Set environment variables for the process (can be repeated).
  • restart_policy: Restart behavior.
    • always: Always restart when the process exits.
    • never: Never restart.
    • on_failure: Restart only if the process exits with a failure.
  • redirect_stdout/redirect_stderr:
    • stdout: Output to stdout.
    • stderr: Output to stderr.
    • null: Discard output.
    • file <filename>: Write output to the specified file.
Handler Configuration

The substrate directive can be added to site blocks to define command execution logic. The syntax is:

server:80 {
  root /x/y/z
  substrate [subpath]
  file_serve

substrate will look for a substrate executable in the root directory.

How It Works

Substrate will start your proxy command and set up a SUBSTRATE env var with a URL. Once your proxy is running, it should send a POST request to this URL, containing a JSON, with the following format:

{
  host: "localhost:3333", // the host:port where the proxy is listening at.
  match: ["*.ext"],       // the list of file extensions we should listen to.
                          // this also automatically handles paths with the omitted
                          // extension or index.ext.
  paths: ["/up"],         // hard-coded paths that this proxy can answer.
  catch_all: ["/path/catchall.ext"],  // files that behave as catch-all for any subdir.
}

once this gets received, Caddy will start forwarding the proper requests to the proxy. You can send multiple jsons to the provided URL, overwriting the previous commands.

For more details, check the example directory.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type App

type App struct {
	Env map[string]string `json:"env,omitempty"`
	// How processes are restarted: "always", "never", "on_failure"
	RestartPolicy  string        `json:"restart_policy,omitempty"`
	RedirectStdout *outputTarget `json:"redirect_stdout,omitempty"`
	RedirectStderr *outputTarget `json:"redirect_stderr,omitempty"`
	// contains filtered or unexported fields
}

App is the main substrate application that manages the substrate server and provides configuration for substrate processes.

func (App) CaddyModule

func (h App) CaddyModule() caddy.ModuleInfo

func (*App) GetWatcher added in v0.2.0

func (h *App) GetWatcher(root string) *Watcher

func (*App) Provision

func (h *App) Provision(ctx caddy.Context) error

func (*App) Start

func (h *App) Start() error

func (*App) Stop

func (h *App) Stop() error

type DebugInfo added in v0.2.0

type DebugInfo struct {
	// Version      string            `json:"version"`
	BuildInfo    *debug.BuildInfo  `json:"build_info,omitempty"`
	GoVersion    string            `json:"go_version"`
	GOOS         string            `json:"goos"`
	GOARCH       string            `json:"goarch"`
	NumGoroutine int               `json:"num_goroutine"`
	NumCPU       int               `json:"num_cpu"`
	Uptime       string            `json:"uptime"`
	StartTime    time.Time         `json:"start_time"`
	MemStats     runtime.MemStats  `json:"mem_stats"`
	Watchers     map[string]string `json:"watchers,omitempty"`
}

DebugInfo contains information about the substrate system

func GetDebugInfo added in v0.2.0

func GetDebugInfo(s *Server) *DebugInfo

type HostReverseProxy

type HostReverseProxy interface {
	caddyhttp.MiddlewareHandler
	caddy.Provisioner

	SetHost(string)
}

type Order

type Order struct {
	// Host is the upstream server to proxy requests to
	Host string `json:"host,omitempty"`

	// Match contains patterns for matching files by extension
	// Format: "/path/*.ext" where path is a directory and ext is a file extension
	Match []string `json:"match,omitempty"`

	// Paths contains exact paths that should be proxied to the upstream
	Paths []string `json:"paths,omitempty"`

	// CatchAll contains fallback paths to use when no other match is found for a path
	CatchAll []string `json:"catch_all,omitempty"`
	// contains filtered or unexported fields
}

Order represents a command from a substrate process

type ReverseProxy

type ReverseProxy struct{ *reverseproxy.Handler }

func (*ReverseProxy) SetHost

func (s *ReverseProxy) SetHost(host string)

type Server

type Server struct {
	http.Server
	Host string
	// contains filtered or unexported fields
}

func (*Server) Destruct

func (s *Server) Destruct() error

func (*Server) ServeHTTP

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)

func (*Server) Start

func (s *Server) Start() error

func (*Server) Stop

func (s *Server) Stop()

func (*Server) WaitForStart

func (s *Server) WaitForStart(app *App)

type SubstrateHandler

type SubstrateHandler struct {
	Prefix string `json:"prefix,omitempty"`
	// contains filtered or unexported fields
}

SubstrateHandler handles requests by proxying to a substrate process

func (SubstrateHandler) CaddyModule

func (s SubstrateHandler) CaddyModule() caddy.ModuleInfo

func (*SubstrateHandler) Provision

func (s *SubstrateHandler) Provision(ctx caddy.Context) error

func (*SubstrateHandler) ServeHTTP

type Watcher added in v0.2.0

type Watcher struct {
	// Root is the directory to watch for a substrate file
	Root string

	// Order is the current active order from the substrate process
	Order *Order
	// contains filtered or unexported fields
}

Watcher watches for a substrate file in a root directory and manages the lifecycle of substrate processes.

func (*Watcher) Close added in v0.2.0

func (w *Watcher) Close()

Close stops watching and cleans up resources

func (*Watcher) GetCmd added in v0.2.0

func (w *Watcher) GetCmd() *execCmd

GetCmd returns the current command

func (*Watcher) IsReady added in v0.2.0

func (w *Watcher) IsReady() bool

IsReady returns true if the watcher has a command with an order

func (*Watcher) Submit added in v0.2.0

func (w *Watcher) Submit(o *Order)

Submit processes an order from a substrate process

func (*Watcher) WaitUntilReady added in v0.2.0

func (w *Watcher) WaitUntilReady(timeout time.Duration) bool

WaitUntilReady waits for the watcher to be ready or determines it has no substrate Returns true if the watcher is ready, false if there's no substrate or timeout occurs

Jump to

Keyboard shortcuts

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