Initial server handling refactor (#9)

This commit is contained in:
2023-03-20 16:33:45 +01:00
committed by Daniel Carrillo
parent 84a767ade0
commit e60d1ae5b7
8 changed files with 284 additions and 176 deletions

54
server/quic_server.go Normal file
View File

@ -0,0 +1,54 @@
package server
import (
"context"
"log"
"net/http"
"github.com/dcarrillo/whatismyip/internal/setting"
"github.com/quic-go/quic-go/http3"
)
type QuicServer struct {
server *http3.Server
tlsServer *TLSServer
ctx context.Context
}
func NewQuicServer(ctx context.Context, tlsServer *TLSServer) QuicServer {
return QuicServer{
tlsServer: tlsServer,
ctx: ctx,
}
}
func (q *QuicServer) Start() {
q.server = &http3.Server{
Addr: setting.App.TLSAddress,
Handler: q.tlsServer.server.Handler,
}
parentHandler := q.tlsServer.server.Handler
q.tlsServer.server.Handler = http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if err := q.server.SetQuicHeaders(rw.Header()); err != nil {
log.Fatal(err)
}
parentHandler.ServeHTTP(rw, req)
})
log.Printf("Starting QUIC server listening on %s (udp)", setting.App.TLSAddress)
go func() {
if err := q.server.ListenAndServeTLS(setting.App.TLSCrtPath, setting.App.TLSKeyPath); err != nil &&
err.Error() != "quic: Server closed" {
log.Fatal(err)
}
}()
log.Printf("Stopping QUIC server...")
}
func (q *QuicServer) Stop() {
if err := q.server.Close(); err != nil {
log.Printf("QUIC server forced to shutdown")
}
}

101
server/server.go Normal file
View File

@ -0,0 +1,101 @@
package server
import (
"log"
"net/http"
"os"
"os/signal"
"syscall"
"github.com/dcarrillo/whatismyip/internal/setting"
"github.com/dcarrillo/whatismyip/models"
"golang.org/x/net/context"
)
type Server interface {
Start()
Stop()
}
type Factory struct {
tcpServer *TCPServer
tlsServer *TLSServer
quicServer *QuicServer
}
func Setup(ctx context.Context, handler http.Handler) *Factory {
var tcpServer TCPServer
var tlsServer TLSServer
var quicServer QuicServer
if setting.App.BindAddress != "" {
tcpServer = NewTCPServer(ctx, &handler)
}
if setting.App.TLSAddress != "" {
tlsServer = NewTLSServer(ctx, &handler)
if setting.App.EnableHTTP3 {
quicServer = NewQuicServer(ctx, &tlsServer)
}
}
return &Factory{
tcpServer: &tcpServer,
tlsServer: &tlsServer,
quicServer: &quicServer,
}
}
func (w *Factory) Run() {
w.start()
log.Printf("Starting server handler...")
w.Watcher()
}
func (w *Factory) Watcher() {
signalChan := make(chan os.Signal, 3)
signal.Notify(signalChan, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM)
var s os.Signal
for {
s = <-signalChan
if s == syscall.SIGHUP {
w.stop()
models.CloseDBs()
models.Setup(setting.App.GeodbPath.City, setting.App.GeodbPath.ASN)
w.start()
} else {
log.Printf("Shutting down...")
w.stop()
models.CloseDBs()
break
}
}
}
func (w *Factory) start() {
if w.tcpServer != nil {
w.tcpServer.Start()
}
if w.tlsServer != nil {
w.tlsServer.Start()
if w.quicServer != nil {
w.quicServer.Start()
}
}
}
func (w *Factory) stop() {
if w.tcpServer != nil {
w.tcpServer.Stop()
}
if w.tlsServer != nil {
if w.quicServer != nil {
w.quicServer.Stop()
}
w.tlsServer.Stop()
}
}

46
server/tcp_server.go Normal file
View File

@ -0,0 +1,46 @@
package server
import (
"context"
"errors"
"log"
"net/http"
"github.com/dcarrillo/whatismyip/internal/setting"
)
type TCPServer struct {
server *http.Server
handler *http.Handler
ctx context.Context
}
func NewTCPServer(ctx context.Context, handler *http.Handler) TCPServer {
return TCPServer{
handler: handler,
ctx: ctx,
}
}
func (t *TCPServer) Start() {
t.server = &http.Server{
Addr: setting.App.BindAddress,
Handler: *t.handler,
ReadTimeout: setting.App.Server.ReadTimeout,
WriteTimeout: setting.App.Server.WriteTimeout,
}
log.Printf("Starting TCP server listening on %s", setting.App.BindAddress)
go func() {
if err := t.server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Fatal(err)
}
}()
log.Printf("Stopping TCP server...")
}
func (t *TCPServer) Stop() {
if err := t.server.Shutdown(t.ctx); err != nil {
log.Printf("TCP server forced to shutdown: %s", err)
}
}

47
server/tls_server.go Normal file
View File

@ -0,0 +1,47 @@
package server
import (
"context"
"errors"
"log"
"net/http"
"github.com/dcarrillo/whatismyip/internal/setting"
)
type TLSServer struct {
server *http.Server
handler *http.Handler
ctx context.Context
}
func NewTLSServer(ctx context.Context, handler *http.Handler) TLSServer {
return TLSServer{
handler: handler,
ctx: ctx,
}
}
func (t *TLSServer) Start() {
t.server = &http.Server{
Addr: setting.App.TLSAddress,
Handler: *t.handler,
ReadTimeout: setting.App.Server.ReadTimeout,
WriteTimeout: setting.App.Server.WriteTimeout,
}
log.Printf("Starting TLS server listening on %s", setting.App.TLSAddress)
go func() {
if err := t.server.ListenAndServeTLS(setting.App.TLSCrtPath, setting.App.TLSKeyPath); err != nil &&
!errors.Is(err, http.ErrServerClosed) {
log.Fatal(err)
}
}()
log.Printf("Stopping TLS server...")
}
func (t *TLSServer) Stop() {
if err := t.server.Shutdown(t.ctx); err != nil {
log.Printf("TLS server forced to shutdown: %s", err)
}
}