Package cloudeng.io/webapp
import cloudeng.io/webappPackage webapp and its sub-packages provide support for building webapps. This includes utility routines for managing http.Server instances, generating self-signed TLS certificates etc. The sub-packages provide support for managing the assets to be served, various forms of authentication and common toolchains such as webpack. For production purposes assets are built into the server's binary, but for development they are built into the binary but can be overridden from a local filesystem or from a running development server that manages those assets (eg. a webpack dev server instance). This provides the flexibility for both simple deployment of production servers and iterative development within the same application.
An example/template can be found in cmd/webapp.
// ACMEHTTP01Prefix is the well-known prefix for ACME HTTP-01 challenges.
ACMEHTTP01Prefix = "/.well-known/acme-challenge/"
// ACMEHTTP01HTTPPrefix is the well-known prefix for ACME HTTP-01 challenges
// when used with http.ServeMux
ACMEHTTP01HTTPPrefix = ACMEHTTP01Prefix
// ACMEHTTP01ChiPrefix is the well-known prefix for ACME HTTP-01 challenges
// when used with chi.Router
ACMEHTTP01ChiPrefix = ACMEHTTP01Prefix + "*"PreferredTLSMinVersion = tls.VersionTLS13PreferredTLSMinVersion is the preferred minimum TLS version for tls.Config instances created by this package.
PreferredCipherSuites = []uint16{
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
}PreferredCipherSuites is the list of preferred cipher suites for tls.Config instances created by this package.
PreferredCurves = []tls.CurveID{
tls.X25519,
tls.CurveP256,
}PreferredCurves is the list of preferred elliptic curves for tls.Config instances created by this package.
PreferredSignatureSchemes = []tls.SignatureScheme{
tls.ECDSAWithP256AndSHA256,
tls.ECDSAWithP384AndSHA384,
tls.ECDSAWithP521AndSHA512,
}PreferredSignatureSchemes is the list of preferred signature schemes generally used for obtainint TLS certificates.
func FindLeafPEM(certsPEM []*pem.Block) ([]byte, *x509.Certificate, error)FindLeafPEM searches the supplied PEM blocks for the leaf certificate and returns its DER encoding along with the parsed x509.Certificate.
func HealthzHandler() http.HandlerHealthzHandler returns a handler that returns "ok" and a 200 status code.
func NewHTTPClient(ctx context.Context, opts ...HTTPClientOption) (*http.Client, error)NewHTTPClient creates a new HTTP client configured according to the specified options.
func NewHTTPServer(ctx context.Context, addr string, handler http.Handler) (net.Listener, *http.Server, error)NewHTTPServer returns a new *http.Server using netutil.ParseAddrDefaultPort(addr "http") to obtain the address to listen on and NewHTTPServerOnly to create the server.
func NewHTTPServerOnly(ctx context.Context, addr string, handler http.Handler) *http.ServerNewHTTPServerOnly returns a new *http.Server whose address defaults to ":http" and with it's BaseContext set to the supplied context. ErrorLog is set to log errors via the ctxlog package.
func NewTLSServer(ctx context.Context, addr string, handler http.Handler, cfg *tls.Config) (net.Listener, *http.Server, error)NewTLSServer returns a new *http.Server using netutil.ParseAddrDefaultPort(addr, "https") to obtain the address to listen on and NewTLSServerOnly to create the server.
func NewTLSServerOnly(ctx context.Context, addr string, handler http.Handler, cfg *tls.Config) *http.ServerNewTLSServerOnly returns a new *http.Server whose address defaults to ":https" and with it's BaseContext set to the supplied context and TLSConfig set to the supplied config. ErrorLog is set to log errors via the ctxlog package.
func ParseCertsPEM(pemData []byte) ([]*x509.Certificate, error)ParseCertsPEM parses certificates from the provided PEM data.
func ParsePEM(pemData []byte) (privateKeys, publicKeys, certs []*pem.Block)ParsePEM parses private keys and certificates from the provided PEM data.
func ParsePrivateKeyDER(der []byte) (crypto.Signer, error)ParsePrivateKeyDER parses a DER encoded private key. It tries PKCS#1, PKCS#8 and then SEC 1 for EC keys.
func ReadAndParseCertsPEM(ctx context.Context, fs file.ReadFileFS, pemFile string) ([]*x509.Certificate, error)ReadAndParseCertsPEM loads certificates from the specified PEM file.
func ReadAndParsePrivateKeyPEM(ctx context.Context, fs file.ReadFileFS, pemFile string) (crypto.Signer, error)ReadAndParsePrivateKeyPEM reads and parses a PEM encoded private key from the specified file.
func RedirectPort80(ctx context.Context, redirects ...Port80Redirect) errorRedirectPort80 starts an http.Server that will redirect port 80 to the specified redirect targets. The server will run in the background until the supplied context is canceled.
func SafePath(path string) errorSafePath checks if the given path is safe for use as a filename screening for control characters, windows device names, relative paths, paths (eg. a/b is not allowed) etc.
func ServeTLSWithShutdown(ctx context.Context, ln net.Listener, srv *http.Server, grace time.Duration) errorServeTLSWithShutdown is like ServeWithShutdown except for a TLS server. Note that any TLS options must be configured prior to calling this function via the TLSConfig field in http.Server. If srv.BaseContext is nil it will be set to return ctx.
func ServeWithShutdown(ctx context.Context, ln net.Listener, srv *http.Server, grace time.Duration) errorServeWithShutdown runs srv.ListenAndServe in background and then waits for the context to be canceled. It will then attempt to shutdown the web server within the specified grace period. If srv.BaseContext is nil it will be set to return ctx.
func TLSConfigUsingCertFiles(certFile, keyFile string) (*tls.Config, error)TLSConfigUsingCertFiles returns a tls.Config configured with the certificate read from the supplied files.
func TLSConfigUsingCertFilesFS(ctx context.Context, store file.ReadFileFS, certFile, keyFile string) (*tls.Config, error)TLSConfigUsingCertFilesFS returns a tls.Config configured with the certificate read from the supplied files which are accessed via the specified file.ReadFileFS.
func TLSConfigUsingCertStore(ctx context.Context, store file.ReadFileFS, cacheOpts ...CertServingCacheOption) (*tls.Config, error)TLSConfigUsingCertStore returns a tls.Config configured with the certificate obtained from the specified certificate store accessed via a CertServingCache created with the supplied options.
func VerifyCertChain(dnsname string, certs []*x509.Certificate, roots *x509.CertPool) ([][]*x509.Certificate, error)VerifyCertChain verifies the supplied certificate chain using the provided root certificates and verifies that the leaf certificate is valid for the specified dnsname. It returns the verified chains on success.
func WaitForServers(ctx context.Context, interval time.Duration, addrs ...string) errorWaitForServers waits for all supplied addresses to be available by attempting to open a TCP connection to each address at the specified interval.
func WaitForURLs(ctx context.Context, client *http.Client, interval time.Duration, urls ...string) errorWaitForURLs waits for all supplied URLs to be available by attempting to perform HTTP GET requests to each URL at the specified interval.
type CertServingCache struct {
// contains filtered or unexported fields
}CertServingCache implements an in-memory cache of TLS/SSL certificates loaded from a backing store. Validation of the certificates is performed on loading rather than every use. It provides a GetCertificate method that can be used by tls.Config. A TTL (default of 6 hours) is used so that the in-memory cache will reload certificates from the store on a periodic basis (with some jitter) to allow for certificates to be refreshed.
func NewCertServingCache(ctx context.Context, certStore file.ReadFileFS, opts ...CertServingCacheOption) *CertServingCacheNewCertServingCache returns a new instance of CertServingCache that uses the supplied file.ReadFileFS. The supplied context is cached and used by the GetCertificate method, this allows for credentials etc to be passed to the ReadFileCtx method called by GetCertificate via the context.
func (m *CertServingCache) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error)GetCertificate can be assigned to tls.Config.GetCertificate.
type CertServingCacheOption func(*CertServingCache)CertServingCacheOption represents options to NewCertServingCache.
func WithCertCacheAllowedHosts(hosts ...string) CertServingCacheOptionWithCertCacheAllowedHosts sets the allowed hosts that the cache will serve certificates for.
func WithCertCacheNowFunc(fn func() time.Time) CertServingCacheOptionWithCertCacheNowFunc sets the function used to obtain the current time. This is generally only required for testing purposes.
func WithCertCacheRootCAs(rootCAs *x509.CertPool) CertServingCacheOptionWithCertCacheRootCAs sets the rootCAs to be used when verifying the validity of the certificate loaded from the back store.
func WithCertCacheTTL(ttl time.Duration) CertServingCacheOptionWithCertCacheTTL sets the in-memory TTL beyond which cache entries are refreshed. This is generally only required for testing purposes.
type CounterAdd func(ctx context.Context, delta float64)CounterAdd is a function that adds a delta to a counter metric.
type CounterInc func(ctx context.Context)CounterInc is a function that increments a counter metric.
type CounterVecAdd func(ctx context.Context, delta float64, labels ...string)CounterVecAdd is a function that adds a delta to a counter metric with the given labels.
type CounterVecInc func(ctx context.Context, labels ...string)CounterVecInc is a function that increments a counter metric with the given labels.
type HTTPClientOption func(o *httpClientOptions)HTTPClientOption is used to configure an HTTP client.
func WithCustomCAPEMFile(caPEMFile string) HTTPClientOptionWithCustomCAPEMFile configures the HTTP client to use the specified custom CA PEM data as a root CA.
func WithCustomCAPool(caPool *x509.CertPool) HTTPClientOptionWithCustomCAPool configures the HTTP client to use the specified custom CA pool. It takes precedence over WithCustomCAPEMFile.
func WithTracingTransport(to ...httptracing.TraceRoundtripOption) HTTPClientOptionWithTracingTransport configures the HTTP client to use a tracing round tripper with the specified options.
type HTTPServerConfig struct {
Address string `yaml:"address,omitempty"`
TLSCerts TLSCertConfig `yaml:"tls_certs,omitempty"`
}HTTPServerConfig defines configuration for an http server.
func (hc HTTPServerConfig) TLSConfig() (*tls.Config, error)type HTTPServerFlags struct {
Address string `subcmd:"https,:8080,address to run https web server on"`
TLSCertFlags
}HTTPServerFlags defines commonly used flags for running an http server. TLS certificates may be retrieved either from a local cert and key file as specified by tls-cert and tls-key; this is generally used for testing or when the domain certificates are available only as files. The altnerative, preferred for production, source for TLS certificates is from a cache as specified by tls-cert-cache-type and tls-cert-cache-name. The cache may be on local disk, or preferably in some shared service such as Amazon's Secrets Service.
func (cl HTTPServerFlags) HTTPServerConfig() HTTPServerConfigHTTPServerConfig returns an HTTPServerConfig based on the supplied flags.
type Observe func(ctx context.Context, value float64)Observe is a function that records a value for an observer metric.
type Port80Redirect struct {
Pattern string
Redirect
}Port80Redirect is a Redirect that that will be registered using http.ServeMux with the specified pattern.
type Redirect struct {
Description string // description of the redirect, only used for logging
Target RedirectTarget // function that returns the target URL and HTTP status code
Log bool // if true then log the redirect
}Redirect defines a URL path prefix which will be redirected to the specified target.
func RedirectAcmeHTTP01(host string) RedirectRedirectAcmeHTTP01 returns a Redirect that will redirect ACME HTTP-01 challenges to the specified host.
func RedirectToHTTPSPort(addr string) RedirectRedirectToHTTPSPort returns a Redirect that will redirect to the specified address using https but with the following defaults: - if addr does not contain a host then the host from the request is used - if addr does not contain a port then port 443 is used.
func (r Redirect) Handler() http.HandlerFuncHandler returns a function that will redirect requests using the Target function to determine the target URL and HTTP status code and will log the redirect. It is provided for use with other middleware packages that expect an http.Handler.
type RedirectTarget func(*http.Request) (string, int)RedirectTarget is a function that given an http.Request returns the target URL for the redirect and the HTTP status code to use. The request and in particular the Request.URL should not be modified by RedirectTarget.
func LiteralRedirectTarget(to string, code int) RedirectTargetLiteralRedirectTarget returns a RedirectTarget that always redirects to the specified URL with the specified status code.
type TLSCertConfig struct {
CertFile string `yaml:"cert_file,omitempty"`
KeyFile string `yaml:"key_file,omitempty"`
}TLSCertConfig defines configuration for TLS certificates obtained from local files.
func (tc TLSCertConfig) TLSConfig() (*tls.Config, error)TLSConfig returns a tls.Config.
type TLSCertFlags struct {
CertFile string `subcmd:"tls-cert,,tls certificate file"`
KeyFile string `subcmd:"tls-key,,tls private key file"`
}TLSCertFlags defines commonly used flags for obtaining TLS/SSL certificates. Certificates may be obtained in one of two ways: from a cache of certificates, or from local files.
func (cl TLSCertFlags) TLSCertConfig() TLSCertConfigConfig returns a TLSCertConfig based on the supplied flags.