summaryrefslogtreecommitdiff
path: root/internal/service/server.go
blob: 15921af01144fae873d0f3cd5c64d9e8da8a5e3f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package service

import (
	"context"
	"net"
	"strings"
	"time"

	"github.com/sirupsen/logrus"
	"github.com/valyala/fasthttp"

	"github.com/authelia/authelia/v4/internal/server"
)

func ProvisionServer(ctx Context) (service Provider, err error) {
	var (
		s        *fasthttp.Server
		listener net.Listener
		paths    []string
		isTLS    bool
	)

	switch s, listener, paths, isTLS, err = server.New(ctx.GetConfiguration(), ctx.GetProviders()); {
	case err != nil:
		return nil, err
	case s != nil && listener != nil:
		service = NewBaseServer("main", s, listener, paths, isTLS, ctx.GetLogger())
	default:
		return nil, nil
	}

	return service, nil
}

func ProvisionServerMetrics(ctx Context) (service Provider, err error) {
	var (
		s        *fasthttp.Server
		listener net.Listener
		paths    []string
		isTLS    bool
	)

	switch s, listener, paths, isTLS, err = server.NewMetrics(ctx.GetConfiguration(), ctx.GetProviders()); {
	case err != nil:
		return nil, err
	case s != nil && listener != nil:
		service = NewBaseServer("metrics", s, listener, paths, isTLS, ctx.GetLogger())
	default:
		return nil, nil
	}

	return service, nil
}

// NewBaseServer creates a new Server with the appropriate logger etc.
func NewBaseServer(name string, server *fasthttp.Server, listener net.Listener, paths []string, isTLS bool, log *logrus.Entry) (service *Server) {
	return &Server{
		name:     name,
		server:   server,
		listener: listener,
		paths:    paths,
		isTLS:    isTLS,
		log:      log.WithFields(map[string]any{logFieldService: serviceTypeServer, serviceTypeServer: name}),
	}
}

// Server is a Provider which runs a web server.
type Server struct {
	name     string
	server   *fasthttp.Server
	paths    []string
	isTLS    bool
	listener net.Listener
	log      *logrus.Entry
}

// ServiceType returns the service type for this service, which is always 'server'.
func (service *Server) ServiceType() string {
	return serviceTypeServer
}

// ServiceName returns the individual name for this service.
func (service *Server) ServiceName() string {
	return service.name
}

// Run the Server.
func (service *Server) Run() (err error) {
	defer func() {
		if r := recover(); r != nil {
			service.log.WithError(recoverErr(r)).Error("Critical error caught (recovered)")
		}
	}()

	service.log.Infof(fmtLogServerListening, connectionType(service.isTLS), service.listener.Addr().String(), strings.Join(service.paths, "' and '"))

	if err = service.server.Serve(service.listener); err != nil {
		service.log.WithError(err).Error("Error returned attempting to serve requests")

		return err
	}

	return nil
}

// Shutdown the Server.
func (service *Server) Shutdown() {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)

	defer cancel()

	if err := service.server.ShutdownWithContext(ctx); err != nil {
		service.log.WithError(err).Error("Error occurred during shutdown")
	}
}

// Log returns the *logrus.Entry of the Server.
func (service *Server) Log() *logrus.Entry {
	return service.log
}