Extract webserver function to allow invdividual testing.
This commit is contained in:
Felix Niederwanger 2024-02-24 20:27:40 +01:00
parent 1c941679ba
commit d0509e3f8a
Signed by: phoenix
GPG key ID: 6E77A590E3F6D71C
2 changed files with 75 additions and 69 deletions

View file

@ -8,6 +8,8 @@ import (
"gopkg.in/yaml.v2"
)
var cf Config
type Config struct {
Settings ConfigSettings `yaml:"settings"`
Hooks []Hook `yaml:"hooks"`

View file

@ -14,8 +14,6 @@ import (
"time"
)
var cf Config
type Handler func(http.ResponseWriter, *http.Request)
func usage() {
@ -58,8 +56,6 @@ func sanityCheckHooks(hooks []Hook) error {
}
func main() {
var err error
cf.SetDefaults()
if len(os.Args) < 2 {
usage()
@ -124,75 +120,15 @@ func main() {
awaitTerminationSignal()
if cf.Settings.TLS.Enabled {
log.Printf("Launching tls webserver on %s", cf.Settings.BindAddress)
server := &http.Server{
Addr: cf.Settings.BindAddress,
ReadTimeout: time.Duration(cf.Settings.ReadTimeout) * time.Second,
WriteTimeout: time.Duration(cf.Settings.WriteTimeout) * time.Second,
MaxHeaderBytes: cf.Settings.MaxHeaderBytes,
}
tlsConfig := &tls.Config{
MinVersion: tls.VersionTLS12,
}
if cf.Settings.TLS.MinVersion != "" {
tlsConfig.MinVersion, err = ParseTLSVersion(cf.Settings.TLS.MinVersion)
if err != nil {
fmt.Fprintf(os.Stderr, "error: tls min version invalid\n")
os.Exit(1)
}
}
if cf.Settings.TLS.MaxVersion != "" {
tlsConfig.MaxVersion, err = ParseTLSVersion(cf.Settings.TLS.MinVersion)
if err != nil {
fmt.Fprintf(os.Stderr, "error: tls min version invalid\n")
os.Exit(1)
}
}
if tlsConfig.MinVersion == tls.VersionTLS10 || tlsConfig.MinVersion == tls.VersionTLS11 {
fmt.Fprintf(os.Stderr, "warning: using of a deprecated TLS version (< 1.2) is not recommended\n")
}
// Create self-signed certificate, when no keyfile and no certificates are present
if len(cf.Settings.TLS.Keypairs) == 0 {
// TODO
fmt.Fprintf(os.Stderr, "error: creating self-signed certificates is not yet supported")
os.Exit(1)
} else {
// Load key/certificates keypairs
tlsConfig.Certificates = make([]tls.Certificate, len(cf.Settings.TLS.Keypairs))
for i, keypair := range cf.Settings.TLS.Keypairs {
tlsConfig.Certificates[i], err = tls.LoadX509KeyPair(keypair.Certificate, keypair.Keyfile)
if err != nil {
fmt.Fprintf(os.Stderr, "error: tls keypair '%s,%s' invalid: %s\n", keypair.Certificate, keypair.Keyfile, err)
os.Exit(1)
}
}
if len(tlsConfig.Certificates) == 1 {
log.Printf("Loaded 1 tls certificate")
} else {
log.Printf("Loaded %d tls certificates", len(tlsConfig.Certificates))
}
}
listener, err := tls.Listen("tcp", cf.Settings.BindAddress, tlsConfig)
if err != nil {
fmt.Fprintf(os.Stderr, "error: cannot listen on '%s': %s\n", cf.Settings.BindAddress, err)
if err := LaunchTLSWebserver(cf); err != nil {
fmt.Fprintf(os.Stderr, "error: %s\n", err)
os.Exit(1)
}
log.Printf("Serving tls requests now on %s", cf.Settings.BindAddress)
err = server.Serve(listener)
log.Fatal(err)
} else {
log.Printf("Launching webserver on %s", cf.Settings.BindAddress)
server := &http.Server{
Addr: cf.Settings.BindAddress,
ReadTimeout: time.Duration(cf.Settings.ReadTimeout) * time.Second,
WriteTimeout: time.Duration(cf.Settings.WriteTimeout) * time.Second,
MaxHeaderBytes: cf.Settings.MaxHeaderBytes,
if err := LaunchWebserver(cf); err != nil {
fmt.Fprintf(os.Stderr, "error: %s\n", err)
os.Exit(1)
}
log.Printf("Serving requests now on %s", cf.Settings.BindAddress)
err := server.ListenAndServe()
log.Fatal(err)
}
// read guard, should never ever ever be called.
@ -200,6 +136,74 @@ func main() {
panic("unexpected end of main loop")
}
func LaunchTLSWebserver(cf Config) error {
var err error
log.Printf("Launching tls webserver on %s", cf.Settings.BindAddress)
server := &http.Server{
Addr: cf.Settings.BindAddress,
ReadTimeout: time.Duration(cf.Settings.ReadTimeout) * time.Second,
WriteTimeout: time.Duration(cf.Settings.WriteTimeout) * time.Second,
MaxHeaderBytes: cf.Settings.MaxHeaderBytes,
}
tlsConfig := &tls.Config{
MinVersion: tls.VersionTLS12,
}
if cf.Settings.TLS.MinVersion != "" {
tlsConfig.MinVersion, err = ParseTLSVersion(cf.Settings.TLS.MinVersion)
if err != nil {
return fmt.Errorf("invalid tls min version\n")
}
}
if cf.Settings.TLS.MaxVersion != "" {
tlsConfig.MaxVersion, err = ParseTLSVersion(cf.Settings.TLS.MinVersion)
if err != nil {
return fmt.Errorf("invalid tls max version\n")
}
}
if tlsConfig.MinVersion == tls.VersionTLS10 || tlsConfig.MinVersion == tls.VersionTLS11 {
fmt.Fprintf(os.Stderr, "warning: using of a deprecated TLS version (< 1.2) is not recommended\n")
}
// Create self-signed certificate, when no keyfile and no certificates are present
if len(cf.Settings.TLS.Keypairs) == 0 {
// TODO
return fmt.Errorf("creating self-signed certificates is not yet supported")
} else {
// Load key/certificates keypairs
tlsConfig.Certificates = make([]tls.Certificate, len(cf.Settings.TLS.Keypairs))
for i, keypair := range cf.Settings.TLS.Keypairs {
tlsConfig.Certificates[i], err = tls.LoadX509KeyPair(keypair.Certificate, keypair.Keyfile)
if err != nil {
return fmt.Errorf("invalid tls keypair '%s,%s' - %s\n", keypair.Certificate, keypair.Keyfile, err)
}
}
if len(tlsConfig.Certificates) == 1 {
log.Printf("Loaded 1 tls certificate")
} else {
log.Printf("Loaded %d tls certificates", len(tlsConfig.Certificates))
}
}
listener, err := tls.Listen("tcp", cf.Settings.BindAddress, tlsConfig)
if err != nil {
return err
}
log.Printf("Serving tls requests now on %s", cf.Settings.BindAddress)
return server.Serve(listener)
}
func LaunchWebserver(cf Config) error {
log.Printf("Launching webserver on %s", cf.Settings.BindAddress)
server := &http.Server{
Addr: cf.Settings.BindAddress,
ReadTimeout: time.Duration(cf.Settings.ReadTimeout) * time.Second,
WriteTimeout: time.Duration(cf.Settings.WriteTimeout) * time.Second,
MaxHeaderBytes: cf.Settings.MaxHeaderBytes,
}
log.Printf("Serving requests now on %s", cf.Settings.BindAddress)
return server.ListenAndServe()
}
// create a http handler function from the given hook
func createHandler(hook Hook) Handler {
return func(w http.ResponseWriter, r *http.Request) {