casket

package module
v1.2.2 Latest Latest
Warning

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

Go to latest
Published: Feb 19, 2021 License: Apache-2.0 Imports: 23 Imported by: 30

README

Casket

Casket is a fork of mholt's Caddy web server v1. Its goal is to maintain Caddy's original goal of being a straight forward, simple to use web server rather than the direction of Caddy v2 which has a focus on microservices and programtic configurability.

Casket will come with all the features you love about Caddy v1, while also adding our own touches for convenience and usability.

Building

To build the main casket executable, the following procedure can be used:

git clone https://github.com/tmpim/casket
cd casket
go build -o ./build/casket ./casket
# The executable can now be found at ./build/casket

Documentation

Overview

package casket implements the Casket server manager.

To use this package:

  1. Set the AppName and AppVersion variables.
  2. Call LoadCasketfile() to get the Casketfile. Pass in the name of the server type (like "http"). Make sure the server type's package is imported (import _ "github.com/tmpim/casket/caskethttp").
  3. Call casket.Start() to start Casket. You get back an Instance, on which you can call Restart() to restart it or Stop() to stop it.

You should call Wait() on your instance to wait for all servers to quit before your process exits.

Index

Examples

Constants

View Source
const (
	StartupEvent         EventName = "startup"
	ShutdownEvent                  = "shutdown"
	CertRenewEvent                 = "certrenew"
	InstanceStartupEvent           = "instancestartup"
	InstanceRestartEvent           = "instancerestart"
)

Define names for the various events

Variables

View Source
var (
	// AppName is the name of the application.
	AppName string

	// AppVersion is the version of the application.
	AppVersion string

	// Quiet mode will not show any informative output on initialization.
	Quiet bool

	// PidFile is the path to the pidfile to create.
	PidFile string

	// GracefulTimeout is the maximum duration of a graceful shutdown.
	GracefulTimeout time.Duration
)

Configurable application parameters

View Source
var (
	// DefaultConfigFile is the name of the configuration file that is loaded
	// by default if no other file is specified.
	DefaultConfigFile = "Casketfile"
)
View Source
var OnProcessExit []func()

OnProcessExit is a list of functions to run when the process exits -- they are ONLY for cleanup and should not block, return errors, or do anything fancy. They will be run with every signal, even if "shutdown callbacks" are not executed. This variable must only be modified in the main goroutine from init() functions.

Functions

func AssetsPath

func AssetsPath() string

AssetsPath returns the path to the folder where the application may store data. If CASKETPATH env variable is set, that value is used. Otherwise, the path is the result of evaluating "$HOME/.casket".

func DescribePlugins

func DescribePlugins() string

DescribePlugins returns a string describing the registered plugins.

func EmitEvent added in v0.10.0

func EmitEvent(event EventName, info interface{})

EmitEvent executes the different hooks passing the EventType as an argument. This is a blocking function. Hook developers should use 'go' keyword if they don't want to block Casket.

func IsInternal added in v0.10.0

func IsInternal(addr string) bool

IsInternal returns true if the IP of addr belongs to a private network IP range. addr must only be an IP or an IP:port combination. Loopback addresses are considered false.

func IsLoopback

func IsLoopback(addr string) bool

IsLoopback returns true if the hostname of addr looks explicitly like a common local hostname. addr must only be a host or a host:port combination.

func IsUpgrade

func IsUpgrade() bool

IsUpgrade returns true if this process is part of an upgrade where a parent casket process spawned this one to upgrade the binary.

func ListPlugins added in v0.11.0

func ListPlugins() map[string][]string

ListPlugins makes a list of the registered plugins, keyed by plugin type.

func RegisterCasketfileLoader added in v1.1.0

func RegisterCasketfileLoader(name string, loader Loader)

RegisterCasketfileLoader registers loader named name.

func RegisterEventHook added in v0.10.0

func RegisterEventHook(name string, hook EventHook)

RegisterEventHook plugs in hook. All the hooks should register themselves and they must have a name.

func RegisterParsingCallback

func RegisterParsingCallback(serverType, afterDir string, callback ParsingCallback)

RegisterParsingCallback registers callback to be called after executing the directive afterDir for server type serverType.

func RegisterPlugin

func RegisterPlugin(name string, plugin Plugin)

RegisterPlugin plugs in plugin. All plugins should register themselves, even if they do not perform an action associated with a directive. It is important for the process to know which plugins are available.

The plugin MUST have a name: lower case and one word. If this plugin has an action, it must be the name of the directive that invokes it. A name is always required and must be unique for the server type.

func RegisterServerType

func RegisterServerType(typeName string, srv ServerType)

RegisterServerType registers a server type srv by its name, typeName.

func SetDefaultCasketfileLoader added in v1.1.0

func SetDefaultCasketfileLoader(name string, loader Loader)

SetDefaultCasketfileLoader registers loader by name as the default Casketfile loader if no others produce a Casketfile. If another Casketfile loader has already been set as the default, this replaces it.

Do not call RegisterCasketfileLoader on the same loader; that would be redundant.

func SplitCommandAndArgs

func SplitCommandAndArgs(command string) (cmd string, args []string, err error)

SplitCommandAndArgs takes a command string and parses it shell-style into the command and its separate arguments.

Example
var commandLine string
var command string
var args []string

// just for the test - change GOOS and reset it at the end of the test
runtimeGoos = "windows"
defer func() {
	runtimeGoos = runtime.GOOS
}()

commandLine = `mkdir /P "C:\Program Files"`
command, args, _ = SplitCommandAndArgs(commandLine)

fmt.Printf("Windows: %s: %s [%s]\n", commandLine, command, strings.Join(args, ","))

// set GOOS to linux
runtimeGoos = "linux"

commandLine = `mkdir -p /path/with\ space`
command, args, _ = SplitCommandAndArgs(commandLine)

fmt.Printf("Linux: %s: %s [%s]\n", commandLine, command, strings.Join(args, ","))
Output:

Windows: mkdir /P "C:\Program Files": mkdir [/P,C:\Program Files]
Linux: mkdir -p /path/with\ space: mkdir [-p,/path/with space]

func Started added in v0.9.1

func Started() bool

Started returns true if at least one instance has been started by this package. It never gets reset to false once it is set to true.

func Stop

func Stop() error

Stop stops ALL servers. It blocks until they are all stopped. It does NOT execute shutdown callbacks, and it deletes all instances after stopping is completed. Do not re-use any references to old instances after calling Stop.

func TrapSignals

func TrapSignals()

TrapSignals create signal handlers for all applicable signals for this system. If your Go program uses signals, this is a rather invasive function; best to implement them yourself in that case. Signals are not required for the casket package to function properly, but this is a convenient way to allow the user to control this part of your program.

func Upgrade

func Upgrade() error

Upgrade re-launches the process, preserving the listeners for a graceful upgrade. It does NOT load new configuration; it only starts the process anew with the current config. This makes it possible to perform zero-downtime binary upgrades.

TODO: For more information when debugging, see: https://forum.golangbridge.org/t/bind-address-already-in-use-even-after-listener-closed/1510?u=matt https://github.com/mholt/shared-conn

func ValidDirectives

func ValidDirectives(serverType string) []string

ValidDirectives returns the list of all directives that are recognized for the server type serverType. However, not all directives may be installed. This makes it possible to give more helpful error messages, like "did you mean ..." or "maybe you need to plug in ...".

func ValidateAndExecuteDirectives added in v0.9.5

func ValidateAndExecuteDirectives(cdyfile Input, inst *Instance, justValidate bool) error

ValidateAndExecuteDirectives will load the server blocks from cdyfile by parsing it, then execute the directives configured by it and store the resulting server blocks into inst. If justValidate is true, parse callbacks will not be executed between directives, since the purpose is only to check the input for valid syntax.

Types

type AfterStartup

type AfterStartup interface {
	OnStartupComplete()
}

AfterStartup is an interface that can be implemented by a server type that wants to run some code after all servers for the same Instance have started.

type CasketfileInput added in v1.1.0

type CasketfileInput struct {
	Filepath       string
	Contents       []byte
	ServerTypeName string
}

CasketfileInput represents a Casketfile as input and is simply a convenient way to implement the Input interface.

func (CasketfileInput) Body added in v1.1.0

func (c CasketfileInput) Body() []byte

Body returns c.Contents.

func (CasketfileInput) Path added in v1.1.0

func (c CasketfileInput) Path() string

Path returns c.Filepath.

func (CasketfileInput) ServerType added in v1.1.0

func (c CasketfileInput) ServerType() string

ServerType returns c.ServerType.

type Context

type Context interface {
	// Called after the Casketfile is parsed into server
	// blocks but before the directives are executed,
	// this method gives you an opportunity to inspect
	// the server blocks and prepare for the execution
	// of directives. Return the server blocks (which
	// you may modify, if desired) and an error, if any.
	// The first argument is the name or path to the
	// configuration file (Casketfile).
	//
	// This function can be a no-op and simply return its
	// input if there is nothing to do here.
	InspectServerBlocks(string, []casketfile.ServerBlock) ([]casketfile.ServerBlock, error)

	// This is what Casket calls to make server instances.
	// By this time, all directives have been executed and,
	// presumably, the context has enough state to produce
	// server instances for Casket to start.
	MakeServers() ([]Server, error)
}

Context is a type which carries a server type through the load and setup phase; it maintains the state between loading the Casketfile, then executing its directives, then making the servers for Casket to manage. Typically, such state involves configuration structs, etc.

type Controller

type Controller struct {
	casketfile.Dispenser

	// Key is the key from the top of the server block, usually
	// an address, hostname, or identifier of some sort.
	Key string

	// OncePerServerBlock is a function that executes f
	// exactly once per server block, no matter how many
	// hosts are associated with it. If it is the first
	// time, the function f is executed immediately
	// (not deferred) and may return an error which is
	// returned by OncePerServerBlock.
	OncePerServerBlock func(f func() error) error

	// ServerBlockIndex is the 0-based index of the
	// server block as it appeared in the input.
	ServerBlockIndex int

	// ServerBlockKeyIndex is the 0-based index of this
	// key as it appeared in the input at the head of the
	// server block.
	ServerBlockKeyIndex int

	// ServerBlockKeys is a list of keys that are
	// associated with this server block. All these
	// keys, consequently, share the same tokens.
	ServerBlockKeys []string

	// ServerBlockStorage is used by a directive's
	// setup function to persist state between all
	// the keys on a server block.
	ServerBlockStorage interface{}
	// contains filtered or unexported fields
}

Controller is given to the setup function of directives which gives them access to be able to read tokens with which to configure themselves. It also stores state for the setup functions, can get the current context, and can be used to identify a particular server block using the Key field.

func NewTestController

func NewTestController(serverType, input string) *Controller

NewTestController creates a new Controller for the server type and input specified. The filename is "Testfile". If the server type is not empty and is plugged in, a context will be created so that the results of setup functions can be checked for correctness.

Used only for testing, but exported so plugins can use this for convenience.

func (*Controller) Context

func (c *Controller) Context() Context

Context gets the context associated with the instance associated with c.

func (*Controller) Get added in v0.10.11

func (c *Controller) Get(key interface{}) interface{}

Get safely gets a value from the Instance's storage.

func (*Controller) OnFinalShutdown

func (c *Controller) OnFinalShutdown(fn func() error)

OnFinalShutdown adds fn to the list of callback functions to execute when the server is about to be shut down NOT as part of a restart.

func (*Controller) OnFirstStartup

func (c *Controller) OnFirstStartup(fn func() error)

OnFirstStartup adds fn to the list of callback functions to execute when the server is about to be started NOT as part of a restart.

func (*Controller) OnRestart

func (c *Controller) OnRestart(fn func() error)

OnRestart adds fn to the list of callback functions to execute when the server is about to be restarted.

func (*Controller) OnRestartFailed added in v0.11.1

func (c *Controller) OnRestartFailed(fn func() error)

OnRestartFailed adds fn to the list of callback functions to execute if the server failed to restart.

func (*Controller) OnShutdown

func (c *Controller) OnShutdown(fn func() error)

OnShutdown adds fn to the list of callback functions to execute when the server is about to be shut down (including restarts).

func (*Controller) OnStartup

func (c *Controller) OnStartup(fn func() error)

OnStartup adds fn to the list of callback functions to execute when the server is about to be started (including restarts).

func (*Controller) ServerType

func (c *Controller) ServerType() string

ServerType gets the name of the server type that is being set up.

func (*Controller) Set added in v0.10.11

func (c *Controller) Set(key, val interface{})

Set safely sets a value on the Instance's storage.

type CtxKey added in v0.10.0

type CtxKey string

CtxKey is a value type for use with context.WithValue.

type EventHook added in v0.10.0

type EventHook func(eventType EventName, eventInfo interface{}) error

EventHook is a type which holds information about a startup hook plugin.

type EventName added in v0.10.0

type EventName string

EventName represents the name of an event used with event hooks.

type GracefulServer

type GracefulServer interface {
	Server
	Stopper

	// Address returns the address the server should
	// listen on; it is used to pair the server to
	// its listener during a graceful/zero-downtime
	// restart. Thus when implementing this method,
	// you must not access a listener to get the
	// address; you must store the address the
	// server is to serve on some other way.
	Address() string

	// WrapListener wraps a listener with the
	// listener middlewares configured for this
	// server, if any.
	WrapListener(net.Listener) net.Listener
}

GracefulServer is a Server and Stopper, the stopping of which is graceful (whatever that means for the kind of server being implemented). It must be able to return the address it is configured to listen on so that its listener can be paired with it upon graceful restarts. The net.Listener that a GracefulServer creates must implement the Listener interface for restarts to be graceful (assuming the listener is for TCP).

type Input

type Input interface {
	// Gets the Casketfile contents
	Body() []byte

	// Gets the path to the origin file
	Path() string

	// The type of server this input is intended for
	ServerType() string
}

Input represents a Casketfile; its contents and file path (which should include the file name at the end of the path). If path does not apply (e.g. piped input) you may use any understandable value. The path is mainly used for logging, error messages, and debugging.

func CasketfileFromPipe added in v1.1.0

func CasketfileFromPipe(f *os.File, serverType string) (Input, error)

CasketfileFromPipe loads the Casketfile input from f if f is not interactive input. f is assumed to be a pipe or stream, such as os.Stdin. If f is not a pipe, no error is returned but the Input value will be nil. An error is only returned if there was an error reading the pipe, even if the length of what was read is 0.

func DefaultInput

func DefaultInput(serverType string) Input

DefaultInput returns the default Casketfile input to use when it is otherwise empty or missing. It uses the default host and port (depends on host, e.g. localhost is 2015, otherwise 443) and root.

func LoadCasketfile added in v1.1.0

func LoadCasketfile(serverType string) (Input, error)

LoadCasketfile loads a Casketfile by calling the plugged in Casketfile loader methods. An error is returned if more than one loader returns a non-nil Casketfile input. If no loaders load a Casketfile, the default loader is used. If no default loader is registered or it returns nil, the server type's default Casketfile is loaded. If the server type does not specify any default Casketfile value, then an empty Casketfile is returned. Consequently, this function never returns a nil value as long as there are no errors.

type Instance

type Instance struct {

	// these callbacks execute when certain events occur
	OnFirstStartup  []func() error // starting, not as part of a restart
	OnStartup       []func() error // starting, even as part of a restart
	OnRestart       []func() error // before restart commences
	OnRestartFailed []func() error // if restart failed
	OnShutdown      []func() error // stopping, even as part of a restart
	OnFinalShutdown []func() error // stopping, not as part of a restart

	// storing values on an instance is preferable to
	// global state because these will get garbage-
	// collected after in-process reloads when the
	// old instances are destroyed; use StorageMu
	// to access this value safely
	Storage   map[interface{}]interface{}
	StorageMu sync.RWMutex
	// contains filtered or unexported fields
}

Instance contains the state of servers created as a result of calling Start and can be used to access or control those servers. It is literally an instance of a server type. Instance values should NOT be copied. Use *Instance for safety.

func Instances added in v0.10.11

func Instances() []*Instance

Instances returns the list of instances.

func Start

func Start(cdyfile Input) (*Instance, error)

Start starts Casket with the given Casketfile.

This function blocks until all the servers are listening.

func (*Instance) Casketfile added in v1.1.0

func (i *Instance) Casketfile() Input

Casketfile returns the Casketfile used to create i.

func (*Instance) Restart

func (i *Instance) Restart(newCasketfile Input) (*Instance, error)

Restart replaces the servers in i with new servers created from executing the newCasketfile. Upon success, it returns the new instance to replace i. Upon failure, i will not be replaced.

func (*Instance) SaveServer

func (i *Instance) SaveServer(s Server, ln net.Listener)

SaveServer adds s and its associated listener ln to the internally-kept list of servers that is running. For saved servers, graceful restarts will be provided.

func (*Instance) Servers added in v0.9.2

func (i *Instance) Servers() []ServerListener

Servers returns the ServerListeners in i.

func (*Instance) ShutdownCallbacks

func (i *Instance) ShutdownCallbacks() []error

ShutdownCallbacks executes all the shutdown callbacks of i, including ones that are scheduled only for the final shutdown of i. An error returned from one does not stop execution of the rest. All the non-nil errors will be returned.

func (*Instance) Stop

func (i *Instance) Stop() error

Stop stops all servers contained in i. It does NOT execute shutdown callbacks.

func (*Instance) Wait

func (i *Instance) Wait()

Wait blocks until all of i's servers have stopped.

type Listener

type Listener interface {
	net.Listener
	File() (*os.File, error)
}

Listener is a net.Listener with an underlying file descriptor. A server's listener should implement this interface if it is to support zero-downtime reloads.

type Loader

type Loader interface {
	Load(serverType string) (Input, error)
}

Loader is a type that can load a Casketfile. It is passed the name of the server type. It returns an error only if something went wrong, not simply if there is no Casketfile for this loader to load.

A Loader should only load the Casketfile if a certain condition or requirement is met, as returning a non-nil Input value along with another Loader will result in an error. In other words, loading the Casketfile must be deliberate & deterministic, not haphazard.

The exception is the default Casketfile loader, which will be called only if no other Casketfile loaders return a non-nil Input. The default loader may always return an Input value.

type LoaderFunc

type LoaderFunc func(serverType string) (Input, error)

LoaderFunc is a convenience type similar to http.HandlerFunc that allows you to use a plain function as a Load() method.

func (LoaderFunc) Load

func (lf LoaderFunc) Load(serverType string) (Input, error)

Load loads a Casketfile.

type PacketConn

type PacketConn interface {
	net.PacketConn
	File() (*os.File, error)
}

PacketConn is a net.PacketConn with an underlying file descriptor. A server's packetconn should implement this interface if it is to support zero-downtime reloads (in sofar this holds true for datagram connections).

type ParsingCallback

type ParsingCallback func(Context) error

ParsingCallback is a function that is called after a directive's setup functions have been executed for all the server blocks.

type Plugin

type Plugin struct {
	// ServerType is the type of server this plugin is for.
	// Can be empty if not applicable, or if the plugin
	// can associate with any server type.
	ServerType string

	// Action is the plugin's setup function, if associated
	// with a directive in the Casketfile.
	Action SetupFunc
}

Plugin is a type which holds information about a plugin.

type Server

type Server interface {
	TCPServer
	UDPServer
}

Server is a type that can listen and serve. It supports both TCP and UDP, although the UDPServer interface can be used for more than just UDP.

If the server uses TCP, it should implement TCPServer completely. If it uses UDP or some other protocol, it should implement UDPServer completely. If it uses both, both interfaces should be fully implemented. Any unimplemented methods should be made as no-ops that simply return nil values.

type ServerListener added in v0.9.2

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

ServerListener pairs a server to its listener and/or packetconn.

func (ServerListener) Addr added in v0.9.2

func (s ServerListener) Addr() net.Addr

Addr returns the listener's network address. It returns nil when it is not set.

func (ServerListener) LocalAddr added in v0.9.2

func (s ServerListener) LocalAddr() net.Addr

LocalAddr returns the local network address of the packetconn. It returns nil when it is not set.

type ServerType

type ServerType struct {
	// Function that returns the list of directives, in
	// execution order, that are valid for this server
	// type. Directives should be one word if possible
	// and lower-cased.
	Directives func() []string

	// DefaultInput returns a default config input if none
	// is otherwise loaded. This is optional, but highly
	// recommended, otherwise a blank Casketfile will be
	// used.
	DefaultInput func() Input

	// The function that produces a new server type context.
	// This will be called when a new Casketfile is being
	// loaded, parsed, and executed independently of any
	// startup phases before this one. It's a way to keep
	// each set of server instances separate and to reduce
	// the amount of global state you need.
	NewContext func(inst *Instance) Context
}

ServerType contains information about a server type.

type SetupFunc

type SetupFunc func(c *Controller) error

SetupFunc is used to set up a plugin, or in other words, execute a directive. It will be called once per key for each server block it appears in.

func DirectiveAction

func DirectiveAction(serverType, dir string) (SetupFunc, error)

DirectiveAction gets the action for directive dir of server type serverType.

type Stopper

type Stopper interface {
	// Stop stops the server. It blocks until the
	// server is completely stopped.
	Stop() error
}

Stopper is a type that can stop serving. The stop does not necessarily have to be graceful.

type TCPServer

type TCPServer interface {
	// Listen starts listening by creating a new listener
	// and returning it. It does not start accepting
	// connections. For UDP-only servers, this method
	// can be a no-op that returns (nil, nil).
	Listen() (net.Listener, error)

	// Serve starts serving using the provided listener.
	// Serve must start the server loop nearly immediately,
	// or at least not return any errors before the server
	// loop begins. Serve blocks indefinitely, or in other
	// words, until the server is stopped. For UDP-only
	// servers, this method can be a no-op that returns nil.
	Serve(net.Listener) error
}

TCPServer is a type that can listen and serve connections. A TCPServer must associate with exactly zero or one net.Listeners.

type UDPServer

type UDPServer interface {
	// ListenPacket starts listening by creating a new packetconn
	// and returning it. It does not start accepting connections.
	// TCP-only servers may leave this method blank and return
	// (nil, nil).
	ListenPacket() (net.PacketConn, error)

	// ServePacket starts serving using the provided packetconn.
	// ServePacket must start the server loop nearly immediately,
	// or at least not return any errors before the server
	// loop begins. ServePacket blocks indefinitely, or in other
	// words, until the server is stopped. For TCP-only servers,
	// this method can be a no-op that returns nil.
	ServePacket(net.PacketConn) error
}

UDPServer is a type that can listen and serve packets. A UDPServer must associate with exactly zero or one net.PacketConns.

Directories

Path Synopsis
basicauth
Package basicauth implements HTTP Basic Authentication for Casket.
Package basicauth implements HTTP Basic Authentication for Casket.
browse
Package browse provides middleware for listing files in a directory when directory path is requested instead of a specific file.
Package browse provides middleware for listing files in a directory when directory path is requested instead of a specific file.
errors
Package errors implements an HTTP error handling middleware.
Package errors implements an HTTP error handling middleware.
extensions
Package extensions contains middleware for clean URLs.
Package extensions contains middleware for clean URLs.
fastcgi
Package fastcgi has middleware that acts as a FastCGI client.
Package fastcgi has middleware that acts as a FastCGI client.
gzip
Package gzip provides a middleware layer that performs gzip compression on the response.
Package gzip provides a middleware layer that performs gzip compression on the response.
header
Package header provides middleware that appends headers to requests based on a set of configuration rules that define which routes receive which headers.
Package header provides middleware that appends headers to requests based on a set of configuration rules that define which routes receive which headers.
httpserver
Package httpserver implements an HTTP server on top of Casket.
Package httpserver implements an HTTP server on top of Casket.
internalsrv
Package internalsrv provides a simple middleware that (a) prevents access to internal locations and (b) allows to return files from internal location by setting a special header, e.g.
Package internalsrv provides a simple middleware that (a) prevents access to internal locations and (b) allows to return files from internal location by setting a special header, e.g.
log
Package log implements request (access) logging middleware.
Package log implements request (access) logging middleware.
markdown
Package markdown is middleware to render markdown files as HTML on-the-fly.
Package markdown is middleware to render markdown files as HTML on-the-fly.
proxy
Package proxy is middleware that proxies HTTP requests.
Package proxy is middleware that proxies HTTP requests.
redirect
Package redirect is middleware for redirecting certain requests to other locations.
Package redirect is middleware for redirecting certain requests to other locations.
rewrite
Package rewrite is middleware for rewriting requests internally to a different path.
Package rewrite is middleware for rewriting requests internally to a different path.
staticfiles
Package staticfiles provides middleware for serving static files from disk.
Package staticfiles provides middleware for serving static files from disk.
status
Package status is middleware for returning status code for requests
Package status is middleware for returning status code for requests
templates
Package templates implements template execution for files to be dynamically rendered for the client.
Package templates implements template execution for files to be dynamically rendered for the client.
websocket
Package websocket implements a WebSocket server by executing a command and piping its input and output through the WebSocket connection.
Package websocket implements a WebSocket server by executing a command and piping its input and output through the WebSocket connection.
package caskettls facilitates the management of TLS assets and integrates Let's Encrypt functionality into Casket with first-class support for creating and renewing certificates automatically.
package caskettls facilitates the management of TLS assets and integrates Let's Encrypt functionality into Casket with first-class support for creating and renewing certificates automatically.
Package telemetry implements the client for server-side telemetry of the network.
Package telemetry implements the client for server-side telemetry of the network.

Jump to

Keyboard shortcuts

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