fix auth for file handler
This commit is contained in:
parent
b1390dda1c
commit
f847fa533e
164
api/api.go
164
api/api.go
@ -2,6 +2,13 @@ package api
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-contrib/cors"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-gost/core/auth"
|
||||
"github.com/go-gost/core/service"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -13,3 +20,160 @@ type Response struct {
|
||||
Code int `json:"code,omitempty"`
|
||||
Msg string `json:"msg,omitempty"`
|
||||
}
|
||||
|
||||
type options struct {
|
||||
accessLog bool
|
||||
pathPrefix string
|
||||
auther auth.Authenticator
|
||||
}
|
||||
|
||||
type Option func(*options)
|
||||
|
||||
func PathPrefixOption(pathPrefix string) Option {
|
||||
return func(o *options) {
|
||||
o.pathPrefix = pathPrefix
|
||||
}
|
||||
}
|
||||
|
||||
func AccessLogOption(enable bool) Option {
|
||||
return func(o *options) {
|
||||
o.accessLog = enable
|
||||
}
|
||||
}
|
||||
|
||||
func AutherOption(auther auth.Authenticator) Option {
|
||||
return func(o *options) {
|
||||
o.auther = auther
|
||||
}
|
||||
}
|
||||
|
||||
type server struct {
|
||||
s *http.Server
|
||||
ln net.Listener
|
||||
cclose chan struct{}
|
||||
}
|
||||
|
||||
func NewService(addr string, opts ...Option) (service.Service, error) {
|
||||
ln, err := net.Listen("tcp", addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var options options
|
||||
for _, opt := range opts {
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
|
||||
r := gin.New()
|
||||
r.Use(
|
||||
cors.New((cors.Config{
|
||||
AllowAllOrigins: true,
|
||||
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
|
||||
AllowHeaders: []string{"*"},
|
||||
AllowPrivateNetwork: true,
|
||||
})),
|
||||
gin.Recovery(),
|
||||
)
|
||||
if options.accessLog {
|
||||
r.Use(mwLogger())
|
||||
}
|
||||
|
||||
router := r.Group("")
|
||||
if options.pathPrefix != "" {
|
||||
router = router.Group(options.pathPrefix)
|
||||
}
|
||||
|
||||
router.StaticFS("/docs", http.FS(swaggerDoc))
|
||||
|
||||
config := router.Group("/config")
|
||||
config.Use(mwBasicAuth(options.auther))
|
||||
registerConfig(config)
|
||||
|
||||
return &server{
|
||||
s: &http.Server{
|
||||
Handler: r,
|
||||
},
|
||||
ln: ln,
|
||||
cclose: make(chan struct{}),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *server) Serve() error {
|
||||
return s.s.Serve(s.ln)
|
||||
}
|
||||
|
||||
func (s *server) Addr() net.Addr {
|
||||
return s.ln.Addr()
|
||||
}
|
||||
|
||||
func (s *server) Close() error {
|
||||
return s.s.Close()
|
||||
}
|
||||
|
||||
func (s *server) IsClosed() bool {
|
||||
select {
|
||||
case <-s.cclose:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func registerConfig(config *gin.RouterGroup) {
|
||||
config.GET("", getConfig)
|
||||
config.POST("", saveConfig)
|
||||
|
||||
config.POST("/services", createService)
|
||||
config.PUT("/services/:service", updateService)
|
||||
config.DELETE("/services/:service", deleteService)
|
||||
|
||||
config.POST("/chains", createChain)
|
||||
config.PUT("/chains/:chain", updateChain)
|
||||
config.DELETE("/chains/:chain", deleteChain)
|
||||
|
||||
config.POST("/hops", createHop)
|
||||
config.PUT("/hops/:hop", updateHop)
|
||||
config.DELETE("/hops/:hop", deleteHop)
|
||||
|
||||
config.POST("/authers", createAuther)
|
||||
config.PUT("/authers/:auther", updateAuther)
|
||||
config.DELETE("/authers/:auther", deleteAuther)
|
||||
|
||||
config.POST("/admissions", createAdmission)
|
||||
config.PUT("/admissions/:admission", updateAdmission)
|
||||
config.DELETE("/admissions/:admission", deleteAdmission)
|
||||
|
||||
config.POST("/bypasses", createBypass)
|
||||
config.PUT("/bypasses/:bypass", updateBypass)
|
||||
config.DELETE("/bypasses/:bypass", deleteBypass)
|
||||
|
||||
config.POST("/resolvers", createResolver)
|
||||
config.PUT("/resolvers/:resolver", updateResolver)
|
||||
config.DELETE("/resolvers/:resolver", deleteResolver)
|
||||
|
||||
config.POST("/hosts", createHosts)
|
||||
config.PUT("/hosts/:hosts", updateHosts)
|
||||
config.DELETE("/hosts/:hosts", deleteHosts)
|
||||
|
||||
config.POST("/ingresses", createIngress)
|
||||
config.PUT("/ingresses/:ingress", updateIngress)
|
||||
config.DELETE("/ingresses/:ingress", deleteIngress)
|
||||
|
||||
config.POST("/routers", createRouter)
|
||||
config.PUT("/routers/:router", updateRouter)
|
||||
config.DELETE("/routers/:router", deleteRouter)
|
||||
|
||||
config.POST("/limiters", createLimiter)
|
||||
config.PUT("/limiters/:limiter", updateLimiter)
|
||||
config.DELETE("/limiters/:limiter", deleteLimiter)
|
||||
|
||||
config.POST("/climiters", createConnLimiter)
|
||||
config.PUT("/climiters/:limiter", updateConnLimiter)
|
||||
config.DELETE("/climiters/:limiter", deleteConnLimiter)
|
||||
|
||||
config.POST("/rlimiters", createRateLimiter)
|
||||
config.PUT("/rlimiters/:limiter", updateRateLimiter)
|
||||
config.DELETE("/rlimiters/:limiter", deleteRateLimiter)
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-gost/core/logger"
|
||||
"github.com/go-gost/x/config"
|
||||
parser "github.com/go-gost/x/config/parsing/chain"
|
||||
"github.com/go-gost/x/registry"
|
||||
@ -40,7 +41,7 @@ func createChain(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
v, err := parser.ParseChain(&req.Data)
|
||||
v, err := parser.ParseChain(&req.Data, logger.Default())
|
||||
if err != nil {
|
||||
writeError(ctx, ErrCreate)
|
||||
return
|
||||
@ -99,7 +100,7 @@ func updateChain(ctx *gin.Context) {
|
||||
|
||||
req.Data.Name = req.Chain
|
||||
|
||||
v, err := parser.ParseChain(&req.Data)
|
||||
v, err := parser.ParseChain(&req.Data, logger.Default())
|
||||
if err != nil {
|
||||
writeError(ctx, ErrCreate)
|
||||
return
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-gost/core/logger"
|
||||
"github.com/go-gost/x/config"
|
||||
parser "github.com/go-gost/x/config/parsing/hop"
|
||||
"github.com/go-gost/x/registry"
|
||||
@ -40,7 +41,7 @@ func createHop(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
v, err := parser.ParseHop(&req.Data)
|
||||
v, err := parser.ParseHop(&req.Data, logger.Default())
|
||||
if err != nil {
|
||||
writeError(ctx, ErrCreate)
|
||||
return
|
||||
@ -99,7 +100,7 @@ func updateHop(ctx *gin.Context) {
|
||||
|
||||
req.Data.Name = req.Hop
|
||||
|
||||
v, err := parser.ParseHop(&req.Data)
|
||||
v, err := parser.ParseHop(&req.Data, logger.Default())
|
||||
if err != nil {
|
||||
writeError(ctx, ErrCreate)
|
||||
return
|
||||
|
157
api/service.go
157
api/service.go
@ -1,157 +0,0 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-contrib/cors"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-gost/core/auth"
|
||||
"github.com/go-gost/core/service"
|
||||
)
|
||||
|
||||
type options struct {
|
||||
accessLog bool
|
||||
pathPrefix string
|
||||
auther auth.Authenticator
|
||||
}
|
||||
|
||||
type Option func(*options)
|
||||
|
||||
func PathPrefixOption(pathPrefix string) Option {
|
||||
return func(o *options) {
|
||||
o.pathPrefix = pathPrefix
|
||||
}
|
||||
}
|
||||
|
||||
func AccessLogOption(enable bool) Option {
|
||||
return func(o *options) {
|
||||
o.accessLog = enable
|
||||
}
|
||||
}
|
||||
|
||||
func AutherOption(auther auth.Authenticator) Option {
|
||||
return func(o *options) {
|
||||
o.auther = auther
|
||||
}
|
||||
}
|
||||
|
||||
type server struct {
|
||||
s *http.Server
|
||||
ln net.Listener
|
||||
}
|
||||
|
||||
func NewService(addr string, opts ...Option) (service.Service, error) {
|
||||
ln, err := net.Listen("tcp", addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var options options
|
||||
for _, opt := range opts {
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
|
||||
r := gin.New()
|
||||
r.Use(
|
||||
cors.New((cors.Config{
|
||||
AllowAllOrigins: true,
|
||||
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
|
||||
AllowHeaders: []string{"*"},
|
||||
AllowPrivateNetwork: true,
|
||||
})),
|
||||
gin.Recovery(),
|
||||
)
|
||||
if options.accessLog {
|
||||
r.Use(mwLogger())
|
||||
}
|
||||
|
||||
router := r.Group("")
|
||||
if options.pathPrefix != "" {
|
||||
router = router.Group(options.pathPrefix)
|
||||
}
|
||||
|
||||
router.StaticFS("/docs", http.FS(swaggerDoc))
|
||||
|
||||
config := router.Group("/config")
|
||||
config.Use(mwBasicAuth(options.auther))
|
||||
registerConfig(config)
|
||||
|
||||
return &server{
|
||||
s: &http.Server{
|
||||
Handler: r,
|
||||
},
|
||||
ln: ln,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *server) Serve() error {
|
||||
return s.s.Serve(s.ln)
|
||||
}
|
||||
|
||||
func (s *server) Addr() net.Addr {
|
||||
return s.ln.Addr()
|
||||
}
|
||||
|
||||
func (s *server) Close() error {
|
||||
return s.s.Close()
|
||||
}
|
||||
|
||||
func registerConfig(config *gin.RouterGroup) {
|
||||
config.GET("", getConfig)
|
||||
config.POST("", saveConfig)
|
||||
|
||||
config.POST("/services", createService)
|
||||
config.PUT("/services/:service", updateService)
|
||||
config.DELETE("/services/:service", deleteService)
|
||||
|
||||
config.POST("/chains", createChain)
|
||||
config.PUT("/chains/:chain", updateChain)
|
||||
config.DELETE("/chains/:chain", deleteChain)
|
||||
|
||||
config.POST("/hops", createHop)
|
||||
config.PUT("/hops/:hop", updateHop)
|
||||
config.DELETE("/hops/:hop", deleteHop)
|
||||
|
||||
config.POST("/authers", createAuther)
|
||||
config.PUT("/authers/:auther", updateAuther)
|
||||
config.DELETE("/authers/:auther", deleteAuther)
|
||||
|
||||
config.POST("/admissions", createAdmission)
|
||||
config.PUT("/admissions/:admission", updateAdmission)
|
||||
config.DELETE("/admissions/:admission", deleteAdmission)
|
||||
|
||||
config.POST("/bypasses", createBypass)
|
||||
config.PUT("/bypasses/:bypass", updateBypass)
|
||||
config.DELETE("/bypasses/:bypass", deleteBypass)
|
||||
|
||||
config.POST("/resolvers", createResolver)
|
||||
config.PUT("/resolvers/:resolver", updateResolver)
|
||||
config.DELETE("/resolvers/:resolver", deleteResolver)
|
||||
|
||||
config.POST("/hosts", createHosts)
|
||||
config.PUT("/hosts/:hosts", updateHosts)
|
||||
config.DELETE("/hosts/:hosts", deleteHosts)
|
||||
|
||||
config.POST("/ingresses", createIngress)
|
||||
config.PUT("/ingresses/:ingress", updateIngress)
|
||||
config.DELETE("/ingresses/:ingress", deleteIngress)
|
||||
|
||||
config.POST("/routers", createRouter)
|
||||
config.PUT("/routers/:router", updateRouter)
|
||||
config.DELETE("/routers/:router", deleteRouter)
|
||||
|
||||
config.POST("/limiters", createLimiter)
|
||||
config.PUT("/limiters/:limiter", updateLimiter)
|
||||
config.DELETE("/limiters/:limiter", deleteLimiter)
|
||||
|
||||
config.POST("/climiters", createConnLimiter)
|
||||
config.PUT("/climiters/:limiter", updateConnLimiter)
|
||||
config.DELETE("/climiters/:limiter", deleteConnLimiter)
|
||||
|
||||
config.POST("/rlimiters", createRateLimiter)
|
||||
config.PUT("/rlimiters/:limiter", updateRateLimiter)
|
||||
config.DELETE("/rlimiters/:limiter", deleteRateLimiter)
|
||||
}
|
@ -12,12 +12,12 @@ import (
|
||||
"github.com/go-gost/x/registry"
|
||||
)
|
||||
|
||||
func ParseChain(cfg *config.ChainConfig) (chain.Chainer, error) {
|
||||
func ParseChain(cfg *config.ChainConfig, log logger.Logger) (chain.Chainer, error) {
|
||||
if cfg == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
chainLogger := logger.Default().WithFields(map[string]any{
|
||||
chainLogger := log.WithFields(map[string]any{
|
||||
"kind": "chain",
|
||||
"chain": cfg.Name,
|
||||
})
|
||||
@ -37,7 +37,7 @@ func ParseChain(cfg *config.ChainConfig) (chain.Chainer, error) {
|
||||
var err error
|
||||
|
||||
if ch.Nodes != nil || ch.Plugin != nil {
|
||||
if hop, err = hop_parser.ParseHop(ch); err != nil {
|
||||
if hop, err = hop_parser.ParseHop(ch, log); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
|
@ -17,7 +17,7 @@ import (
|
||||
"github.com/go-gost/x/internal/plugin"
|
||||
)
|
||||
|
||||
func ParseHop(cfg *config.HopConfig) (hop.Hop, error) {
|
||||
func ParseHop(cfg *config.HopConfig, log logger.Logger) (hop.Hop, error) {
|
||||
if cfg == nil {
|
||||
return nil, nil
|
||||
}
|
||||
@ -77,7 +77,7 @@ func ParseHop(cfg *config.HopConfig) (hop.Hop, error) {
|
||||
}
|
||||
}
|
||||
|
||||
node, err := node_parser.ParseNode(cfg.Name, v)
|
||||
node, err := node_parser.ParseNode(cfg.Name, v, log)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -97,7 +97,7 @@ func ParseHop(cfg *config.HopConfig) (hop.Hop, error) {
|
||||
xhop.SelectorOption(sel),
|
||||
xhop.BypassOption(bypass.BypassGroup(bypass_parser.List(cfg.Bypass, cfg.Bypasses...)...)),
|
||||
xhop.ReloadPeriodOption(cfg.Reload),
|
||||
xhop.LoggerOption(logger.Default().WithFields(map[string]any{
|
||||
xhop.LoggerOption(log.WithFields(map[string]any{
|
||||
"kind": "hop",
|
||||
"hop": cfg.Name,
|
||||
})),
|
||||
|
@ -23,7 +23,7 @@ import (
|
||||
"github.com/go-gost/x/registry"
|
||||
)
|
||||
|
||||
func ParseNode(hop string, cfg *config.NodeConfig) (*chain.Node, error) {
|
||||
func ParseNode(hop string, cfg *config.NodeConfig, log logger.Logger) (*chain.Node, error) {
|
||||
if cfg == nil {
|
||||
return nil, nil
|
||||
}
|
||||
@ -40,7 +40,7 @@ func ParseNode(hop string, cfg *config.NodeConfig) (*chain.Node, error) {
|
||||
}
|
||||
}
|
||||
|
||||
nodeLogger := logger.Default().WithFields(map[string]any{
|
||||
nodeLogger := log.WithFields(map[string]any{
|
||||
"hop": hop,
|
||||
"kind": "node",
|
||||
"node": cfg.Name,
|
||||
|
@ -291,7 +291,7 @@ func parseForwarder(cfg *config.ForwarderConfig) (hop.Hop, error) {
|
||||
}
|
||||
}
|
||||
if len(hc.Nodes) > 0 {
|
||||
return hop_parser.ParseHop(&hc)
|
||||
return hop_parser.ParseHop(&hc, logger.Default())
|
||||
}
|
||||
return registry.HopRegistry().Get(hc.Name), nil
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ func (h *fileHandler) handleFunc(w http.ResponseWriter, r *http.Request) {
|
||||
if auther := h.options.Auther; auther != nil {
|
||||
u, p, _ := r.BasicAuth()
|
||||
if _, ok := auther.Authenticate(r.Context(), u, p); !ok {
|
||||
w.Header().Set("WWW-Authenticate", "Basic")
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
@ -31,12 +31,15 @@ func (h *tunnelHandler) handleBind(ctx context.Context, conn net.Conn, network,
|
||||
connectorID = relay.NewUDPConnectorID(uuid[:])
|
||||
}
|
||||
|
||||
v := md5.Sum([]byte(tunnelID.String()))
|
||||
endpoint := hex.EncodeToString(v[:8])
|
||||
|
||||
addr := address
|
||||
if host, port, _ := net.SplitHostPort(addr); host == "" {
|
||||
v := md5.Sum([]byte(tunnelID.String()))
|
||||
host = hex.EncodeToString(v[:8])
|
||||
addr = net.JoinHostPort(host, port)
|
||||
host, port, _ := net.SplitHostPort(addr)
|
||||
if host == "" {
|
||||
addr = net.JoinHostPort(endpoint, port)
|
||||
}
|
||||
|
||||
af := &relay.AddrFeature{}
|
||||
err = af.ParseFrom(addr)
|
||||
if err != nil {
|
||||
@ -58,9 +61,15 @@ func (h *tunnelHandler) handleBind(ctx context.Context, conn net.Conn, network,
|
||||
h.pool.Add(tunnelID, NewConnector(connectorID, tunnelID, h.id, session, h.md.sd), h.md.tunnelTTL)
|
||||
if h.md.ingress != nil {
|
||||
h.md.ingress.SetRule(ctx, &ingress.Rule{
|
||||
Hostname: addr,
|
||||
Hostname: endpoint,
|
||||
Endpoint: tunnelID.String(),
|
||||
})
|
||||
if host != "" {
|
||||
h.md.ingress.SetRule(ctx, &ingress.Rule{
|
||||
Hostname: host,
|
||||
Endpoint: tunnelID.String(),
|
||||
})
|
||||
}
|
||||
}
|
||||
if h.md.sd != nil {
|
||||
err := h.md.sd.Register(ctx, &sd.Service{
|
||||
|
@ -308,7 +308,7 @@ func (p *chainHop) parseNode(r io.Reader) ([]*chain.Node, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
node, err := node_parser.ParseNode(p.options.name, nc)
|
||||
node, err := node_parser.ParseNode(p.options.name, nc, logger.Default())
|
||||
if err != nil {
|
||||
return nodes, err
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ func (p *grpcPlugin) Select(ctx context.Context, opts ...hop.SelectOption) *chai
|
||||
return nil
|
||||
}
|
||||
|
||||
node, err := node_parser.ParseNode(p.name, &cfg)
|
||||
node, err := node_parser.ParseNode(p.name, &cfg, logger.Default())
|
||||
if err != nil {
|
||||
p.log.Error(err)
|
||||
return nil
|
||||
@ -203,7 +203,7 @@ func (p *httpPlugin) Select(ctx context.Context, opts ...hop.SelectOption) *chai
|
||||
return nil
|
||||
}
|
||||
|
||||
node, err := node_parser.ParseNode(p.name, &cfg)
|
||||
node, err := node_parser.ParseNode(p.name, &cfg, logger.Default())
|
||||
if err != nil {
|
||||
p.log.Error(err)
|
||||
return nil
|
||||
|
@ -89,7 +89,15 @@ func (l *rtcpListener) Accept() (conn net.Conn, err error) {
|
||||
ln = climiter.WrapListener(l.options.ConnLimiter, ln)
|
||||
l.setListener(ln)
|
||||
}
|
||||
conn, err = l.ln.Accept()
|
||||
|
||||
select {
|
||||
case <-l.closed:
|
||||
ln.Close()
|
||||
return nil, net.ErrClosed
|
||||
default:
|
||||
}
|
||||
|
||||
conn, err = ln.Accept()
|
||||
if err != nil {
|
||||
ln.Close()
|
||||
l.setListener(nil)
|
||||
@ -107,10 +115,8 @@ func (l *rtcpListener) Close() error {
|
||||
case <-l.closed:
|
||||
default:
|
||||
close(l.closed)
|
||||
ln := l.getListener()
|
||||
if ln != nil {
|
||||
if ln := l.getListener(); ln != nil {
|
||||
ln.Close()
|
||||
// l.ln = nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package rudp
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
"github.com/go-gost/core/chain"
|
||||
"github.com/go-gost/core/listener"
|
||||
@ -27,6 +28,7 @@ type rudpListener struct {
|
||||
logger logger.Logger
|
||||
md metadata
|
||||
options listener.Options
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func NewListener(opts ...listener.Option) listener.Listener {
|
||||
@ -72,8 +74,9 @@ func (l *rudpListener) Accept() (conn net.Conn, err error) {
|
||||
default:
|
||||
}
|
||||
|
||||
if l.ln == nil {
|
||||
l.ln, err = l.router.Bind(
|
||||
ln := l.getListener()
|
||||
if ln == nil {
|
||||
ln, err = l.router.Bind(
|
||||
context.Background(), "udp", l.laddr.String(),
|
||||
chain.BacklogBindOption(l.md.backlog),
|
||||
chain.UDPConnTTLBindOption(l.md.ttl),
|
||||
@ -83,11 +86,20 @@ func (l *rudpListener) Accept() (conn net.Conn, err error) {
|
||||
if err != nil {
|
||||
return nil, listener.NewAcceptError(err)
|
||||
}
|
||||
l.setListener(ln)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-l.closed:
|
||||
ln.Close()
|
||||
return nil, net.ErrClosed
|
||||
default:
|
||||
}
|
||||
|
||||
conn, err = l.ln.Accept()
|
||||
if err != nil {
|
||||
l.ln.Close()
|
||||
l.ln = nil
|
||||
l.setListener(nil)
|
||||
return nil, listener.NewAcceptError(err)
|
||||
}
|
||||
|
||||
@ -109,15 +121,26 @@ func (l *rudpListener) Close() error {
|
||||
case <-l.closed:
|
||||
default:
|
||||
close(l.closed)
|
||||
if l.ln != nil {
|
||||
l.ln.Close()
|
||||
// l.ln = nil
|
||||
if ln := l.getListener(); ln != nil {
|
||||
ln.Close()
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *rudpListener) setListener(ln net.Listener) {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
l.ln = ln
|
||||
}
|
||||
|
||||
func (l *rudpListener) getListener() net.Listener {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
return l.ln
|
||||
}
|
||||
|
||||
type bindAddr struct {
|
||||
addr string
|
||||
}
|
||||
|
@ -9,6 +9,9 @@ import (
|
||||
type mapMetadata map[string]any
|
||||
|
||||
func NewMetadata(m map[string]any) metadata.Metadata {
|
||||
if len(m) == 0 {
|
||||
return nil
|
||||
}
|
||||
md := make(map[string]any)
|
||||
for k, v := range m {
|
||||
md[strings.ToLower(k)] = v
|
||||
|
@ -33,8 +33,9 @@ func AutherOption(auther auth.Authenticator) Option {
|
||||
}
|
||||
|
||||
type metricService struct {
|
||||
s *http.Server
|
||||
ln net.Listener
|
||||
s *http.Server
|
||||
ln net.Listener
|
||||
cclose chan struct{}
|
||||
}
|
||||
|
||||
func NewService(addr string, opts ...Option) (service.Service, error) {
|
||||
@ -66,7 +67,8 @@ func NewService(addr string, opts ...Option) (service.Service, error) {
|
||||
s: &http.Server{
|
||||
Handler: mux,
|
||||
},
|
||||
ln: ln,
|
||||
ln: ln,
|
||||
cclose: make(chan struct{}),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -81,3 +83,12 @@ func (s *metricService) Addr() net.Addr {
|
||||
func (s *metricService) Close() error {
|
||||
return s.s.Close()
|
||||
}
|
||||
|
||||
func (s *metricService) IsClosed() bool {
|
||||
select {
|
||||
case <-s.cclose:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -102,16 +102,6 @@ func (s *defaultService) Addr() net.Addr {
|
||||
return s.listener.Addr()
|
||||
}
|
||||
|
||||
func (s *defaultService) Close() error {
|
||||
s.execCmds("pre-down", s.options.preDown)
|
||||
defer s.execCmds("post-down", s.options.postDown)
|
||||
|
||||
if closer, ok := s.handler.(io.Closer); ok {
|
||||
closer.Close()
|
||||
}
|
||||
return s.listener.Close()
|
||||
}
|
||||
|
||||
func (s *defaultService) Serve() error {
|
||||
s.execCmds("post-up", s.options.postUp)
|
||||
|
||||
@ -201,6 +191,16 @@ func (s *defaultService) Serve() error {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *defaultService) Close() error {
|
||||
s.execCmds("pre-down", s.options.preDown)
|
||||
defer s.execCmds("post-down", s.options.postDown)
|
||||
|
||||
if closer, ok := s.handler.(io.Closer); ok {
|
||||
closer.Close()
|
||||
}
|
||||
return s.listener.Close()
|
||||
}
|
||||
|
||||
func (s *defaultService) execCmds(phase string, cmds []string) {
|
||||
for _, cmd := range cmds {
|
||||
cmd := strings.TrimSpace(cmd)
|
||||
|
Loading…
Reference in New Issue
Block a user