diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 72186658..462e3356 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -18,6 +18,7 @@ jobs: - uses: actions/setup-go@v5 with: go-version: '1.22' + cache: false - name: golangci-lint uses: golangci/golangci-lint-action@v4 with: diff --git a/client/admin_api.go b/client/admin_api.go index 5e4d67c6..e15fc4a4 100644 --- a/client/admin_api.go +++ b/client/admin_api.go @@ -15,19 +15,17 @@ package client import ( + "cmp" "encoding/json" "fmt" "io" "net" "net/http" "os" - "sort" + "slices" "strconv" - "strings" "time" - "github.com/samber/lo" - "github.com/fatedier/frp/client/proxy" "github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/config/v1/validation" @@ -153,7 +151,7 @@ func NewProxyStatusResp(status *proxy.WorkingStatus, serverAddr string) ProxySta if status.Err == "" { psr.RemoteAddr = status.RemoteAddr - if lo.Contains([]string{"tcp", "udp"}, status.Type) { + if slices.Contains([]string{"tcp", "udp"}, status.Type) { psr.RemoteAddr = serverAddr + psr.RemoteAddr } } @@ -190,8 +188,8 @@ func (svr *Service) apiStatus(w http.ResponseWriter, _ *http.Request) { if len(arrs) <= 1 { continue } - sort.Slice(arrs, func(i, j int) bool { - return strings.Compare(arrs[i].Name, arrs[j].Name) < 0 + slices.SortFunc(arrs, func(a, b ProxyStatusResp) int { + return cmp.Compare(a.Name, b.Name) }) } } diff --git a/cmd/frpc/sub/proxy.go b/cmd/frpc/sub/proxy.go index 96050943..c5d76b1e 100644 --- a/cmd/frpc/sub/proxy.go +++ b/cmd/frpc/sub/proxy.go @@ -17,8 +17,8 @@ package sub import ( "fmt" "os" + "slices" - "github.com/samber/lo" "github.com/spf13/cobra" "github.com/fatedier/frp/pkg/config" @@ -55,7 +55,7 @@ func init() { config.RegisterProxyFlags(cmd, c) // add sub command for visitor - if lo.Contains(visitorTypes, v1.VisitorType(typ)) { + if slices.Contains(visitorTypes, v1.VisitorType(typ)) { vc := v1.NewVisitorConfigurerByType(v1.VisitorType(typ)) if vc == nil { panic("visitor type: " + typ + " not support") diff --git a/go.mod b/go.mod index ee9b73ac..90cedc2c 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/prometheus/client_golang v1.16.0 github.com/quic-go/quic-go v0.41.0 github.com/rodaine/table v1.1.0 - github.com/samber/lo v1.38.1 + github.com/samber/lo v1.39.0 github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.4 diff --git a/go.sum b/go.sum index e77c5cf7..a4f7aaf1 100644 --- a/go.sum +++ b/go.sum @@ -125,8 +125,8 @@ github.com/rodaine/table v1.1.0/go.mod h1:Qu3q5wi1jTQD6B6HsP6szie/S4w1QUQ8pq22pz github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= -github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= +github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= +github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= diff --git a/pkg/auth/oidc.go b/pkg/auth/oidc.go index f428a04d..d87420ff 100644 --- a/pkg/auth/oidc.go +++ b/pkg/auth/oidc.go @@ -17,9 +17,9 @@ package auth import ( "context" "fmt" + "slices" "github.com/coreos/go-oidc/v3/oidc" - "github.com/samber/lo" "golang.org/x/oauth2/clientcredentials" v1 "github.com/fatedier/frp/pkg/config/v1" @@ -70,7 +70,7 @@ func (auth *OidcAuthProvider) SetLogin(loginMsg *msg.Login) (err error) { } func (auth *OidcAuthProvider) SetPing(pingMsg *msg.Ping) (err error) { - if !lo.Contains(auth.additionalAuthScopes, v1.AuthScopeHeartBeats) { + if !slices.Contains(auth.additionalAuthScopes, v1.AuthScopeHeartBeats) { return nil } @@ -79,7 +79,7 @@ func (auth *OidcAuthProvider) SetPing(pingMsg *msg.Ping) (err error) { } func (auth *OidcAuthProvider) SetNewWorkConn(newWorkConnMsg *msg.NewWorkConn) (err error) { - if !lo.Contains(auth.additionalAuthScopes, v1.AuthScopeNewWorkConns) { + if !slices.Contains(auth.additionalAuthScopes, v1.AuthScopeNewWorkConns) { return nil } @@ -135,7 +135,7 @@ func (auth *OidcAuthConsumer) verifyPostLoginToken(privilegeKey string) (err err } func (auth *OidcAuthConsumer) VerifyPing(pingMsg *msg.Ping) (err error) { - if !lo.Contains(auth.additionalAuthScopes, v1.AuthScopeHeartBeats) { + if !slices.Contains(auth.additionalAuthScopes, v1.AuthScopeHeartBeats) { return nil } @@ -143,7 +143,7 @@ func (auth *OidcAuthConsumer) VerifyPing(pingMsg *msg.Ping) (err error) { } func (auth *OidcAuthConsumer) VerifyNewWorkConn(newWorkConnMsg *msg.NewWorkConn) (err error) { - if !lo.Contains(auth.additionalAuthScopes, v1.AuthScopeNewWorkConns) { + if !slices.Contains(auth.additionalAuthScopes, v1.AuthScopeNewWorkConns) { return nil } diff --git a/pkg/auth/token.go b/pkg/auth/token.go index 0b34b05e..9ee993f9 100644 --- a/pkg/auth/token.go +++ b/pkg/auth/token.go @@ -16,10 +16,9 @@ package auth import ( "fmt" + "slices" "time" - "github.com/samber/lo" - v1 "github.com/fatedier/frp/pkg/config/v1" "github.com/fatedier/frp/pkg/msg" "github.com/fatedier/frp/pkg/util/util" @@ -43,7 +42,7 @@ func (auth *TokenAuthSetterVerifier) SetLogin(loginMsg *msg.Login) error { } func (auth *TokenAuthSetterVerifier) SetPing(pingMsg *msg.Ping) error { - if !lo.Contains(auth.additionalAuthScopes, v1.AuthScopeHeartBeats) { + if !slices.Contains(auth.additionalAuthScopes, v1.AuthScopeHeartBeats) { return nil } @@ -53,7 +52,7 @@ func (auth *TokenAuthSetterVerifier) SetPing(pingMsg *msg.Ping) error { } func (auth *TokenAuthSetterVerifier) SetNewWorkConn(newWorkConnMsg *msg.NewWorkConn) error { - if !lo.Contains(auth.additionalAuthScopes, v1.AuthScopeNewWorkConns) { + if !slices.Contains(auth.additionalAuthScopes, v1.AuthScopeNewWorkConns) { return nil } @@ -70,7 +69,7 @@ func (auth *TokenAuthSetterVerifier) VerifyLogin(m *msg.Login) error { } func (auth *TokenAuthSetterVerifier) VerifyPing(m *msg.Ping) error { - if !lo.Contains(auth.additionalAuthScopes, v1.AuthScopeHeartBeats) { + if !slices.Contains(auth.additionalAuthScopes, v1.AuthScopeHeartBeats) { return nil } @@ -81,7 +80,7 @@ func (auth *TokenAuthSetterVerifier) VerifyPing(m *msg.Ping) error { } func (auth *TokenAuthSetterVerifier) VerifyNewWorkConn(m *msg.NewWorkConn) error { - if !lo.Contains(auth.additionalAuthScopes, v1.AuthScopeNewWorkConns) { + if !slices.Contains(auth.additionalAuthScopes, v1.AuthScopeNewWorkConns) { return nil } diff --git a/pkg/config/legacy/client.go b/pkg/config/legacy/client.go index 50f62bef..b45ed069 100644 --- a/pkg/config/legacy/client.go +++ b/pkg/config/legacy/client.go @@ -18,9 +18,9 @@ import ( "fmt" "os" "path/filepath" + "slices" "strings" - "github.com/samber/lo" "gopkg.in/ini.v1" legacyauth "github.com/fatedier/frp/pkg/auth/legacy" @@ -399,7 +399,7 @@ func (cfg *ClientCommonConf) Validate() error { } } - if !lo.Contains([]string{"tcp", "kcp", "quic", "websocket", "wss"}, cfg.Protocol) { + if !slices.Contains([]string{"tcp", "kcp", "quic", "websocket", "wss"}, cfg.Protocol) { return fmt.Errorf("invalid protocol") } diff --git a/pkg/config/v1/validation/client.go b/pkg/config/v1/validation/client.go index 16fc4ccb..cc46607c 100644 --- a/pkg/config/v1/validation/client.go +++ b/pkg/config/v1/validation/client.go @@ -18,6 +18,7 @@ import ( "fmt" "os" "path/filepath" + "slices" "github.com/samber/lo" @@ -29,7 +30,7 @@ func ValidateClientCommonConfig(c *v1.ClientCommonConfig) (Warning, error) { warnings Warning errs error ) - if !lo.Contains(SupportedAuthMethods, c.Auth.Method) { + if !slices.Contains(SupportedAuthMethods, c.Auth.Method) { errs = AppendError(errs, fmt.Errorf("invalid auth method, optional values are %v", SupportedAuthMethods)) } if !lo.Every(SupportedAuthAdditionalScopes, c.Auth.AdditionalScopes) { @@ -63,7 +64,7 @@ func ValidateClientCommonConfig(c *v1.ClientCommonConfig) (Warning, error) { warnings = AppendError(warnings, checkTLSConfig("transport.tls.trustedCaFile", c.Transport.TLS.TrustedCaFile)) } - if !lo.Contains(SupportedTransportProtocols, c.Transport.Protocol) { + if !slices.Contains(SupportedTransportProtocols, c.Transport.Protocol) { errs = AppendError(errs, fmt.Errorf("invalid transport.protocol, optional values are %v", SupportedTransportProtocols)) } diff --git a/pkg/config/v1/validation/common.go b/pkg/config/v1/validation/common.go index c159e270..c7b93a32 100644 --- a/pkg/config/v1/validation/common.go +++ b/pkg/config/v1/validation/common.go @@ -16,8 +16,7 @@ package validation import ( "fmt" - - "github.com/samber/lo" + "slices" v1 "github.com/fatedier/frp/pkg/config/v1" ) @@ -44,7 +43,7 @@ func ValidatePort(port int, fieldPath string) error { } func validateLogConfig(c *v1.LogConfig) error { - if !lo.Contains(SupportedLogLevels, c.Level) { + if !slices.Contains(SupportedLogLevels, c.Level) { return fmt.Errorf("invalid log level, optional values are %v", SupportedLogLevels) } return nil diff --git a/pkg/config/v1/validation/proxy.go b/pkg/config/v1/validation/proxy.go index 343e6133..d8e3d01e 100644 --- a/pkg/config/v1/validation/proxy.go +++ b/pkg/config/v1/validation/proxy.go @@ -17,9 +17,9 @@ package validation import ( "errors" "fmt" + "slices" "strings" - "github.com/samber/lo" "k8s.io/apimachinery/pkg/util/validation" v1 "github.com/fatedier/frp/pkg/config/v1" @@ -33,10 +33,10 @@ func validateProxyBaseConfigForClient(c *v1.ProxyBaseConfig) error { if err := ValidateAnnotations(c.Annotations); err != nil { return err } - if !lo.Contains([]string{"", "v1", "v2"}, c.Transport.ProxyProtocolVersion) { + if !slices.Contains([]string{"", "v1", "v2"}, c.Transport.ProxyProtocolVersion) { return fmt.Errorf("not support proxy protocol version: %s", c.Transport.ProxyProtocolVersion) } - if !lo.Contains([]string{"client", "server"}, c.Transport.BandwidthLimitMode) { + if !slices.Contains([]string{"client", "server"}, c.Transport.BandwidthLimitMode) { return fmt.Errorf("bandwidth limit mode should be client or server") } @@ -46,7 +46,7 @@ func validateProxyBaseConfigForClient(c *v1.ProxyBaseConfig) error { } } - if !lo.Contains([]string{"", "tcp", "http"}, c.HealthCheck.Type) { + if !slices.Contains([]string{"", "tcp", "http"}, c.HealthCheck.Type) { return fmt.Errorf("not support health check type: %s", c.HealthCheck.Type) } if c.HealthCheck.Type != "" { @@ -139,7 +139,7 @@ func validateTCPMuxProxyConfigForClient(c *v1.TCPMuxProxyConfig) error { return err } - if !lo.Contains([]string{string(v1.TCPMultiplexerHTTPConnect)}, c.Multiplexer) { + if !slices.Contains([]string{string(v1.TCPMultiplexerHTTPConnect)}, c.Multiplexer) { return fmt.Errorf("not support multiplexer: %s", c.Multiplexer) } return nil diff --git a/pkg/config/v1/validation/server.go b/pkg/config/v1/validation/server.go index 5f17d6c7..cdb80ea3 100644 --- a/pkg/config/v1/validation/server.go +++ b/pkg/config/v1/validation/server.go @@ -16,6 +16,7 @@ package validation import ( "fmt" + "slices" "github.com/samber/lo" @@ -27,7 +28,7 @@ func ValidateServerConfig(c *v1.ServerConfig) (Warning, error) { warnings Warning errs error ) - if !lo.Contains(SupportedAuthMethods, c.Auth.Method) { + if !slices.Contains(SupportedAuthMethods, c.Auth.Method) { errs = AppendError(errs, fmt.Errorf("invalid auth method, optional values are %v", SupportedAuthMethods)) } if !lo.Every(SupportedAuthAdditionalScopes, c.Auth.AdditionalScopes) { diff --git a/pkg/config/v1/validation/visitor.go b/pkg/config/v1/validation/visitor.go index 5307dc90..50efc47d 100644 --- a/pkg/config/v1/validation/visitor.go +++ b/pkg/config/v1/validation/visitor.go @@ -17,8 +17,7 @@ package validation import ( "errors" "fmt" - - "github.com/samber/lo" + "slices" v1 "github.com/fatedier/frp/pkg/config/v1" ) @@ -56,7 +55,7 @@ func validateVisitorBaseConfig(c *v1.VisitorBaseConfig) error { } func validateXTCPVisitorConfig(c *v1.XTCPVisitorConfig) error { - if !lo.Contains([]string{"kcp", "quic"}, c.Protocol) { + if !slices.Contains([]string{"kcp", "quic"}, c.Protocol) { return fmt.Errorf("protocol should be kcp or quic") } return nil diff --git a/pkg/nathole/analysis.go b/pkg/nathole/analysis.go index eb44d6d9..6be0be55 100644 --- a/pkg/nathole/analysis.go +++ b/pkg/nathole/analysis.go @@ -15,6 +15,8 @@ package nathole import ( + "cmp" + "slices" "sync" "time" @@ -233,12 +235,12 @@ func (mhr *MakeHoleRecords) Recommand() (mode, index int) { mhr.mu.Lock() defer mhr.mu.Unlock() - maxScore := lo.MaxBy(mhr.scores, func(item, max *BehaviorScore) bool { - return item.Score > max.Score - }) - if maxScore == nil { + if len(mhr.scores) == 0 { return 0, 0 } + maxScore := slices.MaxFunc(mhr.scores, func(a, b *BehaviorScore) int { + return cmp.Compare(a.Score, b.Score) + }) maxScore.Score-- mhr.LastUpdateTime = time.Now() return maxScore.Mode, maxScore.Index diff --git a/pkg/nathole/classify.go b/pkg/nathole/classify.go index 1ec5952b..5abb0e23 100644 --- a/pkg/nathole/classify.go +++ b/pkg/nathole/classify.go @@ -17,9 +17,8 @@ package nathole import ( "fmt" "net" + "slices" "strconv" - - "github.com/samber/lo" ) const ( @@ -59,7 +58,7 @@ func ClassifyNATFeature(addresses []string, localIPs []string) (*NatFeature, err if err != nil { return nil, err } - if lo.Contains(localIPs, ip) { + if slices.Contains(localIPs, ip) { natFeature.PublicNetwork = true } diff --git a/pkg/nathole/controller.go b/pkg/nathole/controller.go index 03c05b35..9c558326 100644 --- a/pkg/nathole/controller.go +++ b/pkg/nathole/controller.go @@ -20,6 +20,7 @@ import ( "encoding/hex" "fmt" "net" + "slices" "strconv" "sync" "time" @@ -72,7 +73,7 @@ type Session struct { func (s *Session) genAnalysisKey() { hash := md5.New() - vIPs := lo.Uniq(parseIPs(s.visitorMsg.MappedAddrs)) + vIPs := slices.Compact(parseIPs(s.visitorMsg.MappedAddrs)) if len(vIPs) > 0 { hash.Write([]byte(vIPs[0])) } @@ -80,7 +81,7 @@ func (s *Session) genAnalysisKey() { hash.Write([]byte(s.vNatFeature.Behavior)) hash.Write([]byte(strconv.FormatBool(s.vNatFeature.RegularPortsChange))) - cIPs := lo.Uniq(parseIPs(s.clientMsg.MappedAddrs)) + cIPs := slices.Compact(parseIPs(s.clientMsg.MappedAddrs)) if len(cIPs) > 0 { hash.Write([]byte(cIPs[0])) } @@ -156,7 +157,7 @@ func (c *Controller) HandleVisitor(m *msg.NatHoleVisitor, transporter transport. _ = transporter.Send(c.GenNatHoleResponse(m.TransactionID, nil, fmt.Sprintf("xtcp server for [%s] doesn't exist", m.ProxyName))) return } - if !lo.Contains(cfg.allowUsers, visitorUser) && !lo.Contains(cfg.allowUsers, "*") { + if !slices.Contains(cfg.allowUsers, visitorUser) && !slices.Contains(cfg.allowUsers, "*") { _ = transporter.Send(c.GenNatHoleResponse(m.TransactionID, nil, fmt.Sprintf("xtcp visitor user [%s] not allowed for [%s]", visitorUser, m.ProxyName))) return } @@ -327,8 +328,8 @@ func (c *Controller) analysis(session *Session) (*msg.NatHoleResp, *msg.NatHoleR TransactionID: vm.TransactionID, Sid: session.sid, Protocol: protocol, - CandidateAddrs: lo.Uniq(cm.MappedAddrs), - AssistedAddrs: lo.Uniq(cm.AssistedAddrs), + CandidateAddrs: slices.Compact(cm.MappedAddrs), + AssistedAddrs: slices.Compact(cm.AssistedAddrs), DetectBehavior: msg.NatHoleDetectBehavior{ Mode: mode, Role: vBehavior.Role, @@ -344,8 +345,8 @@ func (c *Controller) analysis(session *Session) (*msg.NatHoleResp, *msg.NatHoleR TransactionID: cm.TransactionID, Sid: session.sid, Protocol: protocol, - CandidateAddrs: lo.Uniq(vm.MappedAddrs), - AssistedAddrs: lo.Uniq(vm.AssistedAddrs), + CandidateAddrs: slices.Compact(vm.MappedAddrs), + AssistedAddrs: slices.Compact(vm.AssistedAddrs), DetectBehavior: msg.NatHoleDetectBehavior{ Mode: mode, Role: cBehavior.Role, diff --git a/pkg/nathole/nathole.go b/pkg/nathole/nathole.go index c10eb30d..065d0eb4 100644 --- a/pkg/nathole/nathole.go +++ b/pkg/nathole/nathole.go @@ -19,12 +19,12 @@ import ( "fmt" "math/rand" "net" + "slices" "strconv" "strings" "time" "github.com/fatedier/golib/pool" - "github.com/samber/lo" "golang.org/x/net/ipv4" "k8s.io/apimachinery/pkg/util/sets" @@ -212,7 +212,7 @@ func MakeHole(ctx context.Context, listenConn *net.UDPConn, m *msg.NatHoleResp, } } - detectAddrs = lo.Uniq(detectAddrs) + detectAddrs = slices.Compact(detectAddrs) for _, detectAddr := range detectAddrs { for _, conn := range listenConns { if err := sendSidMessage(ctx, conn, m.Sid, transactionID, detectAddr, key, m.DetectBehavior.TTL); err != nil { @@ -377,7 +377,7 @@ func sendSidMessageToRangePorts( sendFunc func(*net.UDPConn, string) error, ) { xl := xlog.FromContextSafe(ctx) - for _, ip := range lo.Uniq(parseIPs(addrs)) { + for _, ip := range slices.Compact(parseIPs(addrs)) { for _, portsRange := range ports { for i := portsRange.From; i <= portsRange.To; i++ { detectAddr := net.JoinHostPort(ip, strconv.Itoa(i)) @@ -419,7 +419,7 @@ func sendSidMessageToRandomPorts( continue } - for _, ip := range lo.Uniq(parseIPs(addrs)) { + for _, ip := range slices.Compact(parseIPs(addrs)) { detectAddr := net.JoinHostPort(ip, strconv.Itoa(port)) if err := sendFunc(conn, detectAddr); err != nil { xl.Trace("send sid message from %s to %s error: %v", conn.LocalAddr(), detectAddr, err) diff --git a/pkg/ssh/server.go b/pkg/ssh/server.go index f3d68f3c..7fb93c34 100644 --- a/pkg/ssh/server.go +++ b/pkg/ssh/server.go @@ -20,12 +20,12 @@ import ( "errors" "fmt" "net" + "slices" "strings" "sync" "time" libio "github.com/fatedier/golib/io" - "github.com/samber/lo" "github.com/spf13/cobra" flag "github.com/spf13/pflag" "golang.org/x/crypto/ssh" @@ -262,7 +262,7 @@ func (s *TunnelServer) parseClientAndProxyConfigurer(_ *tcpipForward, extraPaylo } proxyType := strings.TrimSpace(args[0]) supportTypes := []string{"tcp", "http", "https", "tcpmux", "stcp"} - if !lo.Contains(supportTypes, proxyType) { + if !slices.Contains(supportTypes, proxyType) { return nil, nil, helpMessage, fmt.Errorf("invalid proxy type: %s, support types: %v", proxyType, supportTypes) } pc := v1.NewProxyConfigurerByType(v1.ProxyType(proxyType)) diff --git a/pkg/util/vhost/router.go b/pkg/util/vhost/router.go index e8e5a53f..4df79aa7 100644 --- a/pkg/util/vhost/router.go +++ b/pkg/util/vhost/router.go @@ -1,8 +1,9 @@ package vhost import ( + "cmp" "errors" - "sort" + "slices" "strings" "sync" ) @@ -58,7 +59,10 @@ func (r *Routers) Add(domain, location, httpUser string, payload interface{}) er payload: payload, } vrs = append(vrs, vr) - sort.Sort(sort.Reverse(ByLocation(vrs))) + + slices.SortFunc(vrs, func(a, b *Router) int { + return -cmp.Compare(a.location, b.location) + }) routersByHTTPUser[httpUser] = vrs r.indexByDomain[domain] = routersByHTTPUser @@ -130,18 +134,3 @@ func (r *Routers) exist(host, path, httpUser string) (route *Router, exist bool) } return } - -// sort by location -type ByLocation []*Router - -func (a ByLocation) Len() int { - return len(a) -} - -func (a ByLocation) Swap(i, j int) { - a[i], a[j] = a[j], a[i] -} - -func (a ByLocation) Less(i, j int) bool { - return strings.Compare(a[i].location, a[j].location) < 0 -} diff --git a/pkg/util/xlog/xlog.go b/pkg/util/xlog/xlog.go index 7b69dcaf..56b07522 100644 --- a/pkg/util/xlog/xlog.go +++ b/pkg/util/xlog/xlog.go @@ -15,7 +15,8 @@ package xlog import ( - "sort" + "cmp" + "slices" "github.com/fatedier/frp/pkg/util/log" ) @@ -77,8 +78,8 @@ func (l *Logger) AddPrefix(prefix LogPrefix) *Logger { } func (l *Logger) renderPrefixString() { - sort.SliceStable(l.prefixes, func(i, j int) bool { - return l.prefixes[i].Priority < l.prefixes[j].Priority + slices.SortStableFunc(l.prefixes, func(a, b LogPrefix) int { + return cmp.Compare(a.Priority, b.Priority) }) l.prefixString = "" for _, v := range l.prefixes { diff --git a/server/dashboard_api.go b/server/dashboard_api.go index 1b0087b4..9ecd5a7c 100644 --- a/server/dashboard_api.go +++ b/server/dashboard_api.go @@ -15,9 +15,10 @@ package server import ( + "cmp" "encoding/json" "net/http" - "sort" + "slices" "github.com/gorilla/mux" "github.com/prometheus/client_golang/prometheus/promhttp" @@ -228,8 +229,8 @@ func (svr *Service) apiProxyByType(w http.ResponseWriter, r *http.Request) { proxyInfoResp := GetProxyInfoResp{} proxyInfoResp.Proxies = svr.getProxyStatsByType(proxyType) - sort.Slice(proxyInfoResp.Proxies, func(i, j int) bool { - return proxyInfoResp.Proxies[i].Name < proxyInfoResp.Proxies[j].Name + slices.SortFunc(proxyInfoResp.Proxies, func(a, b *ProxyStatsInfo) int { + return cmp.Compare(a.Name, b.Name) }) buf, _ := json.Marshal(&proxyInfoResp) diff --git a/server/visitor/visitor.go b/server/visitor/visitor.go index ed06dc4b..57194d98 100644 --- a/server/visitor/visitor.go +++ b/server/visitor/visitor.go @@ -18,10 +18,10 @@ import ( "fmt" "io" "net" + "slices" "sync" libio "github.com/fatedier/golib/io" - "github.com/samber/lo" netpkg "github.com/fatedier/frp/pkg/util/net" "github.com/fatedier/frp/pkg/util/util" @@ -75,7 +75,7 @@ func (vm *Manager) NewConn(name string, conn net.Conn, timestamp int64, signKey return } - if !lo.Contains(l.allowUsers, visitorUser) && !lo.Contains(l.allowUsers, "*") { + if !slices.Contains(l.allowUsers, visitorUser) && !slices.Contains(l.allowUsers, "*") { err = fmt.Errorf("visitor connection of [%s] user [%s] not allowed", name, visitorUser) return }