Documentation
¶
Index ¶
- Constants
- func BecomeUser(userName string) (err error)
- func DefaultDataDir(dataDir, defaultSuffix string) (string, error)
- func Listener(listenAddr, certDir string) (l net.Listener, listenUrl, absCertDir string, err error)
- func LoadCert(certDir string) (cert *tls.Certificate, absCertDir string, err error)
- func LogInfo(logger any, msg string, args ...any)
- func UseDataDir(dataDir string) (string, error)
- type Config
Examples ¶
Constants ¶
const ( FullchainPem = "fullchain.pem" PrivkeyPem = "privkey.pem" )
Variables ¶
This section is empty.
Functions ¶
func BecomeUser ¶
BecomeUser switches to the given userName if not empty.
It sets the GID, UID and changes the USER and HOME environment variables accordingly. It unsets XDG_CONFIG_HOME.
Returns ErrBecomeUserNotImplemented if the current OS is not supported.
func DefaultDataDir ¶
DefaultDataDir returns dataDir if not empty, otherwise if defaultSuffix is not empty it returns the joined path of os.UserConfigDir() and defaultSuffix.
func Listener ¶
Listener creates a net.Listener given an optional preferred address or port and an optional directory containing certificate files.
If certDir is not empty, it calls LoadCert to load fullchain.pem and privkey.pem.
The listener will default to all addresses and standard port depending on privileges and if a certificate was loaded or not.
These defaults can be overridden with the listenAddr argument.
Returns the net.Listener and listenURL if there was no error. If certificates were successfully loaded, absCertDir will be the absolute path to that directory.
func LoadCert ¶
func LoadCert(certDir string) (cert *tls.Certificate, absCertDir string, err error)
LoadCert does nothing if certDir is empty, otherwise tries to load a X509 key pair from files named "fullchain.pem" and "privkey.pem" in the given directory.
Return a non-nil cert and absolute path to certDir if there are no errors.
func UseDataDir ¶
UseDataDir expands environment variables in dataDir, transforms it into an absolute path, creates it if it does not exist and finally changes current directory to that path.
Returns the final path.
Types ¶
type Config ¶
type Config struct { Listen string // optional specific address (and/or port) to listen on CertDir string // if set, directory to look for fullchain.pem and privkey.pem User string // if set, user to switch to after opening listening port DataDir string // if set, ensure this directory exists and switch to it DefaultDataDirSuffix string // if set and DataDir is not set, use the user's default data dir plus this suffix ListenURL string // after Apply called, an URL we listen on (e.g. "https://localhost:8443") }
func (*Config) Apply ¶
Apply performs initial setup for a simple web server, optionally logging informational messages if it loads certificates, switches the current user, or switches to the data directory.
The logger argument can be a log.Logger, a slog.Logger or an io.Writer.
First it loads certificates if CertDir is set, and then starts a net.Listener (TLS or normal). The listener will default to all addresses and standard port depending on privileges and if a certificate was loaded or not.
If Listen was set, any address or port given there overrides these defaults.
If User is set it then switches to that user and the users primary group. Note that this is not supported on Windows.
If DataDir or DefaultDataDirSuffix is set, creates that directory if needed and sets the current working directory to it.
On a non-error return, CertDir and DataDir will be absoulte paths or empty, and ListenURL will be a printable and connectable URL like "http://localhost:80".
Example ¶
package main import ( "fmt" "os" "path" "testing" "github.com/linkdata/webserv" ) func withCertFiles(t *testing.T, fn func(destdir string)) { t.Helper() certPem := []byte(`-----BEGIN CERTIFICATE----- MIIBhTCCASugAwIBAgIQIRi6zePL6mKjOipn+dNuaTAKBggqhkjOPQQDAjASMRAw DgYDVQQKEwdBY21lIENvMB4XDTE3MTAyMDE5NDMwNloXDTE4MTAyMDE5NDMwNlow EjEQMA4GA1UEChMHQWNtZSBDbzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABD0d 7VNhbWvZLWPuj/RtHFjvtJBEwOkhbN/BnnE8rnZR8+sbwnc/KhCk3FhnpHZnQz7B 5aETbbIgmuvewdjvSBSjYzBhMA4GA1UdDwEB/wQEAwICpDATBgNVHSUEDDAKBggr BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdEQQiMCCCDmxvY2FsaG9zdDo1 NDUzgg4xMjcuMC4wLjE6NTQ1MzAKBggqhkjOPQQDAgNIADBFAiEA2zpJEPQyz6/l Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc 6MF9+Yw1Yy0t -----END CERTIFICATE-----`) keyPem := []byte(`-----BEGIN EC PRIVATE KEY----- MHcCAQEEIIrYSSNQFaA2Hwf1duRSxKtLYX5CB04fSeQ6tF1aY/PuoAoGCCqGSM49 AwEHoUQDQgAEPR3tU2Fta9ktY+6P9G0cWO+0kETA6SFs38GecTyudlHz6xvCdz8q EKTcWGekdmdDPsHloRNtsiCa697B2O9IFA== -----END EC PRIVATE KEY-----`) destdir, err := os.MkdirTemp("", "weblistener") if err == nil { defer func() { if err := os.RemoveAll(destdir); err != nil { t.Error(err) } }() if err = os.WriteFile(path.Join(destdir, webserv.FullchainPem), certPem, 0640); err == nil { if err = os.WriteFile(path.Join(destdir, webserv.PrivkeyPem), keyPem, 0640); err == nil { fn(destdir) } } } if err != nil { t.Error(err) } } func main() { cfg := webserv.Config{ Listen: "127.0.0.1:8080", // leave empty for all addresses and default port } if l, err := cfg.Apply(os.Stdout); err == nil { defer l.Close() fmt.Print(cfg.ListenURL) } else { fmt.Print(err) } }
Output: http://localhost:8080