mirror of
https://github.com/fatedier/frp.git
synced 2025-04-23 17:01:27 +00:00
commit
31b44c1feb
@ -2,7 +2,7 @@ version: 2
|
||||
jobs:
|
||||
go-version-latest:
|
||||
docker:
|
||||
- image: cimg/go:1.22-node
|
||||
- image: cimg/go:1.23-node
|
||||
resource_class: large
|
||||
steps:
|
||||
- checkout
|
||||
|
8
.github/workflows/stale.yml
vendored
8
.github/workflows/stale.yml
vendored
@ -21,14 +21,14 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
stale-issue-message: 'Issues go stale after 21d of inactivity. Stale issues rot after an additional 7d of inactivity and eventually close.'
|
||||
stale-pr-message: "PRs go stale after 21d of inactivity. Stale PRs rot after an additional 7d of inactivity and eventually close."
|
||||
stale-issue-message: 'Issues go stale after 14d of inactivity. Stale issues rot after an additional 3d of inactivity and eventually close.'
|
||||
stale-pr-message: "PRs go stale after 14d of inactivity. Stale PRs rot after an additional 3d of inactivity and eventually close."
|
||||
stale-issue-label: 'lifecycle/stale'
|
||||
exempt-issue-labels: 'bug,doc,enhancement,future,proposal,question,testing,todo,easy,help wanted,assigned'
|
||||
stale-pr-label: 'lifecycle/stale'
|
||||
exempt-pr-labels: 'bug,doc,enhancement,future,proposal,question,testing,todo,easy,help wanted,assigned'
|
||||
days-before-stale: 21
|
||||
days-before-close: 7
|
||||
days-before-stale: 14
|
||||
days-before-close: 3
|
||||
debug-only: ${{ github.event.inputs.debug-only }}
|
||||
exempt-all-pr-milestones: true
|
||||
exempt-all-pr-assignees: true
|
||||
|
@ -48,7 +48,8 @@ linters-settings:
|
||||
check-blank: false
|
||||
govet:
|
||||
# report about shadowed variables
|
||||
check-shadowing: false
|
||||
disable:
|
||||
- shadow
|
||||
maligned:
|
||||
# print struct with more effective memory layout or not, false by default
|
||||
suggest-new: true
|
||||
|
@ -97,7 +97,7 @@ frp also offers a P2P connect mode.
|
||||
* [Client Plugins](#client-plugins)
|
||||
* [Server Manage Plugins](#server-manage-plugins)
|
||||
* [SSH Tunnel Gateway](#ssh-tunnel-gateway)
|
||||
* [Releated Projects](#releated-projects)
|
||||
* [Related Projects](#related-projects)
|
||||
* [Contributing](#contributing)
|
||||
* [Donation](#donation)
|
||||
* [GitHub Sponsors](#github-sponsors)
|
||||
@ -1260,7 +1260,7 @@ frpc tcp --proxy_name "test-tcp" --local_ip 127.0.0.1 --local_port 8080 --remote
|
||||
|
||||
Please refer to this [document](/doc/ssh_tunnel_gateway.md) for more information.
|
||||
|
||||
## Releated Projects
|
||||
## Related Projects
|
||||
|
||||
* [gofrp/plugin](https://github.com/gofrp/plugin) - A repository for frp plugins that contains a variety of plugins implemented based on the frp extension mechanism, meeting the customization needs of different scenarios.
|
||||
* [gofrp/tiny-frpc](https://github.com/gofrp/tiny-frpc) - A lightweight version of the frp client (around 3.5MB at minimum) implemented using the ssh protocol, supporting some of the most commonly used features, suitable for devices with limited resources.
|
||||
|
@ -1,5 +1,7 @@
|
||||
### Features
|
||||
|
||||
* `tzdata` is installed by default in the container image, and the time zone can be set using the `TZ` environment variable.
|
||||
* The `quic-bind-port` command line parameter is supported in frps, which specifies the port for accepting frpc connections using the QUIC protocol.
|
||||
* The vhost HTTP proxy of frps supports the h2c protocol.
|
||||
* Support metadatas and annotations in frpc proxy commands.
|
||||
|
||||
### Fixes
|
||||
|
||||
* Properly release resources in service.Close() to prevent resource leaks when used as a library.
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
|
||||
var ErrPayloadType = errors.New("error payload type")
|
||||
|
||||
type Handler func(payload interface{}) error
|
||||
type Handler func(payload any) error
|
||||
|
||||
type StartProxyPayload struct {
|
||||
NewProxyMsg *msg.NewProxy
|
||||
|
@ -96,7 +96,7 @@ func (pm *Manager) HandleWorkConn(name string, workConn net.Conn, m *msg.StartWo
|
||||
}
|
||||
}
|
||||
|
||||
func (pm *Manager) HandleEvent(payload interface{}) error {
|
||||
func (pm *Manager) HandleEvent(payload any) error {
|
||||
var m msg.Message
|
||||
switch e := payload.(type) {
|
||||
case *event.StartProxyPayload:
|
||||
|
4
go.mod
4
go.mod
@ -1,11 +1,11 @@
|
||||
module github.com/fatedier/frp
|
||||
|
||||
go 1.22.0
|
||||
go 1.23.0
|
||||
|
||||
require (
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5
|
||||
github.com/coreos/go-oidc/v3 v3.10.0
|
||||
github.com/fatedier/golib v0.5.0
|
||||
github.com/fatedier/golib v0.5.1
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
|
4
go.sum
4
go.sum
@ -21,8 +21,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatedier/golib v0.5.0 h1:hNcH7hgfIFqVWbP+YojCCAj4eO94pPf4dEF8lmq2jWs=
|
||||
github.com/fatedier/golib v0.5.0/go.mod h1:W6kIYkIFxHsTzbgqg5piCxIiDo4LzwgTY6R5W8l9NFQ=
|
||||
github.com/fatedier/golib v0.5.1 h1:hcKAnaw5mdI/1KWRGejxR+i1Hn/NvbY5UsMKDr7o13M=
|
||||
github.com/fatedier/golib v0.5.1/go.mod h1:W6kIYkIFxHsTzbgqg5piCxIiDo4LzwgTY6R5W8l9NFQ=
|
||||
github.com/fatedier/yamux v0.0.0-20230628132301-7aca4898904d h1:ynk1ra0RUqDWQfvFi5KtMiSobkVQ3cNc0ODb8CfIETo=
|
||||
github.com/fatedier/yamux v0.0.0-20230628132301-7aca4898904d/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
|
||||
github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U=
|
||||
|
@ -106,6 +106,8 @@ func registerProxyBaseConfigFlags(cmd *cobra.Command, c *v1.ProxyBaseConfig, opt
|
||||
}
|
||||
|
||||
cmd.Flags().StringVarP(&c.Name, "proxy_name", "n", "", "proxy name")
|
||||
cmd.Flags().StringToStringVarP(&c.Metadatas, "metadatas", "", nil, "metadata key-value pairs (e.g., key1=value1,key2=value2)")
|
||||
cmd.Flags().StringToStringVarP(&c.Annotations, "annotations", "", nil, "annotation key-value pairs (e.g., key1=value1,key2=value2)")
|
||||
|
||||
if !options.sshMode {
|
||||
cmd.Flags().StringVarP(&c.LocalIP, "local_ip", "i", "127.0.0.1", "local ip")
|
||||
|
@ -170,7 +170,7 @@ type ClientCommonConf struct {
|
||||
}
|
||||
|
||||
// Supported sources including: string(file path), []byte, Reader interface.
|
||||
func UnmarshalClientConfFromIni(source interface{}) (ClientCommonConf, error) {
|
||||
func UnmarshalClientConfFromIni(source any) (ClientCommonConf, error) {
|
||||
f, err := ini.LoadSources(ini.LoadOptions{
|
||||
Insensitive: false,
|
||||
InsensitiveSections: false,
|
||||
@ -203,7 +203,7 @@ func UnmarshalClientConfFromIni(source interface{}) (ClientCommonConf, error) {
|
||||
// otherwise just start proxies in startProxy map
|
||||
func LoadAllProxyConfsFromIni(
|
||||
prefix string,
|
||||
source interface{},
|
||||
source any,
|
||||
start []string,
|
||||
) (map[string]ProxyConf, map[string]VisitorConf, error) {
|
||||
f, err := ini.LoadSources(ini.LoadOptions{
|
||||
|
@ -217,7 +217,7 @@ func GetDefaultServerConf() ServerCommonConf {
|
||||
}
|
||||
}
|
||||
|
||||
func UnmarshalServerConfFromIni(source interface{}) (ServerCommonConf, error) {
|
||||
func UnmarshalServerConfFromIni(source any) (ServerCommonConf, error) {
|
||||
f, err := ini.LoadSources(ini.LoadOptions{
|
||||
Insensitive: false,
|
||||
InsensitiveSections: false,
|
||||
|
@ -18,10 +18,10 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
toml "github.com/pelletier/go-toml/v2"
|
||||
"github.com/samber/lo"
|
||||
@ -118,7 +118,7 @@ func LoadConfigure(b []byte, c any, strict bool) error {
|
||||
defer v1.DisallowUnknownFieldsMu.Unlock()
|
||||
v1.DisallowUnknownFields = strict
|
||||
|
||||
var tomlObj interface{}
|
||||
var tomlObj any
|
||||
// Try to unmarshal as TOML first; swallow errors from that (assume it's not valid TOML).
|
||||
if err := toml.Unmarshal(b, &tomlObj); err == nil {
|
||||
b, err = json.Marshal(&tomlObj)
|
||||
|
@ -112,6 +112,29 @@ func TestLoadServerConfigStrictMode(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenderWithTemplate(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
content string
|
||||
want string
|
||||
}{
|
||||
{"toml", tomlServerContent, tomlServerContent},
|
||||
{"yaml", yamlServerContent, yamlServerContent},
|
||||
{"json", jsonServerContent, jsonServerContent},
|
||||
{"template numeric", `key = {{ 123 }}`, "key = 123"},
|
||||
{"template string", `key = {{ "xyz" }}`, "key = xyz"},
|
||||
{"template quote", `key = {{ printf "%q" "with space" }}`, `key = "with space"`},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
got, err := RenderWithTemplate([]byte(test.content), nil)
|
||||
require.NoError(err)
|
||||
require.EqualValues(test.want, string(got))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCustomStructStrictMode(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
|
@ -39,6 +39,6 @@ func ReadMsgInto(c io.Reader, msg Message) (err error) {
|
||||
return msgCtl.ReadMsgInto(c, msg)
|
||||
}
|
||||
|
||||
func WriteMsg(c io.Writer, msg interface{}) (err error) {
|
||||
func WriteMsg(c io.Writer, msg any) (err error) {
|
||||
return msgCtl.WriteMsg(c, msg)
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ const (
|
||||
TypeNatHoleReport = '6'
|
||||
)
|
||||
|
||||
var msgTypeMap = map[byte]interface{}{
|
||||
var msgTypeMap = map[byte]any{
|
||||
TypeLogin: Login{},
|
||||
TypeLoginResp: LoginResp{},
|
||||
TypeNewProxy: NewProxy{},
|
||||
|
@ -72,7 +72,7 @@ func (p *httpPlugin) IsSupport(op string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *httpPlugin) Handle(ctx context.Context, op string, content interface{}) (*Response, interface{}, error) {
|
||||
func (p *httpPlugin) Handle(ctx context.Context, op string, content any) (*Response, any, error) {
|
||||
r := &Request{
|
||||
Version: APIVersion,
|
||||
Op: op,
|
||||
|
@ -75,7 +75,7 @@ func (m *Manager) Login(content *LoginContent) (*LoginContent, error) {
|
||||
Reject: false,
|
||||
Unchange: true,
|
||||
}
|
||||
retContent interface{}
|
||||
retContent any
|
||||
err error
|
||||
)
|
||||
reqid, _ := util.RandID()
|
||||
@ -109,7 +109,7 @@ func (m *Manager) NewProxy(content *NewProxyContent) (*NewProxyContent, error) {
|
||||
Reject: false,
|
||||
Unchange: true,
|
||||
}
|
||||
retContent interface{}
|
||||
retContent any
|
||||
err error
|
||||
)
|
||||
reqid, _ := util.RandID()
|
||||
@ -168,7 +168,7 @@ func (m *Manager) Ping(content *PingContent) (*PingContent, error) {
|
||||
Reject: false,
|
||||
Unchange: true,
|
||||
}
|
||||
retContent interface{}
|
||||
retContent any
|
||||
err error
|
||||
)
|
||||
reqid, _ := util.RandID()
|
||||
@ -202,7 +202,7 @@ func (m *Manager) NewWorkConn(content *NewWorkConnContent) (*NewWorkConnContent,
|
||||
Reject: false,
|
||||
Unchange: true,
|
||||
}
|
||||
retContent interface{}
|
||||
retContent any
|
||||
err error
|
||||
)
|
||||
reqid, _ := util.RandID()
|
||||
@ -236,7 +236,7 @@ func (m *Manager) NewUserConn(content *NewUserConnContent) (*NewUserConnContent,
|
||||
Reject: false,
|
||||
Unchange: true,
|
||||
}
|
||||
retContent interface{}
|
||||
retContent any
|
||||
err error
|
||||
)
|
||||
reqid, _ := util.RandID()
|
||||
|
@ -32,5 +32,5 @@ const (
|
||||
type Plugin interface {
|
||||
Name() string
|
||||
IsSupport(op string) bool
|
||||
Handle(ctx context.Context, op string, content interface{}) (res *Response, retContent interface{}, err error)
|
||||
Handle(ctx context.Context, op string, content any) (res *Response, retContent any, err error)
|
||||
}
|
||||
|
@ -21,14 +21,14 @@ import (
|
||||
type Request struct {
|
||||
Version string `json:"version"`
|
||||
Op string `json:"op"`
|
||||
Content interface{} `json:"content"`
|
||||
Content any `json:"content"`
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
Reject bool `json:"reject"`
|
||||
RejectReason string `json:"reject_reason"`
|
||||
Unchange bool `json:"unchange"`
|
||||
Content interface{} `json:"content"`
|
||||
Content any `json:"content"`
|
||||
}
|
||||
|
||||
type LoginContent struct {
|
||||
|
@ -112,6 +112,10 @@ func (g *Gateway) Run() {
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Gateway) Close() error {
|
||||
return g.ln.Close()
|
||||
}
|
||||
|
||||
func (g *Gateway) handleConn(conn net.Conn) {
|
||||
defer conn.Close()
|
||||
|
||||
|
@ -67,27 +67,27 @@ func InitLogger(logPath string, levelStr string, maxDays int, disableLogColor bo
|
||||
Logger = Logger.WithOptions(options...)
|
||||
}
|
||||
|
||||
func Errorf(format string, v ...interface{}) {
|
||||
func Errorf(format string, v ...any) {
|
||||
Logger.Errorf(format, v...)
|
||||
}
|
||||
|
||||
func Warnf(format string, v ...interface{}) {
|
||||
func Warnf(format string, v ...any) {
|
||||
Logger.Warnf(format, v...)
|
||||
}
|
||||
|
||||
func Infof(format string, v ...interface{}) {
|
||||
func Infof(format string, v ...any) {
|
||||
Logger.Infof(format, v...)
|
||||
}
|
||||
|
||||
func Debugf(format string, v ...interface{}) {
|
||||
func Debugf(format string, v ...any) {
|
||||
Logger.Debugf(format, v...)
|
||||
}
|
||||
|
||||
func Tracef(format string, v ...interface{}) {
|
||||
func Tracef(format string, v ...any) {
|
||||
Logger.Tracef(format, v...)
|
||||
}
|
||||
|
||||
func Logf(level log.Level, offset int, format string, v ...interface{}) {
|
||||
func Logf(level log.Level, offset int, format string, v ...any) {
|
||||
Logger.Logf(level, offset, format, v...)
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
package version
|
||||
|
||||
var version = "0.61.1"
|
||||
var version = "0.61.2"
|
||||
|
||||
func Full() string {
|
||||
return version
|
||||
|
@ -24,7 +24,7 @@ type Router struct {
|
||||
httpUser string
|
||||
|
||||
// store any object here
|
||||
payload interface{}
|
||||
payload any
|
||||
}
|
||||
|
||||
func NewRouters() *Routers {
|
||||
@ -33,7 +33,7 @@ func NewRouters() *Routers {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Routers) Add(domain, location, httpUser string, payload interface{}) error {
|
||||
func (r *Routers) Add(domain, location, httpUser string, payload any) error {
|
||||
domain = strings.ToLower(domain)
|
||||
|
||||
r.mutex.Lock()
|
||||
|
@ -100,6 +100,10 @@ func (v *Muxer) SetRewriteHostFunc(f hostRewriteFunc) *Muxer {
|
||||
return v
|
||||
}
|
||||
|
||||
func (v *Muxer) Close() error {
|
||||
return v.listener.Close()
|
||||
}
|
||||
|
||||
type ChooseEndpointFunc func() (string, error)
|
||||
|
||||
type CreateConnFunc func(remoteAddr string) (net.Conn, error)
|
||||
|
@ -94,22 +94,22 @@ func (l *Logger) Spawn() *Logger {
|
||||
return nl
|
||||
}
|
||||
|
||||
func (l *Logger) Errorf(format string, v ...interface{}) {
|
||||
func (l *Logger) Errorf(format string, v ...any) {
|
||||
log.Logger.Errorf(l.prefixString+format, v...)
|
||||
}
|
||||
|
||||
func (l *Logger) Warnf(format string, v ...interface{}) {
|
||||
func (l *Logger) Warnf(format string, v ...any) {
|
||||
log.Logger.Warnf(l.prefixString+format, v...)
|
||||
}
|
||||
|
||||
func (l *Logger) Infof(format string, v ...interface{}) {
|
||||
func (l *Logger) Infof(format string, v ...any) {
|
||||
log.Logger.Infof(l.prefixString+format, v...)
|
||||
}
|
||||
|
||||
func (l *Logger) Debugf(format string, v ...interface{}) {
|
||||
func (l *Logger) Debugf(format string, v ...any) {
|
||||
log.Logger.Debugf(l.prefixString+format, v...)
|
||||
}
|
||||
|
||||
func (l *Logger) Tracef(format string, v ...interface{}) {
|
||||
func (l *Logger) Tracef(format string, v ...any) {
|
||||
log.Logger.Tracef(l.prefixString+format, v...)
|
||||
}
|
||||
|
@ -59,3 +59,13 @@ type ResourceController struct {
|
||||
// All server manager plugin
|
||||
PluginManager *plugin.Manager
|
||||
}
|
||||
|
||||
func (rc *ResourceController) Close() error {
|
||||
if rc.VhostHTTPSMuxer != nil {
|
||||
rc.VhostHTTPSMuxer.Close()
|
||||
}
|
||||
if rc.TCPMuxHTTPConnectMuxer != nil {
|
||||
rc.TCPMuxHTTPConnectMuxer.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ func getConfByType(proxyType string) any {
|
||||
// Get proxy info.
|
||||
type ProxyStatsInfo struct {
|
||||
Name string `json:"name"`
|
||||
Conf interface{} `json:"conf"`
|
||||
Conf any `json:"conf"`
|
||||
ClientVersion string `json:"clientVersion,omitempty"`
|
||||
TodayTrafficIn int64 `json:"todayTrafficIn"`
|
||||
TodayTrafficOut int64 `json:"todayTrafficOut"`
|
||||
@ -273,7 +273,7 @@ func (svr *Service) getProxyStatsByType(proxyType string) (proxyInfos []*ProxySt
|
||||
// Get proxy info by name.
|
||||
type GetProxyStatsResp struct {
|
||||
Name string `json:"name"`
|
||||
Conf interface{} `json:"conf"`
|
||||
Conf any `json:"conf"`
|
||||
TodayTrafficIn int64 `json:"todayTrafficIn"`
|
||||
TodayTrafficOut int64 `json:"todayTrafficOut"`
|
||||
CurConns int64 `json:"curConns"`
|
||||
|
@ -17,8 +17,7 @@ package proxy
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/fatedier/golib/errors"
|
||||
"sync"
|
||||
|
||||
v1 "github.com/fatedier/frp/pkg/config/v1"
|
||||
"github.com/fatedier/frp/pkg/msg"
|
||||
@ -33,6 +32,7 @@ type XTCPProxy struct {
|
||||
cfg *v1.XTCPProxyConfig
|
||||
|
||||
closeCh chan struct{}
|
||||
closeOnce sync.Once
|
||||
}
|
||||
|
||||
func NewXTCPProxy(baseProxy *BaseProxy) Proxy {
|
||||
@ -43,6 +43,7 @@ func NewXTCPProxy(baseProxy *BaseProxy) Proxy {
|
||||
return &XTCPProxy{
|
||||
BaseProxy: baseProxy,
|
||||
cfg: unwrapped,
|
||||
closeCh: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,9 +88,9 @@ func (pxy *XTCPProxy) Run() (remoteAddr string, err error) {
|
||||
}
|
||||
|
||||
func (pxy *XTCPProxy) Close() {
|
||||
pxy.closeOnce.Do(func() {
|
||||
pxy.BaseProxy.Close()
|
||||
pxy.rc.NatHoleController.CloseClient(pxy.GetName())
|
||||
_ = errors.PanicToError(func() {
|
||||
close(pxy.closeCh)
|
||||
})
|
||||
}
|
||||
|
@ -386,24 +386,30 @@ func (svr *Service) Run(ctx context.Context) {
|
||||
func (svr *Service) Close() error {
|
||||
if svr.kcpListener != nil {
|
||||
svr.kcpListener.Close()
|
||||
svr.kcpListener = nil
|
||||
}
|
||||
if svr.quicListener != nil {
|
||||
svr.quicListener.Close()
|
||||
svr.quicListener = nil
|
||||
}
|
||||
if svr.websocketListener != nil {
|
||||
svr.websocketListener.Close()
|
||||
svr.websocketListener = nil
|
||||
}
|
||||
if svr.tlsListener != nil {
|
||||
svr.tlsListener.Close()
|
||||
svr.tlsConfig = nil
|
||||
}
|
||||
if svr.sshTunnelListener != nil {
|
||||
svr.sshTunnelListener.Close()
|
||||
}
|
||||
if svr.listener != nil {
|
||||
svr.listener.Close()
|
||||
svr.listener = nil
|
||||
}
|
||||
if svr.webServer != nil {
|
||||
svr.webServer.Close()
|
||||
}
|
||||
if svr.sshTunnelGateway != nil {
|
||||
svr.sshTunnelGateway.Close()
|
||||
}
|
||||
svr.rc.Close()
|
||||
svr.muxer.Close()
|
||||
svr.ctlManager.Close()
|
||||
if svr.cancel != nil {
|
||||
svr.cancel()
|
||||
|
@ -5,75 +5,75 @@ import (
|
||||
)
|
||||
|
||||
// ExpectEqual expects the specified two are the same, otherwise an exception raises
|
||||
func ExpectEqual(actual interface{}, extra interface{}, explain ...interface{}) {
|
||||
func ExpectEqual(actual any, extra any, explain ...any) {
|
||||
gomega.ExpectWithOffset(1, actual).To(gomega.Equal(extra), explain...)
|
||||
}
|
||||
|
||||
// ExpectEqualValues expects the specified two are the same, it not strict about type
|
||||
func ExpectEqualValues(actual interface{}, extra interface{}, explain ...interface{}) {
|
||||
func ExpectEqualValues(actual any, extra any, explain ...any) {
|
||||
gomega.ExpectWithOffset(1, actual).To(gomega.BeEquivalentTo(extra), explain...)
|
||||
}
|
||||
|
||||
func ExpectEqualValuesWithOffset(offset int, actual interface{}, extra interface{}, explain ...interface{}) {
|
||||
func ExpectEqualValuesWithOffset(offset int, actual any, extra any, explain ...any) {
|
||||
gomega.ExpectWithOffset(1+offset, actual).To(gomega.BeEquivalentTo(extra), explain...)
|
||||
}
|
||||
|
||||
// ExpectNotEqual expects the specified two are not the same, otherwise an exception raises
|
||||
func ExpectNotEqual(actual interface{}, extra interface{}, explain ...interface{}) {
|
||||
func ExpectNotEqual(actual any, extra any, explain ...any) {
|
||||
gomega.ExpectWithOffset(1, actual).NotTo(gomega.Equal(extra), explain...)
|
||||
}
|
||||
|
||||
// ExpectError expects an error happens, otherwise an exception raises
|
||||
func ExpectError(err error, explain ...interface{}) {
|
||||
func ExpectError(err error, explain ...any) {
|
||||
gomega.ExpectWithOffset(1, err).To(gomega.HaveOccurred(), explain...)
|
||||
}
|
||||
|
||||
func ExpectErrorWithOffset(offset int, err error, explain ...interface{}) {
|
||||
func ExpectErrorWithOffset(offset int, err error, explain ...any) {
|
||||
gomega.ExpectWithOffset(1+offset, err).To(gomega.HaveOccurred(), explain...)
|
||||
}
|
||||
|
||||
// ExpectNoError checks if "err" is set, and if so, fails assertion while logging the error.
|
||||
func ExpectNoError(err error, explain ...interface{}) {
|
||||
func ExpectNoError(err error, explain ...any) {
|
||||
ExpectNoErrorWithOffset(1, err, explain...)
|
||||
}
|
||||
|
||||
// ExpectNoErrorWithOffset checks if "err" is set, and if so, fails assertion while logging the error at "offset" levels above its caller
|
||||
// (for example, for call chain f -> g -> ExpectNoErrorWithOffset(1, ...) error would be logged for "f").
|
||||
func ExpectNoErrorWithOffset(offset int, err error, explain ...interface{}) {
|
||||
func ExpectNoErrorWithOffset(offset int, err error, explain ...any) {
|
||||
gomega.ExpectWithOffset(1+offset, err).NotTo(gomega.HaveOccurred(), explain...)
|
||||
}
|
||||
|
||||
func ExpectContainSubstring(actual, substr string, explain ...interface{}) {
|
||||
func ExpectContainSubstring(actual, substr string, explain ...any) {
|
||||
gomega.ExpectWithOffset(1, actual).To(gomega.ContainSubstring(substr), explain...)
|
||||
}
|
||||
|
||||
// ExpectConsistOf expects actual contains precisely the extra elements. The ordering of the elements does not matter.
|
||||
func ExpectConsistOf(actual interface{}, extra interface{}, explain ...interface{}) {
|
||||
func ExpectConsistOf(actual any, extra any, explain ...any) {
|
||||
gomega.ExpectWithOffset(1, actual).To(gomega.ConsistOf(extra), explain...)
|
||||
}
|
||||
|
||||
func ExpectContainElements(actual interface{}, extra interface{}, explain ...interface{}) {
|
||||
func ExpectContainElements(actual any, extra any, explain ...any) {
|
||||
gomega.ExpectWithOffset(1, actual).To(gomega.ContainElements(extra), explain...)
|
||||
}
|
||||
|
||||
func ExpectNotContainElements(actual interface{}, extra interface{}, explain ...interface{}) {
|
||||
func ExpectNotContainElements(actual any, extra any, explain ...any) {
|
||||
gomega.ExpectWithOffset(1, actual).NotTo(gomega.ContainElements(extra), explain...)
|
||||
}
|
||||
|
||||
// ExpectHaveKey expects the actual map has the key in the keyset
|
||||
func ExpectHaveKey(actual interface{}, key interface{}, explain ...interface{}) {
|
||||
func ExpectHaveKey(actual any, key any, explain ...any) {
|
||||
gomega.ExpectWithOffset(1, actual).To(gomega.HaveKey(key), explain...)
|
||||
}
|
||||
|
||||
// ExpectEmpty expects actual is empty
|
||||
func ExpectEmpty(actual interface{}, explain ...interface{}) {
|
||||
func ExpectEmpty(actual any, explain ...any) {
|
||||
gomega.ExpectWithOffset(1, actual).To(gomega.BeEmpty(), explain...)
|
||||
}
|
||||
|
||||
func ExpectTrue(actual interface{}, explain ...interface{}) {
|
||||
func ExpectTrue(actual any, explain ...any) {
|
||||
gomega.ExpectWithOffset(1, actual).Should(gomega.BeTrue(), explain...)
|
||||
}
|
||||
|
||||
func ExpectTrueWithOffset(offset int, actual interface{}, explain ...interface{}) {
|
||||
func ExpectTrueWithOffset(offset int, actual any, explain ...any) {
|
||||
gomega.ExpectWithOffset(1+offset, actual).Should(gomega.BeTrue(), explain...)
|
||||
}
|
||||
|
@ -11,18 +11,18 @@ func nowStamp() string {
|
||||
return time.Now().Format(time.StampMilli)
|
||||
}
|
||||
|
||||
func log(level string, format string, args ...interface{}) {
|
||||
func log(level string, format string, args ...any) {
|
||||
fmt.Fprintf(ginkgo.GinkgoWriter, nowStamp()+": "+level+": "+format+"\n", args...)
|
||||
}
|
||||
|
||||
// Logf logs the info.
|
||||
func Logf(format string, args ...interface{}) {
|
||||
func Logf(format string, args ...any) {
|
||||
log("INFO", format, args...)
|
||||
}
|
||||
|
||||
// Failf logs the fail info, including a stack trace starts with its direct caller
|
||||
// (for example, for call chain f -> g -> Failf("foo", ...) error would be logged for "g").
|
||||
func Failf(format string, args ...interface{}) {
|
||||
func Failf(format string, args ...any) {
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
skip := 1
|
||||
ginkgo.Fail(msg, skip)
|
||||
|
@ -67,8 +67,8 @@ func (m *MockServers) Close() {
|
||||
os.Remove(m.udsEchoServer.BindAddr())
|
||||
}
|
||||
|
||||
func (m *MockServers) GetTemplateParams() map[string]interface{} {
|
||||
ret := make(map[string]interface{})
|
||||
func (m *MockServers) GetTemplateParams() map[string]any {
|
||||
ret := make(map[string]any)
|
||||
ret[TCPEchoServerPort] = m.tcpEchoServer.BindPort()
|
||||
ret[UDPEchoServerPort] = m.udpEchoServer.BindPort()
|
||||
ret[UDSEchoServerAddr] = m.udsEchoServer.BindAddr()
|
||||
@ -76,7 +76,7 @@ func (m *MockServers) GetTemplateParams() map[string]interface{} {
|
||||
return ret
|
||||
}
|
||||
|
||||
func (m *MockServers) GetParam(key string) interface{} {
|
||||
func (m *MockServers) GetParam(key string) any {
|
||||
params := m.GetTemplateParams()
|
||||
if v, ok := params[key]; ok {
|
||||
return v
|
||||
|
@ -42,7 +42,7 @@ type RequestExpect struct {
|
||||
f *Framework
|
||||
expectResp []byte
|
||||
expectError bool
|
||||
explain []interface{}
|
||||
explain []any
|
||||
}
|
||||
|
||||
func NewRequestExpect(f *Framework) *RequestExpect {
|
||||
@ -51,7 +51,7 @@ func NewRequestExpect(f *Framework) *RequestExpect {
|
||||
f: f,
|
||||
expectResp: []byte(consts.TestString),
|
||||
expectError: false,
|
||||
explain: make([]interface{}, 0),
|
||||
explain: make([]any, 0),
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,7 +94,7 @@ func (e *RequestExpect) ExpectError(expectErr bool) *RequestExpect {
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *RequestExpect) Explain(explain ...interface{}) *RequestExpect {
|
||||
func (e *RequestExpect) Explain(explain ...any) *RequestExpect {
|
||||
e.explain = explain
|
||||
return e
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
type="textarea"
|
||||
autosize
|
||||
v-model="textarea"
|
||||
placeholder="frpc configrue file, can not be empty..."
|
||||
placeholder="frpc configure file, can not be empty..."
|
||||
></el-input>
|
||||
</div>
|
||||
</template>
|
||||
|
Loading…
x
Reference in New Issue
Block a user