mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-24 17:58:45 +02:00
refactor(server): enhance server start options and support for proxy protocol
This commit is contained in:
@@ -71,6 +71,7 @@ require (
|
|||||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||||
github.com/oschwald/maxminddb-golang v1.13.1 // indirect
|
github.com/oschwald/maxminddb-golang v1.13.1 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||||
|
github.com/pires/go-proxyproto v0.8.1 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
||||||
|
|||||||
@@ -128,6 +128,8 @@ github.com/oschwald/maxminddb-golang v1.13.1 h1:G3wwjdN9JmIK2o/ermkHM+98oX5fS+k5
|
|||||||
github.com/oschwald/maxminddb-golang v1.13.1/go.mod h1:K4pgV9N/GcK694KSTmVSDTODk4IsCNThNdTmnaBZ/F8=
|
github.com/oschwald/maxminddb-golang v1.13.1/go.mod h1:K4pgV9N/GcK694KSTmVSDTODk4IsCNThNdTmnaBZ/F8=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||||
|
github.com/pires/go-proxyproto v0.8.1 h1:9KEixbdJfhrbtjpz/ZwCdWDD2Xem0NZ38qMYaASJgp0=
|
||||||
|
github.com/pires/go-proxyproto v0.8.1/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
|||||||
@@ -39,5 +39,5 @@ func StartAgentServer(parent task.Parent, opt Options) {
|
|||||||
TLSConfig: tlsConfig,
|
TLSConfig: tlsConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
server.Start(parent, agentServer, nil, &log.Logger)
|
server.Start(parent, agentServer, server.WithLogger(&log.Logger))
|
||||||
}
|
}
|
||||||
|
|||||||
1
go.mod
1
go.mod
@@ -213,6 +213,7 @@ require (
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/gin-gonic/gin v1.10.1
|
github.com/gin-gonic/gin v1.10.1
|
||||||
|
github.com/pires/go-proxyproto v0.8.1
|
||||||
github.com/yusing/ds v0.1.0
|
github.com/yusing/ds v0.1.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -1424,6 +1424,8 @@ github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi
|
|||||||
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||||
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
||||||
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||||
|
github.com/pires/go-proxyproto v0.8.1 h1:9KEixbdJfhrbtjpz/ZwCdWDD2Xem0NZ38qMYaASJgp0=
|
||||||
|
github.com/pires/go-proxyproto v0.8.1/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU=
|
||||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
||||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pires/go-proxyproto"
|
||||||
"github.com/quic-go/quic-go/http3"
|
"github.com/quic-go/quic-go/http3"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
@@ -28,6 +29,7 @@ type Server struct {
|
|||||||
https *http.Server
|
https *http.Server
|
||||||
startTime time.Time
|
startTime time.Time
|
||||||
acl *acl.Config
|
acl *acl.Config
|
||||||
|
proxyProto bool
|
||||||
|
|
||||||
l zerolog.Logger
|
l zerolog.Logger
|
||||||
}
|
}
|
||||||
@@ -39,6 +41,8 @@ type Options struct {
|
|||||||
CertProvider CertProvider
|
CertProvider CertProvider
|
||||||
Handler http.Handler
|
Handler http.Handler
|
||||||
ACL *acl.Config
|
ACL *acl.Config
|
||||||
|
|
||||||
|
SupportProxyProtocol bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type httpServer interface {
|
type httpServer interface {
|
||||||
@@ -86,6 +90,7 @@ func NewServer(opt Options) (s *Server) {
|
|||||||
https: httpsSer,
|
https: httpsSer,
|
||||||
l: logger,
|
l: logger,
|
||||||
acl: opt.ACL,
|
acl: opt.ACL,
|
||||||
|
proxyProto: opt.SupportProxyProtocol,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +110,8 @@ func (s *Server) Start(parent task.Parent) {
|
|||||||
Handler: s.https.Handler,
|
Handler: s.https.Handler,
|
||||||
TLSConfig: http3.ConfigureTLSConfig(s.https.TLSConfig),
|
TLSConfig: http3.ConfigureTLSConfig(s.https.TLSConfig),
|
||||||
}
|
}
|
||||||
Start(subtask, h3, s.acl, &s.l)
|
// TODO: support proxy protocol for HTTP/3
|
||||||
|
Start(subtask, h3, WithACL(s.acl), WithLogger(&s.l))
|
||||||
if s.http != nil {
|
if s.http != nil {
|
||||||
s.http.Handler = advertiseHTTP3(s.http.Handler, h3)
|
s.http.Handler = advertiseHTTP3(s.http.Handler, h3)
|
||||||
}
|
}
|
||||||
@@ -113,16 +119,68 @@ func (s *Server) Start(parent task.Parent) {
|
|||||||
s.https.Handler = advertiseHTTP3(s.https.Handler, h3)
|
s.https.Handler = advertiseHTTP3(s.https.Handler, h3)
|
||||||
}
|
}
|
||||||
|
|
||||||
Start(subtask, s.http, s.acl, &s.l)
|
Start(subtask, s.http, WithProxyProtocolSupport(s.proxyProto), WithACL(s.acl), WithLogger(&s.l))
|
||||||
Start(subtask, s.https, s.acl, &s.l)
|
Start(subtask, s.https, WithProxyProtocolSupport(s.proxyProto), WithACL(s.acl), WithLogger(&s.l))
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start[Server httpServer](parent task.Parent, srv Server, acl *acl.Config, logger *zerolog.Logger) (port int) {
|
type ServerStartOptions struct {
|
||||||
|
tcpWrappers []func(l net.Listener) net.Listener
|
||||||
|
udpWrappers []func(l net.PacketConn) net.PacketConn
|
||||||
|
logger *zerolog.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServerStartOption func(opts *ServerStartOptions)
|
||||||
|
|
||||||
|
func WithTCPWrappers(wrappers ...func(l net.Listener) net.Listener) ServerStartOption {
|
||||||
|
return func(opts *ServerStartOptions) {
|
||||||
|
opts.tcpWrappers = wrappers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithUDPWrappers(wrappers ...func(l net.PacketConn) net.PacketConn) ServerStartOption {
|
||||||
|
return func(opts *ServerStartOptions) {
|
||||||
|
opts.udpWrappers = wrappers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithLogger(logger *zerolog.Logger) ServerStartOption {
|
||||||
|
return func(opts *ServerStartOptions) {
|
||||||
|
opts.logger = logger
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithACL(acl *acl.Config) ServerStartOption {
|
||||||
|
return func(opts *ServerStartOptions) {
|
||||||
|
if acl == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
opts.tcpWrappers = append(opts.tcpWrappers, acl.WrapTCP)
|
||||||
|
opts.udpWrappers = append(opts.udpWrappers, acl.WrapUDP)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithProxyProtocolSupport(value bool) ServerStartOption {
|
||||||
|
// TODO: HTTP/3 (UDP) support
|
||||||
|
return func(opts *ServerStartOptions) {
|
||||||
|
if value {
|
||||||
|
opts.tcpWrappers = append(opts.tcpWrappers, func(l net.Listener) net.Listener {
|
||||||
|
return &proxyproto.Listener{Listener: l}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Start[Server httpServer](parent task.Parent, srv Server, optFns ...ServerStartOption) (port int) {
|
||||||
if srv == nil {
|
if srv == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
setDebugLogger(srv, logger)
|
var opts ServerStartOptions
|
||||||
|
for _, optFn := range optFns {
|
||||||
|
optFn(&opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
setDebugLogger(srv, opts.logger)
|
||||||
|
|
||||||
proto := proto(srv)
|
proto := proto(srv)
|
||||||
task := parent.Subtask(proto, true)
|
task := parent.Subtask(proto, true)
|
||||||
@@ -137,40 +195,40 @@ func Start[Server httpServer](parent task.Parent, srv Server, acl *acl.Config, l
|
|||||||
}
|
}
|
||||||
l, err := lc.Listen(task.Context(), "tcp", srv.Addr)
|
l, err := lc.Listen(task.Context(), "tcp", srv.Addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
HandleError(logger, err, "failed to listen on port")
|
HandleError(opts.logger, err, "failed to listen on port")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
port = l.Addr().(*net.TCPAddr).Port
|
port = l.Addr().(*net.TCPAddr).Port
|
||||||
if srv.TLSConfig != nil {
|
if srv.TLSConfig != nil {
|
||||||
l = tls.NewListener(l, srv.TLSConfig)
|
l = tls.NewListener(l, srv.TLSConfig)
|
||||||
}
|
}
|
||||||
if acl != nil {
|
for _, wrapper := range opts.tcpWrappers {
|
||||||
l = acl.WrapTCP(l)
|
l = wrapper(l)
|
||||||
}
|
}
|
||||||
serveFunc = getServeFunc(l, srv.Serve)
|
serveFunc = getServeFunc(l, srv.Serve)
|
||||||
task.OnCancel("stop", func() {
|
task.OnCancel("stop", func() {
|
||||||
stop(srv, l, logger)
|
stop(srv, l, opts.logger)
|
||||||
})
|
})
|
||||||
case *http3.Server:
|
case *http3.Server:
|
||||||
l, err := lc.ListenPacket(task.Context(), "udp", srv.Addr)
|
l, err := lc.ListenPacket(task.Context(), "udp", srv.Addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
HandleError(logger, err, "failed to listen on port")
|
HandleError(opts.logger, err, "failed to listen on port")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
port = l.LocalAddr().(*net.UDPAddr).Port
|
port = l.LocalAddr().(*net.UDPAddr).Port
|
||||||
if acl != nil {
|
for _, wrapper := range opts.udpWrappers {
|
||||||
l = acl.WrapUDP(l)
|
l = wrapper(l)
|
||||||
}
|
}
|
||||||
serveFunc = getServeFunc(l, srv.Serve)
|
serveFunc = getServeFunc(l, srv.Serve)
|
||||||
task.OnCancel("stop", func() {
|
task.OnCancel("stop", func() {
|
||||||
stop(srv, l, logger)
|
stop(srv, l, opts.logger)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
logStarted(srv, logger)
|
logStarted(srv, opts.logger)
|
||||||
go func() {
|
go func() {
|
||||||
err := convertError(serveFunc())
|
err := convertError(serveFunc())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
HandleError(logger, err, "failed to serve "+proto+" server")
|
HandleError(opts.logger, err, "failed to serve "+proto+" server")
|
||||||
}
|
}
|
||||||
task.Finish(err)
|
task.Finish(err)
|
||||||
}()
|
}()
|
||||||
|
|||||||
Reference in New Issue
Block a user