mirror of
https://github.com/yusing/godoxy.git
synced 2026-01-11 22:30:47 +01: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/oschwald/maxminddb-golang v1.13.1 // 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/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // 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/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/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/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
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,
|
||||
}
|
||||
|
||||
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 (
|
||||
github.com/gin-gonic/gin v1.10.1
|
||||
github.com/pires/go-proxyproto v0.8.1
|
||||
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.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
||||
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/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/pires/go-proxyproto"
|
||||
"github.com/quic-go/quic-go/http3"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
@@ -28,6 +29,7 @@ type Server struct {
|
||||
https *http.Server
|
||||
startTime time.Time
|
||||
acl *acl.Config
|
||||
proxyProto bool
|
||||
|
||||
l zerolog.Logger
|
||||
}
|
||||
@@ -39,6 +41,8 @@ type Options struct {
|
||||
CertProvider CertProvider
|
||||
Handler http.Handler
|
||||
ACL *acl.Config
|
||||
|
||||
SupportProxyProtocol bool
|
||||
}
|
||||
|
||||
type httpServer interface {
|
||||
@@ -86,6 +90,7 @@ func NewServer(opt Options) (s *Server) {
|
||||
https: httpsSer,
|
||||
l: logger,
|
||||
acl: opt.ACL,
|
||||
proxyProto: opt.SupportProxyProtocol,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +110,8 @@ func (s *Server) Start(parent task.Parent) {
|
||||
Handler: s.https.Handler,
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
|
||||
Start(subtask, s.http, s.acl, &s.l)
|
||||
Start(subtask, s.https, s.acl, &s.l)
|
||||
Start(subtask, s.http, WithProxyProtocolSupport(s.proxyProto), WithACL(s.acl), WithLogger(&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 {
|
||||
return
|
||||
}
|
||||
|
||||
setDebugLogger(srv, logger)
|
||||
var opts ServerStartOptions
|
||||
for _, optFn := range optFns {
|
||||
optFn(&opts)
|
||||
}
|
||||
|
||||
setDebugLogger(srv, opts.logger)
|
||||
|
||||
proto := proto(srv)
|
||||
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)
|
||||
if err != nil {
|
||||
HandleError(logger, err, "failed to listen on port")
|
||||
HandleError(opts.logger, err, "failed to listen on port")
|
||||
return
|
||||
}
|
||||
port = l.Addr().(*net.TCPAddr).Port
|
||||
if srv.TLSConfig != nil {
|
||||
l = tls.NewListener(l, srv.TLSConfig)
|
||||
}
|
||||
if acl != nil {
|
||||
l = acl.WrapTCP(l)
|
||||
for _, wrapper := range opts.tcpWrappers {
|
||||
l = wrapper(l)
|
||||
}
|
||||
serveFunc = getServeFunc(l, srv.Serve)
|
||||
task.OnCancel("stop", func() {
|
||||
stop(srv, l, logger)
|
||||
stop(srv, l, opts.logger)
|
||||
})
|
||||
case *http3.Server:
|
||||
l, err := lc.ListenPacket(task.Context(), "udp", srv.Addr)
|
||||
if err != nil {
|
||||
HandleError(logger, err, "failed to listen on port")
|
||||
HandleError(opts.logger, err, "failed to listen on port")
|
||||
return
|
||||
}
|
||||
port = l.LocalAddr().(*net.UDPAddr).Port
|
||||
if acl != nil {
|
||||
l = acl.WrapUDP(l)
|
||||
for _, wrapper := range opts.udpWrappers {
|
||||
l = wrapper(l)
|
||||
}
|
||||
serveFunc = getServeFunc(l, srv.Serve)
|
||||
task.OnCancel("stop", func() {
|
||||
stop(srv, l, logger)
|
||||
stop(srv, l, opts.logger)
|
||||
})
|
||||
}
|
||||
logStarted(srv, logger)
|
||||
logStarted(srv, opts.logger)
|
||||
go func() {
|
||||
err := convertError(serveFunc())
|
||||
if err != nil {
|
||||
HandleError(logger, err, "failed to serve "+proto+" server")
|
||||
HandleError(opts.logger, err, "failed to serve "+proto+" server")
|
||||
}
|
||||
task.Finish(err)
|
||||
}()
|
||||
|
||||
Reference in New Issue
Block a user