mirror of
https://github.com/dcarrillo/whatismyip.git
synced 2024-12-21 15:08:00 +00:00
Server handling refactor (#27)
This commit is contained in:
parent
db111642d2
commit
0c14419e7e
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/dcarrillo/whatismyip/internal/httputils"
|
||||
@ -30,8 +31,9 @@ func main() {
|
||||
engine := setupEngine()
|
||||
router.SetupTemplate(engine)
|
||||
router.Setup(engine)
|
||||
servers := setupHTTPServers(context.Background(), engine.Handler())
|
||||
|
||||
whatismyip := server.Setup(context.Background(), engine.Handler())
|
||||
whatismyip := server.Setup(servers)
|
||||
whatismyip.Run()
|
||||
}
|
||||
|
||||
@ -55,3 +57,23 @@ func setupEngine() *gin.Engine {
|
||||
|
||||
return engine
|
||||
}
|
||||
|
||||
func setupHTTPServers(ctx context.Context, handler http.Handler) []server.Server {
|
||||
var servers []server.Server
|
||||
|
||||
if setting.App.BindAddress != "" {
|
||||
tcpServer := server.NewTCPServer(ctx, &handler)
|
||||
servers = append(servers, tcpServer)
|
||||
}
|
||||
|
||||
if setting.App.TLSAddress != "" {
|
||||
tlsServer := server.NewTLSServer(ctx, &handler)
|
||||
servers = append(servers, tlsServer)
|
||||
if setting.App.EnableHTTP3 {
|
||||
quicServer := server.NewQuicServer(ctx, tlsServer)
|
||||
servers = append(servers, quicServer)
|
||||
}
|
||||
}
|
||||
|
||||
return servers
|
||||
}
|
||||
|
8
go.mod
8
go.mod
@ -9,7 +9,6 @@ require (
|
||||
github.com/quic-go/quic-go v0.40.1
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/testcontainers/testcontainers-go v0.27.0
|
||||
golang.org/x/net v0.19.0
|
||||
)
|
||||
|
||||
require (
|
||||
@ -76,12 +75,13 @@ require (
|
||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||
go.uber.org/mock v0.4.0 // indirect
|
||||
golang.org/x/arch v0.6.0 // indirect
|
||||
golang.org/x/crypto v0.17.0 // indirect
|
||||
golang.org/x/crypto v0.18.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20231226003508-02704c960a9b // indirect
|
||||
golang.org/x/mod v0.14.0 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
golang.org/x/net v0.20.0 // indirect
|
||||
golang.org/x/sys v0.16.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/tools v0.16.1 // indirect
|
||||
golang.org/x/tools v0.17.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
|
||||
google.golang.org/grpc v1.59.0 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
|
19
go.sum
19
go.sum
@ -198,8 +198,8 @@ golang.org/x/arch v0.6.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
golang.org/x/exp v0.0.0-20231226003508-02704c960a9b h1:kLiC65FbiHWFAOu+lxwNPujcsl8VYyTYYEZnsOO1WK4=
|
||||
golang.org/x/exp v0.0.0-20231226003508-02704c960a9b/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
@ -210,13 +210,13 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
|
||||
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
|
||||
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
|
||||
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -229,8 +229,9 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
@ -241,8 +242,8 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA=
|
||||
golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
|
||||
golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
|
||||
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
@ -63,7 +63,7 @@ func GetLogFormatter(param gin.LogFormatterParams) string {
|
||||
)
|
||||
}
|
||||
|
||||
func normalizeLog(log interface{}) interface{} {
|
||||
func normalizeLog(log any) any {
|
||||
switch v := log.(type) {
|
||||
case string:
|
||||
if v == "" {
|
||||
|
@ -2,6 +2,7 @@ package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
@ -9,20 +10,20 @@ import (
|
||||
"github.com/quic-go/quic-go/http3"
|
||||
)
|
||||
|
||||
type QuicServer struct {
|
||||
type Quic struct {
|
||||
server *http3.Server
|
||||
tlsServer *TLSServer
|
||||
tlsServer *TLS
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func NewQuicServer(ctx context.Context, tlsServer *TLSServer) *QuicServer {
|
||||
return &QuicServer{
|
||||
func NewQuicServer(ctx context.Context, tlsServer *TLS) *Quic {
|
||||
return &Quic{
|
||||
tlsServer: tlsServer,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
func (q *QuicServer) Start() {
|
||||
func (q *Quic) Start() {
|
||||
q.server = &http3.Server{
|
||||
Addr: setting.App.TLSAddress,
|
||||
Handler: q.tlsServer.server.Handler,
|
||||
@ -40,13 +41,13 @@ func (q *QuicServer) Start() {
|
||||
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" {
|
||||
!errors.Is(err, http.ErrServerClosed) {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (q *QuicServer) Stop() {
|
||||
func (q *Quic) Stop() {
|
||||
log.Printf("Stopping QUIC server...")
|
||||
if err := q.server.Close(); err != nil {
|
||||
log.Printf("QUIC server forced to shutdown")
|
@ -2,14 +2,12 @@ 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 {
|
||||
@ -17,80 +15,47 @@ type Server interface {
|
||||
Stop()
|
||||
}
|
||||
|
||||
type Factory struct {
|
||||
tcpServer *TCPServer
|
||||
tlsServer *TLSServer
|
||||
quicServer *QuicServer
|
||||
type Manager struct {
|
||||
servers []Server
|
||||
}
|
||||
|
||||
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 Setup(servers []Server) *Manager {
|
||||
return &Manager{
|
||||
servers: servers,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Factory) Run() {
|
||||
f.start()
|
||||
func (m *Manager) Run() {
|
||||
m.start()
|
||||
|
||||
signalChan := make(chan os.Signal, 3)
|
||||
signalChan := make(chan os.Signal, len(m.servers))
|
||||
signal.Notify(signalChan, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM)
|
||||
var s os.Signal
|
||||
for {
|
||||
s = <-signalChan
|
||||
|
||||
if s == syscall.SIGHUP {
|
||||
f.stop()
|
||||
m.stop()
|
||||
models.CloseDBs()
|
||||
models.Setup(setting.App.GeodbPath.City, setting.App.GeodbPath.ASN)
|
||||
f.start()
|
||||
m.start()
|
||||
} else {
|
||||
log.Printf("Shutting down...")
|
||||
f.stop()
|
||||
m.stop()
|
||||
models.CloseDBs()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Factory) start() {
|
||||
if f.tcpServer != nil {
|
||||
f.tcpServer.Start()
|
||||
}
|
||||
|
||||
if f.tlsServer != nil {
|
||||
f.tlsServer.Start()
|
||||
if f.quicServer != nil {
|
||||
f.quicServer.Start()
|
||||
}
|
||||
func (m *Manager) start() {
|
||||
for _, s := range m.servers {
|
||||
s.Start()
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Factory) stop() {
|
||||
if f.tcpServer != nil {
|
||||
f.tcpServer.Stop()
|
||||
}
|
||||
|
||||
if f.tlsServer != nil {
|
||||
if f.quicServer != nil {
|
||||
f.quicServer.Stop()
|
||||
}
|
||||
f.tlsServer.Stop()
|
||||
func (m *Manager) stop() {
|
||||
for _, s := range m.servers {
|
||||
s.Stop()
|
||||
}
|
||||
}
|
||||
|
@ -9,20 +9,20 @@ import (
|
||||
"github.com/dcarrillo/whatismyip/internal/setting"
|
||||
)
|
||||
|
||||
type TCPServer struct {
|
||||
type TCP struct {
|
||||
server *http.Server
|
||||
handler *http.Handler
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func NewTCPServer(ctx context.Context, handler *http.Handler) *TCPServer {
|
||||
return &TCPServer{
|
||||
func NewTCPServer(ctx context.Context, handler *http.Handler) *TCP {
|
||||
return &TCP{
|
||||
handler: handler,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TCPServer) Start() {
|
||||
func (t *TCP) Start() {
|
||||
t.server = &http.Server{
|
||||
Addr: setting.App.BindAddress,
|
||||
Handler: *t.handler,
|
||||
@ -38,7 +38,7 @@ func (t *TCPServer) Start() {
|
||||
}()
|
||||
}
|
||||
|
||||
func (t *TCPServer) Stop() {
|
||||
func (t *TCP) Stop() {
|
||||
log.Printf("Stopping TCP server...")
|
||||
if err := t.server.Shutdown(t.ctx); err != nil {
|
||||
log.Printf("TCP server forced to shutdown: %s", err)
|
@ -9,20 +9,20 @@ import (
|
||||
"github.com/dcarrillo/whatismyip/internal/setting"
|
||||
)
|
||||
|
||||
type TLSServer struct {
|
||||
type TLS struct {
|
||||
server *http.Server
|
||||
handler *http.Handler
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func NewTLSServer(ctx context.Context, handler *http.Handler) *TLSServer {
|
||||
return &TLSServer{
|
||||
func NewTLSServer(ctx context.Context, handler *http.Handler) *TLS {
|
||||
return &TLS{
|
||||
handler: handler,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TLSServer) Start() {
|
||||
func (t *TLS) Start() {
|
||||
t.server = &http.Server{
|
||||
Addr: setting.App.TLSAddress,
|
||||
Handler: *t.handler,
|
||||
@ -39,7 +39,7 @@ func (t *TLSServer) Start() {
|
||||
}()
|
||||
}
|
||||
|
||||
func (t *TLSServer) Stop() {
|
||||
func (t *TLS) Stop() {
|
||||
log.Printf("Stopping TLS server...")
|
||||
if err := t.server.Shutdown(t.ctx); err != nil {
|
||||
log.Printf("TLS server forced to shutdown: %s", err)
|
@ -5,17 +5,20 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const scannerTimeOut = 3 * time.Second
|
||||
|
||||
type PortScanner struct {
|
||||
Address net.Addr
|
||||
}
|
||||
|
||||
func (p *PortScanner) IsPortOpen() (bool, error) {
|
||||
conn, err := net.DialTimeout(p.Address.Network(), p.Address.String(), 3*time.Second)
|
||||
conn, err := net.DialTimeout(p.Address.Network(), p.Address.String(), scannerTimeOut)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if conn != nil {
|
||||
defer conn.Close()
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user