refactor(server): improve proxy protocol handling

This commit is contained in:
yusing
2025-09-19 11:59:34 +08:00
parent 193fd9a249
commit a48ccb4423

View File

@@ -10,6 +10,7 @@ import (
"time" "time"
"github.com/pires/go-proxyproto" "github.com/pires/go-proxyproto"
h2proxy "github.com/pires/go-proxyproto/helper/http2"
"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"
@@ -104,19 +105,23 @@ func (s *Server) Start(parent task.Parent) {
subtask := parent.Subtask("server."+s.Name, false) subtask := parent.Subtask("server."+s.Name, false)
if s.https != nil && common.HTTP3Enabled { if s.https != nil && common.HTTP3Enabled {
s.https.TLSConfig.NextProtos = []string{http3.NextProtoH3, "h2", "http/1.1"} if s.proxyProto {
h3 := &http3.Server{ // TODO: support proxy protocol for HTTP/3
Addr: s.https.Addr, s.l.Warn().Msg("HTTP/3 is enabled, but proxy protocol is yet not supported for HTTP/3")
Handler: s.https.Handler, } else {
TLSConfig: http3.ConfigureTLSConfig(s.https.TLSConfig), s.https.TLSConfig.NextProtos = []string{http3.NextProtoH3, "h2", "http/1.1"}
h3 := &http3.Server{
Addr: s.https.Addr,
Handler: s.https.Handler,
TLSConfig: http3.ConfigureTLSConfig(s.https.TLSConfig),
}
Start(subtask, h3, WithProxyProtocolSupport(s.proxyProto), WithACL(s.acl), WithLogger(&s.l))
if s.http != nil {
s.http.Handler = advertiseHTTP3(s.http.Handler, h3)
}
// s.https is not nil (checked above)
s.https.Handler = advertiseHTTP3(s.https.Handler, h3)
} }
// 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)
}
// s.https is not nil (checked above)
s.https.Handler = advertiseHTTP3(s.https.Handler, h3)
} }
Start(subtask, s.http, WithProxyProtocolSupport(s.proxyProto), WithACL(s.acl), WithLogger(&s.l)) Start(subtask, s.http, WithProxyProtocolSupport(s.proxyProto), WithACL(s.acl), WithLogger(&s.l))
@@ -127,6 +132,7 @@ type ServerStartOptions struct {
tcpWrappers []func(l net.Listener) net.Listener tcpWrappers []func(l net.Listener) net.Listener
udpWrappers []func(l net.PacketConn) net.PacketConn udpWrappers []func(l net.PacketConn) net.PacketConn
logger *zerolog.Logger logger *zerolog.Logger
proxyProto bool
} }
type ServerStartOption func(opts *ServerStartOptions) type ServerStartOption func(opts *ServerStartOptions)
@@ -160,13 +166,8 @@ func WithACL(acl *acl.Config) ServerStartOption {
} }
func WithProxyProtocolSupport(value bool) ServerStartOption { func WithProxyProtocolSupport(value bool) ServerStartOption {
// TODO: HTTP/3 (UDP) support
return func(opts *ServerStartOptions) { return func(opts *ServerStartOptions) {
if value { opts.proxyProto = value
opts.tcpWrappers = append(opts.tcpWrappers, func(l net.Listener) net.Listener {
return &proxyproto.Listener{Listener: l}
})
}
} }
} }
@@ -202,13 +203,20 @@ func Start[Server httpServer](parent task.Parent, srv Server, optFns ...ServerSt
return return
} }
port = l.Addr().(*net.TCPAddr).Port port = l.Addr().(*net.TCPAddr).Port
if opts.proxyProto {
l = &proxyproto.Listener{Listener: l}
}
if srv.TLSConfig != nil { if srv.TLSConfig != nil {
l = tls.NewListener(l, srv.TLSConfig) l = tls.NewListener(l, srv.TLSConfig)
} }
for _, wrapper := range opts.tcpWrappers { for _, wrapper := range opts.tcpWrappers {
l = wrapper(l) l = wrapper(l)
} }
serveFunc = getServeFunc(l, srv.Serve) if opts.proxyProto {
serveFunc = getServeFunc(l, h2proxy.NewServer(srv, nil).Serve)
} else {
serveFunc = getServeFunc(l, srv.Serve)
}
task.OnCancel("stop", func() { task.OnCancel("stop", func() {
stop(srv, l, opts.logger) stop(srv, l, opts.logger)
}) })