Jobs & Workflows https://armen.surge.sh
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

143 lines
3.3 KiB

/*
------------------------------------------------------------------------------------------------------------------------
####### server ####### Copyright (c) 2021 mls-361 ################################################## MIT License #######
------------------------------------------------------------------------------------------------------------------------
*/
package server
import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"log"
"net/http"
"os"
"time"
"forge.chapril.org/mls-361/errors"
"forge.chapril.org/mls-361/uuid"
"forge.chapril.org/armen/armen/internal/components"
"forge.chapril.org/armen/armen/internal/config/data"
)
type server struct {
logger components.Logger
server *http.Server
tls bool
cert string
key string
}
func newServer(logger components.Logger, tls bool) *server {
return &server{
logger: logger,
tls: tls,
}
}
func (cs *server) getTLSConfig(d *data.TLS) (*tls.Config, error) {
if !cs.tls {
return nil, nil
}
cs.cert = d.Cert
cs.key = d.Key
var certPool *x509.CertPool
authType := tls.NoClientCert
if d.AuthType != 0 {
buf, err := os.ReadFile(d.CA)
if err != nil {
return nil, errors.WithMessage(err, "unable to read this file", "file", d.CA) //////////////////////////////
}
certPool = x509.NewCertPool()
certPool.AppendCertsFromPEM(buf)
switch d.AuthType {
case 1:
authType = tls.RequestClientCert
case 2:
authType = tls.RequireAnyClientCert
case 3:
authType = tls.VerifyClientCertIfGiven
case 4:
authType = tls.RequireAndVerifyClientCert
}
}
cfg := &tls.Config{
ServerName: d.Host,
ClientAuth: authType,
ClientCAs: certPool,
MinVersion: tls.VersionTLS12,
}
return cfg, nil
}
func Build(ccs *components.Components) (components.Server, error) {
cfg := ccs.Config.Server()
cs := newServer(ccs.Logger.NewLogger(uuid.New(), "server"), cfg.TLS != nil)
tlsConfig, err := cs.getTLSConfig(cfg.TLS)
if err != nil {
return nil, errors.WithMessage(err, "Cannot configure TLS") ////////////////////////////////////////////////////
}
cs.server = &http.Server{
Addr: fmt.Sprintf(":%d", cfg.Port),
Handler: ccs.Router.Handler(),
ErrorLog: cs.logger.NewStdLogger("error", "", log.Llongfile),
IdleTimeout: 1 * time.Minute,
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
TLSConfig: tlsConfig,
}
return cs, nil
}
// Run AFAIRE.
func (cs *server) Run() error {
cs.logger.Info("Started") //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
var err error
if cs.tls {
err = cs.server.ListenAndServeTLS(cs.cert, cs.key)
} else {
err = cs.server.ListenAndServe()
}
if err == http.ErrServerClosed {
return nil
}
return err
}
// Stop AFAIRE.
func (cs *server) Stop() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
cs.server.SetKeepAlivesEnabled(false)
if err := cs.server.Shutdown(ctx); err != nil {
cs.logger.Error( //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
"Server shutdown error",
"reason", err,
)
}
cs.logger.Info("Stopped") //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
}
/*
######################################################################################################## @(°_°)@ #######
*/