mirror of
https://github.com/dcarrillo/whatismyip.git
synced 2024-12-22 07:28:00 +00:00
Initial server handling refactor (#9)
This commit is contained in:
parent
84a767ade0
commit
e60d1ae5b7
@ -2,30 +2,18 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/dcarrillo/whatismyip/internal/httputils"
|
||||
"github.com/dcarrillo/whatismyip/internal/setting"
|
||||
"github.com/dcarrillo/whatismyip/server"
|
||||
"github.com/gin-contrib/secure"
|
||||
|
||||
"github.com/dcarrillo/whatismyip/models"
|
||||
"github.com/dcarrillo/whatismyip/router"
|
||||
"github.com/gin-gonic/gin"
|
||||
http3 "github.com/quic-go/quic-go/http3"
|
||||
)
|
||||
|
||||
var (
|
||||
tcpServer *http.Server
|
||||
tlsServer *http.Server
|
||||
h3Server *http3.Server
|
||||
engine *gin.Engine
|
||||
)
|
||||
|
||||
func main() {
|
||||
@ -39,149 +27,20 @@ func main() {
|
||||
}
|
||||
|
||||
models.Setup(setting.App.GeodbPath.City, setting.App.GeodbPath.ASN)
|
||||
setupEngine()
|
||||
engine := setupEngine()
|
||||
router.SetupTemplate(engine)
|
||||
router.Setup(engine)
|
||||
|
||||
if setting.App.BindAddress != "" {
|
||||
runTCPServer()
|
||||
}
|
||||
|
||||
if setting.App.TLSAddress != "" {
|
||||
runTLSServer()
|
||||
if setting.App.EnableHTTP3 {
|
||||
runQuicServer()
|
||||
}
|
||||
}
|
||||
|
||||
runHandler()
|
||||
whatismyip := server.Setup(context.Background(), engine.Handler())
|
||||
whatismyip.Run()
|
||||
}
|
||||
|
||||
func runHandler() {
|
||||
signalChan := make(chan os.Signal, 3)
|
||||
signal.Notify(signalChan, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM)
|
||||
ctx := context.Background()
|
||||
var s os.Signal
|
||||
|
||||
for {
|
||||
s = <-signalChan
|
||||
|
||||
if s == syscall.SIGHUP {
|
||||
models.CloseDBs()
|
||||
models.Setup(setting.App.GeodbPath.City, setting.App.GeodbPath.ASN)
|
||||
router.SetupTemplate(engine)
|
||||
|
||||
if setting.App.BindAddress != "" {
|
||||
if err := tcpServer.Shutdown(ctx); err != nil {
|
||||
log.Printf("TCP server forced to shutdown: %s", err)
|
||||
}
|
||||
runTCPServer()
|
||||
}
|
||||
if setting.App.TLSAddress != "" {
|
||||
if setting.App.EnableHTTP3 {
|
||||
if err := h3Server.Close(); err != nil {
|
||||
log.Printf("QUIC server forced to shutdown")
|
||||
}
|
||||
}
|
||||
|
||||
if err := tlsServer.Shutdown(ctx); err != nil {
|
||||
log.Printf("TLS server forced to shutdown: %s", err)
|
||||
}
|
||||
runTLSServer()
|
||||
|
||||
if setting.App.EnableHTTP3 {
|
||||
runQuicServer()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.Printf("Shutting down...")
|
||||
if setting.App.BindAddress != "" {
|
||||
if err := tcpServer.Shutdown(ctx); err != nil {
|
||||
log.Printf("TCP server forced to shutdown: %s", err)
|
||||
}
|
||||
}
|
||||
if setting.App.TLSAddress != "" {
|
||||
if setting.App.EnableHTTP3 {
|
||||
if err := h3Server.Close(); err != nil {
|
||||
log.Printf("QUIC server forced to shutdown: %s", err)
|
||||
}
|
||||
}
|
||||
if err := tlsServer.Shutdown(ctx); err != nil {
|
||||
log.Printf("TLS server forced to shutdown: %s", err)
|
||||
}
|
||||
}
|
||||
models.CloseDBs()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func runTCPServer() {
|
||||
tcpServer = &http.Server{
|
||||
Addr: setting.App.BindAddress,
|
||||
Handler: engine,
|
||||
ReadTimeout: setting.App.Server.ReadTimeout,
|
||||
WriteTimeout: setting.App.Server.WriteTimeout,
|
||||
}
|
||||
|
||||
go func() {
|
||||
log.Printf("Starting TCP server listening on %s", setting.App.BindAddress)
|
||||
if err := tcpServer.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Printf("Stopping TCP server...")
|
||||
}()
|
||||
}
|
||||
|
||||
func runTLSServer() {
|
||||
tlsServer = &http.Server{
|
||||
Addr: setting.App.TLSAddress,
|
||||
Handler: engine,
|
||||
ReadTimeout: setting.App.Server.ReadTimeout,
|
||||
WriteTimeout: setting.App.Server.WriteTimeout,
|
||||
}
|
||||
|
||||
go func() {
|
||||
log.Printf("Starting TLS server listening on %s", setting.App.TLSAddress)
|
||||
if err := tlsServer.ListenAndServeTLS(setting.App.TLSCrtPath, setting.App.TLSKeyPath); err != nil &&
|
||||
!errors.Is(err, http.ErrServerClosed) {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Printf("Stopping TLS server...")
|
||||
}()
|
||||
}
|
||||
|
||||
func runQuicServer() {
|
||||
h3Server = &http3.Server{
|
||||
Addr: setting.App.TLSAddress,
|
||||
Handler: tlsServer.Handler,
|
||||
}
|
||||
|
||||
previousHandler := tlsServer.Handler
|
||||
tlsServer.Handler = http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
if err := h3Server.SetQuicHeaders(rw.Header()); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
previousHandler.ServeHTTP(rw, req)
|
||||
})
|
||||
|
||||
go func() {
|
||||
log.Printf("Starting QUIC server listening on %s (udp)", setting.App.TLSAddress)
|
||||
if err := h3Server.ListenAndServeTLS(setting.App.TLSCrtPath, setting.App.TLSKeyPath); err != nil &&
|
||||
err.Error() != "quic: Server closed" {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Printf("Stopping QUIC server...")
|
||||
}()
|
||||
}
|
||||
|
||||
func setupEngine() {
|
||||
func setupEngine() *gin.Engine {
|
||||
gin.DisableConsoleColor()
|
||||
if os.Getenv(gin.EnvGinMode) == "" {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
}
|
||||
engine = gin.New()
|
||||
engine := gin.New()
|
||||
engine.Use(gin.LoggerWithFormatter(httputils.GetLogFormatter))
|
||||
engine.Use(gin.Recovery())
|
||||
if setting.App.EnableSecureHeaders {
|
||||
@ -193,4 +52,6 @@ func setupEngine() {
|
||||
}
|
||||
_ = engine.SetTrustedProxies(nil)
|
||||
engine.TrustedPlatform = setting.App.TrustedHeader
|
||||
|
||||
return engine
|
||||
}
|
||||
|
18
go.mod
18
go.mod
@ -9,6 +9,7 @@ require (
|
||||
github.com/quic-go/quic-go v0.33.0
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/testcontainers/testcontainers-go v0.13.0
|
||||
golang.org/x/net v0.8.0
|
||||
)
|
||||
|
||||
require (
|
||||
@ -34,8 +35,8 @@ require (
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/pprof v0.0.0-20230309165930-d61513b1440d // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||
@ -48,7 +49,7 @@ require (
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.2.0 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.9.1 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect
|
||||
github.com/opencontainers/runc v1.1.3 // indirect
|
||||
@ -56,20 +57,19 @@ require (
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/quic-go/qpack v0.4.0 // indirect
|
||||
github.com/quic-go/qtls-go1-19 v0.2.1 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.1.1 // indirect
|
||||
github.com/quic-go/qtls-go1-19 v0.3.0 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.2.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
go.opencensus.io v0.23.0 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/crypto v0.7.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect
|
||||
golang.org/x/mod v0.8.0 // indirect
|
||||
golang.org/x/net v0.8.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0 // indirect
|
||||
golang.org/x/mod v0.9.0 // indirect
|
||||
golang.org/x/sys v0.6.0 // indirect
|
||||
golang.org/x/text v0.8.0 // indirect
|
||||
golang.org/x/tools v0.6.0 // indirect
|
||||
golang.org/x/tools v0.7.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220810155839-1856144b1d9c // indirect
|
||||
google.golang.org/grpc v1.48.0 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
|
37
go.sum
37
go.sum
@ -317,6 +317,7 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
|
||||
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
@ -392,8 +393,9 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
@ -407,7 +409,7 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
@ -418,8 +420,8 @@ github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hf
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20230309165930-d61513b1440d h1:um9/pc7tKMINFfP1eE7Wv6PRGXlcCSJkVajF7KJw3uQ=
|
||||
github.com/google/pprof v0.0.0-20230309165930-d61513b1440d/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
@ -454,7 +456,6 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
@ -572,8 +573,8 @@ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
|
||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
||||
github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
|
||||
github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk=
|
||||
github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo=
|
||||
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
@ -581,7 +582,7 @@ github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
|
||||
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
|
||||
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
||||
github.com/onsi/gomega v1.27.3 h1:5VwIwnBY3vbBDOJrNtA4rVdiTZCsq9B5F12pvy1Drmk=
|
||||
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
@ -658,10 +659,10 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||
github.com/quic-go/qtls-go1-19 v0.2.1 h1:aJcKNMkH5ASEJB9FXNeZCyTEIHU1J7MmHyz1Q1TSG1A=
|
||||
github.com/quic-go/qtls-go1-19 v0.2.1/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI=
|
||||
github.com/quic-go/qtls-go1-20 v0.1.1 h1:KbChDlg82d3IHqaj2bn6GfKRj84Per2VGf5XV3wSwQk=
|
||||
github.com/quic-go/qtls-go1-20 v0.1.1/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM=
|
||||
github.com/quic-go/qtls-go1-19 v0.3.0 h1:aUBoQdpHzUWtPw5tQZbsD2GnrWCNu7/RIX1PtqGeLYY=
|
||||
github.com/quic-go/qtls-go1-19 v0.3.0/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI=
|
||||
github.com/quic-go/qtls-go1-20 v0.2.0 h1:jUHn+obJ6WI5JudqBO0Iy1ra5Vh5vsitQ1gXQvkmN+E=
|
||||
github.com/quic-go/qtls-go1-20 v0.2.0/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM=
|
||||
github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0=
|
||||
github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
@ -805,8 +806,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o=
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0 h1:pVgRXcIictcr+lBQIFeiwuwtDIs4eL21OuM9nyAADmo=
|
||||
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@ -828,8 +829,8 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
|
||||
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -1032,8 +1033,8 @@ golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3/go.mod h1:z6u4i615ZeAfBE4X
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
|
||||
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||
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=
|
||||
|
@ -122,8 +122,6 @@ func TestContainerIntegration(t *testing.T) {
|
||||
assert.Equal(t, `h3=":8001"; ma=2592000,h3-29=":8001"; ma=2592000`, resp.Header.Get("Alt-Svc"))
|
||||
}
|
||||
}
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 200, resp.StatusCode)
|
||||
|
||||
|
54
server/quic_server.go
Normal file
54
server/quic_server.go
Normal 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
101
server/server.go
Normal 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
46
server/tcp_server.go
Normal 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
47
server/tls_server.go
Normal 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)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user